今天刚好看到这个API函数就分析一下,这个API主要是实现主动让出CPU给同一优先级或更高优先级的任务。首先看一下源码。源码中我删除了一些check以及debug类的代码,便于理解源码逻辑
源码分析
VOID _tx_thread_relinquish(VOID)
{
TX_INTERRUPT_SAVE_AREA //定义了一个用于保存中断信息的变量
UINT priority;
TX_THREAD *thread_ptr;
...
首先我们看一下函数的变量定义,主要分析TX_INTERRUPT_SAVE_AREA
宏定义,其定义了一个变量用于保存中断信息,后续在TX_DISABLE
与TX_RESTORE
中使用
#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save;
#define TX_DISABLE interrupt_save = __disable_interrupts();
#define TX_RESTORE __restore_interrupts(interrupt_save);
...
TX_THREAD_GET_CURRENT(thread_ptr) //获取当前任务指针
/* 关中断 */
TX_DISABLE
#ifndef TX_NO_TIMER
/* 复位任务的时间片值 */
_tx_timer_time_slice = thread_ptr -> tx_thread_new_time_slice;
#endif
/* 获取任务的优先级 */
priority = thread_ptr -> tx_thread_priority;
/* 判断是否有与当前任务同一优先级的其他任务 */
if (thread_ptr -> tx_thread_ready_next != thread_ptr)
{
/* 同一优先级有多个任务,将此优先级列表指向下一个任务控制块 */
_tx_thread_priority_list[priority] = thread_ptr -> tx_thread_ready_next;
/* 赋值给_tx_thread_execute_ptr表明下一个要运行的任务 */
_tx_thread_execute_ptr = thread_ptr -> tx_thread_ready_next;
}
/* 判断一下是否有更高优先级的任务就绪 */
if (_tx_thread_highest_priority < priority)
{
/* 有,设置_tx_thread_execute_ptr为最高优先级对应的任务控制块 */
_tx_thread_execute_ptr = _tx_thread_priority_list[_tx_thread_highest_priority];
/* No need to clear the preempted bit in this case, since the currently running
thread must already have its preempted bit clear. */
}
/* 恢复中断 */
TX_RESTORE
...
然后主要分析一下如何判断与档期那任务同一优先级是否有其他任务if (thread_ptr -> tx_thread_ready_next != thread_ptr)
如图片所示,Threadx的任务模型,同一优先级多个任务采用双向循环链表的形式存储,只有一个任务时其next指针将指向自己
...
/* 判断是否需要返回到系统调用中去 */
if (_tx_thread_execute_ptr != thread_ptr)
{
/* 返回到系统中去以启动系统任务调度 */
_tx_thread_system_return();
}
这段代码主要使判断是需要进行因此任务调度。
流程图
相关知识分析
下面这些指令效果使一样的
CPSID I ;PRIMASK=1, ;关中断
CPSIE I ;PRIMASK=0, ;开中断
CPSID F ;FAULTMASK=1, ;关异常
CPSIE F ;FAULTMASK=0 ;开异常