2、STM32平台与开发环境搭建:STM32系列选型、CubeMX与HAL库入门、ARM GCC工具链配置、Makefile与CMake构建系统

好,咱们直接进入正题。做无人机飞控,选对芯片是第一步。STM32这个系列,我这些年摸过的型号少说也有十几种。说实话,不是每一款都适合飞控。你想想看,飞控要实时处理传感器数据、跑姿态解算、还要输出PWM控制电机,这活儿可不轻。

2.1 STM32系列选型:飞控该用哪一颗?

我个人习惯把STM32分成三类:

  • F1系列:经典款,72MHz主频,适合入门级飞控。我在早期做四轴时用过STM32F103,跑个基本的PID控制还行,但要是加上光流、超声波这些外设,CPU就有点喘了。
  • F4系列:飞控主力。168MHz主频,带FPU(浮点运算单元)。说白了,姿态解算里的三角函数、矩阵运算,硬件浮点比软件快一个数量级。我建议新手直接上F4,别在F1上浪费时间。
  • F7/H7系列:高端玩家。400MHz以上,双核都有。适合做视觉导航、VIO(视觉惯性里程计)这类重计算任务。不过,功耗和成本也上去了。

我的选型建议:

  • 入门级飞控:STM32F405RGT6(100引脚,1MB Flash,192KB RAM)
  • 进阶飞控:STM32F427VIT6(带2MB Flash,256KB RAM,支持双精度浮点)
  • 高端飞控:STM32H743(400MHz,1MB RAM,适合跑EKF)

嗯,这里要注意:引脚数不是越多越好。飞控板子通常很小,100引脚已经是手工焊接的极限了。我见过有人硬上144引脚的芯片,结果焊盘间距0.5mm,手一抖就短路了。

2.2 CubeMX与HAL库入门

STM32CubeMX,说白了就是一个图形化配置工具。你点点鼠标,它就能帮你生成初始化代码。我刚开始用的时候也觉得这玩意儿有点「傻瓜」,但后来发现,它最大的价值是帮你避免「漏配置」。

举个例子:你要用SPI读取MPU6050的数据。手动配置的话,你要翻数据手册查SPI时钟极性、相位、分频系数、DMA通道……漏一个,传感器就不干活。CubeMX把这些都可视化,你勾选一下,它自动帮你算好。

我的使用习惯:

  • 先用CubeMX生成工程,然后只保留HAL库的驱动层
  • 应用层代码自己手写,不用CubeMX生成的模板
  • 每次修改硬件配置,重新生成时注意不要覆盖自己的代码

HAL库,全称Hardware Abstraction Layer。它把寄存器操作封装成了函数。比如你要让PA0输出高电平,HAL库写法是:

HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);

而直接操作寄存器是:

GPIOA->BSRR = GPIO_PIN_0;

哪个快?肯定是寄存器快。但哪个好维护?HAL库。我在项目中遇到过一个问题:一个实习生用寄存器操作GPIO,结果忘了配置时钟,查了两天bug。用HAL库的话,CubeMX会自动帮你把时钟打开。

避坑指南:我曾经在飞控的中断服务函数里调用了HAL_Delay(),结果系统直接死机。为什么?因为HAL_Delay依赖SysTick中断,而中断优先级没配好,导致死锁。记住:中断里别用延时函数,用标志位或者状态机。

2.3 ARM GCC工具链配置

ARM GCC,就是一套开源的交叉编译工具链。你写好的C代码在PC上编译,生成的是ARM芯片能跑的机器码。我推荐用GNU Arm Embedded Toolchain,这是ARM官方维护的版本。

安装很简单,去官网下载,解压,然后把bin目录加到PATH里。验证是否装好:

arm-none-eabi-gcc --version

如果输出版本号,就说明成了。

常用的几个工具:

  • arm-none-eabi-gcc:C编译器
  • arm-none-eabi-g++:C++编译器(飞控里很少用)
  • arm-none-eabi-objcopy:生成.bin或.hex文件
  • arm-none-eabi-objdump:反汇编,看生成的机器码
  • arm-none-eabi-size:查看代码、数据、bss段大小

我个人习惯在编译完成后,用arm-none-eabi-size看一眼固件大小。飞控的Flash通常只有1MB,代码要是超了,就得优化或者换芯片。

2.4 Makefile与CMake构建系统

说到构建系统,很多新手喜欢用IDE(比如Keil、IAR)。但做飞控,我强烈建议你用命令行构建。为什么?因为飞控代码通常要跨平台编译,CI/CD(持续集成)也要自动化构建,IDE搞不定这些。

Makefile是最基础的构建工具。它定义了一系列规则:哪些文件要编译、用什么编译选项、链接哪些库。一个简单的Makefile长这样:

CC = arm-none-eabi-gcc
CFLAGS = -mcpu=cortex-m4 -mthumb -O2 -Wall
TARGET = firmware.elf

SRCS = main.c stm32f4xx_it.c system_stm32f4xx.c
OBJS = $(SRCS:.c=.o)

$(TARGET): $(OBJS)
	$(CC) $(CFLAGS) -o $@ $^

%.o: %.c
	$(CC) $(CFLAGS) -c -o $@ $<

clean:
	rm -f $(OBJS) $(TARGET)

嗯,这里要注意:-mcpu=cortex-m4这个参数不能写错。我见过有人用F4芯片,却配了-mcpu=cortex-m3,结果编译出来的代码跑起来各种异常。

CMake比Makefile更高级。它不直接编译,而是生成Makefile(或者Ninja、Visual Studio工程)。对于大型飞控项目(比如PX4、ArduPilot),CMake是标配。

一个简单的CMakeLists.txt:

cmake_minimum_required(VERSION 3.10)
project(Firmware)

set(CMAKE_C_COMPILER arm-none-eabi-gcc)
set(CMAKE_CXX_COMPILER arm-none-eabi-g++)

add_executable(firmware.elf
    main.c
    stm32f4xx_it.c
    system_stm32f4xx.c
)

target_compile_options(firmware.elf PRIVATE
    -mcpu=cortex-m4
    -mthumb
    -O2
    -Wall
)

构建命令:

mkdir build
cd build
cmake ..
make

我的建议:新手先从Makefile入手,理解编译、链接、目标文件这些概念。等项目大了,再切换到CMake。别一上来就搞CMake,容易晕。

2.5 开发环境搭建实战

好,咱们把上面这些串起来,走一遍完整的流程。

  1. 安装工具链:下载GNU Arm Embedded Toolchain,解压到/opt/gcc-arm-none-eabi,配置PATH。
  2. 安装CubeMX:从ST官网下载,安装后打开,选择芯片型号(比如STM32F405RGT6)。
  3. 配置外设:在CubeMX里勾选RCC(外部晶振)、SYS(调试接口)、USART(串口)、SPI(传感器)、TIM(PWM输出)。
  4. 生成代码:选择Toolchain为「Makefile」,生成工程。
  5. 编译:在工程目录下执行make,生成firmware.elf
  6. 烧录:用openocdst-flash把固件烧进芯片。

避坑指南:我曾经在生成CubeMX工程时,忘了选「HAL库版本」。结果生成的代码里,HAL库函数签名和实际库文件对不上,编译报了一堆错。记住:每次生成前,检查一下CubeMX的「Project Settings」-「HAL Settings」,确保库版本一致。

最后,送你一张速查表:

工具 用途 我的推荐
CubeMX 图形化配置,生成初始化代码 必装,省时省力
ARM GCC 交叉编译 gcc-arm-none-eabi-9-2020-q2-update
Make 构建工具 GNU Make 4.x
CMake 高级构建系统 CMake 3.10+
OpenOCD 调试和烧录 0.11.0+

嗯,环境搭建这部分就到这里。下一章咱们开始写真正的飞控代码——从GPIO和定时器开始,一步步把电机转起来。