简体   繁体   English

为什么不能从“读取”到uint8_t数组中获取数据?

[英]Why can not get data from “ read” into uint8_t array?

Please advise me. 请建议我。 I would like to make the code get data from serial port such as tty/USB0. 我想让代码从tty / USB0等串行端口获取数据。 So,need to make this code read the data from serial protocol as showing below. 因此,需要使该代码从串行协议读取数据,如下所示。

uint8_t recBlk; // receive blk from chunk
ret = read(serial_fd, &recBlk, sizeof(recBlk));
printf("Block Num is %d\n", recBlk);
fflush(stdout);
if (ret != sizeof(recBlk)) {
    perror("read");
    return -errno;
}

However I didn't get it why this lines showing below is not working,but occuring error "read: invalid argument" 但是我不明白为什么下面显示的这行不起作用,但是发生错误“ read:invalid arguments”

How do I get array data from read function? 如何从读取功能获取数组数据?

uint8_t recData[1024]; // receive data from chunk
ret = read(serial_fd, (void *)&recData, sizeof(recData));
    printf("Data buffer is %c\n", &recData);
    fflush(stdout);
if (ret != sizeof(recData)) {
     printf("Can't fetch the Data length!");
     perror("read");
     return -errno;
}

在此处输入图片说明

This code showing below is my implementing function. 下面显示的代码是我的实现功能。

static int xmodem_receive(int serial_fd, char* filename, int _crc, int use_crc){
    int skip = 0;
    uint8_t sdCRC = 'C'; // Request-To-Send
    uint8_t sdACK = X_ACK; //
    uint8_t eof = X_EOF;
    uint8_t sdNAK = X_NAK;
    uint8_t recSTX; // receive SOH from chunk
    uint8_t recBlk; // receive blk from chunk
    uint8_t recNegBlk; // receive blk negative from chunk
    uint8_t recData[1024]; // receive data from chunk
    uint16_t recChksum;
 
    uint8_t expected_blkno;
 
    FILE *fp;
    int ret, fd;
    struct stat stat;
    // If we want to receive, We have to send NAK to Sendor.
 
    if (use_crc)
        use_crc = MAX_RETRY + 1;
 
        /* Writing as binary */
    fp = fopen(filename, "wb");
    //Send NAK still read SOH that header of one data chunks
    /*
    CRC 16
    Sending C
    Sending NAK
 
    */
    while(use_crc){
        char status;
        printf("Waiting for sender ping ...");
        fflush(stdout);
        //
        if(_crc){
            printf("Send C ping....\n");
            ret = write(serial_fd, &sdCRC, sizeof(sdCRC));
        }else{
            // send NAK before read SOH
            printf("Send NAK ping....\n");
            ret = write(serial_fd, &sdNAK, sizeof(sdNAK));
        }    // after sending NAK,receiving SOH from chunk
        fflush(stdout);
        ret = read(serial_fd, &recSTX, sizeof(recSTX));
 
 
        if(recSTX == X_STX){
            printf("STX is %c\n", &recSTX);
            break;
        }else{
            printf("Garabage payload %c\n", &recSTX);
        }
        fflush(stdout);
        if (ret != sizeof(recSTX)) {
                printf("Not working");
                fflush(stdout);
                perror("read");
                return -errno;
        }
        use_crc--;
    }
 
    expected_blkno = 1;
 
    while(ret != EOF){
        //So next, receiving blk
        ret = read(serial_fd, &recBlk, sizeof(recBlk));
        printf("Block Num is %d\n", recBlk);
        fflush(stdout);
        if (ret != sizeof(recBlk)) {
            perror("read");
            return -errno;
        }
        ret = read(serial_fd, &recNegBlk, sizeof(recNegBlk));
        printf("Negative Block Num is %d\n", recNegBlk);
        fflush(stdout);
        if (ret != sizeof(recNegBlk)) {
            perror("read");
            return -errno;
        }
        ret = read(serial_fd, (void *)&recData, sizeof(recData));
        printf("Data buffer is %c\n", &recData);
        fflush(stdout);
        if (ret != sizeof(recData)) {
            printf("Can't fetch the Data length!");
            perror("read");
            return -errno;
        }
        ret = read(serial_fd, &recChksum, sizeof(recChksum));
        printf("Check sum is %c", &recChksum);
        fflush(stdout);
        if (ret != sizeof(recChksum)) {
            printf("Can't fetch the Check sum");
            perror("read");
            return -errno;
        }
        // data block number check
        if(recBlk == 0xff - recNegBlk){
            printf("Can't fetch the Block !");
            perror("read");
 
            return -errno;
        }
        // data integrity check
        if(recChksum == swap16(crc16(recData, sizeof(recData)))){
            perror("read");
            return -errno;
        }
        // check of appended "0xff" from end of data to  end of chunk in chunk
        unsigned char *ptr = recData;
        ptr += sizeof(recData);
        while(*ptr == 0xff){
            ptr--;
        }
        fwrite(recData, (ptr - recData),1,fp); // write Datas bytes from our buffer
        // set skip flag or end connect
        ret = write(serial_fd, &eof, sizeof(uint8_t));
        if (ret != sizeof(eof) || ret != sizeof(X_STX)){
            return -errno;
        }else{
            if(ret == X_STX){
                skip = 1;
                printf("next chunk");
                fflush(stdout);
                expected_blkno++;
            }else if(ret == EOF){
                printf("EOF ...");
                ret = write(serial_fd, &sdACK, sizeof(sdACK));
                break;
            }else{
                return -errno;
            }
        }
 
    }
    printf("done.\n");
    fclose(fp);
    return 0;
 
}

termous setting is here. 此处是高级设置。

static int open_serial(const char *path, int baud)
{
        int fd;
        struct termios tty;

        fd = open(path, O_RDWR | O_SYNC);
        if (fd < 0) {
                perror("open");
                return -errno;
        }

        memset(&tty, 0, sizeof(tty));
        if (tcgetattr(fd, &tty) != 0) {
                perror("tcgetattr");
                return -errno;
        }

        cfsetospeed(&tty, baud);
        cfsetispeed(&tty, baud);

        tty.c_cflag = (tty.c_cflag & ~CSIZE) | CS8;     // 8-bit chars
        tty.c_iflag &= ~IGNBRK;                         // disable break processing
        tty.c_lflag = 0;                                // no signaling chars, no echo,
                                                        // no canonical processing
        tty.c_oflag = 0;                                // no remapping, no delays
        tty.c_cc[VMIN]  = 1;                            // read doesn't block
        tty.c_cc[VTIME] = 5;                            // 0.5 seconds read timeout

        tty.c_iflag &= ~(IXON | IXOFF | IXANY);         // shut off xon/xoff ctrl

        tty.c_cflag |= (CLOCAL | CREAD);                // ignore modem controls,
                                                        // enable reading
        tty.c_cflag &= ~(PARENB | PARODD);              // shut off parity
        tty.c_cflag &= ~CSTOPB;
        tty.c_cflag &= ~CRTSCTS;

        if (tcsetattr(fd, TCSANOW, &tty) != 0) {
                perror("tcsetattr");
                return -errno;
        }

        return fd;
}

The code that is producing the " error " is: 产生“ 错误 ”的代码是:

    uint8_t recData[1024]; // receive data from chunk
  ...
        ret = read(serial_fd, (void *)&recData, sizeof(recData));
        printf("Data buffer is %c\n", &recData);
        fflush(stdout);
        if (ret != sizeof(recData)) {
            printf("Can't fetch the Data length!");
            perror("read");
            return -errno;
        }

1.) The first issue is C syntax. 1.)第一个问题是C语法。
recData is the address of an array, and in the read() and printf() calls, the address of this address is passed as the second argument. recData是数组的地址,在read()printf()调用中,此地址的地址作为第二个参数传递。
The address-of operation on the array address is incorrect. 阵列地址的地址操作不正确。

2.) The second issue is evaluation of the return value. 2.)第二个问题是对返回值的评估。
The man page describes the possible return values of the read() syscall. 手册页描述了read()系统调用的可能返回值。

2a.) The errno variable is only valid when the return value is -1. 2a。) errno变量仅在返回值为-1时有效。
However perror() in your code would be called whenever the return value is not equal the byte count of an array. 但是,只要返回值不等于数组的字节数,就会在代码中调用perror()
Therefore the "read: Invalid argument" message is likely to be bogus. 因此,“ read:Invalid arguments”消息很可能是伪造的。

2b.) The read() syscall is not required to satisfy the requested length argument. 2b。)不需要read()系统调用来满足请求的length参数。
Your termios configuration specifies a minimum read of 1 byte. 您的termios配置指定至少读取1个字节。
So the read() syscall will return with at least one byte, and only as much data as currently received by the serial port driver, up the maximum of the requested length. 因此, read()系统调用将至少返回一个字节,并且仅返回串行端口驱动程序当前所接收的数据,直到请求的最大长度。
So whenever the full read of 1024 bytes cannot be accomplished (which is likely to be always), your program will abort with a bogus error. 因此,每当无法完成1024字节的完全读取时(很可能总是这样),您的程序就会因虚假错误而中止。

我可以初始化一个 std::array <uint8_t with a string literal?< div><div id="text_translate"><p> 我写了很多 C 代码,使用 UART 串口与仪器交互。 我正在开始一个新项目,我试图在 C++ 中使用更面向 object 的方法。 这是我过去使用 C 定义和发送命令的方式。</p><pre> uint8_t pubx04Cmd[] = "$PUBX,04*37\r\n"; HAL_UART_Transmit(&amp;hUART1, pubx04Cmd, sizeof(pubx04Cmd), 5000);</pre><p> 这非常简单。 C++ std::array具有内置的大小,看起来很有用。 但这是我想出如何做到这一点的唯一方法。</p><pre> const char pubx04CString[] = "$PUBX,04*37\r\n"; std::array&lt;uint8_t, 14&gt; pubx04CPPArray; std::copy(std::begin(pubx04CString), std::end(pubx04CString), pubx04CPPArray.begin()); HAL_UART_Transmit(&amp;hUART1, pubx04CPPArray.data(), pubx04CPPArray.size(), 5000);</pre><p> 与 C 方法相比,这似乎相当笨拙。</p><ul><li><p> 使用std::array是否有更清洁的方法?</p></li><li><p> 在这种情况下使用std::array与 C arrays 有什么真正的好处吗?</p></li></ul></div></uint8_t> - Can I initialize a std::array<uint8_t with a string literal?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从uint8_t数组修改数据非常慢? - Modifing data from uint8_t array very slow? 在 uint8_t 数组中插入() - Insert() in uint8_t array 从 std::stringstream 读取 uint8_t 作为数字类型 - Read uint8_t from std::stringstream as a numeric type 将`uint8_t`(从套接字读取)隐式转换为`char`是否安全? - Is it safe to implicitly convert a `uint8_t` (read from a socket) to a `char`? 从volatile uint8_t *到uint8_t *的无效转换 - invalid conversion from volatile uint8_t* to uint8_t* 从向量中提取 uint8_t* 子集<uint8_t></uint8_t> - Extract uint8_t* subset from a vector<uint8_t> 将数据放入 Arduino 上的 uint8_t 数组 (C/C++) - Getting data into a uint8_t array (C/C++) on Arduino 从 const uint8_t* 转换为 uint8_t* 时出错 - Error in conversion from const uint8_t* to uint8_t* 我可以初始化一个 std::array <uint8_t with a string literal?< div><div id="text_translate"><p> 我写了很多 C 代码,使用 UART 串口与仪器交互。 我正在开始一个新项目,我试图在 C++ 中使用更面向 object 的方法。 这是我过去使用 C 定义和发送命令的方式。</p><pre> uint8_t pubx04Cmd[] = "$PUBX,04*37\r\n"; HAL_UART_Transmit(&amp;hUART1, pubx04Cmd, sizeof(pubx04Cmd), 5000);</pre><p> 这非常简单。 C++ std::array具有内置的大小,看起来很有用。 但这是我想出如何做到这一点的唯一方法。</p><pre> const char pubx04CString[] = "$PUBX,04*37\r\n"; std::array&lt;uint8_t, 14&gt; pubx04CPPArray; std::copy(std::begin(pubx04CString), std::end(pubx04CString), pubx04CPPArray.begin()); HAL_UART_Transmit(&amp;hUART1, pubx04CPPArray.data(), pubx04CPPArray.size(), 5000);</pre><p> 与 C 方法相比,这似乎相当笨拙。</p><ul><li><p> 使用std::array是否有更清洁的方法?</p></li><li><p> 在这种情况下使用std::array与 C arrays 有什么真正的好处吗?</p></li></ul></div></uint8_t> - Can I initialize a std::array<uint8_t with a string literal? 如何在 Java 中声明一个 uint8_t 数组 - How can I declare an uint8_t array in Java
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM