开启辅助访问 切换到窄版

打印 上一主题 下一主题

UCOSIII消息队列API实验

[复制链接]
楼主
跳转到指定楼层
| 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本文设计一个应用程序,该程序有4个任务,两个消息队列和一个定时器,任务start_task用于创建其他3个任务。Main_task任务为主任务,用来检测按键,并且将按键的值通过消息队列KEY_Msg发送给任务Keyprocessing_taskmain_task任务还用于检测消息队列Data_msg的总大小和剩余空间大小,并且控制LED0的闪烁,Keyprocess_tasK任务获取KEY_Msg内的消息,根据不同消息做出相应的处理。
定时器1的回调函数tmr1_callback通过消息队列DATA_MSG将定时器1的运行次数作为信息发送给任务msgdis_task,任务msgdis_taskdata_msg中的消息显示在LCD上。
首先定义两个消息队列和一个定时器以及相关的宏。




结构体OS_Q用来描述消息队列,在OS_Q中有个字段MsgQMsgQ也是一个结构体,MsgQ中的字段NbrEntriesSizeNbrEntries用来记录消息队列总大小和已经使用了的消息队列大小,二者之差就是消息队列剩余的空间大小,函数check_msg_queue()就是用来检测消息队列DATA_Msg的总空间大小和剩余空间大小。



前面虽然定义2个消息队列和1个定时器,但此时还不能用,需要调用OSQCreate()OSTmrCreate()两个函数来创建消息队列和定时器,我们在任务start_task中创建这两个消息队列和定时器。

上面代码中,
调用函数OSCreate()创建一个消息队列KEY_MsgKEY_Msg队列长度为1,我们来模拟UCOSIII中的消息邮箱。
调用函数OSCreate()创建一个消息队列DATA_Msg,队列长度为4.
调用函数OSTmrCreate()创建一个定时器tmr1tmr1为周期定时器,定时器周期为500ms








上面有四个函数:
tmr1_callback()main_task()keyprocess_task()msgdis_task(),这四个函数分别为定时器1的回调函数,主任务的任务函数,按键处理任务函数和显示任务的任务函数。

Tmr1_callback()函数是定时器1的回调函数,在start_task任务中我们创建了一个定时器tmr1tmr1是一个周期定时器,定时周期为500ms,在tmr1的回调函数tmr1_callback()中通过函数OSQPost()向消息队列DATA_Msg发送信息,这里向消息队列发送数据采用的是FIFO方式,当发送任务失败的话,就释放相应内存关闭定时器。
Main_task()函数为主任务的任务函数,在这个函数中我们不断扫描按键的键值,然后将键值发送到消息队列KEY_Msg中,这里向消息队列发送数据采用的是FIFO方式,main_task()任务还要每隔100ms检测一次消息队列DATA_Msg总的大小和剩余大小并显示在LCD上,最后还要控制LED0的闪烁。
Keyprocess_task()为按键处理任务,在main_task任务中我们将按键值发送到消息队列KEY_msg中,在本函数我们调用OSQPend()函数从消息队列Key_Msg中获取消息,也就是按键值,然后根据不同按键值做出相应的处理,KEY_UP控制LED1KEY0刷新LCD部分背景颜色;
Key1控制tmr1的开关。



可以看出DATA_Msg总大小为4,这个和我们创建DATA_Msg消息队列时设置的一样,由于此时定时器1并没有启动,所以消息队列DATA_Msg的剩余大小也为4,右下角部分方框颜色为背景白色,当按下KEY0后刷新此背景。

可以看出当按下KEY0以后,右下部分的LCD背景就会被刷新为其他颜色,按下KEY1开启定时器,那么定时器的回掉函数就会每隔500ms向消息队列DATA_MSG中发送一条消息。

此时消息队列DATA_msg还剩一个可用空间,定时器1还会一直向DATA_Msg发送消息,直到消息队列满,就会关闭定时器1,停止发送。

可以看出此时消息队列DATA_msg剩余空间为0,那么定时器1回调函数中再次调用函数OSQPost()向消息队列DATA_Msg中发送数据的话就会发送失败,此时err就为OS_ERR_MSG_POOL_EMPTY,提示消息队列空了,err不等于OS_ERR_NONE,那么就会关闭定时器1,停止向消息队列发送数据,除非再次手动开启定时器1.

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表