Home > other >  Read() in C but without waiting for EOF character
Read() in C but without waiting for EOF character

Time:08-10

I am doing some embedded programming using Python for the PC side and C for a controller side. Serial reading in python is easy in a sense that you can read a certain amount of bytes, but I am having ,,problems,, with reading in C. Is it possible to read, for example 5 bytes, without waiting for the 'EOL' character('\n' or 0x0a)? For now, I am adding '\n' at the end of every buffer transmitted from PC to controller but I would like to get rid of that since there is around 1 in 255 chance of failing the transmission (for every byte sent) if byte gets the value b'\x0a' and I always know the number of bytes I should expect from the value of the first byte. Thanks in advance everyone :-)

this is a part of the function

void recv(int port){          //function to receive buffer
//we are gonna receive a message and since this is an echo type of program we will signal
//signal thread to loop it back around
printf("Opened connection on port:%d \n",port);
while(1){
    if(stop){
        break;
    }
    //values are simulated with rand(), there is 10% movement to fall out of range
    voltage=rand_value(VOLTAGE_MIN-100000,VOLTAGE_MAX 100000);
    current=rand_value(CURRENT_MIN-100000,CURRENT_MAX 100000);
    temperature=rand_value(TEMP_MIN-30,TEMP_MAX 30);

    int nread;
    ioctl(port, FIONREAD, &nread);
    if (nread > 0) {
        memset(buf,0,sizeof(buf));
        int n=read(port,&buf,nread);  //blocking operation, it waits for "\n"
        /* for(int i=0; i<BUF_LEN; i  ){
            //printf("Msg received: %s",buf);
            printf("buf index %d, data 0x%x \n", i, buf[i]);
        } */
        req=buf[0];                     //here we have command ID   data ID
                                        //                2bit        6bit
        printf("Bytes received: %d, req= 0x%x\n",n,req);    //prints the register and count of data received (always gets one above the actual data!)
        switch (((req&0b11000000)>>6)){     //SWITCHES COMMAND ID-S

this is opening the port in main

   int port=open("/dev/ttyPS1",O_RDWR);

in between these 2 goes termios setup

    recv(port);

so even tho i use number of available bytes it completely ignores that and waits for the 0x0a value

CodePudding user response:

You can use the read system call (or fread for FILE*).

Usage with file descriptor:

int fd = STDIN_FILENO; // or your stream
int max_len = 10;
char buffer[max_len];
int actual_len = read(fd, buffer, max_len);
if (actual_len < 0) {
    exit(1); // error
}

Usage with FILE*:

FILE* file = stdin; // or your stream
int max_len = 10;
char buffer[max_len];
int actual_len = fread(file, buffer, max_len);
if (actual_len < 0) {
    exit(1); // error
}

The read systemcall reads up to n bytes into a buffer and returnes the number it could read. So if your stream has "hello" (without null terminator) as content, it will return 5.

And also I think you missunerstood EOF. EOF isn't actually a transmitted byte, it is a placeholder for stdio to signal that no more bytes were availible. Depending on the settings of the stream it can happen that you never get a EOF and the process just blocks until the stream is closed.

CodePudding user response:

So from thinking about things people said in the comments and reading a recommended question this post about buffer reading I made it work pretty much as I was trying for days

I used this time flags where BUF_LEN is defined constant of the max possible buffer received What I don't like about this solution is that it is load depended but it is what it is.

    tty.c_cc[VTIME] = 2;    // Wait for up to 0.2s (2 deciseconds), returning as soon as any data is received.
    tty.c_cc[VMIN] = BUF_LEN;

This is how communication in terminals looks like

  • Related