使用Clion开发STM32——移植FreeRTOS

FreeRTOS版本:202212.01
STM32型号:STM32H743VIT6
使用工具:Clion

其实在STM32cubeMX中就可以直接配置FreeRTOS,rtthread等操作系统,而且使用接口封装过的,很方便。

但我还是想手动一直一遍,肯定有不一样的收获。

1.下载FreeRTOS源码

FreeRTOS官网https://www.freertos.org/

源码如下

FreeRTOS文件夹

FreeRTOS是内核源码还有一些Demo

FreeRTOS-Plus文件夹

FreeRTOS-Plus是一个包含扩展功能的文件夹

它提供了一些额外的组件和库,这些组件和库并非FreeRTOS内核的一部分,但可以增强系统的功能或提供额外的支持。具体内容包括但不限于:

FreeRTOS-Plus-CLI:一个命令行接口库,允许用户通过串口或其他通信接口与系统进行交互,执行命令和获取信息。

FreeRTOS-Plus-TCP:一个TCP/IP协议栈,为嵌入式系统提供网络通信能力,支持标准的网络协议如TCP、UDP、ICMP等。

FreeRTOS-Plus-FAT:一个文件系统库,支持FAT文件系统,使得嵌入式设备能够读写标准的FAT格式的存储介质,如SD卡或USB闪存驱动器。

FreeRTOS-Plus-IO:一个输入输出库,提供了一套统一的接口来管理不同硬件平台的输入输出设备,简化了设备驱动程序的开发。

FreeRTOS-Plus-Trace:一个跟踪和调试工具,帮助开发者监控和分析系统的运行状态,特别是任务调度和资源使用情况。

【参考文章:二、FreeRTOS目录结构与配置选项讲解

tools文件夹

tools文件夹是一些工具脚本

所以我们移植FreeRTOS与学习它的内核的话,只看FreeRTOS这个文件夹即可。

2.FreeRTOS源码文件

Demo文件夹

FreeRTOS/Demo文件夹中,包含各种演示应用程序,展示了如何在不同的硬件平台上使用 FreeRTOS。每个子文件夹对应一个特定的硬件平台或开发板

移植时要参考和你的芯片相同内核或者类似的Demo,用得到其中的配置文件FreeRTOSConfig.h。

比如我的芯片类型是STM32H743,是cortex M7内核的,但是Demo中并没有STM32H743的例程,那我就找同样cortex M7内核的例程,发现有个CORTEX_M7_STM32F7_STM32756G-EVAL_IAR_Keil,那就它了。

Source文件夹

FreeRTOS/Source是 FreeRTOS 内核源码。

include是头文件

portable 是移植文件:包含与具体硬件平台相关的移植代码。

内核主要文件包括:

tasks.c:任务管理。

queue.c:队列管理。

list.c:链表管理。

timers.c:软件定时器管理。

event_groups.c:事件组管理。

croutine.c:协程(几乎不用)

stream_buffer.c:缓冲区

Portable 文件夹

包含与具体硬件平台相关的移植代码。FreeRTOS 支持多种不同的处理器架构和编译器,因此需要针对不同的平台进行移植。

主要子文件夹包括:

MemMang:内存管理相关代码。

GCC:GNU 编译器集合相关的移植代码。

RVDS:ARM RealView 编译工具链相关的移植代码。

IAR:IAR 编译器相关的移植代码。

因为Clion是使用GCC来编译,所以只关注GCC这个文件夹,如下:

ARM_CM7文件内容如下:

遇见readMe就读一读,肯定没有坏处。

机翻一下:

在ARM Cortex-M7微控制器上运行FreeRTOS有两种选择。最佳选择取决于所使用的ARM Cortex-M7内核的版本。这个revision由一个'r'数字和一个'p'数字指定,所以看起来会有些不同比如"r0p1"。检查正在使用的微控制器的文档,以找到该微控制器中使用的Cortex-M7内核的修订版。如有疑问,请使用FreeRTOS端口是专门为r0p1版本提供的,因为它可以使用所有核心修订。

第一种选择是使用ARM Cortex-M4F端口,第二种选择是使用Cortex-M7 r0p1端口,后者包含一个小的勘误解决方法。

如果ARM Cortex-M7内核的版本不是r0p1,则可以选择已使用,但建议使用FreeRTOS ARM Cortex-M4F接口

/FreeRTOS/Source/portable/GCC/ARM_CM4F目录。

如果ARM Cortex-M7内核的版本为r0p1,则使用FreeRTOS ARM Cortex-M7 r0p1接口位于

/FreeRTOS/Source/portable/GCC/ARM_CM7/r0p1中目录。

就是说r0p1是内核版本,好像这个内核版本有个小bug?如果内核版本是r0p1就使用CM7接口,不是r0p1版本就使用CM4F接口。

老实讲,我并没有找到STM32H743的内核版本是啥。(如有大佬知道请求告知或指点)

算了,先移植一个试试。就CM7的吧

3.拷贝FreeRTOS必要文件到工程

首先有一个可正常运行的裸机工程,比如点灯工程。

在此基础上进行移植。

工程目录下新建文件夹(自己任意起名字)

我建的是

My_Middlewares/FreeRTOS。

(如果使用cubeMX配置其他中间件的话,会自动生成一个文件夹Middlewares,为了与它避免因为名字冲突所带来的麻烦,所以我建的是My_Middlewares)

文件结构如下:

inc是头文件,就是FreeRTOS源码中include文件夹中的内容,还有把Demo中的FreeRTOSConfig.h文件也拷贝过来。

src是源文件

port是接口文件

MemMang是内存管理文件

4.修改CMakelists_temaplate

修改cmakelists的模版文件,不要直接修改cmakelists文件,因为每次生成代码都会重新覆盖这个文件。所以修改CMakelists_temaplate

增加头文件路径

增加编译文件

将21到23取消注释,即开启硬件浮点单元FPU

然后更新cmakelists

5.修改FreeRTOSConfig.h

这个文件毕竟是从人家那拷贝过来的,手动修改一下

大家的每个FreeRTOSConfig.h可能都不一样,修改也可能不一样。

这里仅以我拷贝的这个文件进行说明

这里是#ifndef IAR_SYSTEMS_ASM,反正我不是使用IAR,那这个就不删了。

将#include "stm32F7xx_hal.h"修改为#include "stm32h7xx_hal.h"

将configASSERT注释掉,没注释掉一直报错。

或者可以自己加一个断言

比如这样(前提是串口可以正常使用):

#define vAssertCalled(char,int) printf("Error:%s,%d\r\n",char,int)

#define configASSERT(x) if((x)==0) vAssertCalled(FILE ,LINE )

我这里先不加了直接注释掉了。

将一些钩子函数hook都置为0

configCPU_CLOCK_HZ默认为系统时钟

configTICK_RATE_HZ滴答频率默认1ms

这个不用修改

6.修改stm32h7xx_it.c

在stm32中,基础时钟默认使用的是Systick定时器,用于滴答计数,就是用于HAL_Delay这些。

但是在FreeRTOS中,因为所有的 Cortex M内核的单片机都有Systick定时器,所以FreeRTOS使用的是Systick产生滴答信号。

在FreeRTOSConfig.h中使用宏定义了这几个函数,与我们在stm32h7xx_it.c中的函数冲突,所以将stm32h7xx_it.c中将这三个修改为弱定义

7.验证

c 复制代码
/*************************************FreeRTOS includes*************************************/
#include "FreeRTOS.h"
#include "task.h"

static TaskHandle_t xHandleTaskLED1 = NULL;
static TaskHandle_t xHandleTaskuart1 = NULL;

static void vTaskLED1(void *pvParameters);
static void vTaskUART1(void *pvParameters);

void vTaskLED1(void *pvParameters)
{
    while(1)
    {
        bsp_LedToggle();
        vTaskDelay(100);
    }
}
void vTaskUART1(void *pvParameters)
{
    while(1)
    {
        printf("vTaskUART1: Hello World!\r\n");
        vTaskDelay(500);
    }
}
void AppTaskCreate (void) {
    xTaskCreate(vTaskLED1,    /* 任务函数  */
                "vTaskLED1",        /* 任务名    */
                100,                /* 任务栈大小,单位word,也就是4字节 */
                NULL,                /* 任务参数  */
                1,                    /* 任务优先级*/
                &xHandleTaskLED1);  /* 任务句柄  */

    xTaskCreate(vTaskUART1,    /* 任务函数  */
                "vTaskUART1",        /* 任务名    */
                100,                /* 任务栈大小,单位word,也就是4字节 */
                NULL,                /* 任务参数  */
                1,                    /* 任务优先级*/
                &xHandleTaskuart1);  /* 任务句柄  */
}

int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MPU Configuration--------------------------------------------------------*/
  MPU_Config();

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /******** 省略********/


  /*创建任务*/
  AppTaskCreate();
  /* 启动调度,开始执行任务 */
  vTaskStartScheduler();

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

同时led灯也在闪烁

OK!移植完成

8.修改时钟源

为了避免HAL的基础时钟和FreeRTOS的时钟冲突,可以选用其他定时器作为HAL的基础时钟,比如基本定时器TIM6

时钟这一块的内容向大佬学习的【11.2】FreeRTOS源码精讲② HAL和FreeRTOS基础时钟------Kevin带你读《STM32Cube高效开发教程高级篇》

相关推荐
scan14 小时前
单片机串口接收状态机STM32
stm32·单片机·串口·51·串口接收
Qingniu014 小时前
【青牛科技】应用方案 | RTC实时时钟芯片D8563和D1302
科技·单片机·嵌入式硬件·实时音视频·安防·工控·储能
Mortal_hhh6 小时前
VScode的C/C++点击转到定义,不是跳转定义而是跳转声明怎么办?(内附详细做法)
ide·vscode·stm32·编辑器
深圳市青牛科技实业有限公司6 小时前
【青牛科技】应用方案|D2587A高压大电流DC-DC
人工智能·科技·单片机·嵌入式硬件·机器人·安防监控
Mr.谢尔比7 小时前
电赛入门之软件stm32keil+cubemx
stm32·单片机·嵌入式硬件·mcu·信息与通信·信号处理
LightningJie7 小时前
STM32中ARR(自动重装寄存器)为什么要减1
stm32·单片机·嵌入式硬件
鹿屿二向箔7 小时前
STM32外设之SPI的介绍
stm32
西瓜籽@8 小时前
STM32——毕设基于单片机的多功能节能窗控制系统
stm32·单片机·课程设计
远翔调光芯片^1382879887210 小时前
远翔升压恒流芯片FP7209X与FP7209M什么区别?做以下应用市场摄影补光灯、便携灯、智能家居(调光)市场、太阳能、车灯、洗墙灯、舞台灯必看!
科技·单片机·智能家居·能源
极客小张11 小时前
基于STM32的智能充电桩:集成RTOS、MQTT与SQLite的先进管理系统设计思路
stm32·单片机·嵌入式硬件·mqtt·sqlite·毕业设计·智能充电桩