UTIL序列器介绍
-
UTIL_SEQ是一个通用的、可配置的任务调度器,它提供了一种简单而灵活的方法来管理多个任务。它可以用于各种嵌入式系统中,包括单片机、嵌入式Linux系统等。
-
UTIL序列器通过使用一组全局变量来管理任务序列。这些变量包括:
TaskSet:表示当前需要执行的任务集合。
TaskMask:表示可以执行的任务集合。
SuperMask:表示可以暂停的任务集合。
EvtSet:表示当前已经发生的事件集合。
EvtWaited:表示当前正在等待的事件集合。
-
每个任务都可以被分配一个优先级,从而确定任务在任务序列中的执行顺序。
-
当一个任务完成时,序列器会检查 TaskSet 和 TaskMask,然后选择下一个需要执行的任务。如果没有任务需要执行,序列器将进入休眠状态,等待下一个事件的发生。
-
UTIL序列器还提供了一些其他的功能,例如:
时间延迟:允许任务在指定的时间延迟后再执行。
事件等待:允许任务等待某个事件的发生。
轮询任务:允许任务按照轮询方式执行,以确保每个任务都有机会被执行。
临界区保护:允许任务序列中的关键部分被保护起来,以避免竞争条件和死锁。
- UTIL_SEQ提供了一组API,用于管理任务序列的执行。这些API包括:
UTIL_SEQ_Init():初始化任务序列。
UTIL_SEQ_Run():启动任务序列的执行。
UTIL_SEQ_SetTask():设置任务的状态。
UTIL_SEQ_SetEvt():设置事件的状态。
UTIL_SEQ_WaitEvt():等待指定事件的发生。
初始化函数 UTIL_SEQ_Init() 介绍
// 初始化实例如下:
void UTIL_SEQ_Init( void )
{
//表示当前需要执行的任务集合。UTIL_SEQ_NO_BIT_SET意味着没有任务需要执行。
TaskSet = UTIL_SEQ_NO_BIT_SET;
//表示可以执行的任务集合。UTIL_SEQ_ALL_BIT_SET表示所有任务都可以执行。
TaskMask = UTIL_SEQ_ALL_BIT_SET;
//表示可以暂时禁用的任务集合。UTIL_SEQ_ALL_BIT_SET表示所有任务都可以暂停。
SuperMask = UTIL_SEQ_ALL_BIT_SET;
//表示当前已经发生的事件集合。UTIL_SEQ_NO_BIT_SET意味着没有事件发生。
EvtSet = UTIL_SEQ_NO_BIT_SET;
//表示当前正在等待的事件集合。UTIL_SEQ_NO_BIT_SET意味着没有事件需要等待。
EvtWaited = UTIL_SEQ_NO_BIT_SET;
CurrentTaskIdx = 0U;
//使用UTIL_SEQ_MEMSET8函数将全局变量TaskCb的所有元素初始化为0
(void)UTIL_SEQ_MEMSET8((uint8_t *)TaskCb, 0, sizeof(TaskCb));
//使用for循环将TaskPrio数组中的所有元素初始化为0
for(uint32_t index = 0; index < UTIL_SEQ_CONF_PRIO_NBR; index++)
{
TaskPrio[index].priority = 0;
TaskPrio[index].round_robin = 0;
}
//调用UTIL_SEQ_INIT_CRITICAL_SECTION函数,该函数用于初始化任务序列的关键部分
UTIL_SEQ_INIT_CRITICAL_SECTION( );
}
启动函数 UTIL_SEQ_Run() 介绍
void UTIL_SEQ_Run( UTIL_SEQ_bm_t Mask_bm );
typedef uint32_t UTIL_SEQ_bm_t;
// 启动任务序列的执行,并允许所有任务都可以执行
#define UTIL_SEQ_DEFAULT (~0U)
UTIL_SEQ_Run(UTIL_SEQ_DEFAULT);
-
UTIL_SEQ_Run是 UTIL 序列器中的一个函数,它用于启动任务序列的执行。当 UTIL_SEQ_Run 被调用时,任务序列会开始执行,直到所有任务都被执行完毕或者没有任务需要执行。
-
UTIL_SEQ_Run 的实现通常包括一个无限循环,以便不断地检查和执行任务。在每次循环中,UTIL_SEQ_Run 会检查 TaskSet 和 TaskMask,以确定下一个需要执行的任务。如果没有任务需要执行,UTIL_SEQ_Run 会等待下一个事件的发生,或者进入休眠状态以节省系统资源。
-
在 UTIL_SEQ_Run 的实现中,通常还会包括一些其他的功能,例如:
时间延迟:在检查和执行任务之前,UTIL_SEQ_Run会检查是否有任务需要在指定的时间延迟后执行。
事件等待:如果某个任务需要等待某个事件的发生,UTIL_SEQ_Run会将该任务从TaskSet中删除,并将其添加到EvtWaited中,直到事件发生为止。
临界区保护:UTIL_SEQ_Run会使用临界区保护机制来确保关键部分在任务序列执行时不会出现竞争条件或死锁。
任务相关函数介绍
// 任务注册函数 UTIL_SEQ_RegTask()
void UTIL_SEQ_RegTask( UTIL_SEQ_bm_t TaskId_bm, uint32_t Flags, void (*Task)( void ) );
// 任务设置函数 UTIL_SEQ_SetTask()
void UTIL_SEQ_SetTask( UTIL_SEQ_bm_t TaskId_bm , uint32_t Task_Prio );
// 任务停止函数 UTIL_SEQ_PauseTask()
void UTIL_SEQ_PauseTask( UTIL_SEQ_bm_t TaskId_bm );
// 任务恢复函数 UTIL_SEQ_ResumeTask()
void UTIL_SEQ_ResumeTask( UTIL_SEQ_bm_t TaskId_bm );
-
UTIL_SEQ_RegTask():该函数用于注册一个任务,即将任务的执行函数和参数注册到任务管理器中。它接受三个参数:TaskId_bm 表示任务的ID(标识符),Flags表示任务的标志,Task表示任务的执行函数。
-
UTIL_SEQ_SetTask():该函数用于设置一个任务的执行函数和参数。它接受两个参数:TaskId_bm 是任务的ID,Task_Prio表示任务的优先级。
-
UTIL_SEQ_PauseTask():该函数用于暂停一个任务的执行。它接受一个参数:TaskId_bm是任务的ID。
-
UTIL_SEQ_ResumeTask():该函数用于恢复一个暂停的任务的执行。它接受一个参数:TaskId_bm 是任务的ID。
-
通过使用这些函数,可以方便地创建和管理多个任务,实现多任务调度。
事件相关函数介绍
// 设置事件函数
void UTIL_SEQ_SetEvt( UTIL_SEQ_bm_t EvtId_bm );
// 清除事件函数
void UTIL_SEQ_ClrEvt( UTIL_SEQ_bm_t EvtId_bm );
// 等待事件函数
void UTIL_SEQ_WaitEvt( UTIL_SEQ_bm_t EvtId_bm );
// 设置等待事件函数
void UTIL_SEQ_EvtIdle( UTIL_SEQ_bm_t TaskId_bm, UTIL_SEQ_bm_t EvtWaited_bm );
-
UTIL_SEQ_SetEvt()、UTIL_SEQ_ClrEvt() 一般和 UTIL_SEQ_WaitEvt() 结合使用,以等待事件触发再往下执行
-
UTIL_SEQ_WaitEvt()函数可以等待设置的特定事件。序列器将会一直循环 UTIL_SEQ_EvtIdle(),直到设置事件触发为止。
-
UTIL_SEQ_EvtIdle()可以设置事件空闲时的执行函数,比如让控制器进入低功耗模式
-
UTIL_SEQ_SetEvt():该函数用于设置一个事件的状态为“已发生”(signaled)。它接受一个参数:EvtId_bm是事件的ID(标识符)。
-
UTIL_SEQ_ClrEvt():该函数用于清除一个事件的状态为“未发生”(unsigaled)。它接受一个参数:EvtId_bm是事件的ID。
-
UTIL_SEQ_WaitEvt():该函数用于等待一个事件的发生。如果事件没有发生,函数会将当前任务挂起等待。它接受一个参数:EvtId_bm是事件的ID。
-
UTIL_SEQ_EvtIdle():该函数用于在任务空闲时等待一个事件的发生。如果事件没有发生,函数会将当前任务挂起等待。它接受两个参数:TaskId_bm是任务的ID,EvtWaited_bm是等待的事件的ID。