avatar🌌
零醇零醇の小屋

愿你有一天,能与你最重要的人重逢。

摸鱼摸鱼

抛弃CubeMX一键生成,手把手教你硬核移植 FreeRTOS

闲着没事摸摸鱼,感觉 CubeMX 一键生成的 FreeRTOS 差点意思。今天试试自己从零来移植 FreeRTOS.

1. 创建并配置 Cube 工程

首先,第一步先创建一个新的 Cube 工程: 图1

配置好系统时钟和调试接口: 图2图3图4

这里我们开一个 PC13 的灯、UART1 的串口和 I2C 上的屏幕,用来作为后续跑 RTOS 的演示外设: 图5图6图7

⚠️ 最重要的一步:不要忘记关掉系统默认的中断函数生成! 在 NVIC 设置里,必须取消勾选 PendSVSysTickSVC 的中断生成,因为这三个中断要留给 FreeRTOS 自己来接管。 图8

选好工具链,直接点击生成代码: 图9图10


2. 下载并导入 FreeRTOS 源码

在 GitHub 上找到 FreeRTOS 官方源码仓库,并且下载它: 图11图12

在刚刚生成的 STM32 工程目录里新建一个 RTOS 文件夹: 图13

在这个文件夹里头新建三个子文件夹(Core, Inc, Port),如图整理好源码文件: 图14

  • Core 里面我们引入这几个核心 C 文件: 图15图16

  • Inc 里面我们引入这几个头文件: 图17图18图19

  • Port 里面引入这几个接口文件(这里以 stm32f103c6t6 也就是 Cortex-M3 为例): 图20图21图22


3. Keil 工程配置

打开生成的 Keil 工程,更改编译器为 ARM Compiler 6,并且在工程设置里添加刚才那几个文件夹的头文件路径。 在左侧工程目录中导入对应的 C 文件。完成后,工程目录结构应该是这样的: 图23图24图25


4. 编写并修改配置文件

打开 FreeRTOSConfig.h,开始核心配置:设置主频、滴答时钟、FPU、MPU等等。 图26图27图28图29图32

⚠️ 注意:并在文件最后补上中断向量映射代码:

c
#define vPortSVCHandler    SVC_Handler
#define xPortPendSVHandler PendSV_Handler

接着,新建 RTOSManage.cRTOSManage.h图30

RTOSManage.c 代码如下:

c
#include "RTOSManage.h"

extern void xPortSysTickHandler(void);

//栈溢出
void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName)
{
    while(1)
    {
    }
}

//SysTick重载
void SysTick_Handler(void)
{
    HAL_IncTick(); 
  
    if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
    {
        xPortSysTickHandler();
    }
}

RTOSManage.h 代码如下:

c
#ifndef _RTOSMANAGE_H
#define _RTOSMANAGE_H

#include "FreeRTOS.h"
#include "task.h"
#include "stm32f1xx_hal.h"

//栈溢出
void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName);

//SysTick重载
void SysTick_Handler(void);

#endif

5. 编写任务并测试跑通

main.c 里加入 vTaskStartScheduler();,基本的配置就结束了。 图31

接下来我们来测试一下,引入几个简单的点灯和串口打印任务: 图33图34图35图36图37

可以看到 整个项目正常工作 完结撒花!🎉


RT-Thread Nano 的初体验
零醇的小屋正式启航!