Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
RTOS
内核开发
线程上下文调度切换_context
操作系统内核技术研究:任务上下文切换
发布于 2021-07-26 12:44:45 浏览:3122
订阅该版
[tocm] [入门学习笔记 - 目录](https://club.rt-thread.org/ask/article/3420.html) [操作系统内核技术研究:开篇](https://club.rt-thread.org/ask/article/2905.html) [操作系统内核技术研究:环境搭建](https://club.rt-thread.org/ask/article/2906.html) [操作系统内核技术研究:ARM汇编指令](https://club.rt-thread.org/ask/article/2913.html) [操作系统内核技术研究:STMFD与LDMFD的使用](https://club.rt-thread.org/ask/article/2914.html) [操作系统内核技术研究:任务上下文切换](https://club.rt-thread.org/ask/article/2918.html) [操作系统内核技术研究:线程切换与运行](https://club.rt-thread.org/ask/article/2919.html) ## 前言 - 任务(task)或线程(thread),可以理解为一个个【用户的】功能函数,RTOS内核就是管理这些功能函数的运行逻辑,根据某些策略,如优先级、时间片,在各个运行的函数之间进行切换。 - 为何任务或线程不能【并行】工作,需要切换?原因是一般的MCU,都是单核处理,所以如果想实现多任务,需要分时复用CPU,宏观上,任务在各自的并行运行,微观上,任务根据调度,不断的切换运行,每个时间片,只有一个任务在运行。 - 切换任务,不单单是PC指针的跳转,还需要保存各个任务的现场,【这样任务被打断或切走后,还能正确的再切换回来】,各个任务的现场称之为:任务上下文,context,包括CPU的一些寄存器等 - 像裸机系统,中断来了CPU会【自动保存现场】,自动压栈部分必要的CPU寄存器,这个可以理解为CPU本身的功能【硬件行为】 - 中断处理完后,会执行LR,【弹栈】恢复压栈的CPU寄存器的值,这样PC指针也恢复了,所以程序跳转到上次被中断的地方接着跑,像没被打断过一样,注意被打断的程序【不是】从头开始重新跑。 ## 如何切换任务 - 任务或线程切换的实质:【上下文的切换】,上下就是CPU的关键寄存器,也就是寄存器的保存【压栈】与恢复【弹栈】,这样模拟了中断的行为,当然需要涉及【调度器】,用于管理多个任务的切换 - 两个核心问题: - 任务的切换时的CPU的寄存器保存与恢复 - 任务调度器,用于多个任务的有序切换 - 每个任务或线程,都要设置一个控制块(结构体),用于保存CPU的一组寄存器,CPU好比【织布机】的梭子,在各个任务之间穿梭运行 - 任务上下文切换时,可能会被外部中断打断,造成寄存器的错误保存,所以一般在上下文切换过程中,需要关闭全局中断响应。 - STM32 ARM架构的MCU,有一个异常:PendSV,可悬起异常。这个PendSV,可以手动Pend,触发PendSV中断,并进入PendSV_Handler 中断处理函数。如果这个PendSV中断的优先级调整到最低,保证其他高优先级的中断处理完成,再进入PendSV中断,在关闭全局中断的情况下进行任务上下文切换,这样实时性得到保证,并能【安全】地进行任务上下文切换。 ## 切换流程 - 【被切换任务】上下文SP(栈指针)、【新任务】的上下文SP,作为入参。如果第一次切换任务,则没有【被切换任务】上下文SP。 - 手动Pending PendSV,此时可以被优先级更高的中断打断,等其他优先级高的中断处理完成后,CPU因为PendSV被Pending,进入PendSV_Handler中断处理函数,此时关闭【全局中断响应】,防止任务上下文被中断修改。 - 保存现场,CPU部分寄存器已经压栈,剩余的寄存器,手动压栈,压栈到【被切换任务】上下文的SP中。这样,就完成了上下文的【保存】。 - 再把【新任务】上下文,POP或加载的方式,恢复到CPU寄存器。设置当前的psp 指向【新任务】的上下文的SP。更换了现场(上下文),CPU下次执行,就执行【新任务】了。 - 任务切换,跟普通中断一样,保存、恢复CPU寄存器即可。只是多任务,每个任务都有自己的栈空间,都保存一套CPU寄存器,有自己的SP(栈指针)。 ## 自动压栈 - ARM处理器中断时,会自动压栈部分寄存器。 - 上下文切换时,在PendSV中断处理函数中执行前,`psr, pc, lr, r12, r3, r2, r1, r0` CPU 寄存器,会自动压栈,当前运行的被切换线程(from线程)。 ## 手动压栈 - 为了保证任务上下文的完整,上下文切换时,CPU 寄存器`r4 r5 r6 r7 r8 r9 r10 r11`,因为没有自动压栈,需要手动压栈,压栈到当前运行的被切换线程(from线程)。 - 注意如果有FPU开启(浮点),还需要压栈浮点相关的寄存器。 ## r13寄存器(SP) - 压栈的寄存器,r0~r12,lr(r14),pc(r15),还要psr(程序状态寄存器)。少了r13(栈指针寄存器)?这个寄存器,直接设置到了任务控制块,也保存了下来。 ## 手动触发PendSV - STM32可以下载编程手册,里面有ARM寄存器的介绍。PendSV可以手动触发,自己可以写个汇编小函数测试一下。 ![2021-07-26_123526.png](https://oss-club.rt-thread.org/uploads/20210726/302193c9d6e3d2164d9d4b53b21bc2ce.png.webp) ![2021-07-26_123931.png](https://oss-club.rt-thread.org/uploads/20210726/07b93b1feaf1b37118c95a05a65cb32b.png.webp) ![2021-07-26_124038.png](https://oss-club.rt-thread.org/uploads/20210726/a97f2636fe0ce4720513ae2fc0ed40df.png.webp) ```c SCB_ICSR EQU 0xE000ED04 NVIC_PENDSV_SET EQU 0x10000000 ;/* ; * void trigger_PendSV(void); ; */ trigger_PendSV PROC EXPORT trigger_PendSV LDR r0, =SCB_ICSR LDR r1, =NVIC_PENDSV_SET STR r1, [r0] BX LR ENDP ``` - 在main中调用:trigger_PendSV,即可进入PendSV_Handler中断处理函数。 - PendSV_Handler这个函数,在STM32启动文件默认为【B .】,也就是while (1),因为是【weak】属性,所以用户可以重写。 - 任务上下文切换是在:PendSV_Handler中实现的。 ## 小结 - 先初步了解任务切换,任务上下文切换的概念。 - 了解PendSV中断特性。 - 后面继续研究任务上下文切换的整个过程。 - 熟悉了任务的切换流程,详细对RTOS就会有了一个【崭新】的认知。
2
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
张世争
学以致用
文章
131
回答
812
被采纳
177
关注TA
发私信
相关文章
1
modbusRTU如何避免因为被高优先级任务切走而导致本次通讯失败
2
RT-Thread 4.0.2初次上下文切换失败
3
pendSV中bx lr指令,lr指向哪里?psp中剩余的寄存器啥时候弹出的?
4
Cortex-M0在bootloader环境下的上下文切换问题?
5
arc内核移植线程切换
6
rt_thread_yield 无法在同级别中释放cpu
7
线程执行完后退出 是如何通知cpu切换任务的
8
RTT-NANO 3.1.3 线程切换问题
9
线程切换,打印出来的时间不对
10
软件定时器的回调函数里可以挂起或解挂另一个线程吗?
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
PWM
cubemx
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
编译报错
Debug
rt_mq_消息队列_msg_queue
SFUD
keil_MDK
msh
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1444
个答案
290
次被采纳
张世争
812
个答案
177
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
1
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
2
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部