拓冰建站拓冰建站
首页 / 资讯中心 / 正文

LiteOS-M移植-两种工程范式-直接改内核VS完整保留内核

技术博客面向刚接触 RTOS 移植的初学者一句话结论两种方式都能跑通工程但维护成本、后续内核升级代价完全不同。再强调一遍磁盘源码 ≠ 烧录固件磁盘上的冗余源码不会增大芯片固件镜像。前言很多同学做LiteOS-M鸿蒙轻量内核移植时会遇到两条完全不同的实践路线路线 1直接进入内核仓库修改内核内部的.c / .h改完编译跑通。我早期的移植博客就是这种验证方式确实可以跑起来。路线 2完整原样保留kernel_liteos_m这个 Git 仓库不改动内核内部任何文件所有板级修改、适配全部放到工程外部的 BSP / board 目录如targets通过编译列表与配置宏做裁剪适配。疑问就来了两种都能跑到底选哪一种直接改内核源码会有什么隐患把全套内核源码完整放在磁盘上会不会把没用到的组件也编译进固件很多初学者容易混淆两个概念「开发主机磁盘上的源码文件」和「最终编译、烧录进芯片的固件镜像」。本文结合实战经验把两种范式讲清楚——不绑定任何具体工程只讲通用原理和选型思路。读完这篇文章你会搞清楚直接改内核源码为什么「能跑」却「不适合量产」完整保留内核源码的工程到底靠什么做裁剪为什么磁盘上的冗余源码不会撑大固件商业产品有哪三条可行路线各自怎么选这两种范式到底怎么选落到自己的项目里该注意什么。图1 说明左半边是「直接改内核」——人钻进内核仓库里改文件仓库被改得乱七八糟右半边是「完整保留内核 外部 BSP」——内核原样不动所有板级适配放在工程外部的 BSP / board 目录干净解耦。两种范式一眼对比。一、两种移植方式简单对比方式一直接修改内核源码快速验证适合学习调试我之前的移植博客采用的就是这套思路直接修改kernel_liteos_m仓库内部的arch、kal、部分内核源文件改完直接编译快速把系统跑起来。✅优点上手快不需要先设计外部 BSP 隔离层可以直接阅读、修改内核内部逻辑学习内核原理时非常直观不需要维护复杂的外部适配层demo 验证效率很高。❌致命短板工程走到产品阶段就会暴露内核 Git 仓库被本地修改污染执行git status会出现大量改动工作区不再干净升级内核版本极其痛苦上游kernel_liteos_m更新了 bug 修复、新特性后你不能简单地更新子模块而要把之前所有修改手动重新移植一遍极易遗漏补丁、引入隐性 bug分不清哪些改动是「官方原生代码」、哪些是「我们为板子打的定制改动」时间久了连自己都搞不清哪些修改是必须的团队协作时别人拉取代码容易误覆盖你的本地改动问题难以复现。定位适合学习、Demo 快速验证不建议直接作为量产工程模板。方式二完整物理保留内核仓库内核零改动通用推荐范式做法kernel_liteos_m完整 Git 仓库原样引入不物理删除、不修改仓库内任何源文件用git status --short校验内核工作区干净。裁剪、板级适配不碰内核内部文件全部通过两处外部手段完成外部配置头文件工程侧targets/xxx/target_config.h或对应 board 目录下的配置头通过宏开关关闭不需要的组件Makefile 编译源文件清单C_SOURCES只把真正需要参与编译的源文件纳入编译列表。磁盘上虽然全套源码都存在但不会参与编译。校验命令gitstatus--short如果内核子模块输出为空就证明内核源码没有任何本地篡改。✅优点内核与板级 BSP 完全解耦所有板子差异收敛在工程自己的 BSP / board 目录升级 LiteOS-M 内核只需要切换 git submodule 的 commit idBSP 代码几乎不用改内核出现 bug可以直接查官方git log、官方提交快速定位官方修复团队协作干净内核源码完全来自上游本地改动全部可控、可追溯。⚠️代价前期工程架构设计工作量更大需要搭好外部 BSP 适配层IDE 索引会看到磁盘上的全部源码但很多文件并不参与编译新手容易混淆「磁盘文件」和「实际链接进固件的文件」。定位量产 / 通用推荐范式优先采用这套。⚠️重点这套不是行业强制法律标准而是工程维护最佳实践。遇到紧急 bug 修复依然允许打补丁但要以patch 文件形式保存不直接污染子模块工作区。关键认知磁盘源码冗余 ≠ 单片机固件冗余电脑磁盘存放完整全套内核源码完全不会增加单片机 Flash / RAM 的占用。没有加入 Makefile 编译清单的源码仅仅躺在硬盘里不会参与编译过程。再配合编译链接参数-ffunction-sections -fdata-sections -Wl,--gc-sections编译器把每一个函数、每一份数据切分成独立的段section链接器执行垃圾回收--gc-sections把所有「没有被引用到」的段直接丢弃最终elf / bin固件里只保留真正需要运行的代码。类比硬盘上是全部「原材料素材」编译链接相当于漏斗筛选只有被 Makefile 选中的代码才进入下一步。实际工程里最终固件的 text 段往往只有二十几 KB和磁盘内核仓库有多大没有任何关系。图2 说明用「漏斗」比喻编译前的筛选——磁盘上全套内核源码倒在漏斗上方只有被 Makefile 编译清单选中的文件才从漏斗口流下去进入编译没被选中的停在上面、不会进固件。图2 讲的是「哪些文件参与编译」下面图3 是更细的一步编译之后链接器还会再筛一遍。图3 说明用「筛子」比喻链接时的垃圾回收——编译出来的代码块一股脑倒进筛子--gc-sections就是筛网只有被别处代码引用“挂住”的颗粒留下进固件没被引用的渣滓直接漏掉丢弃。注意它和图2 的区别图2 决定进不进编译图3 决定编译后丢不丢未用段。比方把编译出来的所有代码块倒进一张筛子--gc-sections就是那张筛网——只有被别处代码「挂住」引用的颗粒能留下来进固件那些谁都没调用的零散渣滓直接穿过筛网、掉进垃圾桶。所以即便某个文件被编译了只要里面的函数没人调用最终也不会占芯片空间。二、真实商业产品的三条可行路线方案 Agit submodule 引入完整内核内核仓库零本地修改推荐大多数项目kernel_liteos_m作为git 子模块引入不在子模块目录做任何源码修改所有板级适配、硬件修改全部收敛到工程外部 BSP / board 目录。裁剪依靠Makefile 源文件清单 target_config.h配置宏实现。✅收益内核升级成本最低bug 溯源简单。磁盘虽然存放全套源码但不会全部编译进固件PC 硬盘存储成本很低真正稀缺的是 MCU 的 Flash、SRAM。方案 B物理拷贝筛选源码部分公司项目在用从官方内核仓库手动复制项目需要的.c / .h删除testsuits、不需要的components等目录工程不再携带完整 Git 仓库。✅优点工程目录文件少磁盘目录清爽。❌代价后续内核版本升级需要人工重新拷贝、比对源码很容易漏掉官方 bug 修复维护成本高。方案 C子模块完整引入必要时打补丁折中内核必须修改时优先方案 A只有官方内核确实存在 bug、必须修改内核源码才能跑通时不要直接在子模块目录改代码。正确做法保存.patch补丁文件由编译脚本自动应用补丁保持子模块工作区原始干净升级内核版本之后重新apply补丁即可。原则能在 BSP / 配置宏解决的绝不修改内核源码。万不得已要改内核用patch 补丁不要直接污染 git 子模块。图4 说明用「三个并列方案面板」概括本章讲的三种工程路线和上面方案 A/B/C 一一对应左栏 完整子模块模块齐全、不改动内核中栏 物理裁剪只留需要的文件、目录精简右栏 子模块 补丁仓库原样额外贴一张 patch 补丁。三条路怎么选看上面三个方案的具体利弊。三、总结直接修改内核源码可以跑通工程适合 Demo 与学习验证但后续维护、内核升级代价很高。对应我早期的移植博客磁盘源码冗余 ≠ 固件镜像冗余源码只是电脑上的文件不会自动进入芯片固件大小由「参与编译链接的内容」决定。工程三条路线完整子模块零修改优先/物理拷贝删减源码目录清爽但维护麻烦/子模块 patch 补丁万不得已修改内核时。选择「完整保留内核源码、板级适配全部收敛到 BSP / board 目录」是大多数量产项目的首选目的不是教条而是贴近真实工业产品的可维护范式。尽量不在内核仓库内直接修改源码必须修改内核 bug 时用patch 补丁保存改动。思考题如果磁盘保存了完整的components组件源码但 Makefile 没有把它加入编译列表这些组件会不会占用单片机 Flash为什么假如遇到 LiteOS-M 内核存在官方 bug必须改动内核源文件才能让你的目标芯片跑通你该如何处理答案都在正文里——欢迎在评论区写下你的理解
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门