赞
踩
RTOS(Real Time OS)即实时操作系统,根据各个任务的要求,进行资源(包括存储器、外设等)管理、消息管理、任务调度、异常处理等工作。在RTOS支持的系统中,每个任务均有一个优先级(类似前面章节的中断抢占优先级),RTOS根据各个任务的优先级,动态地切换各个任务,保证对实时性的要求。
RTOS总是运行优先级最高且就绪的任务。
实时多任务操作系统,以分时方式运行多个任务,任务之间的切换以优先级为根据。只有优先服务方式的RTOS才是真正的实时操作系统。
使用实时操作系统还需要额外的ROM/RAM开销,2~5%的CPU额外负荷,以及内核的费用。
使用实时操作系统的必要性:
当前RTOS已经广泛应用于各种嵌入式设备中,如智能可穿戴设备、智能家居设备等。且RTOS已成为嵌入式、物联网开发者的基础必备技能。对于应届生而言,掌握RTOS是求职应聘、参与产品项目开发的一个优势加分项。
如下所示为当前求职招聘的一些基本要求。
市场上有各色各样的RTOS实时操作系统(UCOS、RT-Thread、FreeRTOS),FreeRTOS 最大的优势就是开源免费,商业使用的话不需要用户公开源代码,也不存在任何版权问题,是当前小型嵌入式操作系统市场使用率最高的。故本文教程选用了FreeRTOS。
在本文档编写时,FreeRTOS最新版本为FreeRTOS 202212.01,因此本文基于此版本进行移植教程,即使后续版本更新,FreeRTOS的整体文件结构不会发生大改变,依然可以采用本文档进行指导移植操作。选择比此版本的更旧的版本移植操作也同本文大致保持一致。
下载源码后,解压打开FreeRTOS源码文件目录结构如下图所示:
FreeRTOS文件夹下,有 Demo和Source文件夹是移植过程中需要使用的,FreeRTOS文件夹下面的其它文件夹及文件可忽略。
RTOS代码的核心包含在三个文件中:tasks.c、queue.c、list.c。这三个文件位于FreeRTOS/Source目录。在该目录下还包含三个可选的文件:timers.c、event_groups.c、croutine.c、stream buffer.c,分别实现软件定时、事件组、协程功能和流式缓冲区。
FreeRTOS官方移植参考说明:Microcontrollers and compiler tool chains supported by FreeRTOS
移植步骤:
①、在KEIL工程主目录下创建FreeRTOS文件夹,然后在FreeRTOS中依次创建include、port、src文件夹,如下图所示。
②、进入下载的FreeRTOSv202212.01源码文件中,将FreeRTOSv202212.01\FreeRTOS\Source\include 的文件拷贝到KEIL工程的FreeRTOS/include中
③、进入FreeRTOSv202212.01\FreeRTOS\Source 目录,将 croutine.c、event groups.c、list.c、 queue.c、stream buffer.c、tasks.c、timers.c拷贝到KEIL工程的 FreeRTOS/src 路径。
④、进入 FreeRTOSv202212.01\FreeRTOS\Source\portable 目录,拷贝MemMang文件到KEIL工程中的FreeRTOS/port路径下。
⑤、进入FreeRTOSv202212.01\FreeRTOS\Demo中,选择对应芯片的Demo例程,然后拷贝FreeRTOSConfig.h文件到 FreeRTOS/include 路径中。
本例程选择了STM32F407系列芯片进行移植,其它芯片的移植操作和本例程操作类似。
⑥进入FreeRTOSv202212.01\FreeRTOS\Source\portable\RVDS\ARM_CM4F,拷贝port.c和portmacro.h到 FreeRTOS/port 路径下。
⑦、将FreeRTOS代码添加到KEIL裸机工程设备树中。
heap_x.c内存分配文件根据需要,只能加入一个!
⑧、打开FreeRTOSConfig.h文件,因MDK默认使用armcc编译器,需在FreeRTOSConfig.h文件中添加defined(_CC_ARM),避免源码找不到SystemCoreClock,详细添加如下:
- /* Ensure stdint is only used by the compiler, and not the assembler. */
- #if defined(__ICCARM__)||defined(__CC_ARM)||defined(__GNU__)
- #include <stdint.h>
- extern uint32_t SystemCoreClock;//系统时钟值168000000,在system_stm32f4xx.c中定义
- #endif
⑨、编译整个工程,如果出现下面的报错信息,则需要修改FreeRTOSConfig.h对应的钩子函数的宏定义开关。
修改下面的这三个宏定义的值为0,即可解决编译报错问题。
- #define configUSE_IDLE_HOOK 0 //设置为0,用户就不用自己写空闲任务
- #define configUSE_TICK_HOOK 0 //宏开启的话,会导致SysTick的中断服务函数每过1ms调用一次或用户自定义
- #define configCHECK_FOR_STACK_OVERFLOW 0 //栈溢出检测方法,如果使用的话,需要用户自己提供一个栈溢出处理钩子回调函数
测试FreeRTOS源代码
- #include "stm32f4xx.h"
- #include "FreeRTOS/FreeRTOS.h"
- #include "FreeRTOS/task.h"
- #include <stdio.h>
- #include "usart.h"
-
- TaskHandle_t app_task1_handle = NULL;
- TaskHandle_t app_task2_handle = NULL;
- void app_task1(void* pvParameters);
- void app_task2(void* pvParameters);
-
- int main(void)
- {
- NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );
- //SysTick_Config(SystemCoreClock/configTICK_RATE_HZ); //开启导致硬件错误中断
- USART1_Init(115200);
- printf("starting...\r\n");
- /* 创建app_task1任务 */
- xTaskCreate((TaskFunction_t )app_task1, /* 任务入口函数 */
- (const char* )"app_task1", /* 任务名字 */
- (uint16_t )512, /* 任务栈大小 */
- (void* )NULL, /* 任务入口函数参数 */
- (UBaseType_t )2, /* 任务的优先级 */
- (TaskHandle_t* )&app_task1_handle); /* 任务控制块指针 */
-
- /* 创建app_task2任务 */
- xTaskCreate((TaskFunction_t )app_task2, /* 任务入口函数 */
- (const char* )"app_task2", /* 任务名字 */
- (uint16_t )512, /* 任务栈大小 */
- (void* )NULL, /* 任务入口函数参数 */
- (UBaseType_t )2, /* 任务的优先级 */
- (TaskHandle_t* )&app_task2_handle); /* 任务控制块指针 */
- /* 开启任务调度 */
- vTaskStartScheduler();
- }
-
- void app_task1(void* pvParameters)
- {
- int cnt = 0;
- for(;;)
- {
- printf("app_task1 is running %d...\r\n", cnt);
- vTaskDelay(1000);
- cnt++;
- }
- }
-
- void app_task2(void* pvParameters)
- {
- int cnt = 0;
- for(;;)
- {
- printf("app_task2 is running %d...\r\n", cnt);
- vTaskDelay(1000);
- cnt++;
- }
- }
-
![](https://csdnimg.cn/release/blogv2/dist/pc/img/newCodeMoreWhite.png)
工程代码编译结果
FreeRTOS程序正常运行
移植正常的FreeRTOS工程代码链接:GitHub - fanghui1234/MCU_FreeRTOS
部分设备编译下载后,程序无法运行,解决方法如下:FreeRTOS移植,解决设备崩溃死机无反应(STM32)-CSDN博客
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。