Home > OS >  Is it possible to increase the data reception size with RS-232?
Is it possible to increase the data reception size with RS-232?

Time:03-10

I am working with this RS-232 implementation: https://www.teuniz.net/RS-232/ on Windows operating system. I wrote a code in C, where one reads the input file and forwards it to the other participant. However, according to this implementation, I can load a maximum of 4096 bytes of data into the OS. Is it possible to increase this number? Because, for example, I sent a file with a size of 5MB and it took about 90 minutes at 9600 baud, but I do not want to increase baud

This is code for sender:

#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <math.h>

#ifdef _WIN32
#include <Windows.h>
#else
#include <unistd.h>
#endif

// RS232 library
#include "rs232.h"

// Maximum size of data in block
#define INTERNALL_BUFFER 20480

// Size of static array
#define STATIC_ARRAY 1024

int main(int argc, char *argv[])
{
    // Checking, if was the correct program parameters have been entered
    if (argc < 2)
    {
        fprintf(stderr, "\nIt was the incorrect program parameters have been entered\n");
        fprintf(stderr, "Usage: test_tx file.suffix\n");
        return 1;
    }

    FILE *stream;

    int cport_nr = 0,        /* /dev/ttyS0 (COM1 on windows) */
        bdrate = 9600,       /* 9600 baud */
        k = 1, fileSize = 0, /* k = counting, fileSize is size of data */
        true_count = 0, again = 0,
        sent_bytes = 0, begin = 0, last_block = 0,
        sent_size = INTERNALL_BUFFER; /* Maximum transfer size in block is sent_size */

    unsigned char convert[STATIC_ARRAY], *contents;

    // 8N1 means eight databits, no parity, one stopbit
    // If flowctrl is set to 0, no flow control is used
    char mode[] = {'8', 'N', '1', 0};

    size_t size;

    // Open file from CLI, find the size of it
    stream = fopen(argv[1], "rb");
    fseek(stream, 0L, SEEK_END);
    fileSize = ftell(stream);
    fseek(stream, 0L, SEEK_SET);

    // Allocate space for the entire file content
    contents = (unsigned char *)malloc(fileSize   1);

    // Check if the memory has been successfully
    // allocated by malloc or not
    if (contents == NULL)
    {
        printf("Memory not allocated.\n");
        exit(0);
    }

    // Stream file into memory
    size = fread(contents, 1, fileSize, stream);
    contents[size] = 0;
    fclose(stream);

    // Counting the number of blocks
    float count_blocks = fileSize / (float)INTERNALL_BUFFER;
    count_blocks = ceil(count_blocks);
    fprintf(stdout, "\nThe count of blocks sent will be: %.0f", count_blocks);

    // Opens the comport
    if (RS232_OpenComport(cport_nr, bdrate, mode, 0))
    {
        printf("Can not open comport\n");
        return (0);
    }

    //////Je mozne upravit prijem a odosielanie dat do funkcii/funkcie...

    // Convert int to char and send size
    sprintf((char *)convert, "%d", fileSize);
    printf("\nSize of data is: %d\n", fileSize);
    int annouc = RS232_SendBuf(cport_nr, convert, STATIC_ARRAY);
    if (annouc > 0)
        printf("\nThe size of the transmitted data was sent\n");

#ifdef _WIN32
    Sleep(5000);
#else
    usleep(1000000);     /* sleep for  1 Seconds */
#endif

    printf("\n");

    while (1)
    {
        int finish = 0;
        // If transmission will be repetead
        if (again)
        {
            begin = 0;
            again--;
        }

        // If the size of the data being sent is less than INTERNALL_BUFFER
        if (fileSize < sent_size)
            sent_size = fileSize;
        // Sends multiple bytes via the serial port
        sent_bytes = RS232_SendBuf(cport_nr, contents   begin, sent_size);
        if (sent_bytes < 0)
        {
            printf("Failed to send data\n");
            printf("Closed sending data and comport\n");
            break;
        }
        //  printf("%d.Sending: %d bytes.\n %.*s\n", k  , sent_bytes, sent_bytes,contents   begin);
        printf("%d.Sending: %d bytes\n", k  , sent_bytes);
        true_count  ;
        begin  = sent_bytes;

#ifdef _WIN32
        Sleep(3000);
#else
        usleep(1000000); /* sleep for  1 Seconds */
#endif
        int help_block = true_count;
        // If we want to send last less data than size of INTERNAL BUFFER
        if (  help_block == count_blocks)
            last_block  ;
        if ((begin % sent_size == 0) && (last_block) && (begin != fileSize))
            sent_size = fileSize - begin;

        // Checking if sending data was successful or no
        while (begin == fileSize && true_count == (int)count_blocks)
        {
            int n = 0, result = 100;
            unsigned char buf[STATIC_ARRAY];
            n = RS232_PollComport(cport_nr, buf, STATIC_ARRAY);
            if (n > 0)
            {
                printf("\nReceiving: %d bytes\n%.*s\n", n, n, (char *)buf);
                result = memcmp(buf, "Sending of data was successful :)\n", n);
            }

            if (result == 0)
            {
                finish  ;
                memset(buf, 0, n);
                break;
            }
            else if (result != 100)
            {
                memset(buf, 0, n);
                again  ;
            }
        }

        if (finish)
            break;
    }

    printf("Finish...\n");
    printf("Closed RS232...\n");

    // Free memory aloccated
    free(contents);
    // Closes the serial port
    RS232_CloseComport(cport_nr);
    return 0;
}

The sender reads the input file, finds its size, sends the expected size to the other party and goes to send the file to the other party, knows how big the file is and follows accordingly. The problem is that the data transfer takes a very long time and the second thing that bothers me is that I want to send data, but the recipient must be able to process all the received data in blocks, I do not want data loss. If I increase the time for sleep, sending data passes without loss, but the sending time is, in my opinion, very long

CodePudding user response:

RS-232 is a bit-oriented transport and as such 9600 baud defines the number of bits you can send a second. Changing the buffering (4k in your example) will not impact the transmission speed; only how often the buffer needs to be replenished or flushed.

CodePudding user response:

As pointed out in other answers and many comments, it does not help reduce communication time, which may be your real purpose, but you can change the receive (and send) buffer size.

It may be possible to achieve this by using this function of Win32API.
SetupComm function (winbase.h)

[in] dwInQueue
The recommended size of the device's internal input buffer, in bytes.

[in] dwOutQueue
The recommended size of the device's internal output buffer, in bytes.

There will be information in this function and the structure it informs about how big the buffer is actually.
GetCommProperties function (winbase.h)
COMMPROP structure (winbase.h)

dwMaxRxQueue
The maximum size of the driver's internal input buffer, in bytes. A value of zero indicates that no maximum value is imposed by the serial provider.

However, as explained above, some device drivers may not have a buffer size setting function.

It may not be a good example, but the .NET SerialPort class allows you to set buffers from 4096 to 2G bytes (perhaps with a buffer inside the .NET class instance instead of the device driver?).
SerialPort.ReadBufferSize Property

The buffer size, in bytes. The default value is 4096; the maximum value is that of a positive int, or 2147483647.


By the way, although the title of the article says reception size, the description of the article and the source code presented only send it.
Which function or buffer size do you need to set after all?

  • Related