基于NXP-LPC55S69手动移植FreeRTOS教程
FreeRTOS 移植总结 — LPC55S69目标板: LPC55S69JBD100 (Cortex-M33, 150MHz, 608KB Flash, 272KB RAM)编译器: ARMCLANG V6.16 (Keil MDK-ARM V5.42)IDE: Keil µVision V5FreeRTOS 内核版本: V11.1.0 (LTS — 2024.06)SDK: MCUXpresso SDK (LPC55S69_DFP.26.06.00)移植日期: 2026-07-18一、下载操作系统代码库下载地址: https://freertos.org/zh-cn点击 “Download” → 选择 “FreeRTOS Kernel” → 下载案例包下载网址(chrome/夸克打开):http://103.236.97.252:48791点击 “Download” → 选择FreeRTOS 202406.05 LTS。解压后得到源码目录FreeRTOS 内核源码路径D:\freertos\FreeRTOSv202406.05-LTS\FreeRTOS-LTS\FreeRTOS\FreeRTOS-Kernel\关键目录结构FreeRTOS-Kernel/ ├── include/ ← 所有头文件22 个 .h ├── *.c ← 内核源文件7 个 .c │ ├── tasks.c │ ├── queue.c │ ├── list.c │ ├── timers.c │ ├── event_groups.c │ ├── stream_buffer.c │ └── croutine.c ← 协程不推荐使用 └── portable/ ├── ARMv8M/non_secure/ ← Cortex-M33/ARMv8-M 移植层 │ ├── port.c ← 通用移植代码 │ ├── portasm.h ← 汇编函数声明 │ ├── portmacrocommon.h ← ARMv8-M 公共宏 │ └── portable/ │ ├── GCC/ │ │ └── ARM_CM33_NTZ/ ← 本工程选用此目录 │ │ ├── portmacro.h ← CM33 特定宏 │ │ └── portasm.c ← 汇编实现 (SVC/PendSV/SysTick) │ └── IAR/ │ └── ARM_CM33_NTZ/ │ └── portmacro.h └── MemMang/ ← 内存管理方案 ├── heap_1.c ~ heap_5.c └── heap_4.c ← 本工程选用 heap_4二、工程中新建文件夹在裸机工程根目录下创建以下目录结构hello_world_cm33_core0/ └── FreeRTOS/ ├── include/ ← 存放 FreeRTOS 头文件 ├── src/ ← 存放 FreeRTOS 内核源文件 ├── portable/ │ └── MemMang/ ← 存放内存管理文件 └── config/ ← 存放 FreeRTOSConfig.h与 STM32 移植的差异LPC55S69 是 Cortex-M33移植层使用ARMv8M/non_secure。移植文件不放进编译器子目录如portable/GCC/ARM_CM33_NTZ/而是统一放在portable/根目录下通过 include path 让port.c能找到portmacro.h和portasm.h。这种扁平化布局是因为 ARMv8M 版本的port.c位于non_secure/根目录它通过#include portmacro.h和#include portasm.h引用同目录下的文件不深入编译器子目录。三、拷贝移植文件3.1 头文件 — 拷贝到FreeRTOS/include/从FreeRTOS-Kernel/include/拷贝全部 22 个文件文件名说明FreeRTOS.h主头文件 — TickType 定义、配置校验、API 重定向task.h任务管理 APIqueue.h队列 APIsemphr.h信号量 APItimers.h软件定时器 APIevent_groups.h事件组 APIstream_buffer.h流缓冲区 APImessage_buffer.h消息缓冲区 APIlist.h链表数据结构内核内部使用croutine.h协程 APIportable.h移植层抽象接口projdefs.h内核宏定义StackMacros.h栈检查宏stack_macros.h栈检查宏 — 小写版atomic.h原子操作deprecated_definitions.h废弃 API 兼容宏mpu_prototypes.hMPU 内存保护函数原型mpu_wrappers.hMPU 包装宏mpu_syscall_numbers.hMPU 系统调用号newlib-freertos.hNewlib C 库集成picolibc-freertos.hPicoLibc C 库集成3.2 内核源码 — 拷贝到FreeRTOS/src/从FreeRTOS-Kernel/拷贝7 个 .c 文件文件名说明tasks.c任务管理核心 — 调度器、任务创建/删除、栈溢出检测、Idle 任务queue.c队列核心 — 队列、信号量、互斥锁list.c链表操作 — 内核数据结构timers.c软件定时器event_groups.c事件组stream_buffer.c流缓冲区和消息缓冲区croutine.c协程可省略configUSE_CO_ROUTINES0时不编译3.3 移植层 — 拷贝到FreeRTOS/portable/这是 ARMv8M 移植与 STM32ARMv7-M/ARM_CM4F最大的不同移植层拆成了 4 个文件分布于两个层级。序号源文件目标位置说明1ARMv8M/non_secure/port.cportable/port.c通用移植代码2ARMv8M/non_secure/portasm.hportable/portasm.h汇编函数声明3ARMv8M/non_secure/portmacrocommon.hportable/portmacrocommon.hARMv8-M 公共宏4ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.hportable/portmacro.hCM33 ARMCLANG 特定宏5ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portasm.cportable/portasm.c汇编实现SVC/PendSV/SysTick handler关键ARMCLANG 兼容 GCC 内联汇编语法所以选用GCC/ARM_CM33_NTZ子目录的portmacro.h和portasm.c。不要选IAR/下的文件。STM32 移植通常只有port.cportmacro.h两个文件而 ARMv8M 版本多出portasm.c和portasm.h漏掉任何一个都会导致编译/链接失败。3.4 内存管理 — 拷贝到FreeRTOS/portable/MemMang/从FreeRTOS-Kernel/portable/MemMang/选择1 个文件文件名说明heap_4.c首次适配 相邻空闲块合并最推荐的单核方案四、编写 FreeRTOSConfig.hFreeRTOS/config/FreeRTOSConfig.h以官方模板为起点针对 LPC55S69 (Cortex-M33)修改 9 处。此文件来自官方模板文件源路径为D:\freertos\FreeRTOSv202406.05-LTS\FreeRTOS-LTS\FreeRTOS\FreeRTOS-Kernel\examples\template_configuration\FreeRTOSConfig.h改动 ①tick 频率 (第 78 行)修改前修改后#define configTICK_RATE_HZ 100#define configTICK_RATE_HZ 1000100Hz 10ms tick粒度太粗。1000Hz 1ms tick 是主流选择。改动 ②开启时间片轮转 (第 90 行)修改前修改后#define configUSE_TIME_SLICING 0#define configUSE_TIME_SLICING 1改动 ③tick 类型位宽 (第 135 行)修改前修改后#define configTICK_TYPE_WIDTH_IN_BITS TICK_TYPE_WIDTH_64_BITS#define configTICK_TYPE_WIDTH_IN_BITS TICK_TYPE_WIDTH_32_BITSCortex-M33 是 32 位架构64 位 tick 每个 tick 都要做 64 位运算白白浪费性能。32 位 tick 在 1000Hz 下约 49 天溢出完全够用。改动 ④增大内核堆 (第 283 行)修改前修改后#define configTOTAL_HEAP_SIZE 4096#define configTOTAL_HEAP_SIZE 10*1024每个任务 TCB stack 从 FreeRTOS 堆中分配。4KB 只能勉强支持 2~3 个轻量任务。10KB 适合入门验证。改动 ⑤中断优先级 — 致命配置 (第 311–315 行)修改前修改后#define configKERNEL_INTERRUPT_PRIORITY 0#define configPRIO_BITS 3#define configMAX_SYSCALL_INTERRUPT_PRIORITY 0#define configKERNEL_INTERRUPT_PRIORITY ( 7 ( 8 - configPRIO_BITS ) )#define configMAX_API_CALL_INTERRUPT_PRIORITY 0#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( 1 ( 8 - configPRIO_BITS ) )这是 Cortex-M 移植最常见的致命错误。ARM Cortex-M NVIC 使用 bits [7:5] 表示优先级3 位优先级宏值必须左移到寄存器位。0xE0 逻辑优先级 7最低给 SysTick/PendSV0x20 逻辑优先级 1高于此优先级的中断不受 RTOS 管控。如果全部设为 0portasm.c内联汇编中basepri0无法屏蔽任何中断编译还会触发#error。同时删除多余的configMAX_API_CALL_INTERRUPT_PRIORITY已废弃被configMAX_SYSCALL_INTERRUPT_PRIORITY替代。改动 ⑥关闭 TrustZone (第 578、585 行)修改前修改后#define configENABLE_TRUSTZONE 1#define configENABLE_TRUSTZONE 0#define configRUN_FREERTOS_SECURE_ONLY 1#define configRUN_FREERTOS_SECURE_ONLY 0原始 hello_world 是普通 non-secure 单核应用不需要 TrustZone。两个宏同时为 1 构成逻辑矛盾开启 TZ 又声称只跑在 Secure 侧。改动 ⑦关闭 MPU (第 589 行)修改前修改后#define configENABLE_MPU 1#define configENABLE_MPU 0开启 MPU 需要额外链接mpu_wrappers_v2.c和mpu_wrappers_v2_asm.c还会使portasm.c中大量#if ( configENABLE_MPU 1 )的代码路径生效增大代码体积。入门移植先关闭。改动 ⑧关闭 MVE (第 594 行)修改前修改后#define configENABLE_MVE 1#define configENABLE_MVE 0会直接导致编译报错#error。MVE (M-Profile Vector Extension) 是 Cortex-M55/M85 才有的向量扩展指令Cortex-M33 不支持。portmacro.h第 62 行有硬检查#elif(configENABLE_MVE!0)#errorconfigENABLE_MVE must be left undefined,or defined to0forthe Cortex-M33.改动 ⑨保留 FPU 开启 (第 593 行)#defineconfigENABLE_FPU1// ← 保持为 1LPC55S69 有 FPULPC55S69 集成单精度 FPU (SFPU)工程中CpuCPUTYPE(Cortex-M33) FPU3(SFPU) TZ DSP/Cpu已声明。五、Keil 工程配置5.1 添加头文件搜索路径操作: Options for Target (AltF7) → C/C(AC6) 标签页 → Include Paths → 末尾新增 3 个路径.\FreeRTOS\include;.\FreeRTOS\config;.\FreeRTOS\portable完整路径board;CMSIS;CMSIS/m-profile;component/uart;device;device/periph;drivers;utilities;utilities/debug_console_lite;utilities/str;..\hello_world_cm33_core0;.\source;.\FreeRTOS\include;.\FreeRTOS\config;.\FreeRTOS\portable同样在Asm标签页也添加这三个路径。debug 和 release 两个 Target 都要改。5.2 在工程中新增 File Group在 Keil 左侧 Project 窗口中创建以下分组并添加对应文件Group 名称添加的文件FreeRTOS/srcFreeRTOS\src\tasks.c、queue.c、list.c、timers.c、event_groups.c、stream_buffer.c、croutine.cFreeRTOS/portableFreeRTOS\portable\port.c、portasm.c、MemMang\heap_4.c注意文件类型选择All Files才能看到portasm.c不需要添加.h头文件到分组编译器通过 include path 自动查找debug 和 release 两个 Target 都要添加确保Include in Target Build勾选croutine.c虽然添加了但configUSE_CO_ROUTINES0时不参与实际编译5.3 编译器选项现有 Misc Controls 保持不变-include source/mcux_config.h -include source/mcuxsdk_version.h -fno-common -fdata-sections -fno-builtin -mthumbarmclang兼容 GCC 内联汇编语法无需像 ARMCC V5 那样替换为__asm{}块不需要开启 Keil RTX OS 支持选项mOS0/mOS保持关闭六、修改工程现有文件6.1 启动文件 —startup/arm/startup_LPC55S69_cm33_core0.S无需修改。启动文件中 SVC_Handler、PendSV_Handler、SysTick_Handler 全部是.weak声明.weak SVC_Handler .weak PendSV_Handler .weak SysTick_Handler.weak意味着链接器会优先使用port.c/portasm.c中定义的同名强符号。与 STM32 移植不同不需要在 FreeRTOSConfig.h 中添加#define vPortSVCHandler SVC_Handler等宏映射——因为 ARMv8M 版portasm.c中直接定义了SVC_Handler、PendSV_Handler函数名与启动文件向量表中的符号名天然匹配。6.2 主程序 —source/hello_world.c必须添加栈溢出钩子函数configCHECK_FOR_STACK_OVERFLOW 2要求voidvApplicationStackOverflowHook(TaskHandle_t xTask,char*pcTaskName){(void)xTask;(void)pcTaskName;for(;;){/* 死循环调试时在此打断点定位溢出任务 */}}七、调试过程中遇到的错误序号报错/现象根本原因解决方法1error: portmacro.h file not found— 9 个错误portmacro.h未从编译器子目录复制到portable/根目录从ARMv8M/non_secure/portable/GCC/ARM_CM33_NTZ/portmacro.h复制到FreeRTOS/portable/portmacro.h2error: portasm.h file not found— 1 个错误port.c依赖portasm.h但该文件未复制从ARMv8M/non_secure/portasm.h复制到FreeRTOS/portable/portasm.h3L6218E: Undefined symbol ulSetInterruptMaskL6218E: Undefined symbol vClearInterruptMaskL6218E: Undefined symbol vRestoreContextOfFirstTaskL6218E: Undefined symbol vStartFirstTask— 4 个错误portasm.c未加入 Keil 工程编译这几个函数全部在portasm.c中实现Keil 工程 FreeRTOS/portable 分组中添加portasm.c同时需将portasm.h放到portable/目录include path 已配置4L6218E: Undefined symbol vApplicationStackOverflowHook— 1 个错误configCHECK_FOR_STACK_OVERFLOW 2开启栈检测但未提供回调函数在hello_world.c中添加空实现八、ARMv8M 移植与 STM32 ARMv7-M 移植的关键差异总结对比维度STM32F407 (ARMv7-M/CM4F)LPC55S69 (ARMv8-M/CM33)移植层目录portable/RVDS/ARM_CM4F/portable/ARMv8M/non_secure/移植文件数量2 个port.cportmacro.h5 个port.cportmacrocommon.hportasm.hportmacro.hportasm.c汇编文件汇编内嵌在port.c中独立portasm.c文件ISR 命名vPortSVCHandler等 → 需要宏映射SVC_Handler等 → 直接匹配启动文件中断优先级位数4 bitbits [7:4]3 bitbits [7:5]优先级宏值0xF0/0x500xE0/0x20FPU 支持portable/RVDS/ARM_CM4F内置portmacro.h宏configENABLE_FPU1控制TrustZone不支持支持本移植中关闭编译器ARMCC V5 → 需要替换内联汇编语法ARMCLANG V6 → 直接兼容 GCC 语法九、验证结果移植完成后编译 0 错误 0 警告链接成功生成hello_world_cm33_core0.out。最终工程结构hello_world_cm33_core0/ ├── FreeRTOS/ │ ├── include/ ← 22 个 .h │ ├── src/ ← 7 个 .c │ ├── portable/ ← port.c, portasm.c, portasm.h, portmacro.h, portmacrocommon.h │ │ └── MemMang/ │ │ └── heap_4.c │ ├── config/ │ │ └── FreeRTOSConfig.h ├── source/ │ └── hello_world.c ├── startup/arm/ │ └── startup_LPC55S69_cm33_core0.S ├── board/ ├── CMSIS/ ├── drivers/ ├── device/ ├── utilities/ ├── component/ └── hello_world_cm33_core0.uvprojx

相关新闻

5分钟快速上手:AI视频分析工具终极指南

5分钟快速上手:AI视频分析工具终极指南

5分钟快速上手:AI视频分析工具终极指南 【免费下载链接】video-analyzer Analyze videos using LLMs, Computer Vision and Automatic Speech Recognition 项目地址: https://gitcode.com/gh_mirrors/vi/video-analyzer 你是否曾经面对海量视频内容感到无从下…

2026/7/21 18:51:13 阅读更多 →
PowerToys中文版终极指南:让Windows效率提升300%的完整解决方案

PowerToys中文版终极指南:让Windows效率提升300%的完整解决方案

PowerToys中文版终极指南:让Windows效率提升300%的完整解决方案 【免费下载链接】PowerToys-CN PowerToys Simplified Chinese Translation 微软增强工具箱 自制汉化 项目地址: https://gitcode.com/gh_mirrors/po/PowerToys-CN 你是否曾经因为Windows系统操…

2026/7/21 13:06:03 阅读更多 →
3个技术决策打造你的Mac专属影视中心:从开源项目到完美观影体验

3个技术决策打造你的Mac专属影视中心:从开源项目到完美观影体验

3个技术决策打造你的Mac专属影视中心:从开源项目到完美观影体验 【免费下载链接】iMeiJu_Mac 爱美剧Mac客户端 项目地址: https://gitcode.com/gh_mirrors/im/iMeiJu_Mac 在Mac上寻找一款既美观又实用的影视应用,往往需要在多个平台间切换、忍受广…

2026/7/21 7:52:00 阅读更多 →

最新新闻

Java性能调优:JDK诊断工具实战指南

Java性能调优:JDK诊断工具实战指南

1. JDK诊断工具全景概览作为Java开发者最亲密的战友,JDK内置的诊断工具链是我们排查线上问题的瑞士军刀。这套工具诞生于JDK早期版本,经过20余年的迭代已经形成了完整的监控-诊断-分析体系。我曾在一次生产环境FullGC频繁的紧急排查中,仅用js…

2026/7/21 23:43:12 阅读更多 →
Triton+KServe构建高可用机器学习服务的生产实践

Triton+KServe构建高可用机器学习服务的生产实践

1. 项目概述:当模型走出Jupyter,真正开始呼吸真实世界的空气“From Notebook to Production: Running ML in the Real World (Part 4)”——这个标题本身就像一句暗号,专为那些在Jupyter里调通了模型、画出了漂亮ROC曲线、却在部署时被现实狠…

2026/7/21 23:43:12 阅读更多 →
【愚公系列】《Android应用案例开发大全》001-初识庐山真面目Android简介

【愚公系列】《Android应用案例开发大全》001-初识庐山真面目Android简介

💎【行业认证权威头衔】 ✔ 华为云天团核心成员:特约编辑/云享专家/开发者专家/产品云测专家 ✔ 开发者社区全满贯:CSDN博客&商业化双料专家/阿里云签约作者/腾讯云内容共创官/掘金&亚马逊&51CTO顶级博主 ✔ 技术生态共建先锋&am…

2026/7/21 23:43:12 阅读更多 →
深入解析HRPWM高分辨率PWM技术:原理、配置与Buck变换器、PWM DAC实战

深入解析HRPWM高分辨率PWM技术:原理、配置与Buck变换器、PWM DAC实战

1. 项目概述:为什么我们需要HRPWM? 在数字电源和电机驱动的世界里,PWM(脉宽调制)信号的精度直接决定了系统的性能天花板。传统的PWM,其时间分辨率被系统时钟周期(TBCLK)所限制。举个…

2026/7/21 23:43:12 阅读更多 →
Claude Code AI编程助手实战避坑指南:7大关键陷阱与解决方案

Claude Code AI编程助手实战避坑指南:7大关键陷阱与解决方案

Claude Code 作为一款备受关注的 AI 编程助手,其庞大的教程体系(如 52 万字教程)背后,隐藏着许多新手甚至有一定经验的开发者容易忽视的实践陷阱。这篇文章不打算复述那些冗长的入门步骤,而是直接切入核心:…

2026/7/21 23:43:12 阅读更多 →
Claude模型不可选问题排查与修复:从配置到网络全流程指南

Claude模型不可选问题排查与修复:从配置到网络全流程指南

在实际使用 Claude 或类似 AI 模型时,经常会遇到模型不可选或连接问题,特别是当项目依赖特定模型版本时。这类问题不仅影响开发效率,还会导致功能无法正常使用。本文将以修复 Fable 模型不可选问题为例,详细介绍从问题定位到解决的…

2026/7/21 23:42:11 阅读更多 →

日新闻

Octane Render与C4D汉化版安装与优化指南

Octane Render与C4D汉化版安装与优化指南

1. Octane Render与C4D的黄金组合:为什么选择这个方案?在三维创作领域,渲染器的选择往往决定了作品的最终呈现质量和工作效率。作为Cinema 4D(C4D)用户,Octane Render的GPU加速特性与实时预览功能&#xff…

2026/7/21 0:00:19 阅读更多 →
GPMC接口设计:异步/同步模式与多路复用配置实战

GPMC接口设计:异步/同步模式与多路复用配置实战

1. GPMC接口设计:从硬件连接到软件配置的全局视角在嵌入式系统开发中,尤其是基于TI Sitara系列如AM263x这类高性能微控制器的项目里,外部存储器的扩展几乎是绕不开的一环。无论是存放大量非易失性代码的NOR Flash,还是作为高速数据…

2026/7/21 0:00:19 阅读更多 →
UE5 GAS框架下RPG被动技能系统:从核心原理到实战实现

UE5 GAS框架下RPG被动技能系统:从核心原理到实战实现

1. 项目概述:UE5 GAS RPG被动技能的核心价值在UE5里用GAS(Gameplay Ability System)做RPG游戏,主动技能像是你手里的武器,按一下打一下,逻辑直接,反馈也快。但被动技能,它更像是你身…

2026/7/21 0:00:19 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/21 8:48:31 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/21 5:34:47 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/21 8:25:39 阅读更多 →

月新闻