当前位置: 首页 > news >正文

STM32F1+HAL库+FreeTOTS学习2——STM32移植FreeRTOS

STM32F1+HAL库+FreeTOTS学习2——STM32移植FreeRTOS

  • 获取FreeRTOS源码
  • 创建工程
  • 窥探源码
  • 移植

上期我们认识了FreeRTOS,对FreeRTOS有了个初步的认识,这一期我们来上手移植FreeRTOS到STM32上。

获取FreeRTOS源码

  1. 进入官网:https://www.freertos.org/
  2. 点击下载FreeRTOS
    在这里插入图片描述
  3. 跳转至如下界面,再次点击下载,耐心等待,下载完成解压即可。
    在这里插入图片描述

创建工程

由于下载的过程有点漫长,所以在下载的过程中,可以先配置工程,这里直接使用CubeMX配置,配置可以参照:夜深人静学32系列6——CubeMX入门,这里不做介绍,只需要修改SYS选项如下即可:

  1. 设置调试选项和时钟源:
    在这里插入图片描述

  2. 另外这里建议可以开启一个串口,用于调试:方法参考:夜深人静学32系列11——串口通信 中的CubeMX配置部分即可

  3. 创建成功后的文件夹如下:
    在这里插入图片描述

配置完工程之后,我们来开始移植,首先先看看一些源码:

窥探源码

1.解压下载的源码,打开后如下:
在这里插入图片描述
下面是文件夹描述:

名称描述
FreeRTOSFreeRTOS内核
FreeRTOS-PlusFreeRTOS组件
tools工具
GitHub-FreeRTOS-HomeFreeRTOS的GitHub仓库连接
Quick_Start_Guide快速入门文档链接
其他不重要

其中最重要的是FreeRTOS内核文件,打开后如下:
在这里插入图片描述

下面是文件夹描述:

名称描述
Demo演示例程
License相关许可
SourceFreeRTOS的底层实现源码
Test公用及移植层测试代码

主要用到的是Source和Demo文件夹。下面我们开始移植

移植

  1. 在创建的工程目录里面创建一个文件夹:FreeRTOS
    在这里插入图片描述
  2. 将官方源码中:FreeRTOS->Sourse中的所有文件复制到创建的FreeRTOS文件中,复制完如下:
    在这里插入图片描述
  3. 将官方源码中:FreeRTOS->Demo->CORTEX_STM32F103_Keil->中的"FreeRTOSConfig.h"复制到创建的FreeRTOS->include文件夹中,复制完如下:
    在这里插入图片描述
  4. 返回上一级目录,打开portable文件,将除以下三个文件夹之外的全部删除:
    在这里插入图片描述
  5. 完成以上步骤后打开工程。安装如下操作
    在这里插入图片描述
  6. 在低5步的基础上,在新建的group中添加对应的文件,添加完如图
    在这里插入图片描述
  7. 添加头文件路径
    在这里插入图片描述
  8. 在main.c中包含以下头文件:
/* USER CODE BEGIN Includes */
#include "FreeRTOSConfig.h"
#include "FreeRTOS.h"
#include "task.h"
/* USER CODE END Includes */
  1. 在stm32f1xx_it.c中声明以下函数,并改写以下代码
/* USER CODE BEGIN EV */
extern void xPortPendSVHandler(void);
extern void xPortSysTickHandler(void);
extern void vPortSVCHandler(void);/* USER CODE END EV */

在这里插入图片描述

  1. 完成以上步骤后,编译后零错误,零警告,安全下车:

在这里插入图片描述
11.也有可能编译后有问题,出现以下报错:
在这里插入图片描述

应对方法:打开FreeRTOSConfig.h,用以下代码替换掉即可:

#ifndef FREERTOS_CONFIG_H__
#define FREERTOS_CONFIG_H__#include "main.h"
extern uint32_t SystemCoreClock;/* 基础配置项 */
#define configUSE_PREEMPTION                            1                       /* 1: 抢占式调度器, 0: 协程式调度器, 无默认需定义 */
#define configUSE_PORT_OPTIMISED_TASK_SELECTION         1                       /* 1: 使用硬件计算下一个要运行的任务, 0: 使用软件算法计算下一个要运行的任务, 默认: 0 */
#define configUSE_TICKLESS_IDLE                         0                       /* 1: 使能tickless低功耗模式, 默认: 0 */
#define configCPU_CLOCK_HZ                              SystemCoreClock         /* 定义CPU主频, 单位: Hz, 无默认需定义 */
#define configSYSTICK_CLOCK_HZ                          (configCPU_CLOCK_HZ / 8)/* 定义SysTick时钟频率,当SysTick时钟频率与内核时钟频率不同时才可以定义, 单位: Hz, 默认: 不定义 */
#define configTICK_RATE_HZ                              1000                    /* 定义系统时钟节拍频率, 单位: Hz, 无默认需定义 */
#define configMAX_PRIORITIES                            32                      /* 定义最大优先级数, 最大优先级=configMAX_PRIORITIES-1, 无默认需定义 */
#define configMINIMAL_STACK_SIZE                        128                     /* 定义空闲任务的栈空间大小, 单位: Word, 无默认需定义 */
#define configMAX_TASK_NAME_LEN                         16                      /* 定义任务名最大字符数, 默认: 16 */
#define configUSE_16_BIT_TICKS                          0                       /* 1: 定义系统时钟节拍计数器的数据类型为16位无符号数, 无默认需定义 */
#define configIDLE_SHOULD_YIELD                         1                       /* 1: 使能在抢占式调度下,同优先级的任务能抢占空闲任务, 默认: 1 */
#define configUSE_TASK_NOTIFICATIONS                    1                       /* 1: 使能任务间直接的消息传递,包括信号量、事件标志组和消息邮箱, 默认: 1 */
#define configTASK_NOTIFICATION_ARRAY_ENTRIES           1                       /* 定义任务通知数组的大小, 默认: 1 */
#define configUSE_MUTEXES                               1                       /* 1: 使能互斥信号量, 默认: 0 */
#define configUSE_RECURSIVE_MUTEXES                     1                       /* 1: 使能递归互斥信号量, 默认: 0 */
#define configUSE_COUNTING_SEMAPHORES                   1                       /* 1: 使能计数信号量, 默认: 0 */
#define configUSE_ALTERNATIVE_API                       0                       /* 已弃用!!! */
#define configQUEUE_REGISTRY_SIZE                       8                       /* 定义可以注册的信号量和消息队列的个数, 默认: 0 */
#define configUSE_QUEUE_SETS                            1                       /* 1: 使能队列集, 默认: 0 */
#define configUSE_TIME_SLICING                          1                       /* 1: 使能时间片调度, 默认: 1 */
#define configUSE_NEWLIB_REENTRANT                      0                       /* 1: 任务创建时分配Newlib的重入结构体, 默认: 0 */
#define configENABLE_BACKWARD_COMPATIBILITY             0                       /* 1: 使能兼容老版本, 默认: 1 */
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS         0                       /* 定义线程本地存储指针的个数, 默认: 0 */
#define configSTACK_DEPTH_TYPE                          uint16_t                /* 定义任务堆栈深度的数据类型, 默认: uint16_t */
#define configMESSAGE_BUFFER_LENGTH_TYPE                size_t                  /* 定义消息缓冲区中消息长度的数据类型, 默认: size_t *//* 内存分配相关定义 */
#define configSUPPORT_STATIC_ALLOCATION                 0                       /* 1: 支持静态申请内存, 默认: 0 */
#define configSUPPORT_DYNAMIC_ALLOCATION                1                       /* 1: 支持动态申请内存, 默认: 1 */
#define configTOTAL_HEAP_SIZE                           ((size_t)(10 * 1024))   /* FreeRTOS堆中可用的RAM总量, 单位: Byte, 无默认需定义 */
#define configAPPLICATION_ALLOCATED_HEAP                0                       /* 1: 用户手动分配FreeRTOS内存堆(ucHeap), 默认: 0 */
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP       0                       /* 1: 用户自行实现任务创建时使用的内存申请与释放函数, 默认: 0 *//* 钩子函数相关定义 */
#define configUSE_IDLE_HOOK                             0                       /* 1: 使能空闲任务钩子函数, 无默认需定义  */
#define configUSE_TICK_HOOK                             0                       /* 1: 使能系统时钟节拍中断钩子函数, 无默认需定义 */
#define configCHECK_FOR_STACK_OVERFLOW                  0                       /* 1: 使能栈溢出检测方法1, 2: 使能栈溢出检测方法2, 默认: 0 */
#define configUSE_MALLOC_FAILED_HOOK                    0                       /* 1: 使能动态内存申请失败钩子函数, 默认: 0 */
#define configUSE_DAEMON_TASK_STARTUP_HOOK              0                       /* 1: 使能定时器服务任务首次执行前的钩子函数, 默认: 0 *//* 运行时间和任务状态统计相关定义 */
#define configGENERATE_RUN_TIME_STATS                   0                       /* 1: 使能任务运行时间统计功能, 默认: 0 */
#if configGENERATE_RUN_TIME_STATS
#include "./BSP/TIMER/btim.h"
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()        ConfigureTimeForRunTimeStats()
extern uint32_t FreeRTOSRunTimeTicks;
#define portGET_RUN_TIME_COUNTER_VALUE()                FreeRTOSRunTimeTicks
#endif
#define configUSE_TRACE_FACILITY                        1                       /* 1: 使能可视化跟踪调试, 默认: 0 */
#define configUSE_STATS_FORMATTING_FUNCTIONS            1                       /* 1: configUSE_TRACE_FACILITY为1时,会编译vTaskList()和vTaskGetRunTimeStats()函数, 默认: 0 *//* 协程相关定义 */
#define configUSE_CO_ROUTINES                           0                       /* 1: 启用协程, 默认: 0 */
#define configMAX_CO_ROUTINE_PRIORITIES                 2                       /* 定义协程的最大优先级, 最大优先级=configMAX_CO_ROUTINE_PRIORITIES-1, 无默认configUSE_CO_ROUTINES为1时需定义 *//* 软件定时器相关定义 */
#define configUSE_TIMERS                                1                               /* 1: 使能软件定时器, 默认: 0 */
#define configTIMER_TASK_PRIORITY                       ( configMAX_PRIORITIES - 1 )    /* 定义软件定时器任务的优先级, 无默认configUSE_TIMERS为1时需定义 */
#define configTIMER_QUEUE_LENGTH                        5                               /* 定义软件定时器命令队列的长度, 无默认configUSE_TIMERS为1时需定义 */
#define configTIMER_TASK_STACK_DEPTH                    ( configMINIMAL_STACK_SIZE * 2) /* 定义软件定时器任务的栈空间大小, 无默认configUSE_TIMERS为1时需定义 *//* 可选函数, 1: 使能 */
#define INCLUDE_vTaskPrioritySet                        1                       /* 设置任务优先级 */
#define INCLUDE_uxTaskPriorityGet                       1                       /* 获取任务优先级 */
#define INCLUDE_vTaskDelete                             1                       /* 删除任务 */
#define INCLUDE_vTaskSuspend                            1                       /* 挂起任务 */
#define INCLUDE_xResumeFromISR                          1                       /* 恢复在中断中挂起的任务 */
#define INCLUDE_vTaskDelayUntil                         1                       /* 任务绝对延时 */
#define INCLUDE_vTaskDelay                              1                       /* 任务延时 */
#define INCLUDE_xTaskGetSchedulerState                  1                       /* 获取任务调度器状态 */
#define INCLUDE_xTaskGetCurrentTaskHandle               1                       /* 获取当前任务的任务句柄 */
#define INCLUDE_uxTaskGetStackHighWaterMark             1                       /* 获取任务堆栈历史剩余最小值 */
#define INCLUDE_xTaskGetIdleTaskHandle                  1                       /* 获取空闲任务的任务句柄 */
#define INCLUDE_eTaskGetState                           1                       /* 获取任务状态 */
#define INCLUDE_xEventGroupSetBitFromISR                1                       /* 在中断中设置事件标志位 */
#define INCLUDE_xTimerPendFunctionCall                  1                       /* 将函数的执行挂到定时器服务任务 */
#define INCLUDE_xTaskAbortDelay                         1                       /* 中断任务延时 */
#define INCLUDE_xTaskGetHandle                          1                       /* 通过任务名获取任务句柄 */
#define INCLUDE_xTaskResumeFromISR                      1                       /* 恢复在中断中挂起的任务 *//* 中断嵌套行为配置 */
#ifdef __NVIC_PRIO_BITS#define configPRIO_BITS __NVIC_PRIO_BITS
#else#define configPRIO_BITS 4
#endif#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY         15                  /* 中断最低优先级 */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY    5                   /* FreeRTOS可管理的最高中断优先级 */
#define configKERNEL_INTERRUPT_PRIORITY 		( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << 4 )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 	( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << 4 )
#define configMAX_API_CALL_INTERRUPT_PRIORITY           configMAX_SYSCALL_INTERRUPT_PRIORITY/* FreeRTOS中断服务函数相关定义 */
//#define xPortPendSVHandler                              PendSV_Handler
//#define vPortSVCHandler                                 SVC_Handler/* 断言 */
#define vAssertCalled(char, int) printf("Error: %s, %d\r\n", char, int)
#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ )/* FreeRTOS MPU 特殊定义 */
//#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0
//#define configTOTAL_MPU_REGIONS                                8
//#define configTEX_S_C_B_FLASH                                  0x07UL
//#define configTEX_S_C_B_SRAM                                   0x07UL
//#define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY            1
//#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS             1/* ARMv8-M 安全侧端口相关定义。 */
//#define secureconfigMAX_SECURE_CONTEXTS         5#endif  /* FREERTOS_CONFIG_H__ */

至此,STM32移植FreeRTOS完成,可以开始愉快的编写代码了。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 详解前缀码与前缀编码
  • Redis---10---SpringBoot集成Redis
  • (void) (_x == _y)的作用
  • 白嫖A100活动-入门篇-1.Linux+InterStudio
  • C语言从头学30——字符串
  • C#/WPF 自制截图工具
  • ctfshow-web入门-文件包含(web87)巧用 php://filter 流绕过死亡函数的三种方法
  • 陈志泊主编《数据库原理及应用教程第4版微课版》的实验题目参考答案实验2
  • Nuxt3 的生命周期和钩子函数(十一)
  • 【十三】图解 Spring 核心数据结构:BeanDefinition 其二
  • Poker Game, Run Fast
  • 【C++】模板进阶--保姆级解析(什么是非类型模板参数?什么是模板的特化?模板的特化如何应用?)
  • 基于Python爬虫的城市二手房数据分析可视化
  • 算法系列--分治排序|再谈快速排序|快速排序的优化|快速选择算法
  • 在 .NET 8 Web API 中实现弹性
  • 【技术性】Search知识
  • 2017 年终总结 —— 在路上
  • 5、React组件事件详解
  • Angular2开发踩坑系列-生产环境编译
  • golang中接口赋值与方法集
  • JDK9: 集成 Jshell 和 Maven 项目.
  • JS进阶 - JS 、JS-Web-API与DOM、BOM
  • Service Worker
  • 初识MongoDB分片
  • 使用权重正则化较少模型过拟合
  • 通信类
  • 正则与JS中的正则
  • 智能合约Solidity教程-事件和日志(一)
  • ​ubuntu下安装kvm虚拟机
  • ​批处理文件中的errorlevel用法
  • # 服务治理中间件详解:Spring Cloud与Dubbo
  • #NOIP 2014# day.1 T3 飞扬的小鸟 bird
  • (2024.6.23)最新版MAVEN的安装和配置教程(超详细)
  • (3)llvm ir转换过程
  • (精确度,召回率,真阳性,假阳性)ACC、敏感性、特异性等 ROC指标
  • (免费领源码)python+django+mysql线上兼职平台系统83320-计算机毕业设计项目选题推荐
  • (七)Activiti-modeler中文支持
  • (十八)用JAVA编写MP3解码器——迷你播放器
  • (一)kafka实战——kafka源码编译启动
  • (转)Mysql的优化设置
  • . ./ bash dash source 这五种执行shell脚本方式 区别
  • .NET Micro Framework初体验
  • .NET 实现 NTFS 文件系统的硬链接 mklink /J(Junction)
  • .net 逐行读取大文本文件_如何使用 Java 灵活读取 Excel 内容 ?
  • .net解析传过来的xml_DOM4J解析XML文件
  • .net使用excel的cells对象没有value方法——学习.net的Excel工作表问题
  • .Net组件程序设计之线程、并发管理(一)
  • //解决validator验证插件多个name相同只验证第一的问题
  • @Async 异步注解使用
  • @FeignClient 调用另一个服务的test环境,实际上却调用了另一个环境testone的接口,这其中牵扯到k8s容器外容器内的问题,注册到eureka上的是容器外的旧版本...
  • @Pointcut 使用
  • @transaction 提交事务_【读源码】剖析TCCTransaction事务提交实现细节
  • @Transactional 详解
  • [ vulhub漏洞复现篇 ] Apache APISIX 默认密钥漏洞 CVE-2020-13945
  • [AIGC] 如何建立和优化你的工作流?