中级会员
 
- 积分
- 335
- 金钱
- 335
- 注册时间
- 2014-5-25
- 在线时间
- 67 小时
|
本帖最后由 lotoohe 于 2016-8-29 20:09 编辑
最新的zrtos以及实现了timer了,软件定时器,并且任务也不需要写在一个for循环中了,后面揭晓
在zrtos中的消息邮箱,是由一个消息控制块来存放信息,函数来处理信息,这就和面向对象编程中的类的操作方式有一点相识,
在zrtos中的消息邮箱是一个先进先出的消息队列,消息队列的长度是由数组来控制的,为什么不用动态内存分配与链表内:
主要有两个原因:1.内存分配就可能出现内存的泄露。2.方便学习,代码简单。
下面来看看我的的消息队列的控制块:
typedef struct _TCB_MSG{
//消息id
uint32 msg_id;
//队首指针
int32 head_index;
//消息,存放的指针,必须将指针强制转换为uint32类型
uint32 msg[MSG_MAX_LEN];
}TCB_MSG;
当我们每一次进行消息存放或存取成功的时候都会进行队列头指针的更新与消息队列的更新,我们来看看下面的代码:
/**
* 存放消息.
* 存放消息到消息控制块
* @param[in] mTCB_MSG 要存放的消息的消息控制块
* @param[in] msg 要发送的消息的地址
* @param[in] msg_get_delay 存放消息的超时时间,为0xffffffff时一直等待
* @retval true 成功
* @retval false 内存申请失败
*/
uint32 msg_put(TCB_MSG* mTCB_MSG,uint32 msg,uint32 msg_get_delay){
if(mTCB_MSG==null){return false;}
//如果等待时间没有限制
if(msg_get_delay==MSG_WAIT_ENDLESS){
//一直等待直到邮箱有空
for(;mTCB_MSG->head_index >= MSG_MAX_LEN-1;);
}else{
//如果邮箱满了
if(mTCB_MSG->head_index >= MSG_MAX_LEN-1){
//等待一段时间
if(msg_get_delay!=0){
//进行延时等待
os_task_delay(msg_get_delay);
}
//如果还满则退出
if(mTCB_MSG->head_index >= MSG_MAX_LEN-1){
return false;
}
}
}
enter_int();
mTCB_MSG->head_index++;
//存放消息
(mTCB_MSG->msg)[mTCB_MSG->head_index] = msg;
exit_int();
return true;
}
在存放消息的时候我们会先判断队列是否已经满了,然后在根据队列头指针进行消息的存放,如果我们要取消息怎么操作的内,下面我们来看一下:
/**
* 获取消息.
* 从消息队列中获取消息
* @param[in] mTCB_MSG 要获取的消息的消息控制块
* @param[in] msg 要获取的消息存放地址
* @param[in] msg_get_delay 获取消息的超时时间,为0xffffffff时一直等待
* @retval true 成功
* @retval false 内存申请失败
*/
uint32 msg_get(TCB_MSG* mTCB_MSG,void **msg,uint32 msg_get_delay){
int32 i=0;
if(mTCB_MSG==null){return false;}
do{
//没有消息
if(mTCB_MSG->head_index<0){
//如果一直等待
if(msg_get_delay==MSG_WAIT_ENDLESS){
continue;
}
//等待一段时间
if(msg_get_delay!=0){
os_task_delay(msg_get_delay);
}
//还没有消息则退出
if(mTCB_MSG->head_index<0){
return false;
}
}
//有消息
enter_int();
//获取消息
*msg = (void*)mTCB_MSG->msg[0];
//消息右移
for(i=1;i<MSG_MAX_LEN;i++){
mTCB_MSG->msg[i-1]=mTCB_MSG->msg;
}
//队列头减1
mTCB_MSG->head_index--;
exit_int();
return true;
}while(msg_get_delay==MSG_WAIT_ENDLESS);
return false;
}
在取消息中,我们先看消息队列中是否存在有数据,如果有数据,我们则从消息队列中取出最底下的一个数据,然后在将消息队列中的数据向右移动一个。
当然这些都是在临界区完成的。
在使用是,我们需要创建一个消息邮箱 TCB_MSG* msg_create(void);该函数返回一个新的消息控制块,然后我们就可以使用这个消息控制块了。
总的来说zrtos中的消息队列还是非常的简单的。
上次说更新了zrtos的timer,稍后发上来。
zrtos v0.12 源代码:
zrtos操作统.zip
(2.58 MB, 下载次数: 47)
|
|