[英]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字节的完全读取时(很可能总是这样),您的程序就会因虚假错误而中止。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.