一、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年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以+V:Vip1104z获取!!! (备注:嵌入式)
最后
资料整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~
你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!
Vip1104z获取!!! (备注:嵌入式)**
最后
资料整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~
你的支持,我的动力;祝各位前程似锦,offer不断,步步高升!!!