FreeRTOS移植:STM32L476 nucleo-L476RG 开发板《03》

系列文章

FreeRTOS移植:STM32L476 nucleo-L476RG 开发板《01》

FreeRTOS移植:STM32L476 nucleo-L476RG 开发板《02》

说明

c 复制代码
.\Output\stm32l475_freertos.axf: Error: L6218E: Undefined symbol pvPortMalloc (referred from event_groups.o).
.\Output\stm32l475_freertos.axf: Error: L6218E: Undefined symbol vPortFree (referred from event_groups.o).
.\Output\stm32l475_freertos.axf: Error: L6218E: Undefined symbol vApplicationIdleHook (referred from tasks.o).
.\Output\stm32l475_freertos.axf: Error: L6218E: Undefined symbol vApplicationStackOverflowHook (referred from tasks.o).
.\Output\stm32l475_freertos.axf: Error: L6218E: Undefined symbol vApplicationTickHook (referred from tasks.o).
  • 也就是有五个函数需要移植与适配
c 复制代码
 pvPortMalloc
 vPortFree
 vApplicationIdleHook 
 vApplicationStackOverflowHook 
 vApplicationTickHook 

环境

  • Win10 64位:当前 Windows 主流操作系统

  • Keil MDK 5.36,IDE,方便开发与调试

  • STM32CubeMX 6.11.1 用于生成STM32裸机工程,本篇不再使用

动态内存管理

  • FreeRTOS 支持动态内存分配,也就是可以从内存比如 STM32 SRAM 中划出一个区域,用于动态内存的管理,可以定义一个较大的静态数组,作为内存池

  • FreeRTOS 当前支持 5 种 动态内存的管理,只能使用其中的一种,经过初步了解, 内存管理第四种方法最简单,因此本次移植使用 内存管理四,也就是把 FreeRTOS\Source\portable\MemMang\heap_4.c 加入工程

  • 增加 内存管理: heap_4.c 后,继续编译,发现还有 四个 函数需要适配
c 复制代码
.\Output\stm32l475_freertos.axf: Error: L6218E: Undefined symbol vApplicationIdleHook (referred from tasks.o).
.\Output\stm32l475_freertos.axf: Error: L6218E: Undefined symbol vApplicationStackOverflowHook (referred from tasks.o).
.\Output\stm32l475_freertos.axf: Error: L6218E: Undefined symbol vApplicationTickHook (referred from tasks.o).
.\Output\stm32l475_freertos.axf: Error: L6218E: Undefined symbol vApplicationMallocFailedHook (referred from heap_4.o).
Not enough information to list image symbols.
Not enough information to list load addresses in the image map.
Finished: 2 information, 0 warning and 4 error messages.
".\Output\stm32l475_freertos.axf" - 4 Error(s), 0 Warning(s).

Hook 函数适配

  • 需要适配(实现)的几个 Hook 函数
c 复制代码
vApplicationIdleHook
vApplicationStackOverflowHook
vApplicationTickHook
vApplicationMallocFailedHook
  • 在工程中新建一个 port.c 文件,用于实现 FreeRTOS 的 Hook (系统钩子)函数,可以通过全局搜索获取这几个 Hook 钩子函数的定义,如果不确定,有些钩子函数可以为空或者 while (1) 异常处理
c 复制代码
#include "FreeRTOS.h"
#include "task.h"

void vApplicationIdleHook( void )
{
}

void vApplicationTickHook( void )
{
}

/* 内申请失败的 Hook */
void vApplicationMallocFailedHook( void )
{
}

/* 栈溢出 */
void vApplicationStackOverflowHook( TaskHandle_t xTask, char * pcTaskName )
{
    while (1)
    {
        ;
    }
}
  • 并把 port.c 加入 Keil MDK5 工程
  • 此时编译正常通过了

适配完成了吗?

  • 需要运行一下,确认 FreeRTOS 是否可以正常运行,如果发现异常,再进行完善

最大线程优先级设置

  • 下载,调试运行,发现卡住任务的创建部分:任务优先级断言
  • 也就是FreeRTOS 配置一个最大任务优先级,常见的任务的运行优先级不能超过这个值,否则可以更改这个最大任务优先级设置 configMAX_PRIORITIES ,或者更改创建的任务的优先级

  • 这里在 FreeRTOSConfig.h 配置文件中定义,可以配置较大一点,默认 #define configMAX_PRIORITIES ( 5 ) 改为 #define configMAX_PRIORITIES ( 32 )

继续运行

  • 再次运行,发现用户的例程可以进入了,能正常调度了?

  • 不过调试过程,发现创建的两个线程函数,各进入一次后,好像就不再进来,难道延时存在问题(系统定时器)?

  • 继续排查 FreeRTOSConfig.h 的配置,这个配置文件是其他的板子拿过来的,需要看一遍,进行当前 MCU 平台的适配

排查运行问题

  • 当前怀疑系统延时不正常,也就是线程函数只进入一次后,就无法再次进入,线程函数中只有一个 vTaskDelay(1000); 延时,理论上是 1秒延时,如果 一个 tick 是 1ms

  • 确认系统定时器中断是否正常进入

  • FreeRTOS 的 Systick 中断: #define xPortSysTickHandler SysTick_Handler,也就是 xPortSysTickHandler,在 xPortSysTickHandler 中加入断点,调试运行,发现可以周期性进入断点

  • 继续测试,把 延时的时间缩短,发现可以很快的进入,说明调度没有问题
  • 如果延时不准确(调试与实际运行可能存在差异),可以尝试更改调试器时的晶振

  • 当前调度确认没有问题,FreeRTOS 初步适配完成

小结

  • 本篇主要讲解 FreeRTOS 的适配,当前创建的 两个 task,可以正常的切换,说明系统任务调度工作起来了。

  • 记下来可以增加串口打印、LED 驱动(用于指示系统运行),这样就可以摆脱调试,直接看到FreeRTOS 的运行效果了

相关推荐
嵌新程2 小时前
day03(单片机高级)RTOS
stm32·单片机·嵌入式硬件·freertos·rtos·u575
Lin2012302 小时前
STM32 Keil5 attribute 关键字的用法
stm32·单片机·嵌入式硬件
电工小王(全国可飞)2 小时前
STM32 RAM在Memory Map中被分为3个区域
stm32·单片机·嵌入式硬件
maxiumII2 小时前
Diving into the STM32 HAL-----DAC笔记
笔记·stm32·嵌入式硬件
时光の尘6 小时前
C语言菜鸟入门·关键字·float以及double的用法
运维·服务器·c语言·开发语言·stm32·单片机·c
日晨难再9 小时前
嵌入式:STM32的启动(Startup)文件解析
stm32·单片机·嵌入式硬件
PegasusYu19 小时前
STM32CUBEIDE FreeRTOS操作教程(九):eventgroup事件标志组
stm32·教程·rtos·stm32cubeide·free-rtos·eventgroup·时间标志组
文弱书生6561 天前
输出比较简介
stm32
黑客呀1 天前
[系统安全]Rootkit基础
stm32·单片机·系统安全
小A1591 天前
STM32完全学习——使用SysTick精确延时(阻塞式)
stm32·嵌入式硬件·学习