c - Linux UART)多次十六进制写入后如何按顺序读取-C
问题描述
我将通过UART编写一个由十六进制排列组成的命令并读取它。
在这个过程中,随着要写入的命令数量的增加,它们在读取的时候并不是在每个排列中读取,而是随着缓冲区分配大小而飞。
例如)
我想要的读取值(Printf):
a5 01 90 08 01 21 00 00 75 30 03 e4 ec
a5 01 91 08 10 2d 07 10 27 03 03 e4 a4
a5 01 92 08 42 01 42 01 27 03 03 e4 d7
输出值(printf):
a501900801210000753003e4eca5019108102d07102703
03e4a4a501920842014201270303e4d7
在分析代码时,似乎在Read之前write是同时完成了几件事,并作为一个整体存储在Read缓冲区中,但我不知道如何解决。
如何按照写1时的read排列进行剪切打印?目前,它只是使用 print 进行测试,但由于我们将来必须将其发送到服务器,因此我们使用 printf 将其打印为 data3 变量。(我必须在有效载荷上飞行)
目前正在写的代码如下,10个写变量中只放了3个,做个简单的测试。这可能是一个基本问题,因为我不擅长它,但我请求你的帮助。
#include <termios.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <time.h>
#include <pthread.h>
int main(void)
{
int fd;
fd=open("/dev/ttyHSL6", O_RDWR|O_NOCTTY );
struct termios newtio;
unsigned char buffer[40]={0};
int bytes_read=0;
char data[40];
char *data3;
int i=0;
if (fd == -1)
{
printf("Error! in opening port");
exit(-100);
}
memset(&newtio, 0, sizeof(struct termios));
newtio.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR;
newtio.c_oflag = 0;
newtio.c_lflag = 0;
newtio.c_cc[VTIME] = 0;
newtio.c_cc[VMIN] = 1;
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &newtio);
unsigned char str[13] = {0xA5,0x80,0x95,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC2};
unsigned char str1[13] = {0xA5,0x80,0x90,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBD};
unsigned char str2[13] = {0xA5,0x80,0x91,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xBE};
while(1){
data3=malloc(sizeof(char)*100);
memset(buffer, 0, sizeof(buffer));
strcpy(data3,data);
for(i=0;i<10;i++){
switch(i){
case 1:
write(fd, str, sizeof(str)/sizeof(str[0]));
usleep(100000);
break;
case 2:
write(fd, str1, sizeof(str1)/sizeof(str1[0]));
usleep(100000);
break;
case 3:
write(fd, str2, sizeof(str2)/sizeof(str2[0]));
usleep(100000);
break;
}
bytes_read = read(fd, buffer, sizeof(buffer)/sizeof(buffer[0]));
sprintf(data,"%02x",buffer[0]);
if (bytes_read > 0)
{
buffer[bytes_read]=0;
for (int j=1; j< sizeof(buffer)/sizeof(buffer[0]); j++)
{
sprintf(data,"%02x",buffer[j]);
strcat(data3,data);
}
sprintf(data3,"\n");
printf("%s\n",data3);
}
}
}
close(fd);
return 0;
}
(目前,执行此代码时不会打印任何值)
解决方案
for 循环以i = 0
.
i = 1
仅当或i = 2
或时,交换机才会将数据写入端口i = 3
。
我的猜测是线路read(fd, buffer, sizeof(buffer)/sizeof(buffer[0]));
被阻塞(等待有人写东西)。因为你第一次没有写任何东西。
请记住,阻塞 IO 读取器将阻塞,直到写入器写入某些内容(除非涉及超时)。如果需要,您可以尝试使用非阻塞 IO(请参阅 参考资料O_NONBLOCK
)。
顺便说一句,这段代码:
buffer[bytes_read]=0;
for (int j=1; j< sizeof(buffer)/sizeof(buffer[0]); j++)
{
sprintf(data,"%02x",buffer[j]);
strcat(data3,data);
}
第一次最终会打印一堆零,并且可能会在接下来的时间打印来自先前消息的一些数据。你应该停止 for in bytes_read
。
最后,如果您的unsigned char
长度为 1 字节(在大多数平台中),您可以绕过除法并使用sizeof(buffer)
.
推荐阅读
- javascript - 使用香草js将活动元素背景设置为红色并将剩余元素设置为白色背景
- python - Django:从另一个服务捕获授权令牌
- reactjs - 部署 React 应用程序后如何解决 http/https 混合内容问题
- r - 概率矩阵 - 从任何位置开始
- node.js - TypeError:_stream.Readable.from 不是 sequelize node js 中的函数
- javascript - Vuetify - 选定的 v-radio 未在 v-model 上设置值
- r - 如何仅计算 R 中的非空列,而包含稀疏 NA 的列?
- node.js - 收到错误代码“无法获取 /admin/add-product”
- sql - 用于指定 IN 子句中使用的列表的存储过程参数?
- sas - PROC TRANSPOSE 值列,同时保留日期和小时结束