请告诉我。 我想让代码从串口获取数据,如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;
}
但是我没理解为什么下面显示的这些行不起作用,但发生错误“读取:无效参数”
如何从读取功能获取数组数据?
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 :(得分:1)
产生“错误”的代码是:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_FILE=%~dp0system.cfg" & rem // (path/name of file to process)
set "_KEY[1]=1_IP" & rem // (1st key to search for)
set "_KEY[2]=2_IP" & rem // (2nd key to search for)
set "_VAL[1]=10.101.34.214" & rem // (1st value to assign to 1st key)
set "_VAL[2]=10.101.34.216" & rem // (2nd value to assign to 2nd key)
rem // Read specified file and iterate through all lines, preceded by line number:
for /F "delims=" %%L in ('findstr /N "^" "%_FILE%" ^& ^> "%_FILE%" rem/') do (
rem // Write (append) to the specified file:
>> "%_FILE%" (
rem // Split line number plus key from value (key must not contain spaces):
for /F "delims== " %%K in ("%%L") do (
rem // Store extracted key and full line, both including line numbers:
set "KEY=%%K" & set "LINE=%%L"
setlocal EnableDelayedExpansion
rem // Clear flag, remove line number from key:
set "FLAG=" & set "KEY=!KEY:*:=!"
rem // Loop through all available keys:
for /F "tokens=2 delims=[]=" %%M in ('2^> nul set _KEY[') do (
rem /* If key is a predefined one return respective value;
rem otherwise set flag to indicate key has been found: */
if /I "!KEY!"=="!_KEY[%%M]!%" (
echo(!KEY! = "!_VAL[%%M]!"
set "FLAG=#"
)
)
rem // Return current line unedited in case flag is not set:
if not defined FLAG echo(!LINE:*:=!
endlocal
)
)
)
endlocal
exit /B
1。)第一个问题是C语法 recData 是数组的地址,在 read()和 printf()调用中,此地址的地址作为第二个论点 数组地址的操作地址不正确。
2。)第二个问题是评估返回值 手册页描述了 read()系统调用的可能返回值。
2a。) errno 变量仅在返回值为-1时有效
但是,只要返回值不等于数组的字节数,就会调用代码中的 perror()。
因此,“读取:无效参数”消息可能是虚假的。
2b。) read()系统调用不需要满足请求的长度参数。
您的termios配置指定最小读取1个字节
因此, read()系统调用将返回至少一个字节,并且只返回串行端口驱动程序当前接收的数据,超过所请求长度的最大值。
因此,无论何时无法完成1024字节的完全读取(可能总是如此),您的程序将因伪造错误而中止。