作者gn00618777 (非常念旧)
看板C_and_CPP
标题Re: [问题] 一个读取 uart 的 process
时间Sun Jun 6 18:15:15 2021
※ 引述《gn00618777 (非常念旧)》之铭言:
: 版友好
: 我是在 Linux 写 C。之前写了一个 process ,是 1个 byte 1 个 byte 读取的
: blocking 程式,每读1个byte就检查是否是 header,但被说写得不好。
: 於是乎再写了一个 non-blocking的,主要是先蒐集我想要的长度後,再检查是否是
: header。
: protocol header 如下:
: byte0 sig1 (0xab)
: byte1 sig2 (0xba)
: byte2 id
: byte3 packet length
: byte4 seq num
: 概念上,我会读取 uart fd,读到的 rcv_len 加总起来,若有我达到的长度
: 就去检查这5个byte是不是有 header。 只要看到 0xab 0xba 我就认定是一个
: header 的起始。也有可能这2个byte出现在这5个byte的任何地方,甚至 byte4
: 会是 0xab,此时我们就有可能需要再读取1个byte来做判定是否有header。当我发
: 现一个header时,我就会从此header到结尾整个位移到packet的起始。并回传 left
: 值,此left值代表意思是说,我还需要读取几个byte来做判定。 我感觉我这写法满
: 罗嗦的,WAIT_HEADER status这样写,WAIT_PAYLOAD status也会这样写,後面势必
: 一大坨,但又想不出啥更好的方法,所以想来求助一下版友看有没有更好的写法?
: 这是我的范例 code: https://reurl.cc/bzrez3
: 恳请建议,谢谢。
写code驽钝..
我参考了版友建议,改了写法。
我用了类似生产者消费者方式。当 select uart 有资料时,读取 sizeof(rbuf) = 256
的长度。根据uart处於何种状态(MSG_WAIT_ID1, MSG_WAIT_ID2....),来决定抓取的数量
完整header共5byte: ID1, ID2 , OP, SEQ, LEN
假设 select 到了 5 个 byte了,我就去一个byte一个byte去检查,如果这五个byte是
xx,xx,ID1,ID2,OP ,跑了我的 find_header 後就会求出目前 state 状态为
MSG_WAIT_SEQ,根据此状态发现,我还需要再抓取2byte,才足够去判定他是不是一个
完整的 5 个 byte header。
先姑且不论效率和coding style ,我想求问的是以下:
rcv = FRONT_UART_read(fd, rbuf + idx, sizeof(rbuf));
有没有好的改写方式? 我怕的是此行,如果我 idx 停留在 255,当 uart device
搞我送出 256 byte资料,我不就超出记忆体范围了?
还有请问我 99~106 有没有逻辑上的错误呢? 万分感谢..
https://reurl.cc/NrZ4We
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 59.115.95.86 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1622974519.A.2FD.html
1F:→ Lipraxde: 恩...它第三个参数是放 buffer size 吧? 06/06 21:54
2F:→ gn00618777: 你的意思是说,我不该写死,应该动态调整读取长度? 06/06 23:53
3F:→ Lipraxde: 动态调整吗...我觉得应该讲成给的 buffer size 有多少 06/07 00:18
4F:→ Lipraxde: ,就该填多少 06/07 00:18