ST-Forge 路线图
ST-Forge 是一个锁定 STM32F1 与 ARM Cortex-M3 的嵌入式学习工坊,统一用 STM32F103C8T6 Blue Pill 作课程基准。
它不把"会调用 HAL"当成终点。目标是带着学习者从 CPU、内存、总线、寄存器一路看到电气信号,搞懂程序怎么启动、外设怎么跑、抽象层是怎么搭起来的,最后走到调试、升级和单核 RTOS。
工具链固定下来,不在这件事上反复横跳:C、CMake、ARM GCC、OpenOCD、GDB、ST-Link。STM32CubeMX、MDK 这些商业工具只在需要对照生态时出现,不进主线。
我们要建立什么
最终要落地的是一套从零开始、前后连贯的 STM32F103 课程。
认识单片机与开发工具
↓
理解 Cortex-M3、内存、启动与时钟
↓
掌握 GPIO、通信、中断与定时
↓
掌握 ADC、DMA、I2C、SPI 与 Flash
↓
掌握故障、低功耗与启动升级
↓
理解 FreeRTOS 在 Cortex-M3 上如何调度
↓
完成一次课程级综合实践产出一共五样:按学习顺序组织的教程,和教程一一对应的最小实验,同一现象的寄存器实现与 HAL 对照,Host、micro-forge 和真板上的分层验证,以及从真实实验里沉淀出来的调试与排障方法。
怎么教
每个主题都从三个尺度去讲,而不是只丢一个 API。
宏观上,单片机就是一台计算机。STM32F103 把 CPU、Flash、SRAM、总线、时钟和外设塞进一颗芯片。先建立这个完整的系统视角,外设才不会变成一个个孤立的函数调用。中观上,外设就是一组内存映射的寄存器。Cortex-M3 的地址空间同时映射存储器和外设,读写某个地址就是读状态或者驱动硬件状态机。微观上,寄存器背后是电平和时序。GPIO 是电平,UART 是异步比特流,I2C 是开漏总线上的事务,SPI 是时钟约束下的移位。外设控制器做的事情,不过是把这些物理规则自动化。
每个主题开两条轨并排走。寄存器轨探究底层,亲手开时钟、配寄存器、写数据,看清每一步在硅层面到底动了什么。HAL 轨是产业抽象的对照,用封装好的 API 把同一件事做一遍。两条轨一起读,读完寄存器轨,要能说出 HAL 每一句替你省掉了哪些寄存器操作。
能用 DMA 的外设,按能力一步步演进:先轮询,机制全都看得见,代价是 CPU 忙等;再中断,硬件事件主动通知 CPU;最后 DMA,数据搬运彻底脱离 CPU。这不是要求每个外设机械地做三遍。GPIO、UART、ADC 这些只走符合自己硬件能力的路径,强行三遍是浪费时间。
课程起点用 C,工具链、实验和工程都是 C。但 C++ 不是远期选修,而是两条轨的收敛终点:寄存器轨讲清硬件真相,HAL 轨讲清产业抽象的长短,最后用 C++ 把 HAL 重写一遍,两头都摸透了,重写才有意义。在那之前不急着上 C++,先把两条 C 轨走稳。
还有一条贯穿始终的习惯:每个知识点都要能回答三个问题:学什么、为什么学、怎么验证。说不清"它解锁了什么、不学会卡在哪一步",就不该进路线图。坑也是一样,每个主题都把它最常见的几个坑连同根因一起摆出来。入门时大多数挫败感来自踩了坑却没人解释为什么,所以坑要前置,不能等学习者撞上去。
比喻会用到,GPIO 是手,串口是嘴和耳朵,定时器是心跳,DMA 是搬运工。但比喻只是搭脚手架,搭完就要拆,每个比喻后面都得跟上机制层面的精确说法:电平、时序、寄存器位。停在比喻那一层,等于没学。
课程地图
整条路线可以看成一段上山的路,每一站都解锁后面要用的能力。
先认人和认工具,把硬件心智模型立起来,顺手把 C 语言里那点硬件要用的东西补齐。然后搭工具链,把"源码到芯片"这条闭环跑通。接着啃启动、链接、内存和时钟,搞清程序为什么能从复位进 main、能跑多快、变量落在哪。这三段是地基,地基不牢,后面每个外设都会晃。
地基打好进 GPIO、中断、串口和时间。GPIO 是单片机的手,是第一次把"写地址"和"变电平"亲手连起来。中断把 CPU 从轮询的忙等里解放出来。串口给单片机一张嘴,更给我们一双看调试输出的眼睛,串口拿到手之后,后面每个外设都会好调很多。SysTick 和看门狗给系统节拍和自愈能力,定时器把精确时间和波形发生器交到我们手上。这几样凑齐,就算入门了。
再往上走 ADC、DMA、I2C、SPI 和内部 Flash,把"采样、搬运、处理、保存或发送"这条数据链跑通。然后是异常和 HardFault、低功耗、串口 IAP,让系统从"能跑"走到"能诊断、能保存、能恢复、能升级"。最后是 FreeRTOS,看它怎么复用前面学过的异常、双栈和 SysTick/PendSV 去实现调度,再用一个规模受控的综合实践把全部能力收口。
P0 课程准备与硬件心智模型
P1 工具链与最小工程
P2 启动、链接、内存与时钟
P3 GPIO、通信、中断与时间
P4 ADC、DMA、I2C、SPI 与 Flash
P5 异常、低功耗与启动升级
P6 FreeRTOS 单核移植与调度观察
P7 课程综合与收束P0:课程准备与硬件心智模型
这一段的目标,是让学习者知道自己要学什么、怎么查资料、怎么安全地把 Blue Pill 接起来,并在脑子里立起"单片机是一台计算机"这层认识。
先分清层级。ST 是厂商,STM32 是产品线,F1 是系列,F103 是子系列,C8T6 是具体型号。Cortex-M3 是 ARM 设计的 CPU 内核,STM32 是 ST 在这个内核外面加了一堆外设拼出来的芯片。这层关系搞不清,连"出了问题该查哪本书"都不知道:内核的行为查《Cortex-M3 权威指南》,外设寄存器查 RM0008,电气极限查数据手册。这三本文档各有分工,参考手册讲功能,数据手册讲极限,权威指南讲内核。往后每一章遇到问题,都要回到它们里面找答案,而不是靠搜索引擎碰运气。
Blue Pill 的硬件全貌要摸熟。64KB Flash、20KB SRAM、72MHz、3.3V 供电。复位、BOOT0、SWD 的四线、USART1 的引脚位置,心里要有数。板载只有一盏 PC13 的 LED,而且是低电平点亮,这点和很多教程相反,第一次照抄别人的点灯代码常常就卡在这里。还有一个坑:Blue Pill 上的 micro-USB 接的是芯片的 USB 外设,不是串口,想用串口得另接一根 USB-TTL。BOOT0 跳线也要留意,烧录时拨到 1 进系统存储器的 bootloader,运行时拨回 0 从 Flash 启动,跳错了就会出现"代码下进去了但板子没反应"。
C 语言里那点硬件要用的东西,单独拎出来补,不能含糊。整数类型为什么不用 int 而用 uint32_t,因为寄存器宽度必须精确,int 的宽度会随编译器和平台变。位操作是寄存器编程的母语,置位、清零、读位、写字段,这四个惯用法要练到不假思索。指针怎么指向寄存器,结构体怎么把一串连续的寄存器封装起来,#define GPIOA ((GPIO_TypeDef *) 0x40010800) 到底在说什么。宏给地址和掩码起语义名,条件编译用来跨板跨容量。还有 volatile,它告诉编译器这个变量随时会被硬件改,别优化掉。漏写 volatile 是 release 模式莫名失败的元凶,代码在 debug 下好好的,一开优化就废了。这些不过关,后面每一行寄存器代码都像看天书。这部分用 Host 练就够了,不需要硬件:做位掩码练习,用结构体加指针模拟一段寄存器读写,再故意漏掉 volatile,对比 -O0 和 -O2 下编译器生成的指令。
最后是 3.3V 逻辑、电源和共地。LVCMOS 电平,除了少数标注 FT 的引脚,不能直接接 5V 信号。外设和主控必须共地,否则信号再对也读不到。上拉下拉电阻什么时候要用。这些听起来琐碎,但电源和接地不对,后面信号层面再怎么调都白搭。
这一段走完的标志,是学习者能说清 CPU、存储器、总线和外设的关系,能从官方文档里翻出后续实验要用的信息,C 语言那几个惯用法也练到位了。
P1:工具链与最小工程
目标是把从源码到芯片这条闭环亲手跑一遍:C 源码、编译、链接、ELF 和 BIN、烧录、运行、调试。
C 源码 → 编译 → 链接 → ELF/BIN → 烧录 → 运行 → 调试从 Arduino 或纯软件转过来的人,容易把装工具链当成"下一步下一步我同意"的事。在嵌入式里,工具链每一环都可能是个坑:编译器版本不对,代码跑飞;驱动装错,下载器变砖;WSL 里访问 ST-Link 还得处理 USB 透传和 udev 规则。这一步跳过,后面调试时"下载器连不上、代码烧进去没反应"会吃掉一半时间。所以 P1 不打仗,先磨刀。
ARM GCC 是交叉编译工具链,arm-none-eabi-gcc 那一套。CMake 负责 configure、build 和 target 三步,交叉编译要指定 target 和工具链文件。生成的产物各有用途:ELF 带调试符号,是给 GDB 用的;BIN 是纯二进制,给烧录器;HEX 带地址信息,工业上常用;MAP 是符号和段布局的"体检报告"。Blue Pill 只有 64KB Flash,不看 map 就不知道还能不能再塞一个模块。读 map 用 binutils 那套:size、nm、readelf、objdump。
烧录用 OpenOCD 配 ST-Link,走 SWD 的四线。OpenOCD 的 target 配芯片、interface 配调试器,program、verify、reset、halt 这几条命令要会用。烧录的本质就是通过 SWD 写 Flash,理解了这一层,脱离 IDE 的下载按钮才不会慌。调试用 arm-none-eabi-gdb 连上 OpenOCD,断点、单步、查变量、查内存、查寄存器。第一次分别断在 Reset_Handler 和 main,看看 PC、SP、xPSR 和一段 SRAM 长什么样。会 GDB,后面调 HardFault 才有上帝视角,不会就只能重启瞪眼。
实验就编译一个只有启动加死循环的最小工程,生成 ELF、BIN 和 MAP,用 OpenOCD 烧进去校验复位,用 GDB 断点单步。这一段走完的标志,是学习者能在 Blue Pill 上独立完成编译、烧录和调试,不依赖 CubeMX 也不依赖某个特定 IDE。
P2:启动、链接、内存与时钟
这一段回答几个"为什么"。程序为什么能从复位进 main,代码和变量是怎么进到 Flash 和 SRAM 的,系统时钟怎么驱动 CPU 和外设。
先看 Cortex-M3 的寄存器组和栈。R0 到 R15,MSP 和 PSP 两个栈指针,xPSR,CONTROL,Handler mode 和 Thread mode 的区别。这些现在看着抽象,但到 P6 讲 FreeRTOS 任务切换的时候会全部用回来,任务切换就建立在 PSP 和 MSP 之上。
然后是 4GB 地址空间和 STM32F103 的存储器映射。Flash 在 0x08000000,SRAM 在 0x20000000,外设在 0x40000000。总线分 AHB 和两条 APB,APB1 上限 36MHz,APB2 上限 72MHz。把高频外设挂到 APB1 上会直接超频死机,这是常见坑。
向量表是上电到 main 之间那段黑盒子的入口。向量表头两项是初始 MSP 和 Reset_Handler 的地址,复位时硬件自动从 0x00000000(重映射到 Flash)把这两项读出来。这两项写错,上电瞬间就死。Reset_Handler 干的事情很具体:把 .data 从 Flash 搬到 SRAM,清零 .bss,调用 SystemInit,跳进 main。全局变量的初值从哪来?.data 的初值存在 Flash 里,启动时搬到 SRAM,.bss 只在 SRAM 里清零。程序为什么能跑,答案就在这里。
GNU 链接脚本决定代码放哪、栈多大、堆多大。MEMORY 定义 Flash 和 SRAM 区域,SECTIONS 描述 .isr_vector、.text、.rodata、.data、.bss 怎么摆,栈和堆要预留。64KB Flash、20KB SRAM 的板子上,栈和堆的预算是硬约束,直接关系到 P6 能不能塞下 FreeRTOS。
时钟在这一段讲透,但要注意,时钟在课程里会出现两次,头一次在 P3 点灯的时候,那时候只学"用哪个外设就开哪个时钟",把它当成外设的入场券。这一段是第二次,讲完整的时钟树。HSI 是内部 8MHz,启动快但不准,是模板工程的默认时钟源,经 PLL 到 64MHz,好处是不依赖外部晶振;HSE 是外部 8MHz 晶振,准,但廉价 Blue Pill 常常没贴或不起振,得先用 MCO 或定时器确认它真的在跑,确认后才能经 PLL 上到 72MHz 当 SYSCLK。AHB 和 APB 怎么分频,外设时钟怎么使能。还有 Flash 的 wait state,跑 72MHz 就要配两个等待周期,不配就会取指出错、随机崩溃。坑最集中的就是时钟:忘开外设时钟,外设完全没反应;Flash latency 没配,72MHz 下随机死机;把 72MHz 硬灌给 36MHz 上限的 APB1,也是超频。
实验是单步跟踪复位到 main,在复位前后观察 .data 和 .bss,改全局变量预测 map 变化,直接手算一个外设寄存器地址和 CMSIS 定义对照。先用 HSI 跑通,确认板子晶振后配 HSE 加 PLL 到 72MHz,用 MCO 或者定时器测时钟验证。这一段走完的标志,是学习者能解释启动文件、链接脚本、芯片内存和系统时钟之间的关系,而不是把它们当成模板里几个不能动的固定文件。
P3:GPIO、通信、中断与时间
这一段集中拿下入门要用的几样能力:输入输出、通信、中断和时间控制。
GPIO 输出
GPIO 是单片机的手,第一次点灯是把"写一个地址"和"引脚电平翻转"亲手连起来,也是建立"外设就是内存映射寄存器"这层心智的入口。配置 GPIO 第一步是开它所在端口的时钟,这一步漏掉,后面代码再正确也没反应,外设根本没上电。然后是 CRL 和 CRH,每四个位描述一根引脚的模式和输出速度,推挽还是开漏也要在这里选。翻转电平用 ODR,但更顺手的是 BSRR,它一次只动指定的位,是原子操作,不用操心读改写的竞争。Blue Pill 上只有 PC13 一盏灯,低电平点亮。实验先只用寄存器点灯,再用 HAL 做同样的事,最后用 BSRR 体会原子置位和复位。
GPIO 输入与按键
输入端要分清浮空、上拉、下拉和模拟输入,读引脚用 IDR。按键的麻烦在机械抖动。按一下,触点会弹跳几十次,不处理就会出现"按一次灯亮,再按想关,灯反而更亮或乱闪"的诡异现象。软件消抖要用状态机来做,这部分逻辑在 Host 上能测,不用占硬件。实验是轮询读按键、Host 测消抖状态机、按键控制 LED。
EXTI 与 NVIC
到这里从轮询走向事件驱动。EXTI 是外部中断,AFIO 负责把 PAx、PBx 这些同名引脚路由到同一条 EXTI 线上。选上升沿、下降沿还是双边沿触发,pending 标志怎么看,NVIC 怎么使能、优先级怎么分抢占和子优先级。这里有个原则要立住:中断服务函数要短,消抖和业务逻辑都得移出 ISR,ISR 只做"标记发生了,然后走"。坑也不少。忘开 AFIO 时钟,EXTI 路由会静默失效,配置都对就是触发不了。EXTI15_10 这六条线共用一个中断号,进了一个 handler 要在里面判 pending 分辨到底是哪根。不消抖的话,一次按压触发几十次中断。实验是按键边沿触发中断,观察 EXTI pending 和 NVIC 状态。走完的标志是能说清抢占优先级和子优先级的区别,能把 ISR 写得短小干净。
USART
串口是单片机的嘴和耳朵。把它放在定时器前面学是有意为之。拿到串口就拿到了 printf 这双眼睛,后面每个外设调试都会轻松一个量级。要理解波特率和时钟的关系,TX、RX、状态标志 TXE 和 RXNE、数据寄存器怎么用。先轮询收发,再上 RXNE 中断,配一个环形缓冲区。串口日志和 printf 的代价也要讲清楚:_write 怎么 retarget 到串口,为什么不能在 ISR 或高频路径里 printf(会阻塞),半主机模式没关也会卡死。波特率算错或分频寄存器写错,收发全是乱码,这是最常见的坑。实验是发固定字符串、串口回显、中断接收、Host 测行缓冲和命令解析,再做 HAL UART 对照。
SysTick 与软件时间
让一个 72MHz 的核心停下来 while 等时间,是浪费算力。SysTick 给系统一个节拍,是非阻塞状态机的基础。CTRL、LOAD、VAL 三个寄存器,tick 怎么累加,阻塞延时和非阻塞状态机的区别,计数器溢出怎么处理。PSC 和 ARR 都是 N+1 分频,少写一个加号就差一档,ISR 里忘了清 UIF 中断会连续触发停不下来。实验是寄存器实现毫秒 tick,对比忙等、HAL_Delay 和非阻塞闪烁,在 Host 上测 tick 溢出。
看门狗
看门狗是系统的自愈能力,死机后能自动复位而不是永久卡死。IWDG 是独立看门狗,由 LSI 驱动;WWDG 是窗口看门狗,有窗口概念。喂狗、超时、复位来源要搞清。实验是正常喂狗、故意停喂、复位后读出并报告复位原因。
定时器
定时器是精确时间和波形的发生器。PSC、ARR、CNT 三件套,更新事件 UIF,输出比较,PWM,输入捕获,TIM1 这个高级定时器和通用定时器差在哪。呼吸灯、测脉宽、硬件节拍,这些只能靠定时器,软件循环做既不准又费 CPU。APB1 上挂的定时器有时钟倍频(36MHz 总线喂出 72MHz 定时器时钟),这点容易算错。实验是 TIM2 周期中断、非阻塞闪烁、PWM 呼吸灯、输入捕获测脉宽或周期,再做 HAL TIM 对照。
这一整段走完,学习者要能写出一个由中断和时间状态机驱动的串口交互程序,并解释每一条输入输出链路经过了哪些寄存器和硬件模块。
P4:ADC、DMA、I2C、SPI 与 Flash
这一段把数据采集、自动搬运、同步总线和非易失存储凑齐,看 MCU 怎么跟外部器件交换信息。
ADC 看着简单,不就是读个电压。但在生产环境里要拿到一个稳定可信的读数,是一个关于时钟、采样、中断和 DMA 的系统设计问题。ADC 时钟、输入通道、采样时间、转换序列、校准、量化、参考电压,这些概念要过一遍。采样时间不够,高阻源读数会偏小;输入超过 Vref 会损坏 ADC。实验是电位器单通道采样,原始值换算成电压,对比不同采样时间的影响,再做 HAL ADC 对照。
DMA 是解放 CPU 的搬运工。外设地址和内存地址、传输方向、数据宽度、普通和循环模式、半传输和传输完成中断、缓冲区归谁所有。ADC 连续采样、串口不丢字节,全靠 DMA;不学它,高吞吐场景下 CPU 全耗在搬数据上。最大的坑是缓冲区所有权:CPU 和 DMA 同时改一段内存,数据就乱了。实验把 ADC 轮询和 ADC 加 DMA 放在一起对照,再做循环采样和半缓冲、双缓冲处理。
I2C 和 SPI 是跟外部芯片对话的两条主流总线。I2C 是开漏加 上拉,靠 START、STOP、地址、读写位和 ACK、NACK 组织一次事务,可以先 bit-bang 再用硬件状态机,总线卡死要会恢复。忘加上拉电阻,开漏总线根本拉不起来。SPI 快一些,SCK、MOSI、MISO、CS 四根线,主从、CPOL 和 CPHA 四种模式、全双工移位。CPOL 和 CPHA 跟从设备对不上,读到的数据全是错位的。实验先用 GPIO 产生 START、STOP 和一个字节,用逻辑分析仪看事务,再用硬件 I2C 访问 EEPROM;SPI 做回环、对比不同模式、读外部 Flash 的 JEDEC ID,各自再做 HAL 对照。
内部 Flash 解决掉电要保留的参数。Flash 的规矩是必须先擦后写,擦除粒度是页不是字节,不擦就写会写不进去,误擦相邻页又会丢别的数据。解锁、忙状态、错误标志怎么处理,参数区怎么规划,记录格式、版本和 CRC 怎么设计才能掉电恢复。实验是写一个参数块再读回,处理空白、有效、CRC 错、版本错这几种记录,记录编码和 CRC 在 Host 上测。
这一段走完,学习者要能跑通一条"采样、搬运、处理、保存或发送"的数据链,并从总线波形解释一次 I2C 或 SPI 事务。
P5:异常、低功耗与启动升级
到这里,系统要从"能运行"走到"能诊断、能保存、能恢复、能升级"。
异常和 HardFault 是 P2 那些启动和栈知识的直接回收。Handler mode,异常栈帧(硬件自动压栈的那八个寄存器),SCB、CFSR、HFSR、BFAR、MMFAR 怎么读,怎么从压栈的 PC 和 LR 还原出故障指令。不学这个,死机就只能重启瞪眼。实验是故意做未对齐或非法地址访问,调用一个损坏的函数指针,然后从异常栈定位故障指令。走完的标志是从 CFSR 和压栈的 PC 能看出是哪条指令崩了、什么类型的错。
RTC 和后备域要不要进主线,看 Blue Pill 的 LSE 和后备供电条件。机制教学保留,硬件实验可选。低功耗讲 Sleep、Stop、Standby 三种模式,WFI 和 WFE,唤醒源,时钟怎么恢复。要诚实说明 Blue Pill 的外围电路(稳压器、USB、LED)会严重影响实测功耗,所以这部分偏机制教学,不是追求极致微安。实验是进三种模式,用按键、RTC 或外部中断唤醒,记录电流和唤醒过程。
串口 IAP 把前面几样全串起来。Bootloader 和 Application 怎么分区,镜像格式和 CRC,向量表怎么重定位,怎么设 MSP,怎么跳转到应用,坏包和传输中断怎么恢复。这一段综合了 P2 的链接和向量表、P4 的 Flash 和 CRC、P3 的串口。实验是 Host 端写一个固件发送器,串口下载应用,校验后启动新应用,传输中断后还能保留恢复能力。
P6:FreeRTOS 单核移植与调度观察
这一段看 FreeRTOS 怎么复用前面学过的异常、双栈和 SysTick、PendSV,在 Cortex-M3 上实现单核抢占式调度。它是对 P2 的第二次回收。
讲裸机主循环和任务模型的差别,FreeRTOS 内核目录和 Cortex-M3 的 port,FreeRTOSConfig.h 怎么配,任务栈和 MSP、PSP、CONTROL 的关系,SysTick、PendSV、SVC 各自的角色,上下文怎么保存和恢复,中断优先级和 configMAX_SYSCALL_INTERRUPT_PRIORITY 的边界。20KB SRAM 下的栈、堆和静态分配预算要精打细算,这是 Blue Pill 的硬约束。队列、任务通知、互斥怎么在板上观察,ISR 怎么唤醒高优先级任务。
FreeRTOS 的通用概念和 Host 实验不在 ST-Forge 里重复,由 Tutorial_FreeRTOS 提供。ST-Forge 只管上板过程和硬件观察。实验是两个任务交替运行,用 GPIO 或逻辑分析仪看上下文切换,输出任务栈水位和剩余堆空间,UART RX 中断通知解析任务,再观察一次 ISR 导致的任务抢占。走完的标志,是学习者能从 PendSV 异常和任务栈解释一次上下文切换,能在 20KB SRAM 限制下设计一个简单的多任务程序。
P7:课程综合与收束
最后用一次规模受控的综合实践,把前面所有能力收口,不在结尾突然引入一批新模块。
综合实践至少要覆盖 GPIO 输入输出、UART 交互、中断、非阻塞时间状态机或 FreeRTOS 任务、参数检查与错误处理、内部 Flash 参数保存、GDB 和 HardFault 调试、Host 测试、micro-forge 支持范围内的仿真,以及 STM32F103 真板验收。默认方向可以是一个串口控制终端,但最终题目等 P6 完成后再定。综合实践的目标是课程验收,不是做个宣传用的花架子。
走完的标志,是学习者能独立完成需求拆分、硬件连接、模块实现、调试、验证和结果说明,并清楚哪些行为只能由真板确认。
验证分工
每一层验证负责自己那一摊,不能越界代劳。
Host 负责硬件无关的逻辑。消抖状态机、环形缓冲区、命令和协议解析、CRC 与记录格式、IAP 传输状态机、业务状态机,这些都能在主机上跑测试,不依赖芯片。
micro-forge 负责它支持范围内的 STM32F103 行为:Cortex-M3 启动与指令执行、NVIC、SCB、SysTick、RCC、GPIO 的 A、B、C 端口、USART1、TIM2、AFIO 和 EXTI。ADC、DMA、I2C、SPI 和真实 Flash 擦写这些,在 micro-forge 还没实现的时候不能标记成仿真通过。
真板是最终裁判。SWD 连接、烧录和 GDB 调试,实际的 GPIO 电平和板载 LED 极性,UART 波特率与线路,中断边沿和机械按键,PWM、输入捕获和总线波形,ADC 精度与噪声,DMA 外设请求,I2C 和 SPI 器件通信,Flash 擦写和掉电保持,RTC、低功耗、电流和唤醒,IAP 恢复,FreeRTOS 板上调度,这些只能由真板确认。没有真板记录的能力,不能写成"已验证"。
与其他仓库的关系
| 仓库 | 职责 |
|---|---|
| ST-Forge | 课程、最小实验、Blue Pill 工程、HAL 对照和真板验证 |
| micro-forge | 已支持 STM32F103 能力的仿真、追踪和可观测性 |
| BareMetal-Drivers | 可复用的器件、协议和生产型驱动资产 |
| Tutorial_FreeRTOS | FreeRTOS 通识、Host 模拟和内核原语教学 |
ST-Forge 里的寄存器实验服务于教学,可以故意写得直接、简单、低效。成熟可复用的驱动应该进 BareMetal-Drivers,而不是在两个仓库各养一份。
远期选修
下面这些内容,等主线稳定、硬件条件明确、不会开并行实现线的时候再评估是否纳入:OLED 显示与菜单、RTC 完整板上实验、红外遥控、DS18B20 和 DHT11 这类单一传感器、CAN 与 RS485、SD 卡与 FATFS、USB Device、其他 STM32F1 容量和封装、现代 C++ 寄存器抽象。
Blue Pill 不具备或不适合做主线的那些,比如 DAC、FSMC LCD、触摸屏、摄像头、外部 SRAM、手写识别,不纳入当前课程。对于STM32F103C8T6而言,太吃力了。