欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 维修 > 基于OSAL的嵌入式裸机事件驱动框架——事件及任务osal_task

基于OSAL的嵌入式裸机事件驱动框架——事件及任务osal_task

2025/2/21 3:14:58 来源:https://blog.csdn.net/rerrick_rose/article/details/145371187  浏览:    关键词:基于OSAL的嵌入式裸机事件驱动框架——事件及任务osal_task

参考B站up主【架构分析】嵌入式祼机事件驱动框架
感谢大佬分享


用户任务通过单向链表连接起来,最后一项指向NULL
task_id 唯一且充当优先级的作用,task_id越大,优先级越高
每个任务最多可以对应16个独立事件,最高位对应消息队列事件,留给用户设置0-14位。(注:事件集这16个事件只针对于此一个任务)
![[Pasted image 20250124221941.png]]

osal_event.h

#ifndef  OSAL_EVENT_H  
#define  OSAL_EVENT_H  #include "osal.h"  #define SYS_EVE_NONE      (0)        //无事件  
#define SYS_EVE_MSG       (1<<15)    //消息事件  
#define SYS_EVE_ANY       (0xFFFF)   //任意事件  #define SYS_TSK_INIT      (0xFFFF)   //系统任务初始化  typedef osal_uint16_t  task_id_t;    //任务ID类型定义  
typedef osal_uint16_t  task_prio_t;  //任务优先级类型定义  
typedef osal_uint16_t  event_id_t;   //事件类型定义  
typedef event_id_t     event_asb_t;  //事件集类型定义  typedef struct _osal_task_ops  
{  void (*init)(task_id_t task_id);                                    //任务初始化函数  osal_uint16_t (*handler)(task_id_t task_id,event_asb_t events);     //任务事件处理函数  
}osal_task_ops_t;  typedef struct _osal_task  
{  struct _osal_task *next;                //下一个任务  task_id_t task_id;                      //任务ID  event_asb_t events;                     //任务事件集  struct _osal_task_ops *ops;             //任务操作函数  
}osal_task_t;  /*函数接口  * osal event task functions prototype*/  
osal_uint16_t osal_task_create(osal_task_ops_t *ops,task_id_t task_id);  
void osal_task_init(void);  osal_task_t *osal_task_active(void);  
osal_task_t *osal_task_find(task_id_t task_id);  
osal_uint16_t osal_task_cnt(void);  osal_uint8_t osal_task_seteve(task_id_t task_id,event_id_t event_id);  
osal_uint8_t osal_task_clreve(task_id_t task_id,event_id_t event_id);  #endif

osal_event.c

#include "osal_event.h"  
#include "osal_memory.h"  static osal_task_t *task_head = NULL;       //任务链表头指针  /***************************************************************************  * @fn       osal_task_init * * @brief   init task * * @param   none * * @return */void osal_task_init(void)  
{  osal_task_t *task_index;//任务索引  task_index = task_head;  //遍历任务链表,初始化任务  while(task_index != NULL)  {  if(task_index->ops->init != NULL)  {  task_index->ops->init(task_index->task_id);  }  task_index = task_index->next;  }  task_index = (osal_task_t *)NULL;  
}  
/***************************************************************************  * @fn       osal_task_create * * @brief   osal_task_create * * @param   none * * @return */osal_uint16_t osal_task_create(osal_task_ops_t *ops,task_id_t task_id)  
{  osal_task_t *task_new;  osal_task_t *task_sech;  osal_task_t **task_index;  task_index = &task_head;  task_sech = task_head;  //申请内存空间  task_new = (osal_task_t *)osal_mem_alloc(sizeof(osal_task_t));  task_new->ops = (osal_task_ops_t *)osal_mem_alloc(sizeof(osal_task_ops_t));  if(task_new == NULL || task_new->ops == NULL){  return INVALID_TASK;  }  //任务初始化  task_new->ops->init = ops->init;  task_new->ops->handler = ops->handler;  task_new->task_id = task_id;  task_new->events = SYS_EVE_NONE;  task_new->next = (osal_task_t *)NULL;  /*遍历任务链表,插入新任务  * 1,任务链表为空,不会进入循环,直接退出  * 2,任务链表不为空,从head开始遍历任务链表  *    task_new的id大于task_sech,则将task_new插入到task_sech之前  *    遍历过程中一直没有插入,则将task_new插入到链表尾部*/  while(task_sech != NULL)  {  if(task_new->task_id > task_sech->task_id){  task_new->next = task_sech;  *task_index = task_new;  return OSAL_SUCCESS;  }  task_index = &task_sech->next;  task_sech = task_sech->next;  }  /*其实这里是task_sech->next = task_new,但是经过遍历之后,task_sech已经指向NULL了,不能将task_new赋值给task_sech->next,  * 所以这里是*task_index = task_new;即将task_new插入到task_sech之后*/  *task_index = task_new;  return OSAL_SUCCESS;  
}  /*********************************************************************  * @fn      osal_task_active * * @brief   This function will return the active task. * * NOTE:    Task queue is in priority order. We can stop at the *          first task that is "ready" (events element non-zero) * * @param   none * * @return  pointer to the found task, NULL if not found */osal_task_t *osal_task_active(void)  
{  osal_task_t *task_sech;  task_sech = task_head;  while(task_sech != NULL)  {  if(task_sech->events != SYS_EVE_NONE){  return task_sech;  }  task_sech = task_sech->next;  }  return NULL;  
}  /*********************************************************************  * @fn      osal_task_find * * @brief   This function will return the taskid task. * * NOTE:    Task queue is in priority order. We can stop at the *          first task that is "ready" (events element non-zero) * * @param   task_id * * @return  pointer to the found task, NULL if not found */osal_task_t *osal_task_find(task_id_t task_id)  
{  osal_task_t *task_sech;  task_sech = task_head;  while(task_sech != NULL)  {  if(task_sech->task_id == task_id){  return task_sech;  }  task_sech = task_sech->next;  }  return NULL;  
}  osal_uint16_t osal_task_cnt(void)  
{  osal_task_t *task_sech;  osal_uint16_t cnt = 0;  task_sech = task_head;  while(task_sech != NULL)  {  cnt++;  task_sech = task_sech->next;  }  return cnt;  
}  
/*********************************************************************  * @fn      osal_task_seteve * * @brief * *    This function is called to set the event flags for a task.  The *    event passed in is OR'd into the task's event variable. * * @param   byte task_id - receiving tasks ID * @param   byte event_flag - what event to set * * @return  OSAL_SUCCESS, INVALID_TASK */osal_uint8_t osal_task_seteve(task_id_t task_id,event_id_t event_id)  
{  osal_task_t *task;  task = osal_task_find(task_id);  if(task != NULL) {  OSAL_ENTER_CRITICAL();  task->events |= event_id;  OSAL_EXIT_CRITICAL();  }else{  return INVALID_TASK;  }  return OSAL_SUCCESS;  
}  /*********************************************************************  * @fn      osal_task_clreve * * @brief * *    This function is called to clear the event flags for a task. The *    event passed in is masked out of the task's event variable. * * @param   uint8 task_id - receiving tasks ID * @param   uint8 event_flag - what event to clear * * @return  OSAL_SUCCESS, INVALID_TASK */osal_uint8_t osal_task_clreve(task_id_t task_id,event_id_t event_id)  
{  osal_task_t *task;  task = osal_task_find(task_id);  if(task != NULL) {  OSAL_ENTER_CRITICAL();  task->events &= ~event_id;  OSAL_EXIT_CRITICAL();  }else{  return INVALID_TASK;  }  return OSAL_SUCCESS;  
}

osal_task_create

创建任务,按照优先级(task_id)顺序插入任务链表中

/***************************************************************************  * @fn       osal_task_create * * @brief   osal_task_create * * @param   none * * @return */osal_uint16_t osal_task_create(osal_task_ops_t *ops,task_id_t task_id)  
{  osal_task_t *task_new;  osal_task_t *task_sech;  osal_task_t **task_index;  task_index = &task_head;  task_sech = task_head;  //申请内存空间  task_new = (osal_task_t *)osal_mem_alloc(sizeof(osal_task_t));  task_new->ops = (osal_task_ops_t *)osal_mem_alloc(sizeof(osal_task_ops_t));  if(task_new == NULL || task_new->ops == NULL){  return INVALID_TASK;  }  //任务初始化  task_new->ops->init = ops->init;  task_new->ops->handler = ops->handler;  task_new->task_id = task_id;  task_new->events = SYS_EVE_NONE;  task_new->next = (osal_task_t *)NULL;  /*遍历任务链表,插入新任务  * 1,任务链表为空,不会进入循环,直接退出  * 2,任务链表不为空,从head开始遍历任务链表  *    task_new的id大于task_sech,则将task_new插入到task_sech之前  *    遍历过程中一直没有插入,则将task_new插入到链表尾部*/  while(task_sech != NULL)  {  if(task_new->task_id > task_sech->task_id){  task_new->next = task_sech;  *task_index = task_new;  return OSAL_SUCCESS;  }  task_index = &task_sech->next;  task_sech = task_sech->next;  }  /*其实这里是task_sech->next = task_new,但是经过遍历之后,task_sech已经指向NULL了,不能将task_new赋值给task_sech->next,  * 所以这里是*task_index = task_new;即将task_new插入到task_sech之后*/  *task_index = task_new;  return OSAL_SUCCESS;  
}

osal_task_init

任务初始化
遍历任务链表,执行每个任务的init函数

/***************************************************************************  * @fn       osal_task_init * * @brief   init task * * @param   none * * @return */void osal_task_init(void)  
{  osal_task_t *task_index;//任务索引  task_index = task_head;  //遍历任务链表,初始化任务  while(task_index != NULL)  {  if(task_index->ops->init != NULL)  {  task_index->ops->init(task_index->task_id);  }  task_index = task_index->next;  }  task_index = (osal_task_t *)NULL;  
}

osal_task_active

任务按照优先级(task_id)顺序排列,找到第一个事件集非空的任务,返回任务句柄

/*********************************************************************  * @fn      osal_task_active * * @brief   This function will return the active task. * * NOTE:    Task queue is in priority order. We can stop at the *          first task that is "ready" (events element non-zero) * * @param   none * * @return  pointer to the found task, NULL if not found */osal_task_t *osal_task_active(void)  
{  osal_task_t *task_sech;  task_sech = task_head;  while(task_sech != NULL)  {  if(task_sech->events != SYS_EVE_NONE){  return task_sech;  }  task_sech = task_sech->next;  }  return NULL;  
}

osal_task_seteve

设置任务事件
将任务事件集中的某个事件置位,或上某位

/*********************************************************************  * @fn      osal_task_seteve * * @brief * *    This function is called to set the event flags for a task.  The *    event passed in is OR'd into the task's event variable. * * @param   byte task_id - receiving tasks ID * @param   byte event_flag - what event to set * * @return  OSAL_SUCCESS, INVALID_TASK */osal_uint8_t osal_task_seteve(task_id_t task_id,event_id_t event_id)  
{  osal_task_t *task;  task = osal_task_find(task_id);  if(task != NULL) {  OSAL_ENTER_CRITICAL();  task->events |= event_id;  OSAL_EXIT_CRITICAL();  }else{  return INVALID_TASK;  }  return OSAL_SUCCESS;  
}

osal_task_clreve

清除任务事件
将任务事件集中某位清0

/*********************************************************************  * @fn      osal_task_clreve * * @brief * *    This function is called to clear the event flags for a task. The *    event passed in is masked out of the task's event variable. * * @param   uint8 task_id - receiving tasks ID * @param   uint8 event_flag - what event to clear * * @return  OSAL_SUCCESS, INVALID_TASK */osal_uint8_t osal_task_clreve(task_id_t task_id,event_id_t event_id)  
{  osal_task_t *task;  task = osal_task_find(task_id);  if(task != NULL) {  OSAL_ENTER_CRITICAL();  task->events &= ~event_id;  OSAL_EXIT_CRITICAL();  }else{  return INVALID_TASK;  }  return OSAL_SUCCESS;  
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词