【RT-Thread基础教程】Delay函数与空闲线程及其钩子函数_rtthread空闲任务钩子

一、Delay函数

1.1 rt_thread_delay()函数

我们可以使用下面这个函数延时tick

rt\_err\_t rt\_thread\_delay(rt\_tick\_t tick);

参数为你要延时的tick。当前线程会阻塞让出 CPU 资源

1.2 rt_thread_mdelay()函数

我们可以使用下面这个函数实现ms级延时:

rt\_err\_t rt\_thread\_mdelay(rt\_int32\_t ms);

参数1为你要延时的ms时间
当前线程会阻塞让出 CPU 资源

1.3 rt_hw_us_delay()函数

我们可以使用下面这个函数实现微秒的延时

void rt\_hw\_us\_delay(rt\_uint32\_t us);

参数为你要延时的us时间。当前线程不会阻塞,这个函数是"死等指定时间“

1.4 rt_thread_delay_until函数

我们可以使用下面这个函数延时指定延时到tick+n

rt\_err\_t rt\_thread\_delay\_until(rt\_tick\_t \*tick, rt\_tick\_t inc_tick);

参数1为开始的tick,参数2为延时的tick多少

1.5 获取当前tick数

我们可以使用下面这个函数获取当前系统的tick数:

rt\_tick\_t rt\_tick\_get(void);

他返回当前的tick

二、空闲线程与钩子函数

2.1 空闲线程

空闲线程是在操作系统中用于处理系统空闲时间的特殊线程。当系统中没有其他任务需要执行时,CPU 就会执行空闲线程。这个线程的任务通常是执行一些系统维护工作,或者在低功耗模式下帮助节省能源。

换句话说,就像是一个不忙的保安一样,当没有其他事情需要他处理时,他就会在岗位上待着,保持警惕,随时准备处理突发事件。

空闲线程优先级最低:它不能阻碍用户线程运行
空闲线程要么处于就绪态,要么处于运行态,永远不会挂起
空闲线程的优先级为最低,这意味着一旦某个用户的线程变为就绪态,那么空闲线程马上被切换出去,让这个用户线程运行。
在这种情况下,我们说用户线程"抢占"(pre-empt)了空闲线程,这是由调度器实现的。要注意的是:如果某
个线程被删除,那么需要确保后面空闲线程有机会执行,否则就无法释放被删除线程的内存。

下面的这个函数就是空闲线程的函数了,如果定义了RT_USING_IDLE_HOOK宏,他会去把idle_hook_list里面的东西取出来,然后执行。rt_thread_idle_excute函数用于清楚工作

static void rt\_thread\_idle\_entry(void \*parameter)
{
#ifdef RT\_USING\_SMP
    if (rt\_hw\_cpu\_id() != 0)
    {
        while (1)
        {
            rt\_hw\_secondary\_cpu\_idle\_exec();
        }
    }
#endif

    while (1)
    {
#ifdef RT\_USING\_IDLE\_HOOK
        rt\_size\_t i;

        for (i = 0; i < RT_IDLE_HOOK_LIST_SIZE; i++)
        {
            if (idle_hook_list[i] != RT_NULL)
            {
                idle_hook_list[i]();
            }
        }
#endif

        rt\_thread\_idle\_excute();
#ifdef RT\_USING\_PM 
        rt\_system\_power\_manager();
#endif
    }
}

rt_thread_idle_excute函数实现如下:

void rt\_thread\_idle\_excute(void)
{
    /\* Loop until there is no dead thread. So one call to rt\_thread\_idle\_excute
 \* will do all the cleanups. \*/
    /\* disable interrupt \*/

    RT_DEBUG_NOT_IN_INTERRUPT;

#ifdef RT\_USING\_HEAP
    while (1)
    {
        rt\_base\_t lock;
        rt\_thread\_t thread;

        lock = rt\_hw\_interrupt\_disable();

        /\* check whether list is empty \*/
        if (!\_has\_defunct\_thread())
        {
            rt\_hw\_interrupt\_enable(lock);
            break;
        }
        /\* get defunct thread \*/
        thread = rt\_list\_entry(rt_thread_defunct.next,
                struct rt\_thread,
                tlist);
        /\* remove defunct thread \*/
        rt\_list\_remove(&(thread->tlist));
        /\* release thread's stack \*/
        RT\_KERNEL\_FREE(thread->stack_addr);
        /\* delete thread object \*/
        rt\_object\_delete((rt\_object\_t)thread);
        rt\_hw\_interrupt\_enable(lock);
    }
#endif
}

首先他会取出要释放内存的线程:

/\* get defunct thread \*/
thread = rt\_list\_entry(rt_thread_defunct.next,
        struct rt\_thread,
        tlist);

接下来他会把这个线程从线程链表里面移除:

/\* remove defunct thread \*/
rt\_list\_remove(&(thread->tlist));

然后他会释放对应的栈空间:

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数嵌入式工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!

img

img

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以+V:Vip1104z获取!!! (备注:嵌入式)

img

最后

资料整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~

你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!

Vip1104z获取!!! (备注:嵌入式)**

img

最后

资料整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~

你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!

更多资料点击此处获qu!!

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值