一.消息队列
1.概念
信号量本身不能传递数据,如果希望在任务通信同时传递数据,可以使用消息队列
任务和中断都可以发送消息,但是只有任务能够接收消息
2.编程使用
(1)创建消息队列
void OSQCreate (OS_Q *p_q,//消息队列控制块(指向一个消息队列) CPU_CHAR *p_name,//消息队列名字 OS_MSG_QTY max_qty,//消息队列的长度(不为0) OS_ERR *p_err)//错误返回 |
(2)发送消息
void OSQPost (OS_Q *p_q,//消息队列控制块(指向一个消息队列) void *p_void,//发送消息首地址 OS_MSG_SIZE msg_size,//消息的长度 OS_OPT opt,//发送选项 OS_ERR *p_err)//错误返回 |
(3)接收消息
void *OSQPend (OS_Q *p_q,//消息队列控制块(指向一个消息队列) OS_TICK timeout,//超时时间,给0无限等待 OS_OPT opt,//接收选项 OS_MSG_SIZE *p_msg_size,//消息长度 CPU_TS *p_ts,//时间戳 OS_ERR *p_err)//错误返回 消息首地址通过返回值返回 |
3.任务内部的消息队列
这种消息队列属于任务,只有本任务从消息队列中读取消息,其他的任务和中断可以往该消息队列中发送消息
编程使用:
(1)无需创建初始化
(2)发送消息
void OSTaskQPost (OS_TCB *p_tcb,//任务控制块 void *p_void,//消息首地址 OS_MSG_SIZE msg_size,//消息长度 OS_OPT opt,//发送属性 OS_ERR *p_err)//错误返回 |
(3)接收消息(本任务调用)
void *OSTaskQPend (OS_TICK timeout,//超时时间 OS_OPT opt,//接收属性 OS_MSG_SIZE *p_msg_size,//消息大小 CPU_TS *p_ts,//时间戳 OS_ERR *p_err)//错误返回 返回收到消息首地址 |
二.软件定时器
1.概念
软件定时器通过系统时钟节拍(tick)作为时钟源,实现定时的功能,适用于定时精度无需太高的场合,实现通过定时任务来实现
定时器常用于完成某些周期性的工作
定时器任务优先级和工作频率可以设置
OS_CFG_TMR_TASK_PRIO决定了定时器任务优先级(2)
OS_CFG_TMR_TASK_RATE_HZ决定了定时器的频率(100Hz)
2.编程使用
(1)创建定时器
void OSTmrCreate (OS_TMR *p_tmr,//指向定时器 CPU_CHAR *p_name,//定时器名字 OS_TICK dly,//延时时间(单位是定时器参考周期 10ms) OS_TICK period,//周期时间(单位是定时器参考周期 10ms) OS_OPT opt,//定时器模式(单次模式/周期模式) OS_TMR_CALLBACK_PTR p_callback,//定时器回调函数(无返回值,两个void *参数,第一个代表定时器) void *p_callback_arg,//传递给回调函数的第二个参数 OS_ERR *p_err)//错误返回 |
(2)如果不在使用,可以删除定时器
CPU_BOOLEAN OSTmrDel (OS_TMR *p_tmr,//指向定时器 OS_ERR *p_err))//错误返回 |
(3)启动定时器
CPU_BOOLEAN OSTmrStart (OS_TMR *p_tmr,//指向定时器 OS_ERR *p_err)//错误返回 |
1)定时器以单次模式工作时,以延时时间(dly)间,只工作一次
2)定时器以周期模式工作时,延时时间为0,以周期时间(period)超时时间,周期性工作
3)定时器以周期模式工作时,延时时间非0,第一个周期超时时间为(dly),以后周期超时时间是周期时间(period),周期性工作
练习:
使用软件定时器3s读取一次温湿度并且通过串口打印(将DHT11中的ms延时换成us)
三.事件标识组
1.概念
事件标识组也是用来实现同步,而且用于多个对象之间的同步,同步方式有与同步/或同步
与同步就是等待所有的条件成立,或同步等待其中一个条件成立
2.编程接口
(1)创建
void OSFlagCreate (OS_FLAG_GRP *p_grp,//指向事件标识组 CPU_CHAR *p_name,//名称 OS_FLAGS flags,//初始值(32位) OS_ERR *p_err)//错误返回 |
(2)修改事件标识组标识
OS_FLAGS OSFlagPost (OS_FLAG_GRP *p_grp,//指向事件标识组 OS_FLAGS flags,//代表要修改的位(要修改的位为1,不修改的位为0) OS_OPT opt,//改为1/改为0 OS_ERR *p_err)//错误返回 |
(3)等待事件标识组
OS_FLAGS OSFlagPend (OS_FLAG_GRP *p_grp,//指向事件标识组 OS_FLAGS flags,//代表要等待的位(要等待的位为1,不等待的位为0) OS_TICK timeout,//超时时间 OS_OPT opt,//等待选项 CPU_TS *p_ts,//时间戳 OS_ERR *p_err)//错误返回 |
四.等待多个内核对象
1.概念
等待多个内核对象允许等待多个不同的内核对象(信号量,消息队列,标识组),根据等到的不同的内核对象进行不同的处理,类似与Linux中多路复用
要使用等待多个内核对象的功能,需要将 宏 OS_CFG_PEND_MULTI_EN 的值置1
2.函数接口(等待)
OS_OBJ_QTY OSPendMulti (OS_PEND_DATA *p_pend_data_tbl,//等待对象数组 OS_OBJ_QTY tbl_size,//数组长度 OS_TICK timeout,//超时时间 OS_OPT opt,//等待选项 OS_ERR *p_err)//错误返回 //对象数组成员类型 struct os_pend_data { OS_PEND_DATA *PrevPtr; OS_PEND_DATA *NextPtr; OS_TCB *TCBPtr;//任务控制块 OS_PEND_OBJ *PendObjPtr;//要等待的对象 OS_PEND_OBJ *RdyObjPtr;//等到的对象 void *RdyMsgPtr;//消息首地址 OS_MSG_SIZE RdyMsgSize;//消息长度 CPU_TS RdyTS;//时间戳 }; |