4.调度相关

调度

​ RT-Thread 的调度算法为基于优先级调度和基于时间片轮转调度共存的策略。系统中可能有多个线程,它们的优先级可能相同、可能不同,RT-Thread 采用的调度策略是:可抢占:高优先级的就绪线程会“立刻”抢占低优先级的线程;时间片轮转:同优先级别的就绪线程,依次运行

​ 在rtt运行中,会不断的切换线程,这由rt_schedule()来实现。在调度器中我们可以绑定一个钩子函数,用于我们查看调度情况

rt_schedule()的部分代码如下:

void rt_schedule(void)
{
    rt_base_t level;
    struct rt_thread *to_thread;
    struct rt_thread *from_thread;

    /* disable interrupt */
    level = rt_hw_interrupt_disable();

    /* check the scheduler is enabled or not */
    if (rt_scheduler_lock_nest == 0)
    {
        register rt_ubase_t highest_ready_priority;

#if RT_THREAD_PRIORITY_MAX <= 32
        highest_ready_priority = __rt_ffs(rt_thread_ready_priority_group) - 1;
#else
        register rt_ubase_t number;

        number = __rt_ffs(rt_thread_ready_priority_group) - 1;
        highest_ready_priority = (number << 3) + __rt_ffs(rt_thread_ready_table[number]) - 1;
#endif

        /* get switch to thread */
        to_thread = rt_list_entry(rt_thread_priority_table[highest_ready_priority].next,
                                  struct rt_thread,
                                  tlist);

        /* if the destination thread is not the same as current thread */
        if (to_thread != rt_current_thread)
        {
            rt_current_priority = (rt_uint8_t)highest_ready_priority;
            from_thread         = rt_current_thread;
            rt_current_thread   = to_thread;

            RT_OBJECT_HOOK_CALL(rt_scheduler_hook, (from_thread, to_thread));
.............................................................
.............................................................

在这段代码的最后一行 RT_OBJECT_HOOK_CALL(rt_scheduler_hook, (from_thread, to_thread));,就是调度器触发钩子函数的入口,可以看看该宏的实现:

#define RT_OBJECT_HOOK_CALL(func, argv) \
    do { if ((func) != RT_NULL) func argv; } while (0)

将该宏展开就是:

do
{
    if(rt_scheduler_hook != RT_NULL)
        rt_scheduler_hook(from_thread, to_thread);
}while(0)

现在我们只需要编写rt_scheduler_hook函数,就可以让调度器进去我们的钩子函数,在rtt中提供了一个API:rt_scheduler_sethook,该函数的实现是:

rt_scheduler_sethook(void (*hook)(struct rt_thread *from, struct rt_thread *to))
{
    rt_scheduler_hook = hook;
}

这个函数非常简单,就是将我们传进去的函数入口当作rt_scheduler_hook,是调度器执行时进入我们的钩子函数,在调度器的钩子函数中有两个参数from_thread和to_thread,前者是调度时上一个线程的名称,后者时调度时下一个线程的名称。所以我们可以用该钩子函数查看调度的上下文

//在main函数中绑定钩子函数
rt_scheduler_sethook(hook_of_scheduler);
//自己编写的钩子函数
static void hook_of_scheduler(struct rt_thread* from, struct rt_thread* to)
{
    rt_kprintf("Thread:%s -->  Thread:%s \r\n", from->name, to->name);
}
//打印结果
Thread:led1 -->  Thread:tidle
Thread:tidle -->  Thread:led
//
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值