嵌入式开发交流网论坛
标题:
UCOSIII消息队列API实验
[打印本页]
作者:
萌萌男神丶Lin
时间:
2019-3-11 15:48
标题:
UCOSIII消息队列API实验
本文设计一个应用程序,该程序有
4
个任务,两个
消息队列
和一个
定时器
,任务
start_task
用于创建其他
3
个任务。
Main_task
任务为主任务,用来检测按键,并且将按键的值通过消息队列
KEY_Msg
发送给
任务
Keyprocessing_task
,
main_task
任务还用于检测消息队列
Data_msg
的总大小和剩余空间大小,并且控制
LED0
的闪烁,
Keyprocess_tasK
任务获取
KEY_Msg
内的消息,根据不同消息做出相应的处理。
定时器
1
的回调函数
tmr1_callback
通过消息队列
DATA_MSG
将定时器
1
的运行次数作为信息发送给
任务
msgdis_task
,任务
msgdis_task
将
data_msg
中的消息显示在
LCD
上。
首先定义两个消息队列和一个定时器以及相关的宏。
[attach]28867[/attach]
[attach]28868[/attach]
结构体
OS_Q
用来描述消息队列,在
OS_Q
中有个字段
MsgQ
,
MsgQ
也是一个结构体,
MsgQ
中的字段
NbrEntriesSize
和
NbrEntries
用来记录消息队列总大小和已经使用了的消息队列大小,二者之差就是消息队列剩余的空间大小,函数
check_msg_queue()
就是用来检测消息队列
DATA_Msg
的总空间大小和剩余空间大小。
[attach]28869[/attach]
前面虽然定义
2
个消息队列和
1
个定时器,但此时还不能用,需要调用
OSQCreate
()
和
OSTmrCreate
()
两个函数来创建消息队列和定时器,我们在任务
start_task
中创建这两个消息队列和定时器。
[attach]28870[/attach]
上面代码中,
调用函数
OSCreate()
创建一个消息队列
KEY_Msg
,
KEY_Msg
队列长度为
1
,我们来模拟
UCOSIII
中的消息邮箱。
调用函数
OSCreate()
创建一个消息队列
DATA_Msg
,队列长度为
4.
调用函数
OSTmrCreate()
创建一个定时器
tmr1
,
tmr1
为周期定时器,定时器周期为
500ms
。
[attach]28871[/attach]
[attach]28872[/attach]
[attach]28873[/attach]
[attach]28874[/attach]
上面有四个函数:
tmr1_callback()
,
main_task()
,
keyprocess_task()
和
msgdis_task()
,这四个函数分别为定时器
1
的回调函数,主任务的任务函数,按键处理任务函数和显示任务的任务函数。
Tmr1_callback()
函数是定时器
1
的回调函数,在
start_task
任务中我们创建了一个定时器
tmr1
,
tmr1
是一个周期定时器,定时周期为
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
控制
LED1
;
KEY0
刷新
LCD
部分背景颜色;
Key1
控制
tmr1
的开关。
[attach]28875[/attach]
可以看出
DATA_Msg
总大小为
4
,这个和我们创建
DATA_Msg
消息队列时设置的一样,由于此时定时器
1
并没有启动,所以消息队列
DATA_Msg
的剩余大小也为
4
,右下角部分方框颜色为背景白色,当按下
KEY0
后刷新此背景。
[attach]28876[/attach]
可以看出当按下
KEY0
以后,右下部分的
LCD
背景就会被刷新为其他颜色,按下
KEY1
开启定时器,那么定时器的回掉函数就会每隔
500ms
向消息队列
DATA_MSG
中发送一条消息。
[attach]28877[/attach]
此时消息队列
DATA_msg
还剩一个可用空间,定时器
1
还会一直向
DATA_Msg
发送消息,直到消息队列满,就会关闭定时器
1
,停止发送。
[attach]28878[/attach]
可以看出此时消息队列
DATA_msg
剩余空间为
0
,那么定时器
1
回调函数中再次调用函数
OSQPost()
向消息队列
DATA_Msg
中发送数据的话就会发送失败,此时
err
就为
OS_ERR_MSG_POOL_EMPTY
,提示消息队列空了,
err
不等于
OS_ERR_NONE,
那么就会关闭定时器
1
,停止向消息队列发送数据,除非再次手动开启定时器
1.
欢迎光临 嵌入式开发交流网论坛 (http://www.dianzixuexi.com/bbs/)
Powered by Discuz! X3.2