嵌入式技术william hill官网
直播中

张宇

7年用户 1669经验值
私信 关注
[问答]

请教大神RTT是一个os时钟中断调度一次吗

比如我用stm32,systick 1ms中断一次
那么每个线程最少得运行1ms,再去systick中断里检查线程优先级和等待资源超时
同样,某个线程结束,假如等到下一次systick中断到来之前,系统没有执行任何程序吗? idel线程也只会到下个中断到来后才执行

回帖(3)

刘满贵

2022-8-2 10:50:33
可以搜下:rt_schedule();,这是执行调度的,
举报

王芳

2022-8-2 10:50:56
是在内核滴答计时器的中断中进行判断和线程的调度的。

内核滴答计时器中断的处理函数如下:

/* 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);
    ......
}
  
举报

刘伟

2022-8-2 10:51:05
几种调度方式。

线程时间片耗尽,这个时候是在 systick 中断里进行的调度。时间片轮换式。
线程等待资源自动挂起,这个时候可能出现在任何时间,不一定是 systick 中断。让出 cpu 资源给低优先级线程,比如 idle。
其它外设中断里,资源可用,引起线程调度,可能出现挂起当前线程,转向更高优先级线程。抢占式。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分