0

I'm going to write a command consisting of a hexadecimal arrangement through UART and read it.

In the process, as the number of commands to write increases, they do not read in each arrangement when reading, but fly along to the buffer allocation size.

For example)

The Read value I want (Printf):

a5 01 90 08 01 21 00 00 75 30 03 e4 ec

a5 01 91 08 10 2d 07 10 27 03 03 e4 a4

a5 01 92 08 42 01 42 01 27 03 03 e4 d7

Output value (printf):

a501900801210000753003e4eca5019108102d07102703 
03e4a4a501920842014201270303e4d7

When analyzing the code, it seems that write is done several things at once before Read and stored in the Read buffer as a lump, but I don't know how to solve it.

How can I cut and print it according to the read arrangement at the time of writing 1? Currently, it is simply testing with print, but since we have to send it to the server in the future, we printed it out as a data3 variable using printf. (I have to fly it on Payload)

The code currently being written is as follows, and only three of the 10 write variables have been put in for a simple test. It may be a basic question because I am not good at it, but I ask for your help.

#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <time.h>
#include <pthread.h>

int main(void)
{
    int fd;
    fd=open("/dev/ttyHSL6", O_RDWR|O_NOCTTY );
    struct termios newtio;

    unsigned char buffer[40]={0};
    int bytes_read=0;
    char data[40];
    char *data3;
    int i=0;
    if (fd == -1)
    {
        printf("Error! in opening port");
        exit(-100);
    }

    memset(&newtio, 0, sizeof(struct termios));
    newtio.c_cflag = B9600 | CS8 | CLOCAL | CREAD;

    newtio.c_iflag = IGNPAR;

    newtio.c_oflag = 0;
    newtio.c_lflag = 0;
    newtio.c_cc[VTIME] = 0;
    newtio.c_cc[VMIN] = 1;
    tcflush(fd, TCIFLUSH);
    tcsetattr(fd, TCSANOW, &newtio);
    unsigned char str[13] = {0xA5,0x80,0x95,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC2};
    unsigned char str1[13] = {0xA5,0x80,0x90,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBD};
    unsigned char str2[13] = {0xA5,0x80,0x91,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBE};

    while(1){
        data3=malloc(sizeof(char)*100);
        memset(buffer, 0, sizeof(buffer));
        strcpy(data3,data);
        for(i=0;i<10;i++){
            switch(i){
                case 1:
                    write(fd, str, sizeof(str)/sizeof(str[0]));
                    usleep(100000);
                    break;
                case 2:
                    write(fd, str1, sizeof(str1)/sizeof(str1[0]));
                    usleep(100000);
                    break;
                case 3:
                    write(fd, str2, sizeof(str2)/sizeof(str2[0]));
                    usleep(100000);
                    break;
            }



            bytes_read = read(fd, buffer, sizeof(buffer)/sizeof(buffer[0]));
            sprintf(data,"%02x",buffer[0]);
            
            if (bytes_read > 0)
            {
                buffer[bytes_read]=0;
                for (int j=1; j< sizeof(buffer)/sizeof(buffer[0]); j++)        
                {
                    sprintf(data,"%02x",buffer[j]);
                    strcat(data3,data);
                }
                sprintf(data3,"\n");
                printf("%s\n",data3);   
            }

        }
    }
    close(fd);
    return 0;
}


(Currently, no value is being printed out when this code is executed)

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • Why does this post resemble those by @youna such as https://stackoverflow.com/questions/69355133/how-to-communicate-uart-in-hexadecimal-arrangements-c-language with the same data and code constructs? Now that you're focusing on reading, that improper termios setup needs fixing. See my comment in https://stackoverflow.com/questions/69309976/uart-communication-in-c-language-hex – sawdust Oct 07 '21 at 18:41
  • Does this answer your question? [UART Communication In C language (Hex)](https://stackoverflow.com/questions/69309976/uart-communication-in-c-language-hex) – Adrian Mole Oct 11 '21 at 08:25

1 Answers1

0

The for loop starts with i = 0.

The switch writes data to the port only if i = 1 or i = 2 or i = 3.

My guess is the line read(fd, buffer, sizeof(buffer)/sizeof(buffer[0])); is blocked (waiting for someone to write something). Because you don't write anything the first time.

Have in mind that with blocking IO readers will block until a writers writes something (unless there are timeouts involved). You could try to use non blocking IO (see O_NONBLOCK) if you want.

BTW, this code:

            buffer[bytes_read]=0;
            for (int j=1; j< sizeof(buffer)/sizeof(buffer[0]); j++)        
            {
                sprintf(data,"%02x",buffer[j]);
                strcat(data3,data);
            }

Will end up printing a bunch of zeros the first time, and maybe some data from a previous messages the following times. You should stop the for in bytes_read.

Finally, if your unsigned char is 1 byte long (which is in most platforms), you can bypass the division and just use sizeof(buffer).

ichramm
  • 6,437
  • 19
  • 30
  • Thank you for your answer. Referring to the advice, nothing is being printed even though i in the switch statement has been changed to start with 1. As you said, I think we need to revise the read part. How can I modify it if I want to read and print out each written part? I can't get the hang of it. I'm sorry I'm a beginner. – blackcatTan Oct 19 '21 at 03:22