本篇目标:基于上一篇的基础工程(stm32f4_first_demo)上,移植freertos,建立移植工程(stm32f4_freertos)。

资料准备:

  • Freertos源文件
  • 最后工程:项目工程(github分支) project 文件夹下的 stm32f4_freertos 工程。

Freertos源文件目录说明

.
├─FreeRTOS                          //只展示了会用到的子文件夹
│  ├─Demo
│  │  └─CORTEX_M4F_STM32F407ZG-SK   //应用示例,会用到文件夹下的FreeRTOSConfig.h文件
│  ├─License
│  └─Source                         //源代码文件夹
│      ├─include                    //头文件
│      └─portable                   //移植相关文件
│          ├─GCC
│          │  └─ARM_CM4F            //在stm32cubeide(gcc)环境下的stm32移植文件
│          ├─MemMang                //内存管理文件
│          └─RVDS
│              └─ARM_CM4F           //在keil环境下的stm32移植文件
└─FreeRTOS-Plus                     //其他freertos应用文件

ps:上述是freertos源文件目录,一些用不到的目录做了一些过滤,主要关注这几个目录文件就可以了:

  • source 文件目录,目录下的 .c 文件为freertos的核心文件。
  • ARM_CM4F 文件夹下是对应各种stm32的移植文件。
  • MemMang 文件夹下是内存管理文件,一般场景都选择 heap_4,具体可以在后面分析的时候看。
  • FreeRTOSConfig.h 用于配置 freertos ,可以在demo工程中copy一个然后结合自己的情况修改。

Freertos源文件移植改动

这部分主要涉及的是 freertos 部分的改动。

  1. 我们创建一个 stm32_port 文件夹专门来存放移植相关的配置文件,这样可以更好的模块化。

  2. 复制 MemMang 文件夹到 stm32_port 下,实际用到的是 heap_4.c 文件。

  3. keil环境复制 portable目录下的 RVDS 文件夹到 stm32_port 下;stm32cubeide复制 portable目录下的 GCC 文件夹到 stm32_port 下。

  4. 复制 demo 工程中 CORTEX_M4F_STM32F407ZG-SK 文件夹下的 FreeRTOSConfig.h 到 stm32_port 下。

    以上是修改建立直观的移植目录,接下来就是代码修改,修改 FreeRTOSConfig.h 相关配置项:

// 1. ------------------------------------------------------
//源--45行
#ifdef __ICCARM__#include <stdint.h>extern uint32_t SystemCoreClock;
#endif
// 修改后:增加不同编译环境的配置
#if defined (__ICCARM__) || defined (__CC_ARM) || defined (__GNUC__)#include <stdint.h>extern uint32_t SystemCoreClock;
#endif// 2. ------------------------------------------------------
// 源--51、52、64、66行,修改宏定义为0,暂时不需要使用到这些钩子函数
#define configUSE_IDLE_HOOK             0//1
#define configUSE_TICK_HOOK             0//1
#define configCHECK_FOR_STACK_OVERFLOW  0//2
#define configUSE_MALLOC_FAILED_HOOK    0//1// 3. ------------------------------------------------------
// 源--124行,注释宏定义,该中断函数我们自己实现
//#define xPortSysTickHandler SysTick_Handler

上面是修改的内容,贴一份实际修改后的配置文件:

/** FreeRTOS Kernel V10.3.1* Copyright (C) 2020 Amazon.com, Inc. or its affiliates.  All Rights Reserved.** Permission is hereby granted, free of charge, to any person obtaining a copy of* this software and associated documentation files (the "Software"), to deal in* the Software without restriction, including without limitation the rights to* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of* the Software, and to permit persons to whom the Software is furnished to do so,* subject to the following conditions:** The above copyright notice and this permission notice shall be included in all* copies or substantial portions of the Software.** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.** http://www.FreeRTOS.org* http://aws.amazon.com/freertos** 1 tab == 4 spaces!*/#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H/*-----------------------------------------------------------* Application specific definitions.** These definitions should be adjusted for your particular hardware and* application requirements.** THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.** See http://www.freertos.org/a00110.html*----------------------------------------------------------*//* Ensure stdint is only used by the compiler, and not the assembler. */
#if defined (__ICCARM__) || defined (__CC_ARM) || defined (__GNUC__)#include <stdint.h>extern uint32_t SystemCoreClock;
#endif#ifndef USE_OS
#define USE_OS
#endif#define configUSE_PREEMPTION          1
#define configUSE_IDLE_HOOK             0
#define configUSE_TICK_HOOK             0
#define configCPU_CLOCK_HZ              ( SystemCoreClock )
#define configTICK_RATE_HZ              ( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES            ( 5 )
#define configMINIMAL_STACK_SIZE        ( ( unsigned short ) 130 )
#define configTOTAL_HEAP_SIZE           ( ( size_t ) ( 75 * 1024 ) )
#define configMAX_TASK_NAME_LEN         ( 10 )
#define configUSE_TRACE_FACILITY        1
#define configUSE_16_BIT_TICKS          0
#define configIDLE_SHOULD_YIELD         1
#define configUSE_MUTEXES               1
#define configQUEUE_REGISTRY_SIZE       8
#define configCHECK_FOR_STACK_OVERFLOW  0
#define configUSE_RECURSIVE_MUTEXES     1
#define configUSE_MALLOC_FAILED_HOOK    0
#define configUSE_APPLICATION_TASK_TAG  0
#define configUSE_COUNTING_SEMAPHORES   1
#define configGENERATE_RUN_TIME_STATS   0/* Co-routine definitions. */
#define configUSE_CO_ROUTINES       0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )/* Software timer definitions. */
#define configUSE_TIMERS                1
#define configTIMER_TASK_PRIORITY       ( 2 )
#define configTIMER_QUEUE_LENGTH        10
#define configTIMER_TASK_STACK_DEPTH    ( configMINIMAL_STACK_SIZE * 2 )/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet        1
#define INCLUDE_uxTaskPriorityGet       1
#define INCLUDE_vTaskDelete             1
#define INCLUDE_vTaskCleanUpResources   1
#define INCLUDE_vTaskSuspend            1
#define INCLUDE_vTaskDelayUntil         1
#define INCLUDE_vTaskDelay              1/* Cortex-M specific definitions. */
#ifdef __NVIC_PRIO_BITS/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */#define configPRIO_BITS            __NVIC_PRIO_BITS
#else#define configPRIO_BITS            4        /* 15 priority levels */
#endif/* The lowest interrupt priority that can be used in a call to a "set priority"
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY         0xf/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions.  DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    5/* Interrupt priorities used by the kernel port layer itself.  These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY         ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY    ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }   /* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names. */
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
// #define xPortSysTickHandler SysTick_Handler#endif /* FREERTOS_CONFIG_H */

stm32f4移植改动

这一部分为涉及到stm32的代码,主要就是我们自己实现的 SysTick_Handler 中断。

  1. 在 stm32_port 文件夹下创建 stm_config.c ,用于涉及 stm32 部分的代码与初始化接口。

  2. 实现 SysTick_Handler 中断函数:

    void SysTick_Handler(void)
    {extern void xPortSysTickHandler( void );/* USER CODE END SysTick_IRQn 0 */#if (INCLUDE_xTaskGetSchedulerState == 1 )if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED){#endif /* INCLUDE_xTaskGetSchedulerState */xPortSysTickHandler();#if (INCLUDE_xTaskGetSchedulerState == 1 )}#endif /* INCLUDE_xTaskGetSchedulerState */
    }
    

初始化Freertos并搭建应用任务

至上,移植工作已经做完了,但是需要把配置好的 freertos 用起来,所以少不了初始化与应用任务的建立。

  1. 在 stm_config.c 实现以下内容:

    #include "FreeRTOS.h"
    #include "task.h"static TaskHandle_t xTask_creat;/*** @note   This function is used to creat app task and delect self.* @brief  None* @param  *p* @retval None*/
    static void creat_task(void *p)
    {log_d("%s", __FUNCTION__);int cnt = 0;/* creat app task in this 在这里创建应用任务 */taskENTER_CRITICAL();//user_main(NULL);     //调用自己的应用函数接口taskEXIT_CRITICAL();/* creat app task in this 在这里创建应用任务 */#if 1/* delay task 延时退出,并删除本任务 */while(1){log_d("this is creat task:idle-%d", cnt++);vTaskDelay(1000);if (cnt >= 10){break;}}
    #endiflog_d("delete creat task");vTaskDelete(xTask_creat);
    }/*** @note   This function is used to creat app task and delect self.* @brief  None* @param  *p* @retval None*/
    int rtos_init(void)
    {/* stm32 NVIC config */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);BaseType_t xReturn = pdPASS;log_i("Freertos v10.3.1 start ");/* first creat task in this 创建rtos第一个任务,用于创建其他任务 */xReturn = xTaskCreate(  (TaskFunction_t )creat_task,(const char *   )"creat_task",(unsigned short )1024,(void *         )NULL,(UBaseType_t    )1,(TaskHandle_t * )&xTask_creat);if (pdPASS != xReturn){return -1;}/* start task 开启任务调度 */vTaskStartScheduler();return xReturn;
    }
    
  2. 在 main函数中调用封装好的初始化接口 rtos_init 即可。

    //main函数调用示例
    int main(void)
    {/* stm32系统配置 */Sys_Config();extern int rtos_init(void);rtos_init();log_e("never get here");while(1){}
    }
    

同样贴上 stm_config.c 的全部代码:

/******************************************************************************** @file    : stm_config.c* @author  : Tuu* @version : 1.0.0* @date    : 2020-04-01* @brief   : stm32f407 freertos config file******************************************************************************* @lasteditors  : Tuu* @lasteditTime : 2020-06-02******************************************************************************* @atten   : Copyright (C) by Tuu Inc*******************************************************************************//* Includes -------------------------------------------------------------------*/
#include "config.h"#include "FreeRTOS.h"
#include "task.h"/* Defines --------------------------------------------------------------------*//* Variables ------------------------------------------------------------------*/
static TaskHandle_t xTask_creat;/* Functions ------------------------------------------------------------------*/
extern void user_main(void *p);/*** @note   This function is used to creat app task and delect self.* @brief  None* @param  *p* @retval None*/
static void creat_task(void *p)
{log_d("%s", __FUNCTION__);int cnt = 0;/* creat app task in this 在这里创建应用任务 */taskENTER_CRITICAL();user_main(NULL);taskEXIT_CRITICAL();/* creat app task in this 在这里创建应用任务 */#if 1/* delay task 延时退出,并删除本任务 */while(1){log_d("this is creat task:idle-%d", cnt++);vTaskDelay(1000);if (cnt >= 10){break;}}
#endiflog_d("delete creat task");vTaskDelete(xTask_creat);
}/*** @note   This function is used to creat app task and delect self.* @brief  None* @param  *p* @retval None*/
int rtos_init(void)
{/* stm32 NVIC config 必须配置成分组4 */NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);BaseType_t xReturn = pdPASS;log_i("Freertos v10.3.1 start ");/* first creat task in this 创建rtos第一个任务,用于创建其他任务 */xReturn = xTaskCreate(  (TaskFunction_t )creat_task,(const char *   )"creat_task",(unsigned short )1024,(void *         )NULL,(UBaseType_t    )1,(TaskHandle_t * )&xTask_creat);if (pdPASS != xReturn){return -1;}/* start task 开启任务调度 */vTaskStartScheduler();return xReturn;
}/* systick */
#if 1
void SysTick_Handler(void)
{extern void xPortSysTickHandler( void );/* USER CODE END SysTick_IRQn 0 */#if (INCLUDE_xTaskGetSchedulerState == 1 )if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED){#endif /* INCLUDE_xTaskGetSchedulerState */xPortSysTickHandler();#if (INCLUDE_xTaskGetSchedulerState == 1 )}#endif /* INCLUDE_xTaskGetSchedulerState */
}
#endif/************************ (C) COPYRIGHT Tuu ********END OF FILE****************/

实际运行

上面基本的移植,初始化 freertos 的工作基本完成了,可以编译烧录运行看一下效果:(可以根据自己的环境打开 stm32f4_freertos 中的工程来运行看看)


小结

做个小结,移植 freertos 涉及到的几个方面:

  1. 与移植硬件相关的 portable 文件,有能力的同学可以自己编写,像stm32比较大众的有现有的文件,可以直接拿来使用,如上移植。
  2. 内存管理默认情况下都使用 heap_4.c 文件,在特殊多内存管理的时候才会用到 heap_5.c等。
  3. 修改 FreeRTOSConfig.h 的配置,将刚开始不必要的HOOK宏定义去除,只编译基本的功能。
  4. 自己定义 SysTick_Handler 函数,方便后续拓展,以及完成初始化创建任务的代码。

ps:为什么要重新创建一个 stm_config.c 文件?因为将所有有关 freertos 移植的文件以及与硬件相关的代码都放在了 stm32_port 文件夹下,这样后续跨平台移植的时候,修改该文件夹下和硬件相关的内容即可,不需要大动工程与框架,保证后续应用移植开发的方便性。

想要不基于上面的基础工程,移植到自己的 stm32f4 工程当中,只需要将 thirdlib 文件夹下的 FreeRTOSv10.3.1 拷贝到自己的工程中,然后调用初始化 rtos_init 即可。


如有其它移植上面的问题可以问我哦~后续会对移植相关及freertos部分源码进行解析,深入理解才可以更好的运用。

Tuu

STM32F4基础工程移植FreeRTOS相关推荐

  1. 单片机 STM32F103C8T6 cubeMX HAL库 从环境到开发 正点原子工程移植 freeRTOS

    文章目录 0 准备材料 1 闪烁PC13的小灯 2 正点原子工程移植 注意点以及细节 3 freeRTOS 3.1 LED KEY 串口1 的一个实验 0 准备材料 1.需要正点原子的HAL介绍书籍可 ...

  2. 基于STM32F4的CANOpen移植教程(超级详细)

    CANopen移植到STM32F4平台 前言 1 物品准备 2 相关软件安装 2.1 CAN上位机 2.2 对象字典生成工具objdictedit环境配置 3 将CANopen移植到STM32F407 ...

  3. STM32F4移植FreeRTOS V10.3.1

                                                                            STM32F429移植FreeRTOS 一.环境 Win ...

  4. 2.STM32F407ZGT6 学习笔记-移植 FreeRTOS

    程序移植的代码: https://gitee.com/chejia12/free-rtos_-f407.git 1. 在工程下建议FreeRTOS文件夹 2. 在FreeRTOS文件夹下建立 src ...

  5. 启明欣欣STM32开发板移植FreeRTOS

    承接这篇文章,本篇讲述如何把FreeRTOS移植到启明欣欣STM32开发板里,比较简单,网上也有各种教程,本文也是参考其它文章,这里再记录一下. 一 搭建基础工程 启明欣欣STM32开发板上的MCU是 ...

  6. stm32f429igt6跑linux,TouchGFX在STM32F429IGT6上的移植(FreeRTOS版本)

    TouchGFX在STM32F429IGT6上的移植(FreeRTOS版本) TouchGFX在STM32F429IGT6上的移植(FreeRTOS版本) 目录 一.移植环境 二.应用框架 三.Tou ...

  7. 移植FreeRTOS到STM32

    移植FreeRTOS到STM32单片机上 引言 介绍 什么是 RTOS? 为什么嵌入式设备往往使用RTOS? FreeRTOS 具体步骤 总结 引言 本文详细介绍如何移植FreeRTOS到STM32单 ...

  8. 转发:stm32 移植 freertos

    原链接:http://www.51hei.com/bbs/dpj-106526-1.html 看到一篇stm32移植freertos的文章,讲述的最完整. 前言: 由于之前听过太多人抱怨移植FreeR ...

  9. STM32F103移植FreeRTOS必须搞明白的系列知识---1(Cortex-CM3中断优先级)

    STM32F103移植FreeRTOS必须搞明白的系列知识---1(Cortex-CM3中断优先级) STM32F103移植FreeRTOS必须搞明白的系列知识---2(FreeRTOS任务优先级) ...

最新文章

  1. Grunt-几个常用的任务配置,加载,执行的写法
  2. 队列学习笔记 顺序队列
  3. 队列加锁无锁栈实现一例
  4. vue项目按需引入element-ui,修改.babelrc文件之后报错
  5. 前端那些年----Webstream快捷键备忘(mac)
  6. hadoop job 数量_Hadoop job任务分配
  7. linux时间子系统之,linux时间子系统(四)
  8. USACO sec2.1 Ordered Fractions
  9. arcgis10.1连接sqlserver数据库常见问题(转载)
  10. 生活中的这些难题,数据库开发者可为你解决!
  11. Word论文插入带有方括号序号的参考文献——尾注+交叉引用
  12. python jinja2_python-Jinja2用法
  13. 图灵工业机器人说明书_从2020世界人工智能大会,看工业机器人领域领军企业布局|机器人大讲堂...
  14. sld中两个条件同时成立时样式配置
  15. 部分彩色图片处理方式的C++实现
  16. S3C22440 JTAG连接不上
  17. 盈致科技2021大事件 感恩回首过去,高歌猛进一同共创未来
  18. MFC中listctrl图片拖拽效果
  19. 基于imx8的成熟360全景方案 ,NVP6324+IMX8,N4+IMX8
  20. java空对象怎么判断,java怎么判断对象为空

热门文章

  1. 【渝粤题库】陕西师范大学164103 网络贸易 作业 (高起专)
  2. VNCTF2021 Ez_game
  3. Esxi虚拟机安装黑群晖实践
  4. 程序员口中的demo是什么意思_怎样让5分钟的曲子不重样播放450天?程序员:用马尔可夫链...
  5. 产品负责人 VS 产品经理
  6. mysql 查询每个科目分数大于80
  7. 《Win10——常用快捷键》
  8. 综述 | 实例分割研究
  9. 用NEON intrinsic实现RGB转YUV420SP(NV12)
  10. 实验四-1:输入一个字符,请判断是字母、数字还是其它字符。