上一篇 FreeRTOS移植:STM32L476 nucleo-L476RG 开发板《01》 主要讲了一下如何快速搭建一个 STM32 裸机工程,其实 STM32CubeMX 可以生成 FreeRTOS 的工程,这就没有了 FreeRTOS 的移植文章
本篇继续讲一下 【手动】移植 FreeRTOS 的步骤,移植完成后,继续研究 FreeRTOS 的使用
Win10 64位:当前 Windows 主流操作系统
Keil MDK 5.36,IDE,方便开发与调试
STM32CubeMX 6.11.1 本篇不再使用
FreeRTOS 官方的网址 https://www.freertos.org/
点击下载 FreeRTOS,发布版本可能没有那么新,比如当前最新版本 FreeRTOS 202212.01,但是下载的压缩包比较小,容易下载


FreeRTOS 主仓库 https://github.com/FreeRTOS/FreeRTOS.git
FreeRTOS 内核仓库 https://github.com/FreeRTOS/FreeRTOS-Kernel.git
由于 FreeRTOS 内核仓库仅仅为内核代码文件,没有 Demo,因此建议直接下载 FreeRTOS 主仓库,使用 Git 命令如下
git clone https://github.com/FreeRTOS/FreeRTOS.git --recurse-submodules


直接下载下来的 FreeRTOS,需要整理一下,这样方便工程的管理,有些不需要的 Demo,无须加入工程
当前平台:STM32L476,可以参考 FreeRTOS 中的一些 Demo,找到相似 CPU,这样 CPU 部分就不需要额外移植了
当前 FreeRTOS 没有 STM32L476 Keil MDK5 的 Demo,因此手动搭建 FreeRTOS 工程即可,使用上次生成的 STM32L476 裸机工程


STM32CubeMX 生成)


FreeRTOS/Kernel 与 FreeRTOS/cpu 的分组(Group)
FreeRTOS\Source\portable\RVDS\ARM_CM4F
"FreeRTOS.h"compiling croutine.c...
..\FreeRTOS\Source\croutine.c(29): error: #5: cannot open source input file "FreeRTOS.h": No such file or directory
#include "FreeRTOS.h"
..\FreeRTOS\Source\croutine.c: 0 warnings, 1 error
... ...



"FreeRTOSConfig.h" 头文件,这个头文件属于工程配置文件,可以在 FreeRTOS Demo 中找到一个类似的,然后进行配置与修改
compiling croutine.c...
..\FreeRTOS\Source\include\FreeRTOS.h(58): error: #5: cannot open source input file "FreeRTOSConfig.h": No such file or directory
#include "FreeRTOSConfig.h"
... ...

FreeRTOS\Demo\CORTEX_M4F_STM32F407ZG-SK\FreeRTOSConfig.h
FreeRTOSConfig.h 放在工程根目录下即可,无须放在 FreeRTOS 目录,因为这个是工程本身的专有的配置文件
此时编译报错比较少了,可以针对性的开始移植与适配了
此时编译,报错 "SystemCoreClock" is undefined
..\FreeRTOS\Source\portable\RVDS\ARM_CM4F\port.c(813): error: #20: identifier "SystemCoreClock" is undefined
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
..\FreeRTOS\Source\portable\RVDS\ARM_CM4F\port.c: 0 warnings, 1 error
"stm32l475_freertos\stm32l475_freertos.axf" - 1 Error(s), 0 Warning(s).
#include "main.h"
#include "FreeRTOS.h"
#include "task.h"
UART_HandleTypeDef huart2;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
#define TASK_TEST_PRIORITY (tskIDLE_PRIORITY + 6)
#define TASK_TEST2_PRIORITY (tskIDLE_PRIORITY + 8)
static void task_test_entry(void *pvParameters)
{
while (1)
{
vTaskDelay(1000);
}
}
static void task_test2_entry(void *pvParameters)
{
while (1)
{
vTaskDelay(2000);
}
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART2_UART_Init();
xTaskCreate(task_test_entry, "task_test", 512, NULL, TASK_TEST_PRIORITY, NULL);
xTaskCreate(task_test2_entry, "task_test2", 512, NULL, TASK_TEST2_PRIORITY, NULL);
vTaskStartScheduler();
while (1)
{
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_SET);
HAL_Delay(500);
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
HAL_Delay(500);
}
}
解决 SystemCoreClock 找不到的编译报错,这里有个 编译器的判断,或者改为 Keil MDK5 编译器的,armcc 或者 armclang 等,建议去掉即可,因为这个配置文件来自其他的编译器
【备注】 FreeRTOSConfig.h 文件为工程配置文件,可以根据当前的平台随时修改(适配)


stm32l475_freertos\stm32l475_freertos.axf: Error: L6200E: Symbol SVC_Handler multiply defined (by port.o and stm32l4xx_it.o).
stm32l475_freertos\stm32l475_freertos.axf: Error: L6200E: Symbol PendSV_Handler multiply defined (by port.o and stm32l4xx_it.o).
stm32l475_freertos\stm32l475_freertos.axf: Error: L6200E: Symbol SysTick_Handler multiply defined (by port.o and stm32l4xx_it.o).
stm32l4xx_it.c 中的自动生成的中断函数【注释掉】
stm32l475_freertos\stm32l475_freertos.axf: Error: L6218E: Undefined symbol pvPortMalloc (referred from event_groups.o).
stm32l475_freertos\stm32l475_freertos.axf: Error: L6218E: Undefined symbol vPortFree (referred from event_groups.o).
stm32l475_freertos\stm32l475_freertos.axf: Error: L6218E: Undefined symbol vApplicationIdleHook (referred from tasks.o).
stm32l475_freertos\stm32l475_freertos.axf: Error: L6218E: Undefined symbol vApplicationStackOverflowHook (referred from tasks.o).
stm32l475_freertos\stm32l475_freertos.axf: Error: L6218E: Undefined symbol vApplicationTickHook (referred from tasks.o).

FreeRTOS 在 STM32L476 平台(Cortex-M4)上适配其实很容易,当然也需要一些细节的处理
本篇主要搭建 FreeRTOS 的工程,几个编译问题的【修改】
下一篇继续讲解 FreeRTOS 的适配,让FreeRTOS 在 STM32L476 平台上运行起来