2017-01-10 12 views
0

Просьба сообщить мне. Я хотел бы сделать код получения данных из последовательного порта, такого как tty/USB0. Итак, необходимо, чтобы этот код считывал данные из последовательного протокола, как показано ниже.Почему не удается получить данные из «read» в массив uint8_t?

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; 
} 

Однако я не понимаю, почему эти линии, показывающие ниже не работают, но встречающаяся ошибку «следующим образом: неверный аргумент»

Как получить данные массива из функции чтения?

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; 
} 

enter image description here

Этот код показывает ниже моей реализации функции.

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; 
  
} 

термическое урегулирование здесь.

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; 
} 
+0

Возможно, 'serial_fd' недопустим. – user2079303

+0

Можете рассказать мне больше, как это неправильно? serial_fd получен из open_serial ("/ dev/ttyUSB0", 115200) основной функции. – NEWBIEEBIEE

+0

Я не знаю о 'open_serial'. Это вещь с малиной? Вы проверили возвращаемое значение, чтобы убедиться, что это удалось? – user2079303

ответ

1

Код, который производит на "ошибку" является:

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.) Первый вопрос синтаксиса С.
recData является адресом массива, а в чтения() и Х() вызовов, адрес этого адреса передаются в качестве второго аргумента.
Неверный адрес-адрес адреса массива.

2.) Второй вопрос - это оценка возвращаемого значения.
На странице руководства описаны возможные возвращаемые значения системного вызова ().

2a.) переменная errno действительна только в том случае, если возвращаемое значение равно -1.
Однако perror() в вашем коде будет вызываться всякий раз, когда возвращаемое значение не равно количеству байтов массива.
Поэтому сообщение «read: Invalid argument» скорее всего будет фиктивным.

2b.) read() syscall не требуется для удовлетворения аргумента длины запроса.
Ваша конфигурация termios указывает минимальное количество чтения 1 байт.
Так что read() syscall вернется с по меньшей мере одним байтом и будет иметь столько же данных, сколько и в настоящее время, полученных драйвером последовательного порта, до максимальной требуемой длины.
Таким образом, всякий раз, когда полное чтение 1024 байтов не может быть выполнено (что может быть всегда), ваша программа будет прервана с ложной ошибкой.

+0

Спасибо, @sawdust. Я полностью согласен с вашей перспективой. – NEWBIEEBIEE

Смежные вопросы