是在内核滴答计时器的中断中进行判断和线程的调度的。
内核滴答计时器中断的处理函数如下:
/* libraries/HAL_Drivers/drv_common.c */
void SysTick_Handler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_IncTick();
rt_tick_increase(); // 检查线程的状态进行调度;检查定时器列表的状态
/* leave interrupt */
rt_interrupt_leave();
}
rt_tick_increase() 的源码如下:里面判断了是否有就绪的线程有的话进行调度器的调度,最后查看了定时器列表查看是都有定时器到时,有的话执行定时器的回调函数。
/* rt-thread/src/clock.c */
void rt_tick_increase(void)
{
struct rt_thread *thread;
rt_base_t level;
level = rt_hw_interrupt_disable();
/* increase the global tick */
#ifdef RT_USING_SMP
rt_cpu_self()->tick ++;
#else
++ rt_tick;
#endif /* RT_USING_SMP */
/* check time slice */
thread = rt_thread_self(); // 获取当前运行的线程
-- thread->remaining_tick; // 剩余的时间片计数自减1
if (thread->remaining_tick == 0) // 剩余的时间片计数检查
{
/* change to initialized tick */
thread->remaining_tick = thread->init_tick;
thread->stat |= RT_THREAD_STAT_YIELD;
rt_hw_interrupt_enable(level);
rt_schedule(); // 调度器
}
else
{
rt_hw_interrupt_enable(level);
}
/* check timer */
rt_timer_check(); // 定时器列表检查
}
rt_schedule() 的源码如下:进行线程优先级的判断进行调度。
/* rt-thread/src/scheduler.c */
void rt_schedule(void)
{
......
/* 关中断 */
level = rt_hw_interrupt_disable();
......
/* 获取优先级最高的线程 */
to_thread = _get_highest_priority_thread(&highest_ready_priority);
......
/* 如果当前线程的优先级低于获取到线程的优先级,则让出处理器资源 */
rt_current_thread->stat &= ~RT_THREAD_STAT_YIELD_MASK;
need_insert_from_thread = 1;
......
/* 开启切换 */
rt_current_priority = (rt_uint8_t)highest_ready_priority;
from_thread = rt_current_thread;
rt_current_thread = to_thread;
......
/* 将要切换线程从ready队列移除 */
rt_schedule_remove_thread(to_thread);
/* 将要切换线程的状态设为运行状态 */
to_thread->stat = RT_THREAD_RUNNING | (to_thread->stat & ~RT_THREAD_STAT_MASK);
......
/* 栈溢出检查 */
_rt_scheduler_stack_check(to_thread);
......
/* 这里假设是正常的切换,不是中断触发,所以进入该分支 */
rt_hw_context_switch((rt_ubase_t)&from_thread->sp,
(rt_ubase_t)&to_thread->sp);
......
}
是在内核滴答计时器的中断中进行判断和线程的调度的。
内核滴答计时器中断的处理函数如下:
/* libraries/HAL_Drivers/drv_common.c */
void SysTick_Handler(void)
{
/* enter interrupt */
rt_interrupt_enter();
HAL_IncTick();
rt_tick_increase(); // 检查线程的状态进行调度;检查定时器列表的状态
/* leave interrupt */
rt_interrupt_leave();
}
rt_tick_increase() 的源码如下:里面判断了是否有就绪的线程有的话进行调度器的调度,最后查看了定时器列表查看是都有定时器到时,有的话执行定时器的回调函数。
/* rt-thread/src/clock.c */
void rt_tick_increase(void)
{
struct rt_thread *thread;
rt_base_t level;
level = rt_hw_interrupt_disable();
/* increase the global tick */
#ifdef RT_USING_SMP
rt_cpu_self()->tick ++;
#else
++ rt_tick;
#endif /* RT_USING_SMP */
/* check time slice */
thread = rt_thread_self(); // 获取当前运行的线程
-- thread->remaining_tick; // 剩余的时间片计数自减1
if (thread->remaining_tick == 0) // 剩余的时间片计数检查
{
/* change to initialized tick */
thread->remaining_tick = thread->init_tick;
thread->stat |= RT_THREAD_STAT_YIELD;
rt_hw_interrupt_enable(level);
rt_schedule(); // 调度器
}
else
{
rt_hw_interrupt_enable(level);
}
/* check timer */
rt_timer_check(); // 定时器列表检查
}
rt_schedule() 的源码如下:进行线程优先级的判断进行调度。
/* rt-thread/src/scheduler.c */
void rt_schedule(void)
{
......
/* 关中断 */
level = rt_hw_interrupt_disable();
......
/* 获取优先级最高的线程 */
to_thread = _get_highest_priority_thread(&highest_ready_priority);
......
/* 如果当前线程的优先级低于获取到线程的优先级,则让出处理器资源 */
rt_current_thread->stat &= ~RT_THREAD_STAT_YIELD_MASK;
need_insert_from_thread = 1;
......
/* 开启切换 */
rt_current_priority = (rt_uint8_t)highest_ready_priority;
from_thread = rt_current_thread;
rt_current_thread = to_thread;
......
/* 将要切换线程从ready队列移除 */
rt_schedule_remove_thread(to_thread);
/* 将要切换线程的状态设为运行状态 */
to_thread->stat = RT_THREAD_RUNNING | (to_thread->stat & ~RT_THREAD_STAT_MASK);
......
/* 栈溢出检查 */
_rt_scheduler_stack_check(to_thread);
......
/* 这里假设是正常的切换,不是中断触发,所以进入该分支 */
rt_hw_context_switch((rt_ubase_t)&from_thread->sp,
(rt_ubase_t)&to_thread->sp);
......
}
举报