详细教程:STM32移植FreeRTOS的经验分享

0、RTOS概述

        RTOS(Real Time OS)即实时操作系统,根据各个任务的要求,进行资源(包括存储器、外设等)管理、消息管理、任务调度、异常处理等工作。在RTOS支持的系统中,每个任务均有一个优先级(类似前面章节的中断抢占优先级),RTOS根据各个任务的优先级,动态地切换各个任务,保证对实时性的要求。

        RTOS总是运行优先级最高且就绪的任务。

        实时多任务操作系统,以分时方式运行多个任务,任务之间的切换以优先级为根据。只有优先服务方式的RTOS才是真正的实时操作系统。

        使用实时操作系统还需要额外的ROM/RAM开销,2~5%的CPU额外负荷,以及内核的费用。

        使用实时操作系统的必要性:

  • 嵌入式实时操作系统提高了系统的可靠性
  • 提高了开发效率,缩短了开发周期。例如官方甚至提高网络协议栈、文件系统、图形界面(ucGUI、emWin、QT….)的支持。
  • 嵌入式实时操作系统充分发挥了32位CPU的多任务潜力(提高吞吐量,就是一个负载均衡)。
  •         当前RTOS已经广泛应用于各种嵌入式设备中,如智能可穿戴设备、智能家居设备等。且RTOS已成为嵌入式、物联网开发者的基础必备技能。对于应届生而言,掌握RTOS是求职应聘、参与产品项目开发的一个优势加分项。

            如下所示为当前求职招聘的一些基本要求。

            市场上有各色各样的RTOS实时操作系统(UCOS、RT-Thread、FreeRTOS),FreeRTOS 最大的优势就是开源免费,商业使用的话不需要用户公开源代码,也不存在任何版权问题,是当前小型嵌入式操作系统市场使用率最高的。故本文教程选用了FreeRTOS。

    1、下载FreeRTOS

            FreeRTOS官网链接如下:FreeRTOS – Market leading RTOS (Real Time Operating System) for embedded systems with Internet of Things extensions

    在本文档编写时,FreeRTOS最新版本为FreeRTOS 202212.01,因此本文基于此版本进行移植教程,即使后续版本更新,FreeRTOS的整体文件结构不会发生大改变,依然可以采用本文档进行指导移植操作。选择比此版本的更旧的版本移植操作也同本文大致保持一致。

    下载源码后,解压打开FreeRTOS源码文件目录结构如下图所示:

    2、FreeRTOS移植

            FreeRTOS文件夹下,有 DemoSource文件夹是移植过程中需要使用的,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

    3、编译运行FreeRTOS

            测试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++;
    	}
    }
    
    

    工程代码编译结果

    FreeRTOS程序正常运行

    移植正常的FreeRTOS工程代码链接:GitHub – fanghui1234/MCU_FreeRTOS

    部分设备编译下载后,程序无法运行,解决方法如下:FreeRTOS移植,解决设备崩溃死机无反应(STM32)-CSDN博客

    作者:牛马大师兄

    物联沃分享整理
    物联沃-IOTWORD物联网 » 详细教程:STM32移植FreeRTOS的经验分享

    发表评论