文章目录
- 🔴🟡🟢其他文章链接,独家吐血整理
- 1、Systick滴答定时器
- 2、SVC中断
- 3、PendSV中断
- 4、❤ Systick、SVC、PendSV小结
- 5、时间片调度
- 6、🧡 韦东山FreeRTOS部分
- 7、💛 其它博主文章链接【转载】
- 1、FreeRTOS任务切换——PendSV
- 2、RTOS系列文章(2):PendSV功能,为什么需要PendSV
- 3、有了Systick中断为什么还要PendSV中断?(==此文章有问题,仅作为参考==)
- 4、【FreeRTOS】FreeRTOS 源码学习笔记 (5) 任务调度器 + vTaskStartScheduler、xPortPendSVHandler、xPortSysTickHandler
- 5、FreeRTOS对系统异常优先级寄存器的PendSV和SysTick 的优先级设置过程
🔴🟡🟢其他文章链接,独家吐血整理
【吐血总结】FreeRTOS难点、Systick中断-滴答定时器、PendSV中断-任务切换、SVC中断-系统底层、时间片调度-时钟节拍【已完结】
(第1-8讲)STM32F4单片机,FreeRTOS基础知识总结【视频笔记、代码讲解】【正点原子】【原创】
(第9-10讲)STM32F4单片机,FreeRTOS任务创建和删除(动态方法)【视频笔记、代码讲解】【正点原子】【原创】
(第12讲)STM32F4单片机,FreeRTOS任务创建和删除(静态方法)【视频笔记、代码讲解】【正点原子】【原创】
(第13-14讲)STM32F4单片机,FreeRTOS任务挂起和恢复【视频笔记、代码讲解】【正点原子】【原创】
(第16-17讲)STM32F4单片机,FreeRTOS中断管理简介【视频笔记、代码讲解】【正点原子】【原创】
(第18-19讲)32单片机,FreeRTOS临界段代码保护、任务调度器的挂起和恢复【视频笔记、代码讲解】【原创】
(第20-22讲)STM32F4单片机,FreeRTOS列表和列表项API函数讲解【视频笔记、代码讲解、正点原子】【原创】
(第40-44讲)STM32F4单片机,FreeRTOS信号量【二值、计数、翻转、互斥】【代码讲解】【正点原子】【原创】
1、Systick滴答定时器
![在这里插入图片描述](https://img-blog.csdnimg.cn/fa9cc6c16486429298d00e0c517285fa.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/e90f4230eb0c46d38b250723299aa222.png)
Systick异常请求=滴答定时器中断,原子的这颗F429芯片晶振是180MHZ,重装载值是18000,从18000计数减到0是一次心跳周期=1/1000s=1ms,这个systick定时器开启是在开启任务调度函数里面的
![在这里插入图片描述](https://img-blog.csdnimg.cn/aea60587952c48b6a9b1f5a697439f9d.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/129b58e3980a403187f51e1e2bf4d25d.png)
这个空任务就是空闲任务,任务优先级是0,即任务最低优先级(不是中断优先级)
![在这里插入图片描述](https://img-blog.csdnimg.cn/5833637a2e3d413eacb8b52ee4f9fec9.png)
其实我仍然不太明白嵌套计数器的含义,前几篇文章也分析过,总觉得理解不对
![在这里插入图片描述](https://img-blog.csdnimg.cn/4141d32b247d4e12810b244f6aa9723b.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/c6c38dd307b145d3b009162bc9c2e091.png)
这个时间片计数轮询表述不恰当,这里其实是开启滴答定时器中断,用于PendSV任务切换使用
至于Systick和PendSV两者之间谁的优先级高?这个我也不知道,待补充
开启定时器中断就是滴答定时器,里面有PendSV切换, 第6步里面全是汇编语言,反正我看不懂,待补充
2、SVC中断
![在这里插入图片描述](https://img-blog.csdnimg.cn/ba9abdb1945f4e3080a0d00cc245b3d8.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/b9c6edff85c64bca980f284307066607.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/2ef92c8701314b1ba592a63b3a07ff74.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/43565c56d1684c5f8ee5db37a9e2c665.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/7d5c6ba4fb0f4766bf24e76f91a6a6af.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/e2175950c40a4c54bc417c5699dbdafc.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/16fcfc689468482dabaf8612079d7a37.png)
已经创建好任务了,才进入的SVC中断,SVC中断是讲任务结构体数据依次按地址pop到cpu寄存器中(SVC中断只在启动第一次任务时会调用一次,以后均不调用),这里的使能全局中断相当于汇编语言开启中断,因为前面有进入临界区保护时关掉了中断,此时手动又开启了(具体为什么,我没有详细研究,会用大致上理解就行了)
![在这里插入图片描述](https://img-blog.csdnimg.cn/17ee0c1a49e04d7081412897f38c9599.png)
绿色颜色很重要,这块原子讲得很详细,建议去看下视频
3、PendSV中断
![在这里插入图片描述](https://img-blog.csdnimg.cn/0d527a99bf254c8a9cbe442593396c7f.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/d787a32f477e4c21aae543a70f044f42.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/82aed5e31bcf4f95bb90fe8092a3fddc.png)
上图中的if( xTaskIncrementTick() != pdFALSE )判断中的xTaskIncrementTick() 函数里面就是一些链表的操作,即列表项之间的判断,插入,删除,阻塞之类的,因为列表项之间判断决定了是否进行任务切换,因为创建任务就是创建了列表
![在这里插入图片描述](https://img-blog.csdnimg.cn/6e090ff1671043aaa762f75813c9aac2.png)
原子中的delay延时函数内部调用了上面橙色圈的函数,也就是说delay可以导致任务切换
![在这里插入图片描述](https://img-blog.csdnimg.cn/145d4115a11146af9baeeb2f34a44d8d.png)
这个是宏替换之后的PendSV中断函数,全是汇编语言,后面不想看了,太细了也很难
4、❤ Systick、SVC、PendSV小结
定时器中断是在开启任务调度器时开启的Systick中断函数(寄存器开启,1ms进入一次),里面有PendSV中断函数(寄存器开启,用来根据列表项操作进行任务函数切换),开启任务调度器之后创建了任务(创建任务的同时也就保存了数据),之后打开了SVC中断(汇编语言,获取任务堆栈地址,将任务数据进行出栈处理给cpu寄存器,用于操作硬件底层)(SVC中断只在启动第一次任务时会调用一次,以后均不调用)
![在这里插入图片描述](https://img-blog.csdnimg.cn/62c5fb9d1a1444d5a100766f83c06462.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/75eb18ad7a1f44d18d78f65d2be07e78.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/b58f14daa2a84e068b232008ff9ce453.png)
5、时间片调度
![在这里插入图片描述](https://img-blog.csdnimg.cn/423568d40ef14a13adcc6cc8666b3cc3.png)
没用完的时间片丢掉
![在这里插入图片描述](https://img-blog.csdnimg.cn/a7f7378c3b1448fc9c30ef5dbe4f2be9.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/34fb897a0fd944b18b70cb33b8d8e531.png)
时间片设置的是50ms,这个实验还是比较容易理解滴!因为没有加临界区,导致task1打印一半被阻塞跳到task2接着打印了
taskENTER_CRITICAL();
printf("task1运行次数:%d\r\n",++task1_num);
taskEXIT_CRITICAL();
taskENTER_CRITICAL();
printf("task2运行次数:%d\r\n",++task2_num);
taskEXIT_CRITICAL();
解决办法是printf上下加上临界区保护即可
6、🧡 韦东山FreeRTOS部分
void vTask1( void *pvParameters )
{
const TickType_t xDelay100ms = pdMS_TO_TICKS( 100UL );
BaseType_t ret;
for( ;; )
{
printf("Task1 is running\r\n");
ret = xTaskCreate( vTask2, "Task 2", 1000, NULL, 2, &xTask2Handle );
if (ret != pdPASS)
printf("Create Task2 Failed\r\n");
vTaskDelay( xDelay100ms );
}
void vTask2( void *pvParameters )
{
printf("Task2 is running and about to delete itself\r\n");
vTaskDelete(xTask2Handle);
}
int main( void )
{
prvSetupHardware();
xTaskCreate(vTask1, "Task 1", 1000, NULL, 1, NULL);
vTaskStartScheduler();
return 0;
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/2348f3cf221940a6a9e1577a07f9e3c2.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/2b019889dcd74c078ac97006af99ff2c.png)
阻塞≠挂起(挂起只能使用具体的挂起函数,阻塞无需),只有freertos自带的taskdelay函数实现了任务切换,即task1被taskdelay挂起,task2执行完之后就delete了自己,因为taskdelay里面调用了vTaskSuspendAll();挂起函数,这里的阻塞就是PendSV里面的列表项操作
![在这里插入图片描述](https://img-blog.csdnimg.cn/1e37955f2bc44d22b02cf4c092be9b96.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/5e9404bbb2c04f1eb690494c3b6faa9c.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/9bbfb92599e148749b750165f123bf52.png)
这个tick中断,时间片就是taskdelay延时,taskdelay(1000)就是1000个时间片,这1000ms内这个任务被阻塞,其它任务可以执行,这就是实时操作系统的妙处所在
![在这里插入图片描述](https://img-blog.csdnimg.cn/f24038a674304899afd567207760f023.png)
svs操作系统底层,pendsv用于任务切换,任务的重要程度肯定比不上系统内核底层,根据上面的小节可知,svs就是获取任务堆栈地址,将任务数据进行出栈处理,用于操作硬件底层
7、💛 其它博主文章链接【转载】
1、FreeRTOS任务切换——PendSV
FreeRTOS任务切换——PendSV
![在这里插入图片描述](https://img-blog.csdnimg.cn/dd0f4b0bfdbc41d8b4e950b6af3c9334.png)
这篇文章主要就是解释了上面张图,中断可打断PendSV,PendSV的作用,以及具有延时特点。
2、RTOS系列文章(2):PendSV功能,为什么需要PendSV
RTOS系列文章(2):PendSV功能,为什么需要PendSV
这篇文章写得很详细了,和我看完原子视频理解的大差不差
1、将Systick的优先级设置成高于IRQ
![在这里插入图片描述](https://img-blog.csdnimg.cn/35cd7720a30c4aaa941016f048ffe742.png)
缺点,IRQ=外部中断被耽误,不可容忍
2、将Systick和PendSV的优先级设置为最低
![在这里插入图片描述](https://img-blog.csdnimg.cn/c98c4eda6be545bf95a5541ab1daed6a.png)
缺点,IRQ影响Systick时钟,可容忍
3、将SysTick的优先级设置成最高,PendSV的优先级设置为低
![在这里插入图片描述](https://img-blog.csdnimg.cn/c3e891b7faf4488d93c8d4d2274b350a.png)
缺点,耽误IRQ,不可容忍
1 PendSV是可悬起系统中断,具有【缓期执行】特征。
2 PendSV一般被嵌入式OS用于 任务调度的上下文切换。
3 使用PendSV时,一般会将PendSV的优先级设置为最低,让外部IRQ先执行,等到没有外部中断后,在执行上下文切换。
4 嵌入式实时操作系统的【实时】概念,并不仅仅指应用程序、任务的调度实时,而是指整个系统的实时性高,具备【可剥夺】特点,当有高优先级的中断、任务具备执行条件时,立刻中断当前正在运行的任务,去执行高优先级的IRQ和高优先级任务。
5 嵌入式OS一般会将SysTick的优先级也设置为最低,保证外部中断IRQ优先,详细的分析,我们下一篇文章讨论。
至于sys中断和pendsv中断谁的优先级更高?不清楚,还是没明白,反正两个都是设置最低!
3、有了Systick中断为什么还要PendSV中断?(此文章有问题,仅作为参考)
有了Systick中断为什么还要PendSV中断?
4、【FreeRTOS】FreeRTOS 源码学习笔记 (5) 任务调度器 + vTaskStartScheduler、xPortPendSVHandler、xPortSysTickHandler
文章1
5、FreeRTOS对系统异常优先级寄存器的PendSV和SysTick 的优先级设置过程
文章2
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)