前几天行业群里有人转了一条消息,飞凌嵌入式联合北京大学出版社出了本新书《嵌入式Linux系统开发21天速成》。说实话,第一眼看到“21天”这几个字,我是有点条件的——毕竟干这行快十年了,见过太多人拿着“XX天精通”的书学了两周就放弃。但飞凌这家做嵌入式板卡的老牌厂商,和北大社这个组合本身就有一定的说服力,再加上这两年Rockchip、NXP平台的项目需求明显变多,我觉得有必要以这本书为引子,把嵌入式Linux开发这条学习路径、实操要点、以及那些书里未必会写透的坑,认认真真梳理一遍。
这篇文章不是什么书评,也不是广告。我想从一个常年带着团队做嵌入式项目的从业者角度,聊聊嵌入式Linux到底是什么、怎么入门最稳、环境怎么搭、项目怎么做、面试怎么准备,以及这套知识体系里哪些东西是真正值钱的。无论你是刚准备转行入坑的新手,还是已经写了几年单片机、想往更高一层走的老工程师,这篇文章应该能给你一些实在的参考。
1. 新书切入点:为什么嵌入式Linux值得认真学一把
1.1 从热搜词看行业风向
先看几个跟这本书关联度很高的热词:嵌入式linux驱动开发、嵌入式linux学习路线、嵌入式linux面试题、rockchip yocto系统开发、arm-linux嵌入式系统开发综合应用题。这些词背后反映的需求非常明确——市场对“能写驱动、能调系统、能带项目”的嵌入式Linux开发者的渴求程度,已经远远超过了会点单片机的人。
我自己的感受是,这几年消费电子、工业控制、智能座舱、边缘计算设备,底层几乎全部跑着Linux。哪怕你做的产品只是一个小小的数据采集终端,客户也会问一句“能不能跑Linux”。原因是Linux生态太成熟了:网络协议栈现成的、文件系统现成的、图形界面有Qt和LVGL、AI推理有RKNN和NNAPI。你不需要像裸机开发那样什么都从零写,系统本身帮你把底层大量脏活累活干完了。
也正因为这样,嵌入式Linux开发者的薪资天花板明显高于传统单片机工程师。这不是说单片机没前途,而是两者的技术栈深度和覆盖范围不在一个量级上。懂Linux、懂内核、懂驱动、懂ARM体系结构的人,在项目里往往一句话就能决定一个方案的可行性,这种不可替代性直接反映在招聘市场上。
1.2 “21天速成”的真实含义
很多新手一看到“速成”两个字就兴奋,觉得21天就能从零变大神。我先把这话说清楚:21天速成,速成的是“上手路径”和“知识框架”,不是“技术深度”。就像学驾照,21天你可以拿到驾照独立上路,但你就是成不了赛车手。
这本书定位的其实就是“带你上路”的阶段。它不会让你21天变成内核专家,但能让你搞明白:Linux系统是怎么在ARM芯片上跑起来的、U-Boot是什么角色、内核和设备树什么关系、根文件系统怎么构建、驱动框架长什么样。这些知识一旦形成体系,后面你深入任何一个方向——字符设备驱动、网络驱动、GPU/ISP驱动、RISC-V移植——都有了地图。
我特别认可这种“以开发板为载体、以项目为驱动”的写作方式。飞凌作为板卡厂商,手里有大量真实的平台资料和案例,写出来的东西不会像某些纯理论书那样飘在空中。你要是配合一块他们家的开发板边学边练,效果会非常明显。
1.3 谁适合读这本书、按什么节奏读
我大致把读者分成三类:
第一类,单片机工程师转嵌入式Linux。这类读者已有C语言和硬件基础,缺的正是操作系统的抽象思维和Linux工具链的使用经验。21天节奏对这类人很友好,建议重点啃U-Boot、内核编译、根文件系统、设备树这几章,入门后直接往驱动方向走。
第二类,应用层程序员想下沉做系统。这类读者懂Linux用户态编程,但对硬件、交叉编译、ARM体系比较陌生。建议先把ARM汇编基础和裸机开发补上,再看这本书时关注底层是如何对用户态提供服务的,理解“文件”这个概念在Linux内核中是怎么抽象所有硬件设备的。
第三类,在校学生。你们时间最充裕,反而容易走弯路——今天看Android系统开发路线,明天听说Java+分布式系统开发赚钱就转Java,后天又觉得嵌入式Linux有意思。这本书最大的作用就是帮你把路线固定下来,先扎进去学完一遍,再决定未来方向不迟。
我个人给学生的建议是:不要贪多,每天保持3-4个小时连续学习,上午看书敲代码,下午对着开发板做实验,晚上整理笔记和报错记录。21天周末不休息,基本能把书里的主线内容过一遍,这个节奏比断断续续学半年要高效得多。
2. 学习路线整体设计:从点灯到综合应用的四阶段递进
2.1 第一层:ARM体系结构与裸机基础
很多人直接跳过这颗跳板去学Linux,结果卡在“内核启动后控制台没输出”这类问题上无从下手。你连ARM芯片的启动流程都不清楚,怎么理解U-Boot在做什么?连寄存器和MMU都不了解,怎么理解内核里那些内存相关的代码?
ARM体系结构这块,重点要掌握的是这几个东西:ARM处理器的几种工作模式(USR、SVC、IRQ等)、异常向量表、中断处理流程、MMU和Cache的基本原理、大小端模式、GPIO/中断/定时器这些外设的寄存器操作方式。
我建议大家不管用什么平台,先花几天时间写几个裸机程序——比如用寄存器操作点亮一个LED、用中断实现按键检测、用定时器产生PWM波。不需要写得多漂亮,关键是建立“寄存器—外设—程序”的对应感,这样后面看芯片手册、写驱动的时候才不虚。
补充一点:很多学生喜欢用STM32那种库函数思维去做ARM Linux开发,这是个大坑。在Linux驱动里你基本都是在操作寄存器地址(通过ioremap)、操作设备树节点、操作内核提供的API。如果你连寄存器地图都看不懂,驱动代码对你来说就是天书。
2.2 第二层:Linux系统构建三板斧——U-Boot、内核、根文件系统
这是我常说的“三板斧”,也是嵌入式Linux入门最核心、最硬核的部分。很多人学到这层就开始打退堂鼓,但恰恰是这层决定了你能不能独立搞定一个嵌入式Linux项目。
U-Boot是第一个跑在开发板上的程序,负责初始化硬件、加载内核镜像到内存、传启动参数给内核。你要学会的不只是用它的默认配置编译出一个烧录文件,而是要理解它的启动流程:BL0(芯片内部ROM)→ SPL(如果平台有)→ U-Boot → 内核。然后能根据自己的需求修改启动参数、添加自定义命令、实现网络下载内核等操作。
内核编译相对简单,make xxx_defconfig 然后 make -j8 就完了。难点在于配置裁剪——一个通用内核镜像可能三五十兆,但你的产品Flash可能只有16MB,怎么用menuconfig把用不到的驱动、文件系统、网络协议裁掉,这是真本事。
根文件系统的构建同样是硬功夫。早期大家都是手动用BusyBox做一个最简根文件系统,然后一步步添加库、添加应用程序、配置启动脚本。这个过程极其枯燥,但一次完整跑下来,你对Linux系统启动的每一步(kernel→init→rcS→getty→shell)会有非常直观的认识。后来用Buildroot,就是在这个基础上的自动化集成。
这里多说一句Rockchip平台为什么这几年火。Rockchip在资料开放、SDK完整度、性价比上都做得好,而且在AI边缘计算场景有RKNN Toolkit这种比较成熟的工具链。飞凌基于RK3568、RK3588等平台的板子不少,如果你想用yocto或者Buildroot做一个包含QT、Python、AI推理库的完整系统镜像,跟着板卡厂商的文档走会省很多时间。
2.3 第三层:驱动开发入门——从字符设备开始
驱动这层是嵌入式Linux工程师的分水岭。会写驱动的人,和只会调系统的人,拿到的Offer完全不在一个水平线上。
驱动开发别贪多,先把字符设备驱动吃透。理解file_operations结构体、主次设备号、miscdevice框架、platform总线匹配模型、设备树节点的解析(of_property_read_*系列API)、中断申请与底半部处理机制、ioctl的实现方式。把这些用熟,再去理解platform_driver和device_tree的配套关系,基本就能应对大多数工业项目的驱动需求。
很多人对设备树(Device Tree)非常头疼。我举个生活化的例子:设备树就是一张硬件配置清单,告诉内核“我在哪个地址挂了一个GPIO按键、我在哪个I2C总线上接了一个温度传感器、它的中断信号从哪个引脚进入”。内核本身是通用的,它不认识你的硬件,通过设备树这个“配置文件”识别硬件。所以改设备树不是改功能,而是改“接线图”。
2.4 第四层:综合项目实战——把知识串成面
前面三个阶段的单项知识,只有在项目里才会真正融合。一个典型的嵌入式Linux综合项目,比如“基于RK3568的智慧门禁终端”,它的技术栈包括:交叉编译环境搭建、U-Boot定制、内核裁剪、Buildroot制作根文件系统、Qt/LVGL界面开发、GPIO控制门锁、摄像头采集与RTSP推流、MQTT接入云端。这里面单拿任何一块出来都有现成教程,但整合在一起就考验你的系统思维了。
我看到很多新手刷完几章教程就开始信心满满,觉得“嵌入式Linux不过如此”。等你进入项目阶段,遇到的问题是综合性的:系统起不来、驱动崩溃、网络不通、GUI刷新卡顿、内存不足、AI推理延迟高。你需要同时操作系统知识、硬件知识、应用层知识去定位问题。这个过程就是成长最快的过程。
我也建议新手在找工作时,手里至少要有两个拿得出手的综合项目。面试官问起来,你能讲清楚“我为什么选这块板子、系统怎么做裁剪、驱动遇到什么问题怎么解决、应用层和内核层怎么交互”,这比你把八股文背得再溜都有说服力。
3. 实操要点与核心技术细节
3.1 开发环境搭建:Windows/Linux双系统与交叉编译工具链
来倒腾嵌入式Linux开发,我是强烈不支持在Windows上装个虚拟机就开干的。虚拟机共享目录的IO性能问题、串口/USB透传的稳定性问题、编译大型SDK时的内存开销问题,任何一个都足够让人崩溃。有条件的直接自己在主力机上装Ubuntu或者Debian,双系统也好、单独SSD也好,总之要让Linux跑在裸机上。
交叉编译工具链的选择上,不同厂商偏好不同。有些用arm-linux-gnueabihf-gcc(32位),有些用aarch64-linux-gnu-gcc(64位)。写代码之前先把这几个基本问题搞明白:
- 宿主平台(x86_64)和目标平台(aarch64)的区别
- 动态库和静态库在交叉编译时如何指定路径
- sysroot参数的作用(它告诉编译器去哪里找目标平台的头文件与库文件)
- 同一个工具链版本的glibc与目标系统rootfs的兼容性问题
我举个例子,你在Ubuntu上装了一个aarch64-linux-gnu-gcc,用它编译了一个参考了本地头文件的程序,直接拷贝到开发板上一运行,报“No such file or directory”。你拿file命令一看,程序明明是aarch64架构的,怎么会找不到呢?其实十有八九是动态链接器路径不对,或者链接到的库版本比板子上的glibc新。这种问题排查起来很耗时,但遇到一次你就记住了。
3.2 U-Boot编译与烧写:不同启动介质下的注意事项
在RK3568平台上,U-Boot的编译常用make rk3568_defconfig这样方式。编译之前建议先确认几个信息:DDR颗粒型号与容量、启动介质是eMMC还是SD卡还是SPI NOR Flash、是否有安全启动需求。
烧写这块,RK平台一般在maskrom模式下用RKDevTool烧录,也可以进入loader模式。注意不同介质对应的烧录地址是完全不同的——“idbloader”放在0x40扇区、“uboot”放在0x4000扇区、“trust”放在0x6000扇区。很多人板子变砖就是因为这些地址没对上。
NXP平台则会用UUU(Universal Update Utility)这个工具,配合mfgtool(制造工具)镜像,在烧写时可以很方便地把整个系统灌到eMMC里。
这里给大家一个中肯的建议:烧写之前一定备份出厂镜像。不要像我刚入行那样,拿到板子一顿乱试,把原厂系统弄没了,又没有备份,只能花半天时间从官网重新下镜像。备份出厂镜像这个方法,可以救你很多次命。
3.3 内核移植与设备树:从“能跑”到“跑得稳”
内核移植的第一步是让系统“能跑起来”——串口能打印、网络能通、文件系统能挂载。这里的关键是设备树里要有正确的chosen节点(指定内核启动参数)、memory节点(指定内存布局)、以及串口和网卡的节点。
第二步是“跑得稳”——你要根据自己的硬件去裁剪内核配置。这个阶段需要反复使用menuconfig,把不需要的驱动模块直接去掉,把需要的内置(built-in)或模块化(module)理清楚。设备驱动尽量做成模块,方便调试时动态加载,不用每次改代码都重新烧系统。
第三步是“扩展硬件”——添加一个新的外设,比如一个I2C接口的温湿度传感器。你需要做三件事:看懂芯片的数据手册(尤其寄存器地址和时序)、在设备树里新增一个i2c子节点、写一个platform_driver通过i2c-core提供的API读取寄存器。整个过程走一遍,Linux设备模型你会理解得比较透。
反正每次项目评估的时候,我都会问自己一个问题:“默认SDK改动越少,后期维护越轻松”。内核不是不能改,而是要清楚地记录改了什么、为什么改,不然几个月后回过头来看,连自己都忘了当时动了哪里。
3.4 根文件系统制作:Buildroot vs Yocto怎么选
新手阶段,我是不建议一上来就碰Yocto的。Yocto功能极其强大,但学习曲线非常陡,bitbake语法、layer结构、recipe编写、sstate缓存机制,这一套下来没一两个月上不了手。Buildroot的哲学则是“简单直接”,一个menuconfig界面,选择目标平台架构、选择需要的包(busybox、qt、python、openssh等),make一下,几分钟到几十分钟就能生成整个rootfs镜像。
我的建议是:先用Buildroot把一个系统完整跑起来,理解rootfs里到底有什么。等后面你需要做极其复杂的定制——比如多个产品共用一个BSP基线、需要生成几十个工厂镜像、需要严格的license合规管理——再转移到Yocto不迟。
构建rootfs时还有一个容易踩的坑:文件系统的权限和节点。你手动创建的/dev节点、/etc/inittab、/etc/init.d/rcS这些文件的权限设置不对,系统起来后各种奇怪问题。不如一开始就用Buildroot,让它在构建时帮你处理这些细节。
3.5 调试工具与技巧:串口、网络、日志三板斧
嵌入式Linux调试,三分写代码,七分查问题。常用的调试手段我总结了几个层次:
- 串口是最底层、最可靠的调试图口。内核启动日志、驱动打印、应用层printf,都优先从串口看。只要串口还能打印,系统就还没到彻底没救的程度。
- 网络调试是效率最高的方式。通过SSH登录目标板、通过NFS挂载宿主机目录、通过网络传送文件,大大减少插拔SD卡、U盘的次数。
- 日志分析是定位复杂问题的不二法门。内核用dmesg、应用用journalctl或syslog。开启动态调试(dynamic debug)可以让你在不重新编译内核的情况下,动态打开或关闭某个模块的pr_debug输出。
再分享一个实用小技巧:在开发阶段,用NFS挂载根文件系统是个极其爽的做法。你的应用程序和库文件放在宿主机上,开发板通过网络挂载根文件系统启动,修改完代码直接make、直接运行,省掉了反复打包烧写rootfs的巨大时间开销。等调试稳定了再重新生成rootfs烧进eMMC。
4. 综合应用题的应对思路与常见问题排查
4.1 arm-linux嵌入式系统开发综合应用题的答题套路
arm-linux嵌入式系统开发综合应用题,在很多公司的笔试和面试里都是必出的压轴题。这类题不会问你“什么是进程”这种名词解释,而是给你一个场景,要你从系统角度设计解决方案。
比如一道经典题:“在一个基于ARM Linux的工业网关中,需要同时采集多路传感器数据、通过以太网实时上传到云端、并在本地TFT屏上显示数据。请设计软件架构并说明关键实现要点。”
拿到这样的题,我的回答思路是这样的:
- 先分层:应用层用多线程或进程模型,一个线程做数据采集(通过I2C/SPI/ADC驱动接口)、一个线程做网络上传(用MQTT或TCP socket)、一个线程做GUI刷新(用Qt或LVGL)。采集和网络之间用环形缓冲区或消息队列解耦。
- 说清楚实时性:你要指出哪些环节对延迟敏感(比如报警上报),哪些环节可以容忍延迟(比如显示刷新),并说明用什么内核机制保证——比如使用实时线程优先级、用信号量同步,必要时用epoll处理网络I/O避免阻塞。
- 再谈可靠性:掉电保护需要数据持久化到Flash,网络波动需要断线重连和本地缓存,采集线程异常不能拖垮整个进程——用watchdog保证系统级稳定性。
- 最后可以提到性能优化:如果CPU资源紧张,考虑把部分数据预处理放到驱动层或硬件加速器(NPU、DMA)。
这套逻辑说完,面试官基本能判断你是一个有系统观的人,而不是只会调API的代码机器。
4.2 高频问题排查实录:系统起不来怎么办
我把实际项目里遇到频率最高的问题整理了一个速查表,大家可以直接照方抓药。
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| 上电后串口完全无输出 | 电源供电不足、boot引脚设置错误、U-Boot未烧录或烧录地址错误 | 检查电源指示灯、测量核心电压;重新烧录u-boot;确认启动介质切换开关 |
| U-Boot有输出,但内核不启动 | bootargs参数错误、内核镜像损坏、设备树与内核不匹配、DRAM设置错误 | 在U-Boot里printenv看bootargs/machid;重新烧写kernel;ping通tftp后用tftp加载内核验证 |
| 内核启动到一半卡死 | 设备树中某个外设节点初始化超时、驱动probe失败导致panic、rootfs挂载失败 | 打开内核earlycon和DYNAMIC_DEBUG;确认kernel panic最后几行信息;检查root=参数是否指向了正确的分区 |
| 启动后网络不通 | PHY驱动未加载、设备树网口节点GPIO复位脚配置不对、MAC地址全零、vlan配置错误 | dmesg看phy的状态;确认eth0是否存在;ifconfig看MAC地址;用ethtool检查速率与协商状态 |
| 运行时反复重启 | watchdog未喂狗、内核panic触发重启、电源芯片欠压 | 查看重启原因寄存器、kmsg日志;检查pmic状态和电压纹波 |
排查系统启动问题,最核心的思路是利用二分法定位。比如“内核启动一半卡死”,你先用earlycon把输出打开,看到底是走到哪个驱动的时候停的,而不是在U-Boot里瞎按一串命令。有了打印日志,问题就缩小了一大半。
4.3 面试中常见的嵌入式Linux问题清单
再给正在准备面试的读者整理一份高频问题清单,每道题背后都对应一个知识模块:
- U-Boot的启动流程分为哪几个阶段?SPL的作用是什么?(考察启动流程理解)
- Linux内核中system.map和vmlinux有什么区别?(考察内核构建机制)
- 什么是设备树?为什么要引入设备树?platform driver和设备树如何匹配?(考察驱动模型)
- 字符设备和块设备的区别是什么?网络设备属于哪一类?(考察设备分类)
- 内核空间和用户空间如何通信?netlink和ioctl各有什么适用场景?(考察通信机制)
- Linux中断处理的上半部和下半部机制为什么设计成两半?tasklet和workqueue的区别?(考察中断处理)
- copy_to_user/copy_from_user为什么不能用直接指针赋值替代?(考察内存管理安全)
- 如何定位内核panic问题?什么是oops信息?(考察问题排查能力)
- Linux内核中一个驱动模块的编译、加载、卸载如何操作?Makefile里面obj-m和obj-y的区别?(考察工程能力)
这些题看着多,其实核心知识点不算多,你用两周时间把每个模块的原理搞懂、在开发板上亲手做一遍,比死记硬背答案要管用太多。
5. 学习节奏与资源建议:再谈这本书该怎么用
5.1 配套开发板的选择:不一定要顶配,但要足够主流
学习嵌入式Linux,开发板是绕不开的投入。我建议新手不要追求顶配,选一块主流的、资料丰富的板子就够了。主流平台的好处是社区资料多、问题好搜、厂商技术支持跟得上,学习体验会顺畅很多。
飞凌的OK3568-C、OK3588-C这些板子在工业级设计上比较扎实,配套的文档和源码也相当完善,配合他们新出的这本书边看边练是很顺的路径。如果你预算有限,一些国产低价开发板也不是不行,但要注意资料体系的完整性,别光看价格便宜,拿到手发现设备树源码都没配套齐全,学习时间全耗在找资料上。
我个人建议的学习硬件搭配:一块主流ARM开发板+一个USB转串口模块+一根网线+一块面包板和若干传感器模块。整套下来控制在几百到一千多块,性价比很高。
5.2 21天时间规划表:从第一天的装环境到最后的综合实验
按照这本书的编排思路,我帮你画一个合理的时间分配参考:
- 第1-3天:搭建开发环境,Linux基础命令补齐,熟悉交叉编译流程,让你的第一个Hello World在开发板上跑起来。
- 第4-5天:复习ARM体系结构与裸机编程,重点理解中断和寄存器的操作方式。
- 第6-8天:U-Boot编译与烧写,理解启动流程,尝试修改默认环境变量。
- 第9-12天:内核配置、编译、设备树修改,跑通内核启动,看到完整启动日志。
- 第13-15天:制作根文件系统(建议先手动BusyBox后Buildroot),让系统独立启动。
- 第16-18天:字符设备驱动开发,完成LED驱动、按键驱动(中断方式)、定时器驱动。
- 第19-20天:完成一个综合性实验,比如web服务器+传感器采集+远程控制。
- 第21天:复盘,把之前的所有笔记和代码整理成自己的知识库,写一篇项目总结文章。
这个节奏比较紧凑,但主线非常清晰。如果你能严格按这个节奏走完,最后一两天你会发现自己已经能独立完成很多基础的系统裁剪、驱动开发工作了。
5.3 学习过程中一定要避开的几个认知误区
第一个误区是“多而浅”。今天学一下Android系统开发路线,明天看Java+分布式系统开发,后天翻翻嵌入式Linux驱动开发。知识没有任何一条能形成闭环。我见过太多这样的学生,简历上写了一堆“熟悉”,面试一深挖就露馅。
第二个误区是“只读不做”。嵌入式Linux是一门实践性极强的学问,书里的代码如果不敲到自己的板子上、不亲手编译、不亲手烧录、不亲眼看到运行效果,那你对它的记忆只会停留在“眼睛会了”的层面。做一遍,胜过读十遍。
第三个误区是“遇到问题就换方向”。嵌入式Linux学习过程一定会遇到那种让人绝望的问题,比如内核解压后就panic、驱动一加载就OOPS。这些都是正常的成长痛。真正的高手不是不遇到问题,而是遇到问题有一套定位、拆解、解决的思路。很多人栽在第10天就放弃了,但在第15天你会发现当初那些让你崩溃的问题,现在回头看可能就是个bootargs多了一个空格。
6. 实操心得与长期主义
最后聊点掏心窝子的话。
我做了这么多年嵌入式系统开发,最大的体会是这个行业没有什么“一招鲜”。你永远在追赶新的芯片平台、新的内核版本、新的构建系统。但反过来,核心的知识沉淀是永恒的——操作系统原理、计算机组成、C语言和数据结构、debug的能力。这些东西学会了,不管平台怎么换,你都能快速适应。
飞凌这本书的价值,不在于它能让一个零基础的人21天就变成驱动专家,而在于它给了你一条经过验证的主线路径:基于一块真实的开发板,把系统启动到驱动开发到项目实战的整个链路跑通。有了这条主线,你就知道后面该往哪里发力了。
结合我个人经验,如果你真的打算在这个领域长期发展,我再啰嗦几句:
第一,坚持写工程笔记。好记性不如烂笔头。我从入行就坚持用Markdown记笔记,每隔一段时间整理复盘。到了今天,这些笔记就是我的“第二大脑”,很多项目的解决方案都能从历史笔记里找到灵感。
第二,养成看芯片手册和内核源码的习惯。网上教程再全也只是别人的二手理解,只有datasheet和source code才是第一手真相。自己啃下一份两百页的芯片手册,比看一百个视频教程都长本事。
第三,多分享、多交流。把学习过程和踩坑经历写出来发到社区,不仅是帮助别人,更是逼自己把模糊的知识讲清楚。教是最好的学,这条规律在嵌入式领域尤其成立。
第四,保持对新平台的敏感。RISC-V、Chiplet、异构计算、边缘AI,这些方向都在快速演进。你现在掌握的Linux基础不会白费,它们会成为你进入新方向的坚实台阶。
好了,这篇经验分享就写到这里。希望看到这里的你,可以立刻开一个Ubuntu命令行,敲一句gcc --version,或者打开飞凌这块板子的资料页面,开始你的第1天。等你走完这21天后再回头看这篇文章,感受会完全不一样。