作者gn00618777 (非常念旧)
看板C_and_CPP
标题[问题] 一个读取 uart 的 process
时间Sun Apr 25 21:24:42 2021
版友好
我是在 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
恳请建议,谢谢。
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 59.115.86.19 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1619357089.A.EEF.html
1F:→ gn00618777: 此 code 只是概念,不能编过也少了写语法宣告 04/25 21:27
2F:推 ucrxzero: 看起来每次都从packet的开头重新确认是否有0xba跟0xab 04/25 23:44
3F:→ ucrxzero: 还是可先记着这次的结尾让下次不要从for int i = 0开始 04/25 23:45
4F:→ ucrxzero: 还是每次packet都是新的? 04/25 23:46
5F:推 ucrxzero: 我本身是不太懂serial driver 04/25 23:48
6F:→ ucrxzero: if(i == check_len -1 &&..) 应该可以单独拉出去回圈 04/25 23:49
7F:→ ucrxzero: 避免每次loop都检查一次\ 04/25 23:49
8F:推 ucrxzero: 我23:44的推文可以忽略 我看懂了 04/25 23:52
9F:推 ucrxzero: 我第一个想法是sliding window 04/26 00:13
10F:→ ucrxzero: 有没有一些checksum 用数学方法去算0xab 0xba 04/26 00:18
11F:→ Lipraxde: 你是要收到讯息就能反应的,还是可以慢点再去回应? 04/26 08:46
13F:→ longlongint: 怎麽有一种在重刻tcp的感觉(只是比喻) 04/26 13:30
14F:推 eric3243: 我好奇问个 一次读1byte边判断 跟 读到5byte再1byte1byt 05/31 19:31
15F:→ eric3243: e判断不是一样吗? 05/31 19:31
16F:→ eric3243: 感觉要一次读2byte 一次判断2byte 05/31 19:32