编辑
2025-03-30
工作知识
0

目录

一、RTEMS结构体
二、调度器初始化
三、执行调度
四、主动让出
五、阻塞任务调度
六、恢复阻塞任务调度
七、更新任务优先级
八、映射优先级到调度器
九、映射优先级到应用
十、任务的调度器节点初始化/销毁
十一、周期任务创建和销毁
十二、启动空闲任务

rtems作为操作系统,支持任务的调度,对应于程序而言,我们需要清楚的知道任务的调度场景,本文结合rtems的调度结构体,描述一下rtems支持的调度场景

一、RTEMS结构体

默认结构体如下:

typedef struct { /** @see _Scheduler_Handler_initialization() */ void ( *initialize )( const Scheduler_Control * ); /** @see _Scheduler_Schedule() */ void ( *schedule )( const Scheduler_Control *, Thread_Control *); /** @see _Scheduler_Yield() */ void ( *yield )( const Scheduler_Control *, Thread_Control *, Scheduler_Node * ); /** @see _Scheduler_Block() */ void ( *block )( const Scheduler_Control *, Thread_Control *, Scheduler_Node * ); /** @see _Scheduler_Unblock() */ void ( *unblock )( const Scheduler_Control *, Thread_Control *, Scheduler_Node * ); /** @see _Scheduler_Update_priority() */ void ( *update_priority )( const Scheduler_Control *, Thread_Control *, Scheduler_Node * ); /** @see _Scheduler_Map_priority() */ Priority_Control ( *map_priority )( const Scheduler_Control *, Priority_Control ); /** @see _Scheduler_Unmap_priority() */ Priority_Control ( *unmap_priority )( const Scheduler_Control *, Priority_Control ); #if defined(RTEMS_SMP) /** * @brief Ask for help operation. * * @param[in] scheduler The scheduler instance to ask for help. * @param[in] the_thread The thread needing help. * @param[in] node The scheduler node. * * @retval true Ask for help was successful. * @retval false Otherwise. */ bool ( *ask_for_help )( const Scheduler_Control *scheduler, Thread_Control *the_thread, Scheduler_Node *node ); /** * @brief Reconsider help operation. * * @param[in] scheduler The scheduler instance to reconsider the help * request. * @param[in] the_thread The thread reconsidering a help request. * @param[in] node The scheduler node. */ void ( *reconsider_help_request )( const Scheduler_Control *scheduler, Thread_Control *the_thread, Scheduler_Node *node ); /** * @brief Withdraw node operation. * * @param[in] scheduler The scheduler instance to withdraw the node. * @param[in] the_thread The thread using the node. * @param[in] node The scheduler node to withdraw. * @param[in] next_state The next thread scheduler state in case the node is * scheduled. */ void ( *withdraw_node )( const Scheduler_Control *scheduler, Thread_Control *the_thread, Scheduler_Node *node, Thread_Scheduler_state next_state ); /** * @brief Makes the node sticky. * * This operation is used by _Thread_Priority_update_and_make_sticky(). It * is only called for the scheduler node of the home scheduler. * * Uniprocessor schedulers schould provide * _Scheduler_default_Sticky_do_nothing() for this operation. * * SMP schedulers should provide this operation using * _Scheduler_SMP_Make_sticky(). * * The make and clean sticky operations are an optimization to simplify the * control flow in the update priority operation. The update priority * operation is used for all scheduler nodes and not just the scheduler node * of home schedulers. The update priority operation is a commonly used * operations together with block and unblock. The make and clean sticky * operations are used only in specific scenarios. * * @param scheduler is the scheduler of the node. * * @param[in, out] the_thread is the thread owning the node. * * @param[in, out] node is the scheduler node to make sticky. */ void ( *make_sticky )( const Scheduler_Control *scheduler, Thread_Control *the_thread, Scheduler_Node *node ); /** * @brief Cleans the sticky property from the node. * * This operation is used by _Thread_Priority_update_and_clean_sticky(). It * is only called for the scheduler node of the home scheduler. * * Uniprocessor schedulers schould provide * _Scheduler_default_Sticky_do_nothing() for this operation. * * SMP schedulers should provide this operation using * _Scheduler_SMP_Clean_sticky(). * * @param scheduler is the scheduler of the node. * * @param[in, out] the_thread is the thread owning the node. * * @param[in, out] node is the scheduler node to clean the sticky property. */ void ( *clean_sticky )( const Scheduler_Control *scheduler, Thread_Control *the_thread, Scheduler_Node *node ); /** * @brief Pin thread operation. * * @param[in] scheduler The scheduler instance of the specified processor. * @param[in] the_thread The thread to pin. * @param[in] node The scheduler node of the thread. * @param[in] cpu The processor to pin the thread. */ void ( *pin )( const Scheduler_Control *scheduler, Thread_Control *the_thread, Scheduler_Node *node, struct Per_CPU_Control *cpu ); /** * @brief Unpin thread operation. * * @param[in] scheduler The scheduler instance of the specified processor. * @param[in] the_thread The thread to unpin. * @param[in] node The scheduler node of the thread. * @param[in] cpu The processor to unpin the thread. */ void ( *unpin )( const Scheduler_Control *scheduler, Thread_Control *the_thread, Scheduler_Node *node, struct Per_CPU_Control *cpu ); /** * @brief Add processor operation. * * @param[in] scheduler The scheduler instance to add the processor. * @param[in] idle The idle thread of the processor to add. */ void ( *add_processor )( const Scheduler_Control *scheduler, Thread_Control *idle ); /** * @brief Remove processor operation. * * @param[in] scheduler The scheduler instance to remove the processor. * @param[in] cpu The processor to remove. * * @return The idle thread of the removed processor. */ Thread_Control *( *remove_processor )( const Scheduler_Control *scheduler, struct Per_CPU_Control *cpu ); #endif /** @see _Scheduler_Node_initialize() */ void ( *node_initialize )( const Scheduler_Control *, Scheduler_Node *, Thread_Control *, Priority_Control ); /** @see _Scheduler_Node_destroy() */ void ( *node_destroy )( const Scheduler_Control *, Scheduler_Node * ); /** @see _Scheduler_Release_job() */ void ( *release_job ) ( const Scheduler_Control *, Thread_Control *, Priority_Node *, uint64_t, Thread_queue_Context * ); /** @see _Scheduler_Cancel_job() */ void ( *cancel_job ) ( const Scheduler_Control *, Thread_Control *, Priority_Node *, Thread_queue_Context * ); /** @see _Scheduler_Start_idle() */ void ( *start_idle )( const Scheduler_Control *, Thread_Control *, struct Per_CPU_Control * ); #if defined(RTEMS_SMP) /** @see _Scheduler_Set_affinity() */ Status_Control ( *set_affinity )( const Scheduler_Control *, Thread_Control *, Scheduler_Node *, const Processor_mask * ); #endif } Scheduler_Operations;

针对结构体的成员,我们知道需要实现上述的函数回调,这些回调有RTEMS的应用程序和系统下发。下面主要介绍其调度的场景

二、调度器初始化

_Scheduler_Handler_initialization作为调度器的初始化函数,在RTEMS初始化流程中,我们知道rtems_initialize_data_structures会初始化调度器,其函数为_Scheduler_Handler_initialization,这里会根据_Scheduler_Table的值,对每种调度器进行初始化。

三、执行调度

_Scheduler_Schedule可以标记当前线程可以调度,这种情况下,修改当前线程的heir,并设置需要被调度。然后等待系统调度

四、主动让出

_Scheduler_Yield作为让出调度的函数,提供给用户程序用来主动让出当前任务,让调度器选择下一个任务

五、阻塞任务调度

_Scheduler_Block函数可以主动阻塞当前任务,并将自身任务从就绪队列移除,然后修改自身的heir,等待调度

六、恢复阻塞任务调度

_Scheduler_Unblock_Scheduler_Block成对,将自身添加到就绪队列中,然后修改自身的heir,等待调度

七、更新任务优先级

_Scheduler_Update_priority会遍历调度器的所有任务,修改其任务优先级。

八、映射优先级到调度器

_Scheduler_Map_priority将指定的优先级从应用程序域映射到调度器域

九、映射优先级到应用

_Scheduler_Unmap_priority将指定的优先级从调度器域映射到应用程序域

十、任务的调度器节点初始化/销毁

_Scheduler_Node_initialize在线程创建时,默认初始化本线程的调度节点

_Scheduler_Node_destroy在线程销毁时,销毁线程的调度节点

十一、周期任务创建和销毁

_Scheduler_Release_job将任务释放出来,用作周期任务

_Scheduler_Cancel_job将周期任务取消,用作周期任务

十二、启动空闲任务

_Scheduler_Start_idle为调度器启动空闲任务