尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
板级适配 · SystemInit:给芯片上电后的“自检程序“动手
阅读指引这篇讲的是芯片刚通电、还没进 main那一刻发生的事。下面术语不少CMSIS、HAL、FPU、VTOR…但每个术语我都会先给一句直白的解释跟着读就行别被缩写吓到。核心其实就一句**上电后、进 main 前有人得先把 CPU 自己的几个总闸拨对后面的代码才跑得稳。**读完整篇若想速查文末第八节有按首字母排序的统一术语表。配套代码stm32mp157-liteos-m· 本系列工程基于基线版 v0.1-baseline· 全部版本标签 /tags系列目录本篇是板级适配系列第 3 篇工程总览见第 07 篇BSP 契约见第 08 篇。上一篇我们把 LED、内核堆这些板子上的外设初始化好了这一篇往里走一层——CPU 芯片自己在上电之后、main() 之前还需要拨哪几个开关。一、这个文件是干嘛的CPU 的开机自检一句话理解它负责芯片上电后、你的 main() 跑起来之前那一段最底层的初始化。你按下电脑电源屏幕亮起、Windows 出来之前其实有一段 BIOS/UEFI 在后台跑检测内存、初始化总线、把启动盘找出来。这段代码不是你写的平时也看不见但没有它操作系统根本起不来。targets/board/system_stm32mp1xx.c就是 STM32MP157 这颗芯片的BIOS 片段它不初始化 LED那是 board.c 的事它不创建任务那是 app 的事它只干一件事把 Cortex-M4 内核自身的几个关键开关拨到正确位置让后面所有代码包括 RTOS 内核能安全运行。它对外提供的是函数 一个全局变量——函数是SystemInit开机自检本体外加第五节要讲的_init/_fini两个 newlib 空桩本工程实际对外就这 3 个函数变量是SystemCoreClock详见 3.3 节。官方那份还有个SystemCoreClockUpdate()本工程已裁掉voidSystemInit(void);// 开机自检本体voidSystemCoreClockUpdate();// 官方有本工程裁掉了后面讲为什么uint32_tSystemCoreClock;// 内核时钟频率CMSIS 约定的全局变量每个是干嘛的先逐个说明SystemInit()——正主。开机自检逻辑全在这里。SystemCoreClockUpdate()——本来用来时钟变了就重算频率但我们时钟恒定不变所以裁掉了第四节讲。SystemCoreClock——一个对外报价的数字告诉整个系统内核现在跑多快。SystemInit()是谁调用的不是 main也不是内核——是启动文件startup_stm32mp15xx.S第 13 篇的主角在跳 main 之前bl SystemInit调的。所以它的执行时机比所有 C 代码都早是真正的第一棒。二、它从哪来官方文件我只动刀、不改逻辑一句话理解这个文件不是凭空手写的是以 ST 官方模板为唯一基底、从零生成的改动文件——而且只拆依赖、不动逻辑。文件来源写在文件头注释里ST 官方 STM32CubeMP1 固件包 Drivers/CMSIS/Device/ST/STM32MP1xx/Source/Templates/system_stm32mp1xx.c这是 ST 官方给所有 STM32MP1 工程的统一模板——CubeMX 生成的工程、官方例程用的都是这一份。相当于厂家给的标准答案。那为什么不直接拷来用看官方文件的第一行 include 你就明白了#includestm32mp1xx_hal.h// 官方模板依赖 HAL 全家桶HAL 是啥ST 家的硬件抽象库一套几十个文件把寄存器操作全包成好用的函数——相当于汽车的自动挡踩油门就走看不见引擎。但我们这门移植课偏偏要讲裸机真相第 08 篇 board.c 就是直接写寄存器引入 HAL 等于把要讲的底层全糊上了所以本工程是**“无 HAL”**的。所以这里的做法是以官方模板为唯一基底把 HAL 依赖拆掉逻辑一行不改。文件头注释里有一段适配说明把每一处裁剪的为什么都写清楚了——这个习惯值得学基于官方模板从零生成我们自己的板级文件时把改了什么、为什么敢改直接写在文件头半年后的你会感谢现在的你。可复用经验后续移植直接用拿到任何芯片的官方 CMSIS / system 模板第一件事不是照抄而是以官方模板为唯一基底从零生成改动文件——生成过程中只拆依赖、不改逻辑并把“哪几行与官方不同、为什么敢动”写进文件头注释。换 STM32 其他型号、GD32、HC32… 这套“以官方模板为基底、只拆依赖不改逻辑、改动原因留痕”的流程完全通用。三、SystemInit 干的三件事一句话理解拨三个总闸——① 打开浮点计算器② 告诉 CPU 中断电话本在哪③ 报一下内核跑多快。3.1 第一件开 FPU硬浮点协处理器一句话理解芯片里有个专门算小数的计算器出厂默认没插电这里负责给它通电。#if(__FPU_PRESENT1)(__FPU_USED1)SCB_CPACR|((3UL10*2)|(3UL11*2));/* set CP10 and CP11 Full Access */#endifCortex-M4 后面那个“F” 就是 FPUFloat 浮点单元的缩写。但芯片出厂时这个浮点单元是关着的——由协处理器访问控制寄存器CPACR固定地址0xE000ED88里 CP10/CP11 两位控制默认值是不允许访问。不用懂位运算也能明白那行看着吓人的3UL 10*2之类翻译成人话就是——把 CP10、CP11 两个浮点协处理器的访问权限设成 Full Access全开。芯片手册规定 CP10/CP11 各占 2 个 bit写11就是全权限。愿意往下抠位运算的看这段其实就三层第一C 里*永远是乘号不是幂——想算 2¹⁰ 得写1 10或pow(2,10)绝不会写成10*2而且*的优先级高于所以(3UL 10*2)实际等于3UL (10*2)3UL 20。第二CPACR 的规矩是每个协处理器 CPn 占 2 个 bit且从 bit2n开始CP10 落在 bit 20、21CP11 落在 bit 22、23。于是3 20就是把0b11即 3摆到 20、21 位3 22摆到 22、23 位。第三为什么偏偏是 CP10、CP11因为在 Cortex-M 上FPU 是以协处理器 CP10 和 CP11的身份挂在内核里的浮点扩展就这么编号每对 bit 写0b11 Full Access特权态、用户态都能用正好对应注释里的set CP10 and CP11 Full Access。一句话10*2/11*2只是第几个协处理器 × 每个占 2 bit 字段起始位的乘法定位再把0b11这个数搬过去。不开会怎样本工程的编译选项固定了硬浮点 ABI-mfloat-abihard -mfpufpv4-sp-d16编译器会大方地用 s0~s15 这些浮点寄存器生成代码。FPU 没开时第一条碰到浮点寄存器的指令直接触发 UsageFault/HardFault——于是程序莫名其妙死在我明明没写浮点运算的地方就是这个原因。一个细节不纠结也行本工程的core_cm4.h是精简版SCB_TypeSCB System Control Block内核里的系统控制寄存器组CPACR、VTOR 都归它管结构体里没留 CPACR 字段所以这里没写SCB-CPACR而是按 ARM 规定的固定地址直接访问#defineSCB_CPACR(*(volatileuint32_t*)0xE000ED88UL)效果完全等价——寄存器访问的本质就是往那个地址读写结构体只是给地址起了个好记的名字。3.2 第二件把向量表搬到 SRAMVTOR 重定向一句话理解给 CPU 一张中断电话本明确告诉它遇事查表时去 0x10000000 那页找别去空白的 0 地址翻。#ifdefined(VECT_TAB_SRAM)SCB-VTORMCU_AHB_SRAM|VECT_TAB_OFFSET;/* Vector Table Relocation in Internal SRAM */#endif先解释两个词中断/异常CPU 跑着跑着突然被打断去处理急事比如定时器到点、串口收到数据。向量表Vector Table一张通讯录——记录了哪个中断对应哪个处理函数。CPU 一接到中断就按这张表找到该打的电话函数地址。Cortex-M 有个铁律中断一来CPU 立刻去 VTOR 寄存器指向的地址取向量表。而 M4 复位后 VTOR 的默认值是0x00000000。先说清这两个地址是哪儿来的——不然总觉得是拍脑袋定的。0x10000000不是我们选的是芯片硬件写死的。STM32MP157 给 M4 核预留了一块片内 MCU SRAM0x10000000 起共 384KB含 SRAM1~SRAM4它在芯片地址空间里的基址被硅片译码固定为0x10000000——这是个硬件事实换任何工程都一样。本工程启动拨码拨到001M4 独立启动意思是 M4 一上电就自己跑、不赖 A7 大核来给它搬固件系统把编译好的固件直接放进这片 MCU SRAM所以固件在地址空间里的家就是0x10000000。也正因如此链接脚本的加载基址、向量表摆放位置、以及后面 VTOR 重定向的目标三者都必须以0x10000000为准否则对不上账这是第 10 篇 lds 的对账点。0x00000000为什么是空的这是 ARM Cortex-M 的复位铁律上电后 CPU 固定先从地址0取两样东西——主栈指针 MSP地址0x0的 4 字节和复位向量地址0x4的 4 字节。而在 STM32MP157 上地址0默认映射到RETRAM一块 64KB 的保留 RAM。我们的固件并没有烧进 RETRAM而是住在0x10000000的 MCU SRAM 里——所以0x00000000这片是空的、没内容。出处ST《RM0436 参考手册》Memory map 章节——其中 0x10000000 起为 MCU SRAM 区、0x00000000 起为 RETRAMST 官方 Wiki《STM32MP15 RAM mapping》也明确写道 “the MCU SRAM is defined from 0x10000000”“RETRAM base address is fixed, the vector table must be stored at address 0”。也就是说如果不重定向 VTOR上电后第一个中断一来哪怕是 PendSV/SVC 这类内核调度异常这种最普通的中断CPU 去地址 0 取电话本取到的是乱码而不是函数地址直接 HardFault。而且这种死机很难查——你明明觉得中断都还没开但 HardFault 本身也是一种异常也要查表照样死。所以这两行是 M4 独立启动场景的生死开关MCU_AHB_SRAM 0x10000000向量表的实际位置必须和链接脚本把.isr_vector就是那段向量表在固件里的段名放的位置一致这是下一篇 lds 的对账点VECT_TAB_OFFSET 0x00表内偏移必须是 0x400 的倍数我们整表加载偏移为 0。注意官方模板里VECT_TAB_SRAM本来是注释状态官方默认场景向量表在 Flash。我们把它打开——这属于按场景启用官方预留开关不是魔改。“本文 VTOR0x10000000 是启动期初始向量表落 SRAM内核初始化时 HalHwiInit第14篇会再次改 VTOR 指向 g_hwiForm 完成运行期中断接管两次操作不冲突——前者让芯片先能启动后者接管中断。”3.3 第三件全局时钟变量一句话理解向全系统报个数“内核现在跑 64MHz”记在一个大家约定好都会读的地方。uint32_tSystemCoreClockHSI_VALUE;// HSI 内部高速时钟芯片自带HSI_VALUE 64000000ULSystemCoreClock是 CMSIS 生态的惯例变量告诉整个系统内核现在跑多快。CMSIS 是 ARM 给 Cortex-M 定的软件接口标准芯片厂都照它写系统/启动文件所以CMSIS 生态就是所有遵守这套标准的代码。HAL 库的延时、串口波特率计算都读它。本工程没有 HAL但这个变量在源码里保留着system_stm32mp1xx.c:84uint32_t SystemCoreClock HSI_VALUE;原因有二CMSIS 生态的代码将来移植的组件默认它在删了反而埋雷⚠️但别以为它真的躺进了固件里。Makefile 开了-Wl,--gc-sections而本工程没有任何代码引用SystemCoreClock所以它被链接器当垃圾回收了——arm-none-eabi-nm build/liteos_m.elf查不到这个符号map 文件里它所在的.data.SystemCoreClock段地址是0x00000000已丢弃。源码留着 ≠ 固件里有这是为了将来移植方便和现在不占 4 字节的兼顾不是 bug。真要用它比如在某处extern引用一次gc 就不会回收了。它和target_config.h里的OS_SYS_CLOCK 64000000必须数值一致——内核算 SysTick 节拍用的是后者前者是 CMSIS 侧的对外报价。两个数一旦对不上比如你改了时钟只改一处节拍周期就悄悄错了 2 倍、4 倍LED 闪烁快慢不对、超时全部失真而且极难定位。这是本篇最值得记住的对账点SystemCoreClockCMSIS 侧和OS_SYS_CLOCK内核侧是一对必须保持一致的孪生数字。即便当前固件未引用、被 gc 回收源码数值仍须与 OS_SYS_CLOCK 同步以便将来引用后即刻生效。可复用经验后续移植直接用凡是CMSIS 惯例的全局变量如SystemCoreClock只要 CMSIS 生态代码将来会读它就不要删而且它和内核侧的对外报价宏OS_SYS_CLOCK是孪生数字——改一处必须同步另一处。换芯片时先把哪些数字是孪生的记进移植笔记能省掉一半LED 快慢不对、超时全乱的离奇 bug。四、裁剪清单官方 → 精简版一句话理解从官方全家桶到我们这锅汤一共三类动作——补几个宏、删两段冗余、加两项刚需。4.1 显式补宏原来 HAL 头文件给的现在自己给这五个宏是怎么找出来的把官方模板里的#include stm32mp1xx_hal.h删掉编译一遍——编译器报xxx undeclared/implicit declaration的那一批注意宏缺失是预处理期/编译期的诊断链接器不会为宏报undefined reference就是 HAL 头文件之前顺手替我们喂的宏。把它们逐个拎出来、过下面三核对后再写死就是去 HAL 依赖的完整动作。注意编译报错只当发现清单用不当落地手段——别在报错那行上面直接塞个#define把错消掉那样宏值可能只满足编译器、不满足硬件而且散落各处没出处见下方可复用经验。把它们逐个拎出来、过下面三核对后再写死就是去 HAL 依赖的完整动作。注意编译报错只当发现清单用不当落地手段——别在报错那行上面直接塞个#define把错消掉那样宏值可能只满足编译器、不满足硬件而且散落各处没出处见下方可复用经验。宏值官方谁给的为什么敢直接写死说明CORE_CM4定义即可CMSIS 设备头SystemInit 用它选 M4 分支。⚠️ 本工程只有#if defined(CORE_CM4) … #endif没有官方那句#else #error文件角注释里官方 SystemInit 用 #else #error 检查说的是 ST 原始版裁剪时连同 HAL 依赖一起去掉了__FPU_PRESENT1CMSIS 设备头MP157 的 M4 核就是 M4F带 FPU这是硬件事实__FPU_USED1CMSIS 按编译选项推导精简版 core_cm4.h 不再自动推导而工程 Makefile 固定-mfloat-abihard手工对齐HSI_VALUE64000000ULhal_conf.h启动拨码 001 独立启动时钟恒为 HSI 64MHzMCU_AHB_SRAM0x10000000HAL 宏固件加载地址链接脚本同款数字这五个宏本来是 HAL 头文件顺手给的。现在我们不用 HAL 了就得自己把它们喂进去。值都是板上钉钉的硬件事实所以直接写死完全放心。可复用经验后续移植直接用去 HAL 化以后原本HAL 头文件顺手给的那批宏核型号、FPU 开关、时钟值、SRAM 基址…都要自己补。补之前先三核对① 芯片手册确认硬件事实FPU 有没有、时钟多少② 和 Makefile 编译选项对齐-mfloat-abihard↔__FPU_USED1③ 和链接脚本数字一致SRAM 基址 ↔ lds 加载基址。三处对不上后面必踩坑。漏了哪些宏怎么知道不用死记——把 HAL include 删掉编译一遍链接器报的undefined就是清单但每个宏都必须先过上面三核对、再集中写进文件头适配说明绝不在报错处就地补丁那是满足编译器、不满足硬件的懒人补法正是本系列反对的。4.2 删两段官方逻辑本场景冗余① SystemInit 里的 EXTI_C2 清零段。官方在 SystemInit 里把 Cortex-M 侧 EXTI外部中断/事件控制器的 6 个中断/事件屏蔽寄存器IMR1~EMR3清零用的是 HAL 的 EXTI 结构体。为什么敢删查芯片手册M4 复位后这些寄存器的复位值本来就是全 0——往已经是 0 的寄存器上再写 0是幂等的保险动作删掉行为完全不变。文件头注释把这层推理写明白了。② SystemCoreClockUpdate() 整个函数。官方提供它是为了运行期时钟频率变了比如切了 PLLPLL 即锁相环、用来给时钟倍频就动态重算。本工程时钟恒为 HSI 64MHz开机是多少、关机还是多少没有更新可言所以整个函数连同它依赖的 RCC复位与时钟控制寄存器位宏一起裁掉。可复用经验后续移植直接用删官方逻辑前先拷问一句“删了以后芯片上电的行为变不变”两种可删① 写往复位值本来就是这个值的寄存器清零段幂等② 依赖永远不变的前提的动态逻辑时钟恒定 → 动态更新函数多余。反之只要行为会变就改成按场景开关而不是物理删。4.3 加两段独立启动的刚需①VECT_TAB_SRAM VTOR 重定向——上一节讲过的生死开关。②_init/_fini空桩——这个最有意思单独开一节。五、_init/_fini-nostartfiles开出的账单一句话理解这是我们用-nostartfiles这把省事开关时欠下的债——链接器要求这两个函数必须存在哪怕是空壳。文件末尾孤零零挂着两个空函数void_init(void){}void_fini(void){}空函数删了行不行——不行链接直接报undefined reference to _init。来龙去脉是这样的官方 CubeIDE 工程链接时会带上 GCC 的 C 启动文件crt0.o / crti.o_init/_fini由它们提供_init负责 C 全局构造器、库初始化等。本工程 Makefile 用了-nostartfiles所有 C 启动文件一概不要。为什么因为我们的启动流程被startup_stm32mp15xx.S完全接管了——如果再让 crt0 的默认_start进来两套启动逻辑打架。但启动文件里有一句bl __libc_init_arraynewlib嵌入式常用的 C 标准库实现的 C 库初始化而 newlib 编译时开了HAVE_INIT_FINI一个决定要不要调用_init/_fini的开关__libc_init_array内部一定会调用_init。现在没人提供_init→ 链接器翻脸报错。打个比方物业规定每户必须挂个门牌联系人你家虽然空着没人住但也得挂个牌子有人敲门时牌子应一声就行。这两个空函数就是那个应一声的空壳——必须存在但可以什么都不做。解法就是这两个空桩_init被调就调函数体什么都不干。因为我们没有 C 全局构造器、没有需要初始化的库。这一段是-nostartfiles这类全接管式移植的典型代价你省掉的每一个默认服务都要自己补上等价物哪怕补的是个空壳。Makefile 为什么这么配第 04 篇Makefile 详解已经铺过底这里算是收到了账单。可复用经验后续移植直接用凡是启动流程完全接管-nostartfiles、自写Reset_Handler的移植都会收到类似的账单链接器要求的默认符号_init/_fini/__libc_init_array等得自己补。遇到undefined reference to _init别慌——补两个空桩即可这是全接管式移植的标配动作不是你移植错了。六、为什么这些开关必须放 SystemInit而不是 Reset_Handler一句话理解功能上塞哪儿都行但放 SystemInit 是约定俗成 职责清晰 踩过坑更稳更省心。一个常见的能跑就行写法把 FPU/VTOR 的寄存器操作直接内联塞进启动文件的Reset_Handler开头。功能上确实等价——反正都是 main 之前执行。但本工程坚持放在 SystemInit理由有三CMSIS 约定SystemInit是 CMSIS 标准入口名任何拿到这个工程的人以及 CMSIS 生态工具都知道去哪找系统级初始化塞进 Reset_Handler 就是私有约定了。职责边界启动文件.S只该有搬运 .data已赋初值的全局变量要从 Flash 拷进 RAM、清零 BSS未赋初值的全局变量、跳转这类无法用 C 表达的活所有配置寄存器的 C 逻辑收敛到 system 文件。启动文件越笨越可靠。踩过坑的教训FPU 相关的初始化时机错位正是本工程当年真实卡死事故的根源之一FPU 栈帧错位见系列勘误复盘篇。把这类内核级开关固定收敛在一个约定位置是给自己上保险——换板子时你只需要检查一个文件。可复用经验后续移植直接用内核级开关FPU / VTOR / 时钟固定收敛在SystemInit这一个 CMSIS 约定入口别为了能跑就行塞进Reset_Handler。好处是换任何芯片时系统级初始化只在一个文件里检查不会散落到汇编里到处找。这是降低移植维护成本的铁律。顺便留个思考题SystemInit 是被启动文件调用的那它自己能不能调用 board.c 的 BoardInit()提示想想 SystemInit 执行时 .data 还有没有被拷贝、BSS 清没清——答案在第 13 篇那里会逐行走Reset_Handler的五步设 SP → 拷 .data → 清 .bss →bl SystemInit→bl main。七、小结问题答案这个文件的角色CPU 的开机自检比所有 C 代码都早来源ST 官方 CMSIS 模板裁剪不改逻辑理由全写在文件头三件事开 FPUCPACR、向量表搬 SRAMVTOR0x10000000、时钟变量 64MHz删了什么EXTI_C2 清零复位即 0、SystemCoreClockUpdate时钟恒定加了什么VECT_TAB_SRAM 开关、_init/_fini 空桩-nostartfiles 的账单对账点SystemCoreClockOS_SYS_CLOCK 64MHz两处必须一致 本篇可复用经验速记换芯片直接套官方模板只拆依赖、不改逻辑改动原因写进文件头 —— 通用。CMSIS 惯例全局变量如SystemCoreClock别删且必须与内核侧时钟宏成对对账孪生数字。去 HAL 后原 HAL 给的宏自己补补前核对手册事实 × Makefile 选项 × 链接脚本数字。删官方逻辑前先问删了行为变不变只有幂等清零段 / 恒定前提的动态逻辑才可删。全接管式启动-nostartfiles的账单缺的默认符号自己补空壳_init/_fini。内核级开关固定收敛在SystemInit换板子只查一个文件。下一篇讲targets/lds/stm32mp157_m4_256k.lds——链接脚本。本文埋的两个问题分头揭晓向量表为什么恰好落在 0x10000000VTOR 重定向的另一半就在这一篇思考题的答案SystemInit 执行时 .data/.bss 的真实状态在第 13 篇——那里讲Reset_Handler五步法会看清SystemInit排在拷 .data、清 .bss之后所以它执行时 C 环境已经就绪。八、术语表中英对照速查正文里凡是加粗或首次出现的英文缩写这里给一份统一速查按英文首字母排序方便回查。英文中文含义ABI应用二进制接口Application Binary Interface规定编译产物之间如何互相调用。本文指硬浮点 ABI即函数用硬件浮点寄存器传参、而非走栈A7Cortex-A7STM32MP157 上的大核/应用核通常跑 Linux本工程 M4 独立启动不依赖它BSS / .data全局变量两段.data 有初值启动文件从 Flash 拷进 RAM.bss 无初值启动文件清零CMSISARM 给 Cortex-M 定的软件接口标准芯片厂据此写系统/启动文件CORE_CM4宏“当前是 Cortex-M4 核”SystemInit 用它做编译期检查CPACR协处理器访问控制寄存器地址 0xE000ED88管 FPUCP10/CP11访问权限crt0 / crtiGCC 的 C 运行时启动目标文件提供_start、_init/_fini等EXTI外部中断/事件控制器Flash闪存掉电不丢用来存放固件/程序FPU浮点运算单元Cortex-M4 型号里的 “F”GCCGNU 编译器套件本工程用它编译 M4 固件HALST 的硬件抽象库HardFault硬错误Cortex-M 最严重异常兜不住的 fault 都会落到这里HSI内部高速时钟芯片自带无需外晶振IMR / EMREXTI 的中断屏蔽 / 事件屏蔽寄存器如 IMR1~EMR3M4Cortex-M4本工程的小核/MCU 核跑 LiteOS-MMCU_AHB_SRAM宏名字面即挂在 AHB 总线上的 MCU SRAM基址0x10000000即 M4 片内主 SRAMMSP主栈指针Main Stack PointerCortex-M 复位后从地址 0 取的第一个值newlib嵌入式常用的 C 标准库实现PLL锁相环给时钟倍频用RAM随机存取存储器泛指内存掉电丢SRAM 是其中一种RCC复位与时钟控制寄存器RETRAM保留 RAMRetention RAMSTM32MP157 上地址 0 默认映射到的 64KB 小 RAMReset_Handler启动汇编里的复位处理例程芯片复位后执行的第一段代码RTOS实时操作系统Real-Time OS本工程即 LiteOS-MSCB系统控制块System Control Block内核里的系统控制寄存器组CPACR、VTOR 归它SRAM静态随机存取存储器片内 MCU SRAM 即 M4 自带的高速内存基址 0x10000000STM32CubeMP1ST 官方的 STM32MP1 固件包本文 system 文件出处SysTick系统节拍定时器内核用它产生周期心跳、驱动任务调度UsageFault用法错误非法指令、除零、未对齐访问等触发的异常VECT_TAB_OFFSET宏“向量表在 SRAM 内的偏移”须为 0x400 倍数VECT_TAB_SRAM宏/开关向量表放在 SRAM标志VTOR向量表偏移寄存器指向当前向量表所在位置_startC 运行时默认入口符号来自 crt0__FPU_PRESENT/__FPU_USED宏芯片是否带 FPU / 编译是否启用 FPU__libc_init_arraynewlib 的库初始化数组函数内部会调用_init-mfpufpv4-sp-d16编译选项指定 FPU 型号单精度 VFPv4、16 个 32 位浮点寄存器-mfloat-abihard编译选项“硬浮点调用约定”见 ABI.S汇编源文件后缀startup_stm32mp15xx.S 即 M4 启动汇编s0~s15单精度浮点寄存器FPU 的 32 位寄存器系列导航上一篇第 08 篇 · 板级适配 BSPboard.h 定契约board.c 给实现 本篇第 09 篇 · SystemInit 与 CMSIS 裁剪 下一篇第 10 篇 · 链接脚本 lds勘误 256KB 硬约束基础 01–0601 环境准备 02 源码下载裁剪与工程搭建 03 os_config 详解 04 Makefile 详解 05 链接脚本与编译运行 06 一键烧录踩坑实录切换汇编 01–06汇编1 汇编是什么与寄存器地图篇 汇编2 指令异常机制全景表篇 汇编3 首任务启动篇 汇编4 临界区与触发篇 汇编5 HalPendSV机制篇 汇编6 完整调度接力与调试篇板级适配与应用 07–2507 工程全景 08 BSP 09 SystemInit 10 lds上 11 lds下·解剖 12 lds下·照妖镜 13 启动文件 14 接管中断 15 target_config上 16 FPU栈档 17 改错速查 18 LED详解 19 LED实战 20 los_exc 21 FPU栈帧 22 八环节 23 全文件对账 24 六类判据 25 经验增删改留版本对账提示第 03 篇的堆机制旧0x10002000 静态堆 / 384KB与第 05 篇的链接脚本旧m4_liteos.elf/._user_stack//DISCARD/均为早期版本请以第 08、16 篇外部堆机制与第 10、11、12 篇链接脚本为准。⚠️ 注意这里的384KB指第 03 篇早期那版把整片 MCU SRAM 当 384KB 静态堆的设计从0x10002000起放 384KB 会越过0x1005FFFF溢出、且没给双核留 IPC 共享区并非说 384KB 这个数本身错了。STM32MP157 给 M4 的 MCU SRAM 物理总量确实是 384KBSRAM1~SRAM4硅片定死这是硬件事实本工程只是主动只圈其中 SRAM1SRAM2256KB把 SRAM3/SRAM4 留给 A7↔M4 的 IPC 与 DMA。即384KB 是芯片总量256KB 是本工程占用两者不冲突更完整的口径说明见第 10 篇一、硬性约束 256KB的口径提醒。代码仓库stm32mp157-liteos-m Gitee · 基线 v0.1-baseline · 全部版本标签与 DMA。即384KB 是芯片总量256KB 是本工程占用两者不冲突更完整的口径说明见第 10 篇一、硬性约束 256KB的口径提醒。代码仓库stm32mp157-liteos-m Gitee · 基线 v0.1-baseline · 全部版本标签
RELATED

相关推荐

HackRF One手册解析:硬件、编译与GNURadio实战

HackRF One手册解析:硬件、编译与GNURadio实战

简介:HackRF One软件无线电平台用户手册是一份面向SDR入门者与嵌入式开发者的中文操作指南,系统讲解HackRF One的硬件构成、驱动安装与环境配置方法。手册从平台简介与射频前端、FPGA处理架构等硬件分析入手,逐步覆盖Windows下的VS2012运行库…

📅 2026/10/10 2:44:18
Graffle 实战:使用 `___on_` 内联片段查询 GraphQL Interface 类型并获得可收窄的判别联合类型

Graffle 实战:使用 `___on_` 内联片段查询 GraphQL Interface 类型并获得可收窄的判别联合类型

后端 【免费下载链接】graffle Simple GraphQL Client for JavaScript. Minimal. Extensible. Type Safe. Runs everywhere. 项目地址: https://gitcode.com/gh_mirrors/gr/graffle 点击查看 免费下载 本篇指南以 Graffle(一个极简、可扩展、类型安全的…

📅 2026/10/10 2:39:18
磨刀不误砍柴工:Gradle 语法浅谈——从 Groovy 闭包到 Android 构建脚本

磨刀不误砍柴工:Gradle 语法浅谈——从 Groovy 闭包到 Android 构建脚本

文档教程知识库 【免费下载链接】android-tech-frontier 【停止维护】一个定期翻译国外Android优质的技术、开源库、软件架构设计、测试等文章的开源项目 项目地址: https://gitcode.com/gh_mirrors/an/android-tech-frontier 点击查看 免费下载 本文是「开发技术前…

📅 2026/10/10 2:39:18
MORE NEWS

更多资讯

📰

磁盘未分配数据恢复,分区消失文件这样找回

一、磁盘未分配是什么故障磁盘未分配是存储故障里十分常见的现象,很多用户打开磁盘管理后,发现磁盘状态直接变为未分配,原有分区全部消失,会误以为磁盘内的数据已经彻底清除。 磁盘未分配本质是分区表损坏,并非扇区内存…

📰

GEO信任机制:企业内容如何通过大模型权威审核

一、搜索引擎的技术演进的四个常见问题企业内容在AI搜索时代面临的第一道门槛是信任。用户问AI“哪家供应商靠谱”,大模型凭什么引用你的信息而不是别人的?第二,传统网页SEO时代靠外链和关键词密度建立的权重,在生成式引擎中几乎失…

📰

传统SEO退场后,企业数字资产的GEO价值分化

一、企业数字资产的GEO价值的四个常见问题传统SEO时代,企业数字资产的核心是关键词密度、外链数量和网页权重,运营逻辑围绕“被搜索引擎抓取并排到前面”展开。进入AI搜索时代,用户不再逐条点击链接,而是直接向豆包、文心一言、De…

📰

第五篇:Keepalived + LVS 四层负载均衡高可用实战:DR 模式全流程

开篇Keepalived 不只是"VIP 漂移工具"——它天生就是为 LVS(Linux Virtual Server)设计的。很多人不知道,Keepalived 的看家本领就是管理 LVS 集群,实现四层负载均衡 高可用的一体化方案。本文作为 Keepalived 系列第 …

📰

第六篇:Keepalived 脑裂专题:成因、危害与防脑裂实战(含检测脚本)

开篇用 Keepalived 做高可用,最怕的不是"主挂了切不过来",而是两台同时认为自己才是 Master——这就是脑裂(Split Brain)。脑裂一旦发生,VIP 被两台机器同时持有,流量被撕成两半,数据…

📰

CentOS下源码编译安装高版本Python:依赖准备与环境配置全指南

1. 为什么Centos默认Python版本那么低:先弄清来龙去脉我用Centos很多年了,每次在这台系统上装新Python都会被同一个问题卡住:系统自带的Python版本老得让人怀疑人生。Centos 7自带的Python是2.7.5,Centos 8内置Python也才到3.6左右…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬