Почему нельзя получить данные от & quot; чтения & Quot; в массив uint8_t?

Пожалуйста, посоветуй мне.
Я хотел бы, чтобы код получал данные из последовательного порта, такого как tty / USB0.
Поэтому необходимо, чтобы этот код считывал данные из последовательного протокола, как показано ниже.

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

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

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

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

введите описание изображения здесь

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

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

Решение

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

    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.) Второй вопрос — оценка возвращаемого значения.
Страница man описывает возможные возвращаемые значения читать() Системный вызов.

2а.) ERRNO Переменная действительна только когда возвращаемое значение -1.
тем не мение PError () в вашем коде будет вызываться всякий раз, когда возвращаемое значение не равно количеству байтов массива.
Поэтому сообщение «прочитано: неверный аргумент» может быть поддельным.

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

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]