目录

FreeRtos 概述

准备

裁剪

portable裁剪

port

heap

freerotsconfig

Freerotsconfig配置修改

总

应用层编写测试

结语


FreeRtos 概述

FreeRTOS是面向单片机MCU的开源轻量级抢占式实时操作系统内核,全部使用标准C语言开发,适合资源有限的嵌入式设备。该系统2003年由Richard Barry开发,2017年被亚马逊AWS收购,采用MIT协议,商用免费且无需开源项目源码,这是相比uCOS的核心优势。Free即免费,RTOS是实时操作系统的缩写,原生Vanilla FreeRTOS只保留任务、队列、信号量、定时器核心调度功能,GD32、STM32项目大多移植这个版本;Amazon FreeRTOS额外配套MQTT、TLS、OTA等IoT组件,用于设备接入亚马逊云。它内核体积很小,编译后ROM仅6~12KB,支持四十余种处理器架构,主流编译器均可适配,在工业和物联网领域应用十分广泛。

FreeRTOS默认使用固定优先级抢占式调度,搭配同优先级时间片轮转,高优先级任务就绪时可直接抢占CPU、切换上下文,实现实时响应,这也是它和裸机while(1)循环最大的区别。Tick滴答定时器周期性产生中断,一般设置为1ms,负责系统计时与任务延时判断。任务拥有运行、就绪、阻塞、挂起四种状态,阻塞状态下任务不占用CPU,此时会执行系统自带最低优先级的空闲任务,空闲任务钩子函数能够实现低功耗功能,被手动挂起的任务,需要主动恢复才会参与调度。

准备

首先我们准备一个干净的工程文件,最好是自己验证过能跑个流水灯啥的

下面提供源码下载地址:

GitHub - FreeRTOS/FreeRTOS-Kernel: FreeRTOS kernel files only, submoduled into https://github.com/FreeRTOS/FreeRTOS and various other repos. · GitHubhttps://github.com/FreeRTOS/FreeRTOS-Kernelhttps://github.com/FreeRTOS/FreeRTOS-Kernelhttps://github.com/FreeRTOS/FreeRTOS-Kernelhttps://github.com/FreeRTOS/FreeRTOS-Kernel通过上面的地址下载可以得到:

裁剪

首先这个文件夹里面大部分文件都可以删除,如下图,后续我们把portable里面需要的文件移植出来,这个portable也可以删除了

portable裁剪

port

  • port.c —— 移植实现(上下文切换、栈初始化、SysTick 等)

我使用的是GD32F450系列芯片不带那个浮点的所以我只能选择这个cm4F,大家可以根据自己的需要进行选择。

参考目录:freerots\portable\RVDS\ARM_CM4F

heap

FreeRTOS 的 5 种堆管理方案,核心区别在于能否释放内存、是否合并碎片、以及能否管理不连续的内存区域。

\portable\MemMang

下面这个是官方关于这五个文件的介绍,我总结了一下,然后常用的就是这个第四个

FreeRTOS Blog - FreeRTOS™https://www.freertos.org/Community/Blogs/Bloghttps://www.freertos.org/Community/Blogs/Bloghttps://www.freertos.org/Community/Blogs/Bloghttps://www.freertos.org/Community/Blogs/Blog

特性heap_1heap_2heap_3heap_4heap_5
能否释放内存❌ 不能✅ 能✅ 能✅ 能✅ 能
是否合并空闲块N/A❌ 不合并N/A (由标准库处理)✅ 自动合并✅ 自动合并
管理不连续内存❌ 不支持❌ 不支持❌ 不支持❌ 不支持✅ 支持
碎片问题一次性分配严重 (不合并)取决于标准库(合并算法)较(合并算法)
实现原理简单分配首次适应算法封装 malloc/free最佳匹配+合并同 heap_4
线程安全✅✅✅✅✅
适用场景一次性初始化后不再创建/删除对象只创建/删除同尺寸对象 (已过时)需要完全依赖标准库的场景通用场景 (最常用)内存分散在多个不连续区域

freerotsconfig

参考目录:FreeRTOS-Kernel-main\FreeRTOS-Kernel-main\examples\template_configuration

简单让ai帮我写一下中文注释

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

/* ========== 硬件描述 ========== */
#define configCPU_CLOCK_HZ                        ( ( unsigned long ) 20000000 )  /* CPU 主频,Hz,按实际改 */
/* #define configSYSTICK_CLOCK_HZ                 [平台相关] */               /* SysTick 时钟频率,一般不用定义 */

/* ========== 调度行为 ========== */
#define configTICK_RATE_HZ                        100        /* tick 频率,Hz */
#define configUSE_PREEMPTION                      1          /* 1=抢占式调度,0=协作式 */
#define configUSE_TIME_SLICING                    0          /* 1=同优先级时间片轮转,0=不轮转 */
#define configUSE_PORT_OPTIMISED_TASK_SELECTION   0          /* 1=用硬件指令选任务,0=通用 C 算法 */
#define configUSE_TICKLESS_IDLE                   0          /* 1=低功耗 tickless 模式,0=常开 tick */
#define configMAX_PRIORITIES                      5          /* 最大任务优先级数 */
#define configMINIMAL_STACK_SIZE                  128        /* 空闲任务栈大小(单位:字) */
#define configMAX_TASK_NAME_LEN                   16         /* 任务名最大长度(含结尾符) */
#define configTICK_TYPE_WIDTH_IN_BITS             TICK_TYPE_WIDTH_32_BITS  /* tick 计数用 32 位 */
#define configIDLE_SHOULD_YIELD                   1          /* 1=空闲任务对同优先级任务让出,0=不让出 */
#define configTASK_NOTIFICATION_ARRAY_ENTRIES     1          /* 任务通知数组条目数 */
#define configQUEUE_REGISTRY_SIZE                 0          /* 队列注册表大小(调试用) */
#define configENABLE_BACKWARD_COMPATIBILITY       0          /* 1=兼容旧版 API 名字,0=不兼容 */
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS   0          /* 线程本地存储指针数量 */
#define configUSE_MINI_LIST_ITEM                  1          /* 1=用精简链表项省 RAM,0=用完整项 */
#define configSTACK_DEPTH_TYPE                    size_t     /* 栈深度参数类型 */
#define configMESSAGE_BUFFER_LENGTH_TYPE          size_t     /* 消息缓冲长度字段类型 */
#define configHEAP_CLEAR_MEMORY_ON_FREE           1          /* 1=释放时清零内存,0=不清零 */
#define configSTATS_BUFFER_MAX_LENGTH             0xFFFF     /* vTaskList 等统计缓冲区最大长度 */
#define configUSE_NEWLIB_REENTRANT                0          /* 1=为每个任务分配 newlib 重入结构,0=不分配 */

/* ========== 软件定时器 ========== */
#define configUSE_TIMERS                          1          /* 1=启用软件定时器,0=不启用 */
#define configTIMER_TASK_PRIORITY                 ( configMAX_PRIORITIES - 1 )  /* 定时器任务优先级 */
#define configTIMER_TASK_STACK_DEPTH              configMINIMAL_STACK_SIZE      /* 定时器任务栈大小(字) */
#define configTIMER_QUEUE_LENGTH                  10         /* 定时器命令队列长度 */

/* ========== 事件组 ========== */
#define configUSE_EVENT_GROUPS                    1          /* 1=启用事件组,0=不启用 */

/* ========== 流缓冲 / 消息缓冲 ========== */
#define configUSE_STREAM_BUFFERS                  1          /* 1=启用流缓冲,0=不启用 */

/* ========== 内存分配 ========== */
#define configSUPPORT_STATIC_ALLOCATION           1          /* 1=支持静态创建对象 */
#define configSUPPORT_DYNAMIC_ALLOCATION          1          /* 1=支持动态创建对象 */
#define configTOTAL_HEAP_SIZE                     4096       /* FreeRTOS 堆总大小,单位:字节 */
#define configAPPLICATION_ALLOCATED_HEAP          0          /* 1=应用自己分配堆数组,0=链接器分配 */
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0          /* 1=任务栈从单独堆分配,0=从主堆分配 */
#define configENABLE_HEAP_PROTECTOR               0          /* 1=启用堆指针保护,0=不启用 */

/* ========== 中断嵌套行为 ========== */
#define configKERNEL_INTERRUPT_PRIORITY           0          /* 内核中断优先级(tick/PendSV) */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY      0          /* 允许调 API 的最高中断优先级 */
#define configMAX_API_CALL_INTERRUPT_PRIORITY     0          /* 同上,不同 port 用的名字 */

/* ========== 钩子函数 ========== */
#define configUSE_IDLE_HOOK                       0          /* 1=启用空闲钩子 */
#define configUSE_TICK_HOOK                       0          /* 1=启用 tick 钩子 */
#define configUSE_MALLOC_FAILED_HOOK              0          /* 1=启用 malloc 失败钩子 */
#define configUSE_DAEMON_TASK_STARTUP_HOOK        0          /* 1=启用守护任务启动钩子 */
#define configUSE_SB_COMPLETED_CALLBACK           0          /* 1=启用流缓冲收发完成回调 */
#define configCHECK_FOR_STACK_OVERFLOW            2          /* 0=不检查栈溢出,1=快但弱,2=慢但强 */

/* ========== 运行时统计 ========== */
#define configGENERATE_RUN_TIME_STATS             0          /* 1=收集各任务运行时间 */
#define configUSE_TRACE_FACILITY                  0          /* 1=启用 trace 调试功能 */
#define configUSE_STATS_FORMATTING_FUNCTIONS      0          /* 1=启用 vTaskList 等格式化函数 */

/* ========== 协程 ========== */
#define configUSE_CO_ROUTINES                     0          /* 1=启用协程 */
#define configMAX_CO_ROUTINE_PRIORITIES           1          /* 协程最大优先级数 */

/* ========== 调试断言 ========== */
#define configASSERT( x )                                                                  \
    if( ( x ) == 0 )                                                                       \
    {                                                                                      \
        taskDISABLE_INTERRUPTS();                                                          \
        for( ; ; )                                                                         \
        ;                                                                                  \
    }                                                                                      \
    /* 断言失败:关中断并死循环,方便调试器查看 */

/* ========== FreeRTOS MPU 相关(标准 Cortex-M port 不用) ========== */
#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS  0   /* 1=允许应用定义特权函数 */
#define configTOTAL_MPU_REGIONS                                 8   /* MPU 区域数量,通常 8 或 16 */
#define configTEX_S_C_B_FLASH                                   0x07UL  /* Flash 区域 TEX/S/C/B 位 */
#define configTEX_S_C_B_SRAM                                    0x07UL  /* RAM 区域 TEX/S/C/B 位 */
#define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY             1   /* 1=只允许内核发起系统调用 */
#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS              0   /* 1=允许非特权任务进临界区 */
#define configUSE_MPU_WRAPPERS_V1                               0   /* 1=用旧版 MPU wrapper,0=用 v2 */
#define configPROTECTED_KERNEL_OBJECT_POOL_SIZE                 10  /* v2 wrapper 下内核对象池大小 */
#define configSYSTEM_CALL_STACK_SIZE                            128 /* 系统调用栈大小(字) */
#define configENABLE_ACCESS_CONTROL_LIST                        1   /* 1=启用访问控制列表 */

/* ========== SMP 多核相关 ========== */
/* #define configNUMBER_OF_CORES                  [核心数] */    /* 多核时定义,单核不定义 */
#define configRUN_MULTIPLE_PRIORITIES             0          /* 多核:1=允许不同优先级同时跑 */
#define configUSE_CORE_AFFINITY                   0          /* 多核:1=启用核亲和性 */
#define configTASK_DEFAULT_CORE_AFFINITY          tskNO_AFFINITY  /* 任务默认核亲和性 */
#define configUSE_TASK_PREEMPTION_DISABLE         0          /* 多核:1=允许单任务关抢占 */
#define configUSE_PASSIVE_IDLE_HOOK               0          /* 多核:1=启用被动空闲钩子 */
#define configTIMER_SERVICE_TASK_CORE_AFFINITY    tskNO_AFFINITY  /* 定时器任务核亲和性 */
#define configIDLE_AFFINITY                       0          /* 多核:1=空闲任务绑核 */

/* ========== ARMv8-M 安全侧 ========== */
#define secureconfigMAX_SECURE_CONTEXTS           5          /* 可调用安全侧的最大任务数 */
#define configKERNEL_PROVIDED_STATIC_MEMORY       1          /* 1=内核提供空闲/定时器任务内存 */

/* ========== ARMv8-M port ========== */
#define configENABLE_TRUSTZONE                    1          /* 1=启用 TrustZone */
#define configRUN_FREERTOS_SECURE_ONLY            1          /* 1=FreeRTOS 只在安全侧跑 */
#define configENABLE_MPU                          1          /* 1=启用 MPU */
#define configENABLE_FPU                          1          /* 1=启用 FPU */
#define configENABLE_MVE                          1          /* 1=启用 MVE(仅 M52/M55/M85/STAR-MC3) */

/* ========== ARMv7-M / ARMv8-M port ========== */
#define configCHECK_HANDLER_INSTALLATION          1          /* 1=检查 SVC/PendSV 中断是否正确安装 */

/* ========== 功能开关 ========== */
#define configUSE_TASK_NOTIFICATIONS              1          /* 1=启用任务通知 */
#define configUSE_MUTEXES                         1          /* 1=启用互斥量 */
#define configUSE_RECURSIVE_MUTEXES               1          /* 1=启用递归互斥量 */
#define configUSE_COUNTING_SEMAPHORES             1          /* 1=启用计数信号量 */
#define configUSE_QUEUE_SETS                      0          /* 1=启用队列集 */
#define configUSE_APPLICATION_TASK_TAG            0          /* 1=启用任务标签 */
#define configUSE_POSIX_ERRNO                     0          /* 1=启用 POSIX errno */

/* ========== API 函数开关 ========== */
#define INCLUDE_vTaskPrioritySet                  1          /* 启用 vTaskPrioritySet */
#define INCLUDE_uxTaskPriorityGet                 1          /* 启用 uxTaskPriorityGet */
#define INCLUDE_vTaskDelete                       1          /* 启用 vTaskDelete */
#define INCLUDE_vTaskSuspend                      1          /* 启用 vTaskSuspend */
#define INCLUDE_xTaskDelayUntil                   1          /* 启用 xTaskDelayUntil */
#define INCLUDE_vTaskDelay                        1          /* 启用 vTaskDelay */
#define INCLUDE_xTaskGetSchedulerState            1          /* 启用 xTaskGetSchedulerState */
#define INCLUDE_xTaskGetCurrentTaskHandle         1          /* 启用 xTaskGetCurrentTaskHandle */
#define INCLUDE_uxTaskGetStackHighWaterMark       0          /* 启用 uxTaskGetStackHighWaterMark */
#define INCLUDE_xTaskGetIdleTaskHandle            0          /* 启用 xTaskGetIdleTaskHandle */
#define INCLUDE_eTaskGetState                     0          /* 启用 eTaskGetState */
#define INCLUDE_xTimerPendFunctionCall            0          /* 启用 xTimerPendFunctionCall */
#define INCLUDE_xTaskAbortDelay                   0          /* 启用 xTaskAbortDelay */
#define INCLUDE_xTaskGetHandle                    0          /* 启用 xTaskGetHandle */
#define INCLUDE_xTaskResumeFromISR                1          /* 启用 xTaskResumeFromISR */

#endif /* FREERTOS_CONFIG_H */

总共裁剪下来就是

我们把文件添加进我们的工程

Freerotsconfig配置修改

这里我们首次尝试编译:

Build started: Project: gd32f450test
*** Using Compiler 'V5.06 update 7 (build 960)', folder: 'D:\keil5\keil535\ARM\ARMCC\Bin'
Build target 'Target 1'
compiling port.c...
..\freerots\port.c(42): error:  #35: #error directive: configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0.  See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
      #error configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to 0.  See http: /*www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */
..\freerots\port.c: 0 warnings, 1 error
".\Objects\gd32f450test.axf" - 1 Error(s), 0 Warning(s).
Target not created.
Build Time Elapsed:  00:00:00

意思说我的这个freerotsconfig一些宏定义没有配置

#define configCPU_CLOCK_HZ这个我们取系统时钟,这里也可以自己去看看主频是多少自己填入也可以

#define configCPU_CLOCK_HZ    ( ( unsigned long ) 200000000 )   /* 200MHz */
#define configCPU_CLOCK_HZ                        SystemCoreClock  /* CPU 主频 */

定义这个tick,能决定我们的调度的时间片是多少,1000的话也就是1ms一个tick

#define configTICK_RATE_HZ                        1000

#define configMAX_PRIORITIES优先级数量,源码是5,可以考虑更改

#define configMAX_PRIORITIES                      30

Cortex-M 的优先级寄存器有 8 位,但芯片实际只用了高 4 位(configPRIO_BITS = 4),低 4 位无效。

所以,一个"逻辑优先级"(0~15)要左移 4 位才能写进寄存器:

逻辑优先级 5  →  二进制 0101  →  左移 4 位  →  0101 0000  →  0x50
逻辑优先级 15 →  二进制 1111  →  左移 4 位  →  1111 0000  →  0xF0

FreeRTOS 里的 0xF0、0x40 就是这种"已经左移过的硬件值"。

configKERNEL_INTERRUPT_PRIORITY        0xF0  
configMAX_SYSCALL_INTERRUPT_PRIORITY   0x40  
configMAX_API_CALL_INTERRUPT_PRIORITY  0x40
宏值含义作用
configKERNEL_INTERRUPT_PRIORITY0xF0PendSV / SysTick 的优先级内核中断设最低,让紧急中断优先,这个优先级就是处理任务调度等任务的优先级
configMAX_SYSCALL_INTERRUPT_PRIORITY0x40分界线:≥ 此值可调 API保护内核,限制哪些中断能调 API,在cortex-m中数字越小优先级越高,所以这里添加这个是为了不允许中断里面添加freerots的任务函数,
  • 优先级数字比 4 小(0、1、2、3)的中断:不许在里面调 FreeRTOS 的函数;

  • 优先级数字比 4 大(5、6、...、15)的中断:可以在里面调 FreeRTOS 的函数。

configMAX_API_CALL_INTERRUPT_PRIORITY0x40同上,别名兼容不同 port 的命名

下面这个根据自己的芯片来

宏修改建议
configTOTAL_HEAP_SIZE100*1024(100KB)注意别超过实际可用 RAM
configUSE_TIMERS0省一个线程。你要用软定时器就改成 1
configCHECK_FOR_STACK_OVERFLOW0调试阶段建议改成 1 或 2,量产再关
configUSE_TRACE_FACILITY01 就是方便调试,多占点 ROM
configUSE_STATS_FORMATTING_FUNCTIONS0同上
configUSE_POSIX_ERRNO0方便拿 errno
configUSE_QUEUE_SETS0开了队列集,不用可以改回 0

下面这些是可以保留,但是没啥必要的

宏修改说明
configENABLE_TRUSTZONE0Cortex-M4 没有 TrustZone,此宏无效
configRUN_FREERTOS_SECURE_ONLY0同上
configENABLE_MPU0没 MPU,此宏只对 MPU port 有效
configENABLE_MVE0Cortex-M4 没有 MVE,此宏无效
configENABLE_FPU1GD32F450 有 FPU
secureconfigMAX_SECURE_CONTEXTS0ARMv8-M 专用,无效
所有 SMP 相关一堆 0单核不用,无效,可以直接删除

对应的还有

我的 GD32F450 启动文件 startup_gd32f450.s 里定义了一张中断向量表,里面列了所有中断的名字,大家去找自己对应的就好了,比如:

DCD     SVC_Handler        ; SVCall 中断
DCD     PendSV_Handler     ; PendSV 中断
DCD     SysTick_Handler    ; SysTick 中断

CPU 遇到这些中断时,会去这张表里找对应的函数名,然后跳过去执行。

#define configCHECK_HANDLER_INSTALLATION          1          //开机时检查 SVC_Handler、PendSV_Handler 有没有正确安装到中断向量表

这里我们需要添加这个在这个文件末尾

  • 启动文件里叫 SVC_Handler、PendSV_Handler、SysTick_Handler;

  • FreeRTOS 里叫 vPortSVCHandler、xPortPendSVHandler、xPortSysTickHandler;

  • 名字对不上,CPU 中断时就找不到 FreeRTOS 的函数,系统跑不起来。

#define vPortSVCHandler     SVC_Handler
#define xPortPendSVHandler  PendSV_Handler
#define xPortSysTickHandler SysTick_Handler

下面给大家全部的修改的代码

总

#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

#include "system_gd32f4xx.h"
/* ========== 硬件描述 ========== */
#define configCPU_CLOCK_HZ                        SystemCoreClock  /* CPU 主频 */

/* ========== 调度行为 ========== */
#define configTICK_RATE_HZ                        1000       
#define configUSE_PREEMPTION                      1          /* 1=抢占式调度,0=协作式 */
#define configUSE_TIME_SLICING                    0          /* 1=同优先级时间片轮转,0=不轮转 */
#define configUSE_PORT_OPTIMISED_TASK_SELECTION   0          /* 1=用硬件指令选任务,0=通用 C 算法 */
#define configUSE_TICKLESS_IDLE                   0          /* 1=低功耗 tickless 模式,0=常开 tick */
#define configMAX_PRIORITIES                      30         /* 最大任务优先级数 */
#define configMINIMAL_STACK_SIZE                  128        /* 空闲任务栈大小(单位:字) */
#define configMAX_TASK_NAME_LEN                   16         /* 任务名最大长度(含结尾符) */
#define configTICK_TYPE_WIDTH_IN_BITS             TICK_TYPE_WIDTH_32_BITS  /* tick 计数用 32 位 */
#define configIDLE_SHOULD_YIELD                   1          /* 1=空闲任务对同优先级任务让出,0=不让出 */
#define configTASK_NOTIFICATION_ARRAY_ENTRIES     1          /* 任务通知数组条目数 */
#define configQUEUE_REGISTRY_SIZE                 0          /* 队列注册表大小(调试用) */
#define configENABLE_BACKWARD_COMPATIBILITY       0          /* 1=兼容旧版 API 名字,0=不兼容 */
#define configNUM_THREAD_LOCAL_STORAGE_POINTERS   0          /* 线程本地存储指针数量 */
#define configUSE_MINI_LIST_ITEM                  1          /* 1=用精简链表项省 RAM,0=用完整项 */
#define configSTACK_DEPTH_TYPE                    size_t     /* 栈深度参数类型 */
#define configMESSAGE_BUFFER_LENGTH_TYPE          size_t     /* 消息缓冲长度字段类型 */
#define configHEAP_CLEAR_MEMORY_ON_FREE           1          /* 1=释放时清零内存,0=不清零 */
#define configSTATS_BUFFER_MAX_LENGTH             0xFFFF     /* vTaskList 等统计缓冲区最大长度 */
#define configUSE_NEWLIB_REENTRANT                0          /* 1=为每个任务分配 newlib 重入结构,0=不分配 */

/* ========== 软件定时器 ========== */
#define configUSE_TIMERS                          0
#define configTIMER_TASK_PRIORITY                 ( configMAX_PRIORITIES - 1 )  /* 定时器任务优先级 */
#define configTIMER_TASK_STACK_DEPTH              configMINIMAL_STACK_SIZE      /* 定时器任务栈大小(字) */
#define configTIMER_QUEUE_LENGTH                  10         /* 定时器命令队列长度 */

/* ========== 事件组 ========== */
#define configUSE_EVENT_GROUPS                    1          /* 1=启用事件组,0=不启用 */

/* ========== 流缓冲 / 消息缓冲 ========== */
#define configUSE_STREAM_BUFFERS                  1          /* 1=启用流缓冲,0=不启用 */

/* ========== 内存分配 ========== */
#define configSUPPORT_STATIC_ALLOCATION           1          /* 1=支持静态创建对象 */
#define configSUPPORT_DYNAMIC_ALLOCATION          1          /* 1=支持动态创建对象 */
#define configTOTAL_HEAP_SIZE                     100*1024     
#define configAPPLICATION_ALLOCATED_HEAP          0          /* 1=应用自己分配堆数组,0=链接器分配 */
#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0          /* 1=任务栈从单独堆分配,0=从主堆分配 */
#define configENABLE_HEAP_PROTECTOR               0          /* 1=启用堆指针保护,0=不启用 */

/* ========== 中断嵌套行为 ========== */
#define configKERNEL_INTERRUPT_PRIORITY           0xF0
#define configMAX_SYSCALL_INTERRUPT_PRIORITY      0x40
#define configMAX_API_CALL_INTERRUPT_PRIORITY     0x40      

/* ========== 钩子函数 ========== */
#define configUSE_IDLE_HOOK                       0          /* 1=启用空闲钩子 */
#define configUSE_TICK_HOOK                       0          /* 1=启用 tick 钩子 */
#define configUSE_MALLOC_FAILED_HOOK              0          /* 1=启用 malloc 失败钩子 */
#define configUSE_DAEMON_TASK_STARTUP_HOOK        0          /* 1=启用守护任务启动钩子 */
#define configUSE_SB_COMPLETED_CALLBACK           0          /* 1=启用流缓冲收发完成回调 */
#define configCHECK_FOR_STACK_OVERFLOW            0          /* 0=不检查栈溢出,1=快但弱,2=慢但强 */

/* ========== 运行时统计 ========== */
#define configGENERATE_RUN_TIME_STATS             0          /* 1=收集各任务运行时间 */
#define configUSE_TRACE_FACILITY                  0          /* 1=启用 trace 调试功能 */
#define configUSE_STATS_FORMATTING_FUNCTIONS      0          /* 1=启用 vTaskList 等格式化函数 */

/* ========== 协程 ========== */
#define configUSE_CO_ROUTINES                     0          /* 1=启用协程 */
#define configMAX_CO_ROUTINE_PRIORITIES           1          /* 协程最大优先级数 */

/* ========== 调试断言 ========== */
#define configASSERT( x )                                                                  \
    if( ( x ) == 0 )                                                                       \
    {                                                                                      \
        taskDISABLE_INTERRUPTS();                                                          \
        for( ; ; )                                                                         \
        ;                                                                                  \
    }                                                                                      \

/* ========== FreeRTOS MPU 相关(标准 Cortex-M port 不用) ========== */
#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS  0   /* 1=允许应用定义特权函数 */
#define configTOTAL_MPU_REGIONS                                 8   /* MPU 区域数量,通常 8 或 16 */
#define configTEX_S_C_B_FLASH                                   0x07UL  /* Flash 区域 TEX/S/C/B 位 */
#define configTEX_S_C_B_SRAM                                    0x07UL  /* RAM 区域 TEX/S/C/B 位 */
#define configENFORCE_SYSTEM_CALLS_FROM_KERNEL_ONLY             1   /* 1=只允许内核发起系统调用 */
#define configALLOW_UNPRIVILEGED_CRITICAL_SECTIONS              0   /* 1=允许非特权任务进临界区 */
#define configUSE_MPU_WRAPPERS_V1                               0   /* 1=用旧版 MPU wrapper,0=用 v2 */
#define configPROTECTED_KERNEL_OBJECT_POOL_SIZE                 10  /* v2 wrapper 下内核对象池大小 */
#define configSYSTEM_CALL_STACK_SIZE                            128 /* 系统调用栈大小(字) */
#define configENABLE_ACCESS_CONTROL_LIST                        1   /* 1=启用访问控制列表 */

/* ========== ARMv8-M 安全侧 ========== */
#define secureconfigMAX_SECURE_CONTEXTS           5          /* 可调用安全侧的最大任务数 */
#define configKERNEL_PROVIDED_STATIC_MEMORY       1          /* 1=内核提供空闲/定时器任务内存 */

/* ========== ARMv8-M port ========== */
#define configENABLE_TRUSTZONE                    0
#define configRUN_FREERTOS_SECURE_ONLY            0
#define configENABLE_MPU                          0
#define configENABLE_FPU                          1          /* 1=启用 FPU */
#define configENABLE_MVE                          0

/* ========== ARMv7-M / ARMv8-M port ========== */
#define configCHECK_HANDLER_INSTALLATION          1          //开机时检查 SVC_Handler、PendSV_Handler 有没有正确安装到中断向量表

/* ========== 功能开关 ========== */
#define configUSE_TASK_NOTIFICATIONS              1          /* 1=启用任务通知 */
#define configUSE_MUTEXES                         1          /* 1=启用互斥量 */
#define configUSE_RECURSIVE_MUTEXES               1          /* 1=启用递归互斥量 */
#define configUSE_COUNTING_SEMAPHORES             1          /* 1=启用计数信号量 */
#define configUSE_QUEUE_SETS                      0          /* 1=启用队列集 */
#define configUSE_APPLICATION_TASK_TAG            0          /* 1=启用任务标签 */
#define configUSE_POSIX_ERRNO                     0          /* 1=启用 POSIX errno */

/* ========== API 函数开关 ========== */
#define INCLUDE_vTaskPrioritySet                  1          /* 启用 vTaskPrioritySet */
#define INCLUDE_uxTaskPriorityGet                 1          /* 启用 uxTaskPriorityGet */
#define INCLUDE_vTaskDelete                       1          /* 启用 vTaskDelete */
#define INCLUDE_vTaskSuspend                      1          /* 启用 vTaskSuspend */
#define INCLUDE_xTaskDelayUntil                   1          /* 启用 xTaskDelayUntil */
#define INCLUDE_vTaskDelay                        1          /* 启用 vTaskDelay */
#define INCLUDE_xTaskGetSchedulerState            1          /* 启用 xTaskGetSchedulerState */
#define INCLUDE_xTaskGetCurrentTaskHandle         1          /* 启用 xTaskGetCurrentTaskHandle */
#define INCLUDE_uxTaskGetStackHighWaterMark       0          /* 启用 uxTaskGetStackHighWaterMark */
#define INCLUDE_xTaskGetIdleTaskHandle            0          /* 启用 xTaskGetIdleTaskHandle */
#define INCLUDE_eTaskGetState                     0          /* 启用 eTaskGetState */
#define INCLUDE_xTimerPendFunctionCall            0          /* 启用 xTimerPendFunctionCall */
#define INCLUDE_xTaskAbortDelay                   0          /* 启用 xTaskAbortDelay */
#define INCLUDE_xTaskGetHandle                    0          /* 启用 xTaskGetHandle */
#define INCLUDE_xTaskResumeFromISR                1          /* 启用 xTaskResumeFromISR */


#define vPortSVCHandler     SVC_Handler
#define xPortPendSVHandler  PendSV_Handler
#define xPortSysTickHandler SysTick_Handler

#endif /* FREERTOS_CONFIG_H */

应用层编写测试

#include "main.h" 

#define INIT_TASK_PRIO  		 	( tskIDLE_PRIORITY + 5 ) 
#define Led_Task_PRIO       		( tskIDLE_PRIORITY + 1 )
#define Regular_Task_PRIO       	( tskIDLE_PRIORITY + 1 )


TaskHandle_t InitTask_Handler	 	 = NULL;
TaskHandle_t LedTask_Handle		 	 = NULL; 
TaskHandle_t RegularTask_Handle		 = NULL; 

void LedTask		(void *pvParameters);
void RegularTask	(void *pvParameters);
void InitTask		(void *pvParameters)
{     
	BaseType_t err;
	SEGGER_RTT_Init();

	taskENTER_CRITICAL();           
		err = xTaskCreate(LedTask,			"_LED"			, configMINIMAL_STACK_SIZE 		, NULL, Led_Task_PRIO				,(TaskHandle_t *)&LedTask_Handle);
		err = xTaskCreate(RegularTask, 		"_REGULAR"		, configMINIMAL_STACK_SIZE 		, NULL, Regular_Task_PRIO			,(TaskHandle_t *)&RegularTask_Handle);  

		if (err == pdPASS){}				 
		vTaskDelete(InitTask_Handler);  
	taskEXIT_CRITICAL();            
} 
void Led_Init(void)
{ 
	rcu_periph_clock_enable(RCU_GPIOD);
    gpio_mode_set(GPIOD, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_14);
    gpio_output_options_set(GPIOD, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_14);
    gpio_bit_set(GPIOD, GPIO_PIN_14);
}
int main(void)
{
    
	nvic_priority_group_set(NVIC_PRIGROUP_PRE4_SUB0);
	__set_PRIMASK(0);                             //开启中断
	
	xTaskCreate(InitTask,  "_INIT",  configMINIMAL_STACK_SIZE, NULL, INIT_TASK_PRIO, (TaskHandle_t*  )&InitTask_Handler);  
	vTaskStartScheduler();
    while(1)
    {	
		
    }
}
void LedTask(void *pvParameters)
{
	Led_Init();
	while(1)
	{
		gpio_bit_set(GPIOD, GPIO_PIN_14);
        vTaskDelay(125);
		gpio_bit_reset(GPIOD, GPIO_PIN_14);
		vTaskDelay(125);
		SEGGER_RTT_printf(0,"OK\n");
	}

}
void RegularTask(void *pvParameters)
{
	while(1)
	{
		SEGGER_RTT_printf(0,"Ready\n");
		vTaskDelay(1000);
	}

}

记得添加头文件

#include "FreeRTOS.h"
#include "Task.h"
#include "queue.h"
#include "semphr.h"
#include "Timers.h"

实验:正常

保持好奇,持续学习,一起努力。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐