FreeRTOS任务调度的原理是什么?
FreeRTOS的任务调度是在中断上下文中实现的!!!!!!
主函数: 在裸机系统中,系统的主体就是 main 函数里面顺序执行的无限循环,这个无限循环里面 CPU 按照顺序完成各种事情。在多任务系统中,我们根据功能的不同,把整个系统分割成一个个独立的且无法返回的函数,这个函数我们称为任务。
栈空间: 在多任务系统中,每个任务都是独立的,互不干扰的,所以要为每个任务都分配独立的栈空间,这个栈空间通常是一个预先定义好的全局数组,也可以是动态分配的一段内存空间,但它们都存在于 RAM 中。任务是一个独立的函数,函数主体无限循环且不能返回。
任务控制块: 系统为了顺利的调度任务,为每个任务都额外定义了一个任务控制块,这个任务控制块就相当于任务的身份证,里面存有任务的所有信息,比如任务的栈指针,任务名称,任务的形参等。有了这个任务控制块之后,以后系统对任务的全部操作都可以通过这个任务控制块来实现。
任务创建: 任务的栈,任务的函数实体,任务的控制块最终需要联系起来才能由系统进行统一调度(xTaskCreateStatic()函数)
就绪列表: 就绪列表实际上就是一个 List_t 类型的数组,数组的大小由决定最大任务优先级宏configMAX_PRIORITIES决定,最大支持 256 个优先级。数组的下标对应了任务的优先级,同一优先级的任务统一插入到就绪列表的同一条链表中。
调度器: 调度器是操作系统的核心,其主要功能就是实现任务的切换,即从就绪列表里面找到优先级最高的任务,然后去执行该任务。从代码上来看,调度器无非也就是由几个全局变量和一些可以实现任务切换的函数组成。
其中PendSV中断是用于实现任务切换的一种特殊中断,SysTick 和PendSV 都会涉及到系统调度,系统调度的优先级要低于系统的其它硬件中断优先级,即优先相应系统中的外部硬件中断,所以 SysTick 和 PendSV 的中断优先级配置为最低。
prvStartFirstTask()函数用于开始第一个任务,主要做了两个动作,一个是更新 MSP 的值,二是产生 SVC 系统调用,然后去到 SVC 的中断服务函数里面真正切换到第一个任务。
prvPortStartFirstTask()为一个汇编函数,主要功能就是触发SVC中断
SVC中断服务函数-- vPortSVCHandler()也是一个汇编函数,主要干了两件事,恢复任务现场(也就是将任务栈中保存的寄存器值POP到对应寄存器);将MSP切换为PSP;
任务切换: 任务切换就是在就绪列表中寻找优先级最高的就绪任务,然后去执行该任务。
任务之间切换时需要保存现场,以便下次跳转回来时可以恢复现场,继续执行。所谓的现场就是内核的寄存器,而保存现场就是将寄存器组的当前值PUSH到栈中保存,恢复现场就是将栈中保存的寄存器值POP到对应寄存器,下图为cortex-M3寄存器组
PendSV 中断服务函数是真正实现任务切换的地方,具体实现见代码清单 7-23。
- 4.运动插补的时候,是知道起点和终点进行插补,只知道起点能不能插补?
在运动控制中,插补是指在给定的起点和终点之间,通过一系列的中间点(插补点)来平滑地生成运动轨迹。这种插补可以应用于各种情况,如机械臂、CNC机床、工业机器人等。关于你的问题,是否能够进行插补取决于多个因素:
-
维度和类型: 插补的可行性通常取决于你处理的物理系统的维度和运动类型。例如,二维平面上的点可以通过线性插补连接,三维空间中的点可以通过插值算法连接。
-
插补算法: 你需要选择适合你应用的插补算法。常见的插补算法包括线性插补、三次样条插值、B样条曲线等。这些算法具有不同的性质和适用范围。
-
约束和条件: 在进行插补之前,你需要了解起点和终点之间的约束和条件。这可能包括最大速度、最大加速度、关节角度限制等。这些约束会影响插补的结果和可行性。
-
硬件和控制器支持: 插补通常由运动控制器或硬件实现。你需要确保你的硬件和控制器支持所选的插补算法和运动类型。
总的来说,插补的可行性不仅取决于起点,还取决于你对终点、插补算法、约束等的要求。通常情况下,插补都需要考虑多个因素,并在实际应用中进行适当的调整和配置。
- 5.什么是SVC?
在操作系统中,"SVC" 通常指的是 "Supervisor Call",也称为 "Supervisor Mode Call" 或 "System Call". 这是一种机制,允许用户程序请求操作系统内核提供特权和受保护的服务,如文件操作、内存管理、进程控制等。当用户程序需要执行特权操作时(因为这些操作可能会影响整个系统),它会通过 SVC 指令切换到操作系统的内核态来执行请求的操作。
一般情况下,操作系统运行在两种不同的模式下:用户态和内核态。用户态是用户应用程序运行的环境,而内核态是操作系统内核运行的环境,拥有更高的权限和访问系统资源的权力。当用户程序需要执行需要特权的操作时(如访问硬件、管理内存等),它就需要通过 SVC 机制进入内核态,请求操作系统执行这些操作。
SVC 通常是通过软中断或异常来实现的。当用户程序执行 SVC 指令时,处理器会触发一个异常,操作系统内核会捕获这个异常并根据用户程序请求的操作来执行相应的操作,然后将控制权返回给用户程序。这个机制确保了操作系统的资源和功能只有在必要的时候才会被用户程序访问,同时也保护了系统的安全性和稳定性。
总之,SVC 是操作系统提供的一种接口,使用户程序可以请求操作系统执行特权操作,从而实现文件管理、内存管理、进程控制等核心功能。 - 6.FreeRTOS中任务的切换中svc和pensv是什么区别和联系?
在 FreeRTOS 中,"svc" 和 "PendSV" 都是与任务切换相关的特殊中断或操作。它们在任务切换过程中扮演不同的角色,下面是它们的区别和联系:
-
PendSV (Pending Supervisor Call) 中断:
- PendSV 中断是一个特殊的中断,用于实现任务切换。
- 它的优先级是最低的,因此在系统中发生的其他中断和异常处理完成后,如果有 PendSV 中断被挂起,处理器会立即切换到 PendSV 中断处理程序。
- PendSV 中断通常由操作系统内核在特定时机触发,用于执行实际的任务切换。在任务切换时,操作系统会切换任务的上下文,包括保存当前任务的寄存器状态并加载下一个任务的寄存器状态。
- PendSV 中断处理程序通常由操作系统内核自动调用,无需用户干预。
-
SVC (Supervisor Call) 调用:
- SVC 是一个软件中断,用于请求操作系统内核的服务。它常用于执行系统调用,例如任务创建、任务删除等操作。
- 当任务需要请求内核服务时,它可以通过调用 SVC 指令触发一个 SVC 调用。这将导致处理器进入一个特殊的 SVC 中断处理程序。
- 在 SVC 中断处理程序中,操作系统内核可以根据调用的参数执行相应的操作。这包括创建、删除、切换任务等。
- 与 PendSV 不同,SVC 调用通常是由用户代码触发的,用于向内核请求服务。
联系:
- 在某些情况下,PendSV 中断可以被用于执行特殊的任务切换,尤其在嵌入式系统中,可以通过手动触发 PendSV 来实现实时性要求更高的任务切换。
- SVC 调用可能导致任务的切换,例如当一个任务请求系统服务时,操作系统内核可能会决定切换到另一个任务来执行该服务。
总之,PendSV 中断和 SVC 调用都与任务切换和操作系统内核的服务相关,但它们在触发机制、用途和实现方式上有一些不同。
参考:《[野火]FreeRTOS内核实现与应用开发实战指南—基于STM32》, la_fe_,还有一个忘了。