- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试创建一个具有最小延迟的函数,以检查串行端口是否有数据,如果有,它将读取每个字节并以十六进制格式打印每个字节,直到没有更多字节可用为止。如果没有数据,该函数必须立即返回。
这是我的代码:
int fd=open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_SYNC);
// Trying to set correct options here
struct termios o;
tcgetattr(fd,&o);
cfsetispeed(&o,57600);
cfsetospeed(&o,57600);
/* 8 bits, no parity, 1 stop bit */
o.c_cflag &= ~PARENB;o.c_cflag &= ~CSTOPB;o.c_cflag &= ~CSIZE;o.c_cflag |= CS8;
/* no hardware flow control */
o.c_cflag &= ~CRTSCTS;
/* enable receiver, ignore status lines */
o.c_cflag |= CREAD | CLOCAL;
/* disable input/output flow control, disable restart chars */
o.c_iflag &= ~(IXON | IXOFF | IXANY);
/* disable canonical input, disable echo, disable visually erase chars, disable terminal-generated signals */
o.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
/* disable output processing */
o.c_oflag &= ~OPOST;
o.c_cc[VMIN] = 0; //to prevent delay in read();
o.c_cc[VTIME] = 0;
tcsetattr(fd, TCSANOW, &o);
tcflush(fd, TCIFLUSH);
char sp[1]; //hold 1 byte
int bytes=read(fd,sp,1); //Good news: this function doesn't lock
if (bytes > 0){
//this is never reached even if a byte is
//present on the serial line. why?
printf("Read: ");
while(bytes > 0){
printf("%X ",sp[0]);
bytes=read(fd,sp,1);
}
}
fclose(fd);
最佳答案
如果事先知道需要写入设备的时间,则可以使用select()
或poll()
等待输入,直到下次您希望/打算进行写入。
一种更简单,更健壮的方法(因为您的读写未按定义的顺序进行,并且您的硬件是全双工的),因此,请使用单独的线程进行读写。基本上,您使用阻止读取和写入(c_cc[VMIN] = 1
,c_cc[VTIME] = 0
进行读取,O_NONBLOCK
不在文件打开标志中)。不过,您应该允许使用更大的缓冲区。读取将返回到目前为止已接收的所有内容,但是使用这些设置,只要至少接收到一个字符,就会唤醒读取器。为了进行写入,我建议您在每次写入后对设备完成命令/消息都执行一个tcdrain(fd);
,以确保它由内核在线发送。 (请记住,对串行端口的写操作可能很短;您需要一个写循环。)
在所有情况下,主机端的内核都会缓存发送和接收的数据。根据硬件和驱动程序的不同,甚至阻塞的write()
可能比实际连接所有数据时更早返回。硬件和内核驱动程序而非主机软件负责串行数据的正确时序。
在主机端使用一个字节的缓冲区根本不会影响微控制器,您只会执行过多的系统调用,从而浪费CPU资源,并可能会降低程序速度。在57600波特下,具有8个数据位,无奇偶校验,1个停止位和隐式起始位,实际数据速率为46080位/秒(通常允许±5%)或每秒5760字节。微控制器将始终有大约1 s / 5760≃0.0001736秒,或超过173微秒,以处理每个输入字节。 (我将固件设计为不允许更高优先级的中断等。即使在最坏的情况下,也要延迟超过100微秒的处理时间,以确保不会丢失任何字符。如果您在中断处理程序中接收到这些字符,我将d使用一个小的循环缓冲区和一个指示符\r
或\n
,这样,如果接收到此字符,则为主程序引发一个标志,以通知已接收到一个新的完整命令。应该足够长以容纳两个完整的命令,或者如果某些命令可能需要更长的时间来解析/处理/处理,则更长。)
如果主机操作系统在接收到第一个字符后1 ms唤醒了进程,则在此同时还有四个或五个字符到达。因为此延迟在某些系统上可能更高,所以我将使用更大的缓冲区(例如最多256个字符),以避免在内核由于某种原因而延迟唤醒阅读器线程时进行多余的syscall。是的,它通常只读取1个字符,这很好。但是,当系统过载时,您不想在需要的时候执行数百个多余的syscall来增加负载。
请记住,带有VMIN=1, VTIME=0
的termios接口,即使接收到单个字符,也会尽快唤醒阻塞读取。只是不能确保程序一直运行,除非您通过旋转就浪费了大约100%的CPU能力(如果这样做,则没人会运行程序)。根据系统的不同,唤醒阻塞读取可能会有延迟,在此期间可能会接收更多数据,因此使用较大的read()
缓冲区绝对是明智的。
同样,尽管大多数串行驱动程序可以返回短计数,但您可以安全地使用所需的大写操作(最多2 GiB的限制),因此无论如何您都需要一个循环。串行端口描述符上的tcdrain(fd)
将阻塞,直到实际写入所有写入的数据为止,因此您可能要使用它。 (如果不这样做,则可以只写更多数据;内核驱动程序将处理细节,而不会重新排序/弄乱数据。)
使用两个线程,一个用于读取,一个用于写入,听起来可能令人生畏/奇特,但这实际上是实现可靠通信的最简单方法。您甚至可以使用pthread_setcancelstate()
,pthread_setcanceltype()
和可选的pthread_testcancel()
编写线程函数,以便即使它们具有关键部分(例如添加一个或多个),也可以简单地取消线程(使用pthread_cancel()
)以停止它们。收到的邮件发送到受互斥锁保护的队列中)。
关于c - 可靠地以56K逐字节读取linux中的串行数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51828498/
我正在使用 python 加密一些文件,但我在逐 block 读取文件时遇到问题。 有时不会返回最后一个 block 的所有数据。 当文件长度为 307200 字节时,我没有问题。当它的长度为 279
我正在使用 WebRTC 将文件发送到连接的对等方,并且我正在以块的形式发送文件。但是,我无法弄清楚如何让对等方在文件逐块流入时保存/下载文件。 我在网上找到的所有例子都推荐做这样的事情: // se
我用 Tiled 做了一张 map 。它的每一 block 图 block 都尺寸为 32x32 像素,我的主要角色 Sprite 也是。 在我的类(class) Player.cpp 中,我有一些计
我见过一些单页网站,您可以逐 block 滚动,因此您没有无限滚动。 你逐 block 移动。 是否有提供此功能的任何脚本或其他东西? 最佳答案 我自己从未使用过它,所以我无法在代码方面为您提供帮助,
这是一个逐 block 反转文件内容的程序。 #include #include #define BS 12 void reverse(char * buffer, int size) { c
在下面的代码中,有没有办法避免 if 语句? s = 13; /*Total size*/ b = 5; /*Block size*/ x = 0; b1 = b; while(x s)
我正在尝试分割输入图像并逐个对其进行模糊处理,但毕竟对相邻图 block 调用 cv::blur 我得到了边界像素,这与我有一次将 cv::blur 集体应用于整个图像。 Mat upper(im,
我想逐个读取文件。该文件被分成几部分,存储在不同类型的媒体上。我目前所做的是调用文件的每个单独部分,然后将其合并回原始文件。 问题是我需要等到所有 block 都到达后才能播放/打开文件。是否可以在
我有一个包含客户和日期列表的 JSON 文件。 文件看起来像这样: { "Customers": [ { "Customer": "Customer Name Here", "Company"
我的邮件目标是从连接到HTTP服务器的TCP套接字读取数据,然后解析 HTTP响应块(传输编码:分块)-服务器在同一连接上每30秒发送一个块 我附上了我的代码。看起来io.Copy读取第一个块,然后等
我认为自己是一位经验丰富的 numpy 用户,但我无法找到以下问题的解决方案。假设有以下数组: # sorted array of times t = numpy.cumsum(numpy.rando
当我将文件添加到暂存区时,我可以 $ git add my_file -p 然后选择我要暂存的 block 。 有没有办法 merge/挑选一个提交并逐 block 应用它的差异? 谢谢 最佳答案 我
我有一个 mongodb 查询,它获取大约 50,000 个大文档。 这对我的 RAM 来说太多了,因此计算机速度变慢了。 现在我想逐 block 迭代 mongodb 结果。 我想获取前 1000
我不会为 AES 或其他加密打开此线程,因为这是我要用来加密 AES 和其他加密的 key 的内容。我从 StackOverflow 和其他一些网站收集了一些代码,并对其进行了编辑以适合我的程序,但是
我在做一些后台工作时尝试收集所有系统统计数据。例如,我使用以下命令来收集 IO 统计信息: iostat -xty 5 此脚本用于每 5 秒收集一次 I/O 统计信息。所以我的日志会包含很多数据 bl
我需要 php 脚本,用于从 url 到服务器的可恢复文件下载。它应该能够开始下载,然后在捕捉时(30 秒 - 5 分钟)恢复,依此类推,直到完成整个文件。 perl 中有类似的东西 http://c
是否有标准的 Linux 命令可用于逐 block 读取文件?例如,我有一个大小为 6kB 的文件。我想读取/打印第一个 1kB,然后是第二个 1kB ...似乎 cat/head/tail 在这种情
我正在处理大量文件,我想逐 block 处理这些文件,假设在每批处理中,我想分别处理每 50 个文件。 如何使用 Spark Structured Streaming 来实现? 我看到 Jacek L
我正在处理大量文件,我想逐 block 处理这些文件,假设在每批处理中,我想分别处理每 50 个文件。 如何使用 Spark Structured Streaming 来实现? 我看到 Jacek L
我想知道:逐 block 读取 jp2 并将数据存储在缓冲区对象中的预期方法是什么? 现在我正在做类似的事情。 /* note I already created stream and configu
我是一名优秀的程序员,十分优秀!