我有一个开发板,它使用USB-Serial适配器连接到我的PC。从电路板上,我发送了8个字节的IEEE mac地址,但由于某种原因,我没有接收到某些字节。
在我的PC上,我有一个守护进程在运行,它监视串行端口,并在终端上打印收到的字符。
由于某种原因,未接收到值0x12 (DC2 (设备控制2))。我知道它是由我的开发板发送的,因为我正在嗅探其中的串行输出,我可以看到发送的是0x12。
我对linux没有足够的经验,但我感觉这可能是我在C代码中初始化串行端口的方式(假设跳过的字符是控制字符)。
我也尝试了发送0x11 (DC1),我可以成功地接收到。
我的代码是
serial_fd serial_open(char* serial_tty_path)
{
//OPEN SERIAL PORT SPECIFIED BY THE ARGUMENT
//AND RETURN HANDLE
int32_t fd = open(serial_tty_path, O_RDONLY | O_NOCTTY);
return (serial_fd)fd;
}
int8_t serial_setup(serial_fd fd, uint32_t serial_baud)
{
//SET THE SPECIFIED SPEED, LENGTH, PARITY NAND STOP BIT
//PARAMETERS FOR THE SUPPLIED SERIAL HANDLE
struct termios serial_settings;
uint32_t baudrate = B9600;
switch(serial_baud)
{
case 2400:
baudrate = B2400;
break;
case 4800:
baudrate = B4800;
break;
case 9600:
baudrate = B9600;
break;
case 115200:
baudrate = B115200;
break;
default:
//invalid baudrate
return -1;
};
tcgetattr(fd, &serial_settings);
//set the same input & output serial speed
cfsetispeed(&serial_settings, baudrate);
cfsetospeed(&serial_settings, baudrate);
//seup serial for 8N1
//no parity
serial_settings.c_cflag &= ~PARENB;
//stop bits = 1
serial_settings.c_cflag &= ~CSTOPB;
//data length = 8
serial_settings.c_cflag &= ~CSIZE;
serial_settings.c_cflag |= CS8;
//set other serial control options
//turn hardware flow control off
serial_settings.c_cflag &= ~CRTSCTS;
//turn software flow control off
serial_settings.c_iflag &= ~(IXON | IXOFF | IXANY);
//turn on the receiver on serial port
serial_settings.c_cflag |= (CREAD | CLOCAL);
//set the serial port mode of operation to NON CANONICAL
//data available to program as soon as it's types
//serial_settings.c_iflag &= ~(ICANON | ECHO | ECHO | ISIG);
//set the minimum character to read from port to 1
serial_settings.c_cc[VMIN] = 1;
//set read timeout to 0.1 second (1 decisecond)
serial_settings.c_cc[VTIME] = 2;
//apply the settings to the serial port
tcsetattr(fd, TCSANOW, &serial_settings);
}
int8_t serial_getc(serial_fd fd, uint8_t* c)
{
//GET ONE CHAR FROM THE SERIAL RX BUFFER
//RETURN -1 ON ERROR
//ASCII CHARACTER RETURNED IN SUPPLIED CHARACTER POINTER
uint8_t d=0;
if(read(fd, &d, 1)<1)
{
perror("msg ");
return -1;
}
*c = d;
if(d == 0x12)
{
printf("hola !\n");
}
return 0;
}
uint8_t serial_readline(serial_fd fd, uint8_t* buffer)
{
//READ INCOMING SERIAL CHARACTERS INTO THE SPECIFIED BUFFER
//TILL LF(\n) RECEIVED
//RETURN : BYTES READ TILL \n (including \n)
uint8_t read_char;
int8_t status;
uint32_t counter = 0;
status = serial_getc(fd, &read_char);
if(status != -1)
{
while(read_char != '\n')
{
buffer[counter] = read_char;
counter++;
while(serial_getc(fd, &read_char) == -1){};
}
buffer[counter] = '\n';
return counter;
}
return 0;
}这是我的主程序
while(1)
{
if((l = serial_readline(serial_handle, &serial_buffer[0])) != 0)
{
//ACTUAL LINE READ FROM SERIAL
if(serial_buffer[0] == '#')
{
printf("l = %d\n", l);
//SENSOR MESSAGE
printf("*** received sensor message\n-*** Sending data to backend\n");
printf("%s\n", serial_buffer);
for(m=1; m<=21; m++)
{
printf("data : %c, %02X\n", serial_buffer[m], serial_buffer[m]);
}
//populate the json request buffer
//sensor mac address (8 bytes)
//note sprintf adds a null terminated char after its output. need to replace
//it manually !
sprintf(&rpc_request_buffer[87], "%02X", serial_buffer[1]);
rpc_request_buffer[89] = ':';
sprintf(&rpc_request_buffer[90], "%02X", serial_buffer[2]);
rpc_request_buffer[92] = ':';
sprintf(&rpc_request_buffer[93], "%02X", serial_buffer[3]);
rpc_request_buffer[95] = ':';
sprintf(&rpc_request_buffer[96], "%02X", serial_buffer[4]);
rpc_request_buffer[98] = ':';
sprintf(&rpc_request_buffer[99], "%02X", serial_buffer[5]);
rpc_request_buffer[101] = ':';
sprintf(&rpc_request_buffer[102], "%02X", serial_buffer[6]);
rpc_request_buffer[104] = ':';
sprintf(&rpc_request_buffer[105], "%02X", serial_buffer[7]);
rpc_request_buffer[107] = ':';
sprintf(&rpc_request_buffer[108], "%02X", serial_buffer[8]);
rpc_request_buffer[110] = '\"';
//amr readings
sprintf(&rpc_request_buffer[136], "%05u", util_8_bit_to_16_bit_unsigned(serial_buffer[9], serial_buffer[10]));
rpc_request_buffer[141] = '-';
sprintf(&rpc_request_buffer[142], "%05u", util_8_bit_to_16_bit_unsigned(serial_buffer[11], serial_buffer[12]));
rpc_request_buffer[147] = '-';
sprintf(&rpc_request_buffer[148], "%05u", util_8_bit_to_16_bit_unsigned(serial_buffer[13], serial_buffer[14]));
rpc_request_buffer[153] = '-';
sprintf(&rpc_request_buffer[154], "%05u", util_8_bit_to_16_bit_unsigned(serial_buffer[15], serial_buffer[16]));
rpc_request_buffer[159] = '-';
sprintf(&rpc_request_buffer[160], "%05u", util_8_bit_to_16_bit_unsigned(serial_buffer[17], serial_buffer[18]));
rpc_request_buffer[165] = '-';
sprintf(&rpc_request_buffer[166], "%05u", util_8_bit_to_16_bit_unsigned(serial_buffer[19], serial_buffer[20]));
rpc_request_buffer[171] = '\"';
//occupied filed
rpc_request_buffer[186] = serial_buffer[21] + 48;
rpc_request_buffer[187] = '\"';
printf("json request\n");
printf("%s\n", rpc_request_buffer);
struct curl_fetch_st* curl_handle = (struct curl_fetch_st*)malloc(sizeof(struct curl_fetch_st));
curl_send_data_get_reply(curl_handle, rpc_request_buffer, rpc_reply_buffer);
//sensordb_add(sensordb_16From8(&serial_buffer[1]), sensordb_16From8(&serial_buffer[3]));
//sensordb_printSerial();
}
else
{
//DEBUG MESSAGE
//IGNORE THE DEBUG MESSAGES FOR NOW
//printf("%s", serial_buffer);
}
}
}这就是我得到的
root@ankit-ThinkPad-W530:/media/ankit/work/projects/parkmon/parkmon_gateway# l = 21
*** received sensor message
-*** Sending data to backend
#
data : , 00
data : K, 4B
data : , 00
data :, 08
data : �, FB
data : $, 24
data : �, 85
data : , 00
data : z, 7A
data : , 01
data : �, F1
data : , 09
data : �, 9F
data : , 07
data : 2, 32
data : , 06
data :, 08
data : , 06
data : �, 86
data : , 01
data :
, 0A
json request
{"src": "5A:D6:34:5E:1C:D8","time": 1468409465,"messages": [{"type": "status?","src": "00:4B:00:08:FB:24:85:00","id": 9,"amr_reading": "31233-61705-40711-12806-02054-34305","occupied": ":"}],"auth":""}
CURL Returned:
1,1479472678,
status,00:4B:00:08:FB:24:85:00,9,1数据为0x00 - 0x12 - 0x4B。但是,如输出所示,0x12被完全跳过。
不确定这可能是什么原因。
谢谢!
发布于 2020-12-18 20:36:44
你有没有试着像Nominal提到的那样取消设置ICANON和IEXTEN并禁用一些控制字符?
我无法在我的串行端口上接收一些字节,并且禁用每个c_cc,只保留VMIN为1解决了这个问题。
//Right after open...
termios ios;
::tcgetattr(fd, &ios);
ios.c_lflag &= ~(ICANON | IEXTEN);
for(int i = 0; i < NCCS; i++)
{
ios.c_cc[i] = i==VMIN ? 1 : 0;
}
::tcsetattr(fd, TCSANOW, &ios);对于那些使用boost_asio的用户,将fd替换为port->native_handle()也可能解决这个问题。
https://stackoverflow.com/questions/40677904
复制相似问题