一 介绍FreeRTOS
FreeRTOS是一个开源的实时操作系统(RTOS),专门设计用于在嵌入式系统中运行。它提供了一套完整的功能,可以管理多个任务、控制任务之间的通信和同步、调度任务和分配系统资源等。FreeRTOS以其高效性和可靠性而闻名,它被广泛应用于许多嵌入式系统领域,例如航空航天、汽车电子、医疗设备、消费电子、工业自动化和智能家居等。该操作系统可以轻松适应各种处理器架构,包括ARM、MIPS、PowerPC、RISC-V等,并提供了丰富的API和示例程序,方便开发人员快速地实现其项目。
二学习进度
2.1FreeRTOS的移植
使用是stm32f103RC开发板,库函数开发。使用keil工具。在原来的工程上加上FreeRTOS_CORE,FreeRTOS_PORTABLE文件夹.
CORE文件放置了freertos中的源代码,PORTABLE放置移植到不同的平台所需要的文件,比如要移植到ARM - cortex-M3架构下,我们就要选择相应的开发文件。
就是要在上述的文件中选择MemMang(内存管理)和RVDS中选择cortex-M3的架构。在这里可以介绍ARM 和 ST 以及cortex-M3之间的关系,ARM 是一种芯片设计架构,就和我们电脑使用的CPU一般都是x86架构也就是8086架构。而cortex-m3是arm公司根据嵌入式设备推出的微指令(精简微指令),微指令的含义:通俗一点解释:比如在编写汇编代码时候,经常使用MOV指令,而汇编代码经过编译器生成的目标文件,也就是将MOV指令翻译成机器码(二进制),CPU就可以识别这些机器码,对于不同的机器码CPU怎么知道如何操作,这时候就要用到微指令集,让CPU根据不同的机器码完成不同工作。
那我们经常提及的ST是: ST(意法半导体公司)是一家芯片生产公司,同时也用自己生产的芯片,制造一些开发板和嵌入设备,ST通过购买ARM公司的授权,根据ARM公司设计的ARM架构生产自己的芯片。
可以举个例子:ARM设计的cortex-m3微指令集,NVIC(中断控制器)提供了一个字节大小的寄存器设置中断优先级的数目。
那么就可以支持2^8 - 1 = 255,256个优先级数目。因为随着优先级的数目的上升,MCU就要更加复杂,成本上升,功耗增大。ST修改了cortex-m3指令集,使用一个字节的高四位设置中断,2^4 - 1 = 15,同时设置中断分组分为抢占优先级和子优先级,因为只有高四位有效,所以中断分为分为5组。学习STM32芯片的同学相信对中断分组肯定不陌生吧。所以ARM是芯片设计公司,而ST是芯片生产公司。
这里也提及一个重要的文件:FreeRTOSConfig.h
可以从图中看到该文件主要是对操作系统的一些宏的配置,也就是是否启用操作系统的的一些功能和配置操作系统的中断优先级等等信息,大多使用到条件编译。
2.2FreeRTOS任务的创建和删除
创建任务函数:
xTaskCreate((TaskFunction_t )start_task, //任务函数
(char* )"start_task", //任务名称
(uint16_t )start_task_sta_size, //任务堆栈大小
(void* )NULL, //传递给任务函数的参数
(UBaseType_t )start_task_priority, //任务优先级
(TaskHandle_t* )&start_task_Handle_t); //任务句柄
该函数中参数看注释基本能看懂,主要是任务句柄,start_task_Handle_t是一个指针,会在任务创建成功后给其赋值,可以通过查看该参数判断任务是否创建成功。
vTaskDelete(void*) 删除任务函数,传入任务句柄指针,或者任务中删除自身也可以传入NULL。
对于整个程序的运行的流程 , 下面 分析代码 解释 运行过程。
int main(){
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
xTaskCreate((TaskFunction_t )start_task, //任务函数
(char* )"start_task", //任务名称
(uint16_t )start_task_sta_size, //任务堆栈大小
(void* )NULL, //传递给任务函数的参数
(UBaseType_t )start_task_priority, //任务优先级
(TaskHandle_t* )&start_task_Handle_t); //任务句柄
vTaskStartScheduler(); //开启任务调度
}
main函数是程序的入口,先设置中断分组,然后创建开始任务,开始任务的作用是:创建用户自定义的任务,创建结束后删除开始任务。
重点:vTaskStartScheduler(); //开启任务调度
在开启任务调度之前,所有任务都不会创建,至此之前RCC时钟(Reset and Clock Control)是STM32微控制器中的一个模块,它提供了系统时钟、外设时钟和复位控制等功能。已经被开启。在开启任务调度后,(可以进入到vTaskStartScheduler 可以看到 里面由 OS时钟任务的创建和Idle Task任务的创建 ),随后用户自定义的任务才会被创建。
全部的解释:在FreeRTOS中,启动OS时钟(滴答定时器)和所有任务的创建都是在启动函数vTaskStartScheduler()中完成的,包括Idle Task和用户定义的第一个任务(通常称为start_task),当vTaskStartScheduler()启动时,会首先创建Idle Task,然后再创建用户定义的第一个任务start_task。只有在start_task创建完成后,FreeRTOS才会开始任务调度。
因此,在FreeRTOS系统中,Idle Task不需要手动创建,而是由操作系统自动创建。在用户程序中,第一个任务start_task的优先级通常设置为较高,以确保它在系统启动后立即运行。然后,当没有其他任务需要运行时,Idle Task会被调度执行,以等待下一个系统节拍周期到来并等待新任务的到来。Idle也被称为空闲任务 优先级设置0 即是优先级最低0.
2.3任务的挂起和恢复
FreeRTOS加入了任务的挂起态,也就是任务的暂停。
vTaskSuspend(task2_Handle_t); //参数任务句柄
vTaskResume(task2_Handle_t);
不过在中断中挂起任务的时候,需要调用另一个函数,解挂还是一样的。
FreeRTOS默认时间片轮转的抢占式优先级调度算法
2.4中断列表和管理
从上面的图中可以看出corter-m3用一个字节寄存器设置优先级,然后所有的中断进行了编号(也包括系统异常中断和外部中断)等,
因为对中断进行了编号, 所以在上图中看到中断列表中存储着所有的中断。
对于FreeRTOS内核可以使用函数实现开关中断。
portDISABLE_INTERRUPTS() //关闭中断
portENABLE_INTERRUPTS() //开启中断
在FreeRTOSConfig.h中的configMAX SYSCALL INTERRUPT PRIORITY,这可以设置 portDISABLE_INTERRUPTS()来改变不被关闭中断的最小优先级。