参考B站up主【架构分析】嵌入式祼机事件驱动框架
感谢大佬分享
消息队列
消息分为hdr和bdy,把消息的头dhr和内容bdy做了一个分离的设计
dhr包括指向下一个消息的指针next,len在创建消息的时候使用,dest_id即目标任务,将消息和任务进行绑定。
bdy是消息的主体,包括数据data,还有事件id。
(注:这里的event_id和任务里的event_id 是不一样的,在任务中有个属性是事件集,表示对应于这个认为的事件集合,有16位,即一个任务最多可以对应16个事件,当有事件触发时,会将事件集对应位置1,通过按位或的方式。而消息中的event_id是不寿16限值的,当消息发送时,会将对应的任务的事件集中的最高位即消息事件置1,代表有消息来了,但是消息带来的是什么事件,这个事件event_id是不用按位或进事件集里的。消息里面的事件event_id做个区分,加个MSG,如EVE_MSG_PRINTSTAT)
消息队列的使用:
我们用户操作的都是消息主体bdy
osal_msg_alloc进行消息的内存分配以及初始化
然后使用osal_msg_send将消息发送到消息队列并触发对应任务的消息事件
在任务处理函数中呢,调用消息接收API 提取消息 osal_msg_receive,将消息bdy提取出来。提取出来之后保存,但是消息占用的空间其实还是存在的,调用osal_msg_free把消息给free掉,把占用的空间给释放掉。
其他的API用不太到
osal_msg.h
#ifndef OSAL_MSG_H #define OSAL_MSG_H #include "osal.h"
#include "osal_task.h" #define OSAL_MSG_NEXT(msg_ptr) ((osal_msg_hdr_t *) (msg_ptr) - 1)->next
#define OSAL_MSG_ID(msg_ptr) ((osal_msg_hdr_t *) (msg_ptr) - 1)->dest_id typedef void* osal_msg_queue_t; typedef struct
{ void *next; /* Pointer to next message in queue */ osal_uint16_t len; /* Length of message */ task_id_t dest_id; /* Destination task ID */
}osal_msg_hdr_t; typedef struct
{ event_id_t event_id; /* Event ID */ osal_uint8_t status; /* Status of event */
}osal_event_hdr_t; typedef struct
{ osal_event_hdr_t hdr; osal_uint8_t* data;
}osal_msg_bdy_t; osal_uint8_t *osal_msg_alloc(osal_uint16_t len);
osal_uint8_t osal_msg_free(void *msg_ptr);
osal_uint8_t osal_msg_send(task_id_t task_id, void *msg_ptr);
osal_uint8_t *osal_msg_receive(task_id_t task_id); osal_event_hdr_t *osal_msg_find(task_id_t task_id, event_id_t event_id);
osal_uint8_t osal_msg_count(task_id_t task_id, event_id_t event_id); void osal_msg_enqueue(void *msg_ptr);
void *osal_msg_dequeue(void);
void osal_msg_push(void *msg_ptr); #endif
宏
#define OSAL_MSG_NEXT(msg_ptr) ((osal_msg_hdr_t *) (msg_ptr) - 1)->next
#define OSAL_MSG_ID(msg_ptr) ((osal_msg_hdr_t *) (msg_ptr) - 1)->dest_id
宏还是要结合这个消息的结构来看
这里的参数msg_ptr呢,其实是bdy消息主体,先把msg_ptr强转为osal_msg_hdr_t,然后 - 1,就指向了hdr,然后就可以获取hdr的 next 或者dest_id了
注:我们在应用层获取到的都是bdy这个位置的指针,用户创建的也都是消息主体bdy,或者称为消息指针msg_ptr,然后消息的头dhr中的len是在分配消息函数的时候赋值的,dest_id是在发送函数中赋值的,next是在入队函数里将消息连接起来的
osal_msg.c
osal_msg.c全部源码
/************************************************************************************************** Filename: osal_msg.c Description: OSAL msg definition and manipulation functions.**************************************************************************************************/ /********************************************************************* * INCLUDES */#include "osal_msg.h"
#include "osal_memory.h" /********************************************************************* * MACROS */
/********************************************************************* * CONSTANTS */
/********************************************************************* * TYPEDEFS */
/********************************************************************* * GLOBAL VARIABLES */
/********************************************************************* * EXTERNAL VARIABLES */
/********************************************************************* * EXTERNAL FUNCTIONS */
/********************************************************************* * LOCAL VARIABLES */static osal_msg_queue_t msg_queue_head = NULL;
/********************************************************************* * LOCAL FUNCTION PROTOTYPES */static void osal_msg_enqueue(void *msg_ptr);
static void osal_msg_extract(void *msg_ptr,void *prev_ptr);
/********************************************************************* * FUNCTIONS *********************************************************************/ /********************************************************************* * @fn osal_msg_alloc * * @brief * * This function is called by a task to allocate a message buffer * into which the task will encode the particular message it wishes * to send. This common buffer scheme is used to strictly limit the * creation of message buffers within the system due to RAM size * limitations on the microprocessor. Note that all message buffers * are a fixed size (at least initially). The parameter len is kept * in case a message pool with varying fixed message sizes is later * created (for example, a pool of message buffers of size LARGE, * MEDIUM and SMALL could be maintained and allocated based on request * from the tasks). * * @param uint8 len - wanted buffer length * @return pointer to allocated buffer or NULL if allocation failed. */osal_uint8_t *osal_msg_alloc(osal_uint16_t len)
{ osal_msg_hdr_t *hdr; if ( len == 0 ) return NULL; hdr = (osal_msg_hdr_t *) osal_mem_alloc( (osal_uint16_t)(len + sizeof( osal_msg_hdr_t )) ); if ( hdr != NULL ) { hdr->next = NULL; hdr->len = len; hdr->dest_id = SYS_TSK_INIT; return (osal_uint8_t *)(hdr + 1); } else return NULL;
} /********************************************************************* * @fn osal_msg_free * * @brief * * This function is used to deallocate a message buffer. This function * is called by a task (or processing element) after it has finished * processing a received message. * * * @param uint8 *msg_ptr - pointer to new message buffer * * @return OSAL_SUCCESS, INVALID_MSG_POINTER */osal_uint8_t osal_msg_free(void *msg_ptr)
{ osal_uint8_t *ptr; if(msg_ptr == NULL || OSAL_MSG_ID(msg_ptr) != SYS_TSK_INIT){ return INVALID_MSG_POINTER; } ptr = (osal_uint8_t *)((osal_uint8_t *)msg_ptr - sizeof( osal_msg_hdr_t )); osal_mem_free((void *)ptr); return OSAL_SUCCESS;
} /********************************************************************* * @fn osal_msg_extract * * @brief * * This function extracts and removes an OSAL message from the * middle of an OSAL queue. * * @param osal_msg_q_t *q_ptr - OSAL queue * @param void *msg_ptr - OSAL message to be extracted * @param void *prev_ptr - OSAL message before msg_ptr in queue * * @return none */static void osal_msg_extract(void *msg_ptr,void *prev_ptr)
{ if (msg_ptr == msg_queue_head) { msg_queue_head = OSAL_MSG_NEXT(msg_ptr); }else{ OSAL_MSG_NEXT(prev_ptr) = OSAL_MSG_NEXT(msg_ptr); } OSAL_MSG_NEXT(msg_ptr) = NULL; OSAL_MSG_ID(msg_ptr) = SYS_TSK_INIT;
} /********************************************************************* * @fn osal_msg_send * * @brief * * This function is called by a task to send a command message to * another task or processing element. The sending_task field must * refer to a valid task, since the task ID will be used * for the response message. This function will also set a message * ready event in the destination tasks event list. * * * @param uint8 destination task - Send msg to? Task ID * @param uint8 *msg_ptr - pointer to new message buffer * @param uint8 len - length of data in message * * @return SUCCESS, INVALID_TASK, INVALID_MSG_POINTER */osal_uint8_t osal_msg_send(task_id_t task_id, void *msg_ptr)
{ if(msg_ptr == NULL){ return INVALID_MSG_POINTER; } if(osal_task_find(task_id) == NULL){ osal_msg_free(msg_ptr); return INVALID_TASK; } if(OSAL_MSG_NEXT(msg_ptr) != NULL || OSAL_MSG_ID(msg_ptr) != SYS_TSK_INIT){ osal_msg_free(msg_ptr); return INVALID_MSG_POINTER; } OSAL_MSG_ID(msg_ptr) = task_id; osal_msg_enqueue(msg_ptr); osal_task_seteve(task_id, SYS_EVE_MSG); return OSAL_SUCCESS;
} /********************************************************************* * @fn osal_msg_receive * * @brief * * This function is called by a task to retrieve a received command * message. The calling task must deallocate the message buffer after * processing the message using the osal_msg_deallocate() call. * * @param uint8 task_id - receiving tasks ID * * @return *uint8 - message information or NULL if no message */osal_uint8_t *osal_msg_receive(task_id_t task_id)
{ osal_msg_hdr_t *list_hdr; // Pointer to current message osal_msg_hdr_t *prev_hdr = NULL; // Pointer to previous message osal_msg_hdr_t *found_hdr = NULL; // Pointer to message to be extracted // Find the first message in the queue for the given task list_hdr = msg_queue_head; while (list_hdr != NULL) { //compare task id if((list_hdr - 1)->dest_id == task_id) { //If found for the first time, set found_hdr to current list_hdr //if not first time, break out of loop if(found_hdr == NULL){ found_hdr = list_hdr; }else{ break; } } //if not found, move prev_hdr to current list_hdr if(found_hdr == NULL){ prev_hdr = list_hdr; } // Move to next message in queue list_hdr = OSAL_MSG_NEXT(list_hdr); } // Set event for task if message found if(list_hdr != NULL){ osal_task_seteve(task_id, SYS_EVE_MSG); }else{ osal_task_clreve(task_id, SYS_EVE_MSG); } // Extract message from queue if(found_hdr != NULL){ osal_msg_extract(found_hdr, prev_hdr); }else{ return NULL; } // Return extracted message return (osal_uint8_t *)found_hdr;
} /********************************************************************* * @fn osal_msg_enqueue * * @brief * * This function enqueues an OSAL message into an OSAL queue. * * @param osal_msg_q_t *q_ptr - OSAL queue * @param void *msg_ptr - OSAL message * * @return none */static void osal_msg_enqueue(void *msg_ptr)
{ void *list; OSAL_MSG_NEXT(msg_ptr) = NULL; if (msg_queue_head == NULL) { msg_queue_head = msg_ptr; }else{ for(list = msg_queue_head; OSAL_MSG_NEXT(list) != NULL; list = OSAL_MSG_NEXT(list)); OSAL_MSG_NEXT(list) = msg_ptr; }
} /********************************************************************* * @fn osal_msg_dequeue * * @brief * * This function dequeues an OSAL message from an OSAL queue. * * @param osal_msg_q_t *q_ptr - OSAL queue * * @return void * - pointer to OSAL message or NULL of queue is empty. */void *osal_msg_dequeue(void)
{ void *msg_ptr = NULL; if (msg_queue_head != NULL) { msg_ptr = msg_queue_head; msg_queue_head = OSAL_MSG_NEXT(msg_ptr); OSAL_MSG_NEXT(msg_ptr) = NULL; OSAL_MSG_ID(msg_ptr) = SYS_TSK_INIT; } return msg_ptr;
} /********************************************************************* * @fn osal_msg_push * * @brief * * This function pushes an OSAL message to the head of an OSAL * queue. * * @param osal_msg_q_t *q_ptr - OSAL queue * @param void *msg_ptr - OSAL message * * @return none */void osal_msg_push(void *msg_ptr)
{ OSAL_MSG_NEXT(msg_ptr) = msg_queue_head; msg_queue_head = msg_ptr;
} /************************************************************************************************** * @fn osal_msg_find * * @brief This function finds in place an OSAL message matching the task_id and event * parameters. * * input parameters * * @param task_id - The OSAL task id that the enqueued OSAL message must match. * @param event - The OSAL event id that the enqueued OSAL message must match. * * output parameters * * None. * * @return NULL if no match, otherwise an in place pointer to the matching OSAL message. ************************************************************************************************** */osal_event_hdr_t *osal_msg_find(task_id_t task_id, event_id_t event_id)
{ osal_msg_hdr_t *header; header = (osal_msg_hdr_t *)msg_queue_head; while(header != NULL) { if(((header - 1)->dest_id == task_id) && (((osal_event_hdr_t *)header)->event_id == event_id)){ break; } header = OSAL_MSG_NEXT(header); } return (osal_event_hdr_t *)header;
} osal_uint8_t osal_msg_count(task_id_t task_id, event_id_t event_id)
{ osal_msg_hdr_t *header; osal_uint8_t msg_cnt = 0; header = msg_queue_head; while(header != NULL) { if(((header - 1)->dest_id == task_id) && ((event_id == SYS_EVE_ANY) || (((osal_event_hdr_t *)header)->event_id == event_id))){ msg_cnt++; } header = OSAL_MSG_NEXT(header); } return msg_cnt;
}
osal_msg_alloc
消息创建
msg_bdy才是消息的主体,才是我们真正想要发送的东西
传进来的参数len是msg_bdy的长度,
因为消息是有hdr+bdy一起构成的嘛,所以分配的空间长度是len + sizeof( osal_msg_hdr_t ),也就是下面这个图的长度
但是返回的指针是osal_msg_hdr_t,也就是指向最左边osal_msg_hdr_t
然后进行初始化,next指向NULL,dest_id现赋值一个SYS_TSK_INIT,等到发送函数中在指定任务id。返回的时候,hdr+1,就指向了hdr后面那块内存,也就是bdy的地址
/********************************************************************* * @fn osal_msg_alloc * * @brief * * This function is called by a task to allocate a message buffer * into which the task will encode the particular message it wishes * to send. This common buffer scheme is used to strictly limit the * creation of message buffers within the system due to RAM size * limitations on the microprocessor. Note that all message buffers * are a fixed size (at least initially). The parameter len is kept * in case a message pool with varying fixed message sizes is later * created (for example, a pool of message buffers of size LARGE, * MEDIUM and SMALL could be maintained and allocated based on request * from the tasks). * * @param uint8 len - wanted buffer length * @return pointer to allocated buffer or NULL if allocation failed. */osal_uint8_t *osal_msg_alloc(osal_uint16_t len)
{ osal_msg_hdr_t *hdr; if ( len == 0 ) return NULL; hdr = (osal_msg_hdr_t *) osal_mem_alloc( (osal_uint16_t)(len + sizeof( osal_msg_hdr_t )) ); if ( hdr != NULL ) { hdr->next = NULL; hdr->len = len; hdr->dest_id = SYS_TSK_INIT; return (osal_uint8_t *)(hdr + 1); } else return NULL;
}
osal_msg_free
释放消息内存
在消息处理后要释放消息内存
如果消息bdy == NULL 是空消息
如果消息的dest_id是SYS_TSK_INIT,则没处理完(处理完的消息会将它的dest_id置为SYS_TSK_INIT)
msg_ptr指向的是bdy,先转为osal_uint8_t,一个字节8位,然后减去osal_msg_hdr_t的大小,就获取到了osal_msg_hdr_t的最开头的地址,然后释放消息内存
/********************************************************************* * @fn osal_msg_free * * @brief * * This function is used to deallocate a message buffer. This function * is called by a task (or processing element) after it has finished * processing a received message. * * * @param uint8 *msg_ptr - pointer to new message buffer * * @return OSAL_SUCCESS, INVALID_MSG_POINTER */osal_uint8_t osal_msg_free(void *msg_ptr)
{ osal_uint8_t *ptr; if(msg_ptr == NULL || OSAL_MSG_ID(msg_ptr) != SYS_TSK_INIT){ return INVALID_MSG_POINTER; } ptr = (osal_uint8_t *)((osal_uint8_t *)msg_ptr - sizeof( osal_msg_hdr_t )); osal_mem_free((void *)ptr); return OSAL_SUCCESS;
}
osal_msg_send
消息发送
- 赋值dest_id
- 将消息入队
- 触发对应任务的消息事件
实际上是做了这么几个操作
首先检测
如果消息为NULL,则是无效消息
如果任务为NULL,则无效任务,将消息释放
如果消息的next!=NULL 或者消息的ID !=SYS_TSK_INIT,这是啥意思的呢?因为你这个消息msg_ptr到目前为止,还是没有入队的,也没有给它赋值dest_id,所以如果消息不满足这个条件,说明它被篡改了。
检测完消息后,赋值dest_id,入队,设置对应任务的系统消息事件
/********************************************************************* * @fn osal_msg_send * * @brief * * This function is called by a task to send a command message to * another task or processing element. The sending_task field must * refer to a valid task, since the task ID will be used * for the response message. This function will also set a message * ready event in the destination tasks event list. * * * @param uint8 destination task - Send msg to? Task ID * @param uint8 *msg_ptr - pointer to new message buffer * @param uint8 len - length of data in message * * @return SUCCESS, INVALID_TASK, INVALID_MSG_POINTER */osal_uint8_t osal_msg_send(task_id_t task_id, void *msg_ptr)
{ if(msg_ptr == NULL){ return INVALID_MSG_POINTER; } if(osal_task_find(task_id) == NULL){ osal_msg_free(msg_ptr); return INVALID_TASK; } if(OSAL_MSG_NEXT(msg_ptr) != NULL || OSAL_MSG_ID(msg_ptr) != SYS_TSK_INIT){ osal_msg_free(msg_ptr); return INVALID_MSG_POINTER; } OSAL_MSG_ID(msg_ptr) = task_id; osal_msg_enqueue(msg_ptr); osal_task_seteve(task_id, SYS_EVE_MSG); return OSAL_SUCCESS;
}
osal_msg_enqueue
消息入队
从消息队列尾添加一个消息
这里才是真正的消息入队,就像把消息连接起来
遍历链表,将消息插入队尾
/********************************************************************* * @fn osal_msg_enqueue * * @brief * * This function enqueues an OSAL message into an OSAL queue. * * @param osal_msg_q_t *q_ptr - OSAL queue * @param void *msg_ptr - OSAL message * * @return none */void osal_msg_enqueue(void *msg_ptr)
{ void *list; OSAL_MSG_NEXT(msg_ptr) = NULL; if (msg_queue_head == NULL) { msg_queue_head = msg_ptr; }else{ for(list = msg_queue_head; OSAL_MSG_NEXT(list) != NULL; list = OSAL_MSG_NEXT(list)); OSAL_MSG_NEXT(list) = msg_ptr; }
}
osal_msg_receive
消息接收函数
在消息发送函数中,调用消息入队函数,然后消息队列头msg_queue_head就会指向消息主体bdy了,而不是消息头hdr
那么这里遍历消息链表为什么将list_hdr定义为osal_msg_hdr_t呢?
首先msg_queue_head其实指向消息主体,那么由消息主体怎么获得消息头dhr呢,将消息主体强制转为osal_msg_hdr_t类型,然后在 -1 ,就得到消息头dhr了。
将list_hdr定义为osal_msg_hdr_t,就相当于省略了强转的这么一个步骤
list_hdr用于遍历消息队列
found_hdr是要提取出来的消息,且在函数最后要返回它
prev_hdr也是一直在移动的,但是它移动到哪里呢?移动到第一个found_hdr之前一个。prev_hdr的作用是将found_hdr提取出去之后,能使这个队列依然保持连接,不能扣掉一个就断了。
为什么说是第一个found_hdr呢?
因为有可能found_hdr不知一个
来依次看一下几种情况
- 消息队列中没有符合task_id的消息:
list_hdr会一直遍历,知道指向NULL。调用osal_task_clreve清除消息事件
prev_hdr指向队列最后一个消息。
因为没有符合task_id的消息,所以found_hdr指向NULL
返回NULL,没有消息提取出来 - 消息队列中只有一个符合task_id的消息msg:
遍历队列,找到符合消息后,found_hdr 就指向msg
prev_hdr指向msg的前一个消息
list_hdr还是一直在遍历,直到指向NULL,然后调用osal_task_clreve清除消息事件
osal_msg_extract会将msg提取出来,并保证队列的连接
返回msg的地址 - 消息队列中存在符合task_id的消息,且不止一个(发生了消息堆积),比如msg1,msg2:
遍历队列,找到符合消息后,found_hdr 就指向msg1
同样prev_hdr指向msg1 的前一个消息
list_hdr还是一直在遍历,但是又遇到了第二个msg2。看程序中如何处理的,found_hdr不指向NULL了,found_hdr 就指向msg1了,所以会break跳出循环。
跳出循环后,这时候list_hdr指向msg2。所以会调用osal_task_seteve再次触发任务的消息事件。
osal_msg_extract会将msg1提取出来,并保证队列的连接
返回msg1的地址
区别是什么呢,就是如果有多个消息,不会将消息事件位清除掉(事件集最高位),而是将其再次置位,因为有消息没处理完呀,所以会再次触发消息事件处理函数handler,然后再次调用消息接收函数osal_msg_receive,在把msg2提取出去。
/********************************************************************* * @fn osal_msg_receive * * @brief * * This function is called by a task to retrieve a received command * message. The calling task must deallocate the message buffer after * processing the message using the osal_msg_deallocate() call. * * @param uint8 task_id - receiving tasks ID * * @return *uint8 - message information or NULL if no message */osal_uint8_t *osal_msg_receive(task_id_t task_id)
{ osal_msg_hdr_t *list_hdr; // Pointer to current message osal_msg_hdr_t *prev_hdr = NULL; // Pointer to previous message osal_msg_hdr_t *found_hdr = NULL; // Pointer to message to be extracted // Find the first message in the queue for the given task list_hdr = msg_queue_head; while (list_hdr != NULL) { //compare task id
if((list_hdr - 1)->dest_id == task_id) { //If found for the first time, set found_hdr to current list_hdr //if not first time, break out of loop if(found_hdr == NULL){ found_hdr = list_hdr; }else{ break; } } //if not found, move prev_hdr to current list_hdr if(found_hdr == NULL){ prev_hdr = list_hdr; } // Move to next message in queue list_hdr = OSAL_MSG_NEXT(list_hdr); } // Set event for task if message found if(list_hdr != NULL){ osal_task_seteve(task_id, SYS_EVE_MSG); }else{ osal_task_clreve(task_id, SYS_EVE_MSG); } // Extract message from queue if(found_hdr != NULL){ osal_msg_extract(found_hdr, prev_hdr); }else{ return NULL; } // Return extracted message return (osal_uint8_t *)found_hdr;
}
osal_msg_extract
消息提取函数
将消息从消息队列中提取出来,并保存队列的连接性
/********************************************************************* * @fn osal_msg_extract * * @brief * * This function extracts and removes an OSAL message from the * middle of an OSAL queue. * * @param osal_msg_q_t *q_ptr - OSAL queue * @param void *msg_ptr - OSAL message to be extracted * @param void *prev_ptr - OSAL message before msg_ptr in queue * * @return none */static void osal_msg_extract(void *msg_ptr,void *prev_ptr)
{ if (msg_ptr == msg_queue_head) { msg_queue_head = OSAL_MSG_NEXT(msg_ptr); }else{ OSAL_MSG_NEXT(prev_ptr) = OSAL_MSG_NEXT(msg_ptr); } OSAL_MSG_NEXT(msg_ptr) = NULL; OSAL_MSG_ID(msg_ptr) = SYS_TSK_INIT;
}
osal_msg_find
我们说过msg_queue_head,队列头其实指向的是第一个消息的dby,这里只是强转为osal_msg_hdr_t类型,是为了-1后就可以获取消息的dest_id了。
查找消息呢,还要满足事件event_id一致。
header指向的其实是消息的bdy这个地址,那么osal_event_hdr hdr呢又是osal_msg_hdr_t的第一个元素,所以这两个其实是同一个地址,直接将header强转为osal_event_hdr_t类型,就可以访问event_id了
/************************************************************************************************** * @fn osal_msg_find * * @brief This function finds in place an OSAL message matching the task_id and event * parameters. * * input parameters * * @param task_id - The OSAL task id that the enqueued OSAL message must match. * @param event - The OSAL event id that the enqueued OSAL message must match. * * output parameters * * None. * * @return NULL if no match, otherwise an in place pointer to the matching OSAL message. ************************************************************************************************** */osal_event_hdr_t *osal_msg_find(task_id_t task_id, event_id_t event_id)
{ osal_msg_hdr_t *header; header = (osal_msg_hdr_t *)msg_queue_head; while(header != NULL) { if(((header - 1)->dest_id == task_id) && (((osal_event_hdr_t *)header)->event_id == event_id)){ break; } header = OSAL_MSG_NEXT(header); } return (osal_event_hdr_t *)header;
}
osal_msg_dequeue
从消息队列头提取一个消息
/********************************************************************* * @fn osal_msg_dequeue * * @brief * * This function dequeues an OSAL message from an OSAL queue. * * @param osal_msg_q_t *q_ptr - OSAL queue * * @return void * - pointer to OSAL message or NULL of queue is empty. */void *osal_msg_dequeue(void)
{ void *msg_ptr = NULL; if (msg_queue_head != NULL) { msg_ptr = msg_queue_head; msg_queue_head = OSAL_MSG_NEXT(msg_ptr); OSAL_MSG_NEXT(msg_ptr) = NULL; OSAL_MSG_ID(msg_ptr) = SYS_TSK_INIT; } return msg_ptr;
}
osal_msg_push
从消息队列头添加一个消息
/********************************************************************* * @fn osal_msg_push * * @brief * * This function pushes an OSAL message to the head of an OSAL * queue. * * @param osal_msg_q_t *q_ptr - OSAL queue * @param void *msg_ptr - OSAL message * * @return none */void osal_msg_push(void *msg_ptr)
{ OSAL_MSG_NEXT(msg_ptr) = msg_queue_head; msg_queue_head = msg_ptr;
}