本周,将之前发表的文章 串口操作的异步实现 应用到项目中的RFID、条码、打印等串口应用时,发现了一些问题:
1. 在使用串口前,应清除串口中无用的数据;
2. 从串口读取数据方法的改进;
3. 数据的解析
4. 发送
5. 资源占用
6. 退出和资源的释放
一.在使用串口前,应清除串口中无用的数据;
一种方法是在CommHandler线程循环进入前清除无用的数据;一种方法是在打开串口时清除无用的数据;由于CommHandler线程的启动时间不确定,在CommHandler中清除可能会造成有用的无用的数据一起被清除了;
二.从串口读取数据方法的改进;
之前的方法是有数据,就读取并压入队列中,然后通知上层,数据来了;这种做法有一个弊端,就是一段完整的数据可能会被分成多段;改进的办法就是在Commhandler中加循环,直到没有数据后,表示收到了一段完整的数据后,再通知上层;
这种处理方法有局限性,至少对于有大量连续的数据接收的情况就不适合;对于我的应用,主要是发送,加少量的接收,就很有效;
三.数据的解析
从串口接收到的数据要被上层解析,不同的应用,协议不同,这部分工作应放在上层来做,对于一串数据,解析一般都是从中提取首尾标志或者是特殊的字符,用队列来处理这种情况就非常适合;
如果要处理的协议较为复杂,还可以采用数据处理和视图分开的形式,这样,结构清晰,数据处理部分还可以直接打成库;我在处理条码symbol Se955协议时,就是这样做的;
四.发送
发送的时机:通过串口发送数据时,要选择合适的时机,否则,可能会造成死锁;
发送接口的变化:将发送方法由send(byte[])改为send(byte[],offset,len),这样的好处在于可以发送一个字节流中的一段数据;
五.资源占用
对于串口操作时,没有其它数据处理的情况,比如条码、RFID应用,可以允许QueueEventHandler一直循环占用处理器资源,而对于在串口接收发送数据的同时,还要同时做大量数据处理的情况,比如打印,QueueEventHandler一直循环查询就太浪费资源了;
处理的办法就是在QueueEventHandler中加入wait,然后通过外部调用来notify;
六.退出和资源的释放
为了能够合适地释放资源,在CommHandler和QueueEventHandler中加入了标志位,在CommHandler的两次wait之间加入了标志位判别,以避免退出时,notify后再次被阻塞;还要清除串口中的数据,以便于下次使用;在串口关闭和Commhandler和QueueEventHandler两个线程间,要避免关闭时产生异常;