luoyiming1984 发表于 2012-12-21 18:06:58

【我是大名鼎鼎罗菜鸟】讨论一下,OS下,UART怎么写?

本帖最后由 luoyiming1984 于 2012-12-21 18:08 编辑

在裸奔的时候,我们经常用环形缓冲的方式,通过中断来收发数据。
具体做法是:接收数据时,数据放到环形缓冲内,串口数据始终是在缓冲的尾部,而读取数据则是从缓冲的头部开始,头尾不能相碰,这样保证了读取的字节序列。
发送的时候,也是按顺序把字节写入缓冲,缓冲的尾部写入数据,头部的数据发到串口,并且都是在一个字节发完后,产生中断时再送入下一个字节,直到缓冲空了为止。

但是在OS上,又该怎么用?这里的OS是一个笼统的概念,支持信号量触发,事件触发,消息邮箱触发,消息队列触发。

第一种方法,是将要收发的数据放入消息队列,接收时中断的时候放,任务里面取;发送时任务里面放,中断里面取。这种方法要求OS支持单字节的消息队列,所以UCOS-II不适合。

第二种方法是用信号量+环形缓冲,在裸奔的基础上,对每个信号量都标记。接收时,收到一个字节,信号量记一个,任务里面取数据时先取信号量,有信号量时才读取字节。发送的时候,刚好相反,信号量是来标记发送缓冲空的,任务里取一个信号量,就往缓冲里面写一个字节,中断的时候,每发完一个字节就计数一个信号量。这种方法好处是,当串口读写时,任务可以被阻塞,直到有字节收到或者发完。同样,这也是一个缺点,比如需要多个串口的通信,就必须开多个任务,占用资源就越多。

第三种方法,还是跟裸奔一样,直接使用环形缓存。但是串口的几个关键事件,通过函数指针来处理,环形缓存加一个函数指针。接收时,当缓存收满,或者超时(STM32和LPC2XXX都支持,没有的可以用定时器来实现),就会执行函数指针里面的函数,指向的函数向应用任务发送一个触发事件,触发事件可以并行。在应用任务里,等待需要的事件,假如是多个串口接收数据,应用任务平时是阻塞的,一旦任何一个串口收到数据,就可以触发任务运行,然后任务里面读取环形缓冲。



给一个STM32在UCOS-II上的文件,可以直接添加到工程。

hamipeter 发表于 2012-12-21 21:20:54

沙发啊,支持一下

1ongquan 发表于 2012-12-21 22:30:48

本帖最后由 1ongquan 于 2012-12-21 22:32 编辑

我用第二种方法,不想对一个OS平台有太深的依赖

think_a_second 发表于 2012-12-21 22:40:32

我用第3种

luoyiming1984 发表于 2012-12-22 02:50:27

1ongquan 发表于 2012-12-21 22:30 static/image/common/back.gif
我用第二种方法,不想对一个OS平台有太深的依赖

第二个方法还是很依赖OS的。
页: [1]
查看完整版本: 【我是大名鼎鼎罗菜鸟】讨论一下,OS下,UART怎么写?