尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

用VSCode+WSL2编译Betaflight固件:AT32F437DEV实战

用VSCode+WSL2编译Betaflight固件:AT32F437DEV实战 折腾穿越机、玩飞控的兄弟应该都有过这种经历官方固件刷来刷去总觉得差点意思想改点默认参数、想加个自己需要的功能或者手头正好有一块非主流甚至全新的飞控板网上根本找不到现成的固件。这个时候唯一靠谱的做法就是自己动手编译固件。今天我要分享的就是用VSCode加Ubuntu这套组合把AT32F437DEV这块目标板的Betaflight固件从源码一步步编译出来的全过程。这篇内容适合三类人一是想给冷门飞控板编译固件的FPV玩家二是刚开始接触飞控二次开发、想搞懂固件是怎么从代码变成hex文件的人三是纯粹想给电脑配一套稳定的嵌入式编译环境、为以后玩其他MCU项目打基础的人。整个过程不依赖任何图形化IDE全是命令行加文本处理真正跑通一遍以后你会对Betaflight整个项目的组织方式有完全不一样的理解。1. 先聊清楚自编译Betaflight到底在解决什么问题1.1 为什么放着现成固件不用非要自己编译Betaflight官方一般只针对主流飞控板发布release固件比如某些使用STM32F405、STM32F722、STM32H743的常见板子。但飞控圈子发展太快隔三差五就有新的芯片、新的板子冒出来这些板子在官方的release列表里可能连名字都找不到。另外还有一个更实际的需求——定制。官方固件为了兼容性默认启用了一大堆功能白白占用了Flash和RAM。而某些场景下你只需要最小系统、特定传感器、特定串口协议自己编译就能精确裁剪。你还可以通过target头文件里的宏定义调整默认PID、开启或关闭特定功能、给某个串口绑定自己的协议这些都是release版固件做不到的。自己编译还有一个隐藏好处你能看到源码。飞机出问题的时候搜索代码也比凭空猜快得多。比如想确认某个引脚是否复用了PWM输出直接在target目录里一搜便知。这种对底层的掌控感是刷现成固件永远体会不到的。1.2 AT32F437DEV目标板这块板子有什么特殊之处AT32F437是雅特力Artery推出的一款Cortex-M4内核MCU主频最高能做到288MHz相比穿越机圈子里常见的STM32F405168MHz和F722216MHz算力明显高出不少内置Flash和SRAM的规格也属于比较激进的那一档。现在用AT32芯片的飞控越来越多Betaflight在4.5版本之后才正式在主线加入了AT32系列的支持所以如果你手里有一块AT32系的飞控基本只能靠自编译来解决固件来源问题。AT32F437DEV这个target对应的是雅特力官方那类全功能评估板/开发板。这类板子不仅引出了几乎全部IO还带了调试器、LED、按键等外设本身并不是为了飞行而设计的但好在它把MCU的资源都暴露出来了。Betaflight里专门针对这块板子做了一套板级配置我们只要把它当作一个“飞控板”来编译就能编译出一个可以在这个硬件上跑起来的固件。理解到这一层你就知道target文件的含义了。1.3 开发环境选型为什么是VSCode加Ubuntu嵌入式固件编译这件事本质上就是一个“GNU make加交叉编译器”的组合这个组合在Linux下的体验是最顺的没有各种批处理和路径注册表的折腾。Ubuntu作为最常见的Linux发行版装上make、git、arm-none-eabi-gcc三件套就基本齐活了。VSCode在这里扮演的是“统一的编辑器加终端入口”。你可以在Windows里安装VSCode然后通过WSL扩展直接切进Ubuntu环境代码编辑、终端命令行、git提交全在一个窗口里完成不用频繁切换界面。而且VSCode对C语言的支持很好语法高亮、函数跳转、全局搜索都非常流畅看Betaflight源码的体验比用文本编辑器或者虚拟机里的vim要友好太多。这套组合还有一个优点可复用。今天你用这套环境编译Betaflight明天想编译INAV、ArduPilot、甚至ESP32相关的项目都是同一套思路。环境上的投入一次到位后面就是改改make参数的事情。2. 环境搭建第一步把Ubuntu和VSCode跑起来2.1 Ubuntu三选一WSL2、虚拟机还是双系统做嵌入式编译Ubuntu的获取方式大概有三种WSL2、虚拟机、双系统。我最推荐的是WSL2。它本质上是Windows上的一层轻量虚拟化启动速度极快和Windows共享文件系统你编译产生的固件文件可以直接在Windows资源管理器里访问非常方便。安装也简单在PowerShell里执行wsl --install -d Ubuntu-22.04重启后设置用户名密码就能用了。需要注意的是WSL2要求Windows10 2004以上版本或者Windows11。如果你内存在16G以上建议在用户目录下新建一个.wslconfig文件写入[wsl2] memory8GB swap0这样WSL2的内存不会挤压Windows编译时也不会因为内存不足被系统kill掉。虚拟机VMware Workstation Player或VirtualBox的好处是拥有完整的Linux桌面系统对有图形界面需求的人更友好USB直通也方便。缺点是占资源而且文件共享、剪贴板共享偶尔会有小毛病跑大型编译时不够轻快。双系统就不多说了性能最好但切换麻烦日常编译根本用不上除非你还想搞硬件调试之类、对实时性要求极高的场景。综合下来对绝大多数只做固件编译的朋友WSL2就已经完美胜出了。2.2 VSCode安装与WSL环境打通先在Windows下安装VSCode这一步没什么难度官方下载安装包一路Next就行唯一要留神的是安装过程中勾上“添加到PATH”那个选项。装好之后在VSCode里安装两个最关键的扩展Remote - WSL和Remote - SSH。前者可以用来连接本机的WSL后者留给以后连远程Linux服务器。扩展装好后打开VSCode用组合键CtrlShiftP打开命令面板输入WSL: Connect to WSL选择你的Ubuntu发行版VSCode就会重新以WSL模式打开。此时你可以直接打开WSL里边的文件夹比如code ~/betaflight系统会提示你“是否在WSL中打开”接受即可。这套连法最大的好处是你在Windows端编辑文件文件实际存储在Linux文件系统里编译环境在Linux里跑两边无缝衔接。不用担心换行符、权限类型这些在Windows和Linux之间常见的玄学问题。2.3 基础依赖一次性装齐进入WSL的Ubuntu后先把系统基础包刷一遍sudo apt update sudo apt upgrade -y sudo apt install -y build-essential git wget curl cmake python3 python3-pipbuild-essential这个包会把make、gcc、g这些基础编译工具一次性装好后面我们还要单独装ARM交叉编译器这里不用装。git用于拉取源码wget和curl用于下载工具链python3和一些基础脚本在Betaflight的构建过程中可能会被调用顺手装上不吃亏。验证一下基础工具是否就绪make --version git --version能正常输出版本号就说明环境的第一步已经走通了。此时你的Ubuntu环境就像一张白纸接下来要往里面填最关键的内容源码和编译器。3. 源码和编译器编译前的硬准备工作3.1 源码拉取git clone递归与子模块Betaflight的源码托管在GitHub上拉取的时候必须用递归方式因为项目使用了多个git子模块用来存放CMSIS库、驱动代码等等git clone --recursive https://github.com/betaflight/betaflight.git cd betaflight如果在clone的时候忘了加--recursive也别急着删除重来在项目目录下执行这条命令可以补救git submodule update --init --recursive这里要提醒一句Betaflight源码体积不小加上子模块总共有几百兆第一次拉取请确保网络稳定磁盘空间建议至少留出10GB。拉完之后你会看到项目根目录下有src/、make/、tools/等目录。其中src/main/target/是最需要关注的里面每一级子目录对应的就是一个target板级配置比如src/main/target/AT32F437DEV后面要做定制化修改基本都是在这个目录里操作。如果后续要切换版本比如从master切到某个release tag切换之后最好再执行一次子模块更新git checkout 4.5.1 git submodule update --init --recursive不然子模块和主仓库代码版本不匹配编译时容易出现奇怪的错误。3.2 ARM交叉编译工具链安装固件是要跑到MCU上的所以不能用电脑自带的x86编译器必须用ARM EABI交叉编译器。这一块有两个安装思路。第一个思路最简单直接用Ubuntu软件源sudo apt install -y gcc-arm-none-eabi缺点也很明显Ubuntu源里的arm-none-eabi版本往往偏老有时候会跟Betaflight要求的最低版本对不上导致编译过程中报出一些莫名其妙的问题。第二个思路是去ARM官网下载官方工具链推荐10.3-2021.10这个版本这是Betaflight社区验证过比较稳的版本。下载解压后把bin目录加入PATHcd ~ wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/10.3-2021.10/gcc-arm-none-eabi-10.3-2021.10-x86_64-linux.tar.bz2 tar xjf gcc-arm-none-eabi-10.3-2021.10-x86_64-linux.tar.bz2 echo export PATH~/gcc-arm-none-eabi-10.3-2021.10/bin:$PATH ~/.bashrc source ~/.bashrc为了确保工具链生效检查版本arm-none-eabi-gcc --version如果能输出类似arm-none-eabi-gcc (GNU Arm Embedded Toolchain 10.3-2021.10)这样的信息交叉编译器就位。3.3 编译前自检与make体系初识在动手编译之前建议先做一次小的环境自检。除了确认工具链版本之外还要确认一下当前代码所在的分支和版本。正式release一般会打tag比如4.5.0、4.5.1。可以看看手里代码处于哪个版本git tag | grep 4.5 git describe --tags如果发现有新版本想切过去参照上一节说的切分支加更新子模块就行。另外建议花五分钟把根目录的Makefile打开扫一眼。Betaflight的构建规则基本都定义在make目录下的各个mk文件里它会自动检测目标板、交叉编译器、以及一些编译选项。翻一翻这些文件你就能理解为什么整个编译只需要一条make命令也就能明白target名在编译过程中的核心作用。这种“先看规则再动手”的习惯能帮你在后面排错时节省大量时间。到了这一步源码有了、工具链有了、make体系也了解了个大概真正的编译动作就可以上了。4. 编译实操从命令到固件的完整流程4.1 target与编译命令拼接Betaflight的每一个板子对应一个target翻译过来就是“目标板配置”。它决定了这次编译要包含哪些外设驱动、启用哪些功能、使用哪些引脚。我们这次要编译的target就叫AT32F437DEV注意这个名称大小写敏感写错了会直接报target不存在。核心编译命令非常简单一条make加一个TARGET参数make TARGETAT32F437DEV如果你想完整看到底层的编译日志加v1make TARGETAT32F437DEV v1如果是多核机器想要加快编译可以加-j参数但要控制好并行度建议用CPU核心数的一半。比如8核机器用-j4make TARGETAT32F437DEV -j4编译之前可以先查看src/main/target/AT32F437DEV/target.h中的宏定义看看这个板子默认开了哪些功能、有没有你不需要的功能心里有个数。想临时裁剪宏可以在make时追加EXTRA_FLAGS例如make TARGETAT32F437DEV EXTRA_FLAGS-DUSE_SERIALRX_CROSSOVEROFF这种方式适合一次性快速验证真正长期的定制还是要改target.h里的宏定义。4.2 编译过程全流程实录我第一次给这块板子编译时键入命令后心里还挺没底。其实编译会分成好几个阶段首先是检查环境make会用内置的规则检测arm-none-eabi-gcc是否存在、版本是否符合要求接着会进入源码编译src目录下大量C文件会被一个个编译成.o目标文件最后是链接阶段把所有目标文件合成一个固件并生成hex和bin格式的烧录文件。全量编译一次的时间取决于你的CPU性能和并行度一般来说几分钟到十几分钟不等。第一次编译慢一点不要紧重要的是看清楚日志里有没有warning和error。看到最后出现类似Building: obj/main/betaflight_4.5.1_AT32F437DEV.hex这样的信息并且没有error就说明编译成功了。生成的固件在obj/main/目录下文件名里会包含版本号和target名。编译过程中如果改了源码或者改乱了target配置下次编译前记得先清理一下历史产物make TARGETAT32F437DEV clean否则可能因为旧的目标文件残留烧进去的还是老代码。4.3 固件产物与刷写烧录编译得到的hex或bin文件就是可以直接刷进MCU的固件。对普通FPV玩家来说最常用的刷写工具是Betaflight Configurator也就是平时调参和刷固件用的那个图形化软件。刷写流程大致是这样的先连接飞控的USB到电脑在Configurator里选择正确的串口然后切换到“固件烧写”页面选择“从本地文件加载”找到刚才编译出来的hex文件点击“刷写固件”即可。如果飞控没有自动进入DFU模式可以按住板子上的boot按键再插USB或者先在CLI命令行里执行bl命令进入bootloader。这里有一个非常重要的经验在WSL2环境下USB设备直通很麻烦即使配了usbipd-win也不一定稳定。所以我的建议是编译在Ubuntu里做刷写回到Windows的Betaflight Configurator里做各干各的省心又稳定。虚拟机方案则可以直接把USB设备直通进Linux在Linux里刷也一样。如果你是拿这个DEV板做开发验证刷完后通常先看LED是否正常、Configurator能否连接确认系统活着再谈扩展外设。5. 踩坑与排错这些问题我基本都遇到过5.1 高频编译错误对照表速查我把自己和周围朋友在编译Betaflight固件时踩过的高频坑整理成了下面这张表建议收藏错误现象常见原因解决方法arm-none-eabi-gcc: command not found交叉编译器没装或没加入PATH安装工具链并确认~/.bashrc里的export是否生效重开终端gcc: command not found宿主机基本编译工具缺失安装build-essential编译中途Error: L6218E: Undefined symbol工具链版本过旧或过新和代码不匹配更换为官方10.3-2021.10版本fatal error: xxx.h: No such file or directory子模块未拉全执行git submodule update --init --recursive编译到一半提示内存不足被killed并行编译任务过多、WSL2内存太小降低-j并行数扩大.wslconfig内存配置Unknown target: AT32F437DEVtarget名称拼错或代码分支不支持该target确认大小写进入src/main/target/看目录名刷写后飞控黑屏无响应固件target选错、bootloader状态不对重新编译正确的target按住boot进入DFU后重刷这张表每一行背后都是一次真实的熬夜经历。尤其是工具链版本问题最容易让人怀疑人生因为报错信息完全不直接翻遍论坛才发现原来是gcc版本不匹配。5.2 WSL2刷机这个大坑要提前绕开编译完成后最让人搓火的就是刷不进板子。WSL2对USB设备的支持本身就比较弱官方推荐的usbipd-win方案在实际操作中经常遇到设备识别不稳定、驱动冲突、权限不够等问题。对于刷飞控这种事完全没必要在WSL2里死磕。可靠的路线是这样的WSL2里跑编译编译出来的hex文件直接存放在Windows能访问的路径下WSL2的home目录在\\wsl$\Ubuntu-22.04\home\用户名\然后到Windows下调出Betaflight Configurator正常刷写。整个过程不超过两分钟。如果你坚持要在Linux里刷优先考虑虚拟机方案在VMware里给Ubuntu开启USB直通将飞控的USB设备挂载到虚拟机中然后在Linux里使用Betaflight Configurator Linux版本或者命令行工具刷写。相比之下比WSL2稳定得多。5.3 个人实操体会与后续扩展编译Betaflight固件这件事第一次跑通时很有成就感但实际上难点从来不在编译本身而在硬件配置上。如果你不小心改错了target.h里的引脚映射或DMA分配固件能编译出来飞机却完全无法解锁甚至在烧录后黑屏。所以我的建议是初期先别急着改复杂的功能老老实实把官方的target原样编译一遍刷进去确认板子能正常工作再慢慢尝试微调。还有一个小技巧是每次修改前先git status看清当前改动修改完编译验证没问题后立刻git commit做一个存档点。这样哪天改崩了一条git checkout .就能回到之前的可用状态比备份文件靠谱得多。从项目扩展的角度讲这套环境完全可以平滑迁移到其他固件项目。把Betaflight源码换成INAV或者ArduPilot还是同一套make加交叉编译的思路。等你对target配置熟悉了甚至可以为自己的DIY飞控板建立一个新的target那才是真正深度参与飞控开发的开端。我个人的经验是先拿这个AT32F437DEV板练手跑通一次完整流程后面遇到任何芯片、任何飞控板都有底气自己动手解决固件问题。
返回列表