UART0串口编程系列(五) (转)
串口(UART0)之UC/OS(二)
------------------------------------------------------------------------
Author :tiger-john
WebSite :blog.csdn.net/tigerjb
Email :jibo.tiger@gmail.com
Tiger声明:本人鄙视直接复制本人文章而不加出处的个人或团体,但不排斥别人转载tiger-john的文章,只是请您注明出处并和本人联系或留言给我。3Q
-----------------------------------------------------------------------
一.串口接收数据在UC/OS设计中应注意的问题
1. 串口通信的数据接收过程:
1> UART 接收FIFO接收到预定字节后触发中断
2> ISR读取接收到的内容并保存
3> 经过一次或若干次ISR完成一个通信帧的接收(拼装通信帧)
4> 处理和解释通信内容
5> 根据处理结果触发其他任务
2. 串口数据接收程序设计时,应该考虑的问题:
1>即使以上的操作过程很简单,也最好不要把它全部安排在ISR中完成,如果放在一起的话,就会给UART0通信带来危机(此处具体请看前面的文章)。
2>所以要安排一个与ISR关联的“串口接收”任务来完成后面的工作。再创建一个帧缓冲区。在接收的过程中,将接收到的内容写入帧缓冲区。接收完一帧后,处理和解释过程需要读帧缓冲区的内容。
3>将写帧缓冲区的操作安排在ISR中完成,读帧缓冲去的操作安排在串口接收任务中完成。
4>由于ISR和串口接收任务是并发程序单元,存在资源同步问题,故需要对帧缓冲区进行互斥访问。
新的危机:
即使采取互斥访问,但是有时候还是有危险的。因为:当系统接收完一帧内容后,开始进行内容解释处理,在尚未处理器完毕之前(帧缓冲区被任务独占),下一帧的接收又开始。这时,新一帧的内容就不能完整保存,就会出现接收差错。
注:在实际情况下,通信过程是一帧一帧进行的,相邻两帧之间的时间间隔通常比处理和解释的耗时要长的多,使的通信过程能够顺利进行。但是,也不排除在偶情况下,某两帧时间间隔很短,采用ISR写“帧缓冲区”的方法是有风险的。
解决方法一:
当内存资源比较宽裕时,可以开辟两个“帧缓冲区”,轮流进行读/写操作。当一个帧缓冲区写满后,开始进行内容解释处理,而下一帧的内容可以继续写到另外一个帧缓冲区,不会遗漏。
解决方法二:
ISR将本次中断接收到的内容放入消息队列,“串口接收”任务将从消息队列中取的数据写入“帧缓冲区”,拼装完一帧后开始处理和解释,然后触发其他任务,最后清空“帧缓冲区”,开始下一帧的拼装过程。
在此方案中,“写帧缓冲区”的读操作和“读帧缓冲区”的操作均为串口接收任务,不存在互斥问题。由于使用了消息队列,故在处理和解释当前帧时,下一帧的新内容又可以暂存在消息队列中,也不会丢失。
(我们在设计程序时,一般采用方法二)