当前位置:首页>Linux>为什么你学 Linux 驱动这么痛苦?因为你缺的不是代码,而是架构路线

为什么你学 Linux 驱动这么痛苦?因为你缺的不是代码,而是架构路线

  • 2026-10-11 07:35:04
为什么你学 Linux 驱动这么痛苦?因为你缺的不是代码,而是架构路线

点击蓝字,关注我们

2026

为什么你学 Linux 驱动这么痛苦?因为你缺的不是代码,而是架构路线

立芯嵌入式|架构学习路线与意义  

写给所有已经会写驱动、会跑 RTOS Demo,但一看 Linux / Zephyr / AUTOSAR 就懵的嵌入式工程师。

01

先问一个扎心的问题

很多同学学嵌入式,前期其实并不慢。

点灯会了,串口会了,I2C、SPI、ADC、DMA 也能调出来。 FreeRTOS 也能跑,任务、队列、信号量、定时器也都知道怎么用。

但一旦进入复杂工程,问题就来了:

  • 为什么项目一大,代码就开始乱?

  • 为什么 BSP、业务、OS、Middleware 越写越耦合?

  • 为什么换一个传感器,改动能一路传到 App?

  • 为什么自己写 RTOS 项目还行,一看 Linux 驱动就像看天书?

  • 为什么 device、driver、bus、probe、file_operations这些东西明明都认识,但组合起来就看不懂?

很多人以为自己卡在 Linux 语法、内核 API、驱动模板。

但我觉得不是。

你真正缺的,是一条从 MCU / RTOS 工程自然过渡到 Linux 驱动架构的学习路线。

更直白一点说:

你不是代码不会写,而是没有理解高手为什么要那样组织代码。

https://www.bilibili.com/video/BV1iBVS6qEbW/?spm_id_from=333.1387.search.video_card.click

02

高手的架构设计,最后都会趋同

我这几年带学员、做项目、拆企业代码,有一个非常强烈的感受:

高手在架构设计上,最后总是趋同的。

不是因为他们互相抄。

而是因为工程复杂度到了一定程度以后,背后的约束是一样的:

  • 业务会变;

  • 硬件会变;

  • 芯片会变;

  • OS 会变;

  • Middleware 会变;

  • 团队会变;

  • 测试、量产、维护、二次开发都会进来。

所以最后大家都会走向同一类设计思想:

分层,是为了隔离变化。抽象,是为了依赖倒置。  对象模型,是为了沉淀语义。  管理模型,是为了让系统不靠人脑硬记。

嵌入式不是不能谈架构。

恰恰相反,嵌入式越往后走,越需要架构。

因为你面对的不是一个函数,也不是一个模块,而是一整个产品系统。

03

第一阶段:先把功能做出来,但别写乱

大多数人刚开始做项目,都会自然形成一个最简单的分层:

  • App

  • Middleware

  • OS

  • BSP / Handler

  • Core / Driver / HAL

这个阶段的核心目标很简单:

先把功能做出来。

比如你做一个智能手表、工业采集终端、温湿度采集 Demo。

App 负责业务逻辑,Middleware 放 LVGL、协议栈、日志库,OS 负责任务调度,BSP 封装外设驱动,底层再调用 STM32 HAL 或芯片原厂 SDK。

这个阶段有没有价值?

当然有。

它适合:

  • Demo 原型验证;

  • 课程入门阶段;

  • 设备数量少、业务简单的项目;

  • 1~2 人快速迭代的小项目。

这个阶段解决的问题是:

代码别写乱。

也就是说,至少你知道 UI 别直接写寄存器,业务别直接碰 HAL,BSP 要把板级外设封一层。

但它的问题也很明显:

只要产品继续变复杂,这套结构很快就会顶不住。

为什么?

因为 App 还是容易碰到底层。 业务逻辑还是容易知道太多硬件细节。 换一个 OS、换一个 BSP、换一个中间件,变化还是会往上层传导。

所以第一阶段够你做 Demo,但不够你做长期产品。

04

第二阶段:从“功能分层”走向“平台抽象”

当项目开始进入产品化,架构就必须往前走一步。

这时候你不能再假设底层是稳定的。

你要反过来思考:

作为 App 的设计者,我应该认为 OS、Middleware、BSP、MCU,甚至芯片平台,未来都有可能被替换。

于是第二阶段就出来了:

App

Service

Platform

├─ platform_mcu

├─ platform_os

├─ platform_bsp

└─ platform_middleware

Impl

Vendor / HAL / FreeRTOS / LVGL / SDK

这一阶段最关键的变化,不是多建几个文件夹。

而是你开始用 Platform Wrapper 去隔离变化。

比如:

  • App 不直接调用 FreeRTOS,而是调用 platform_os;

  • Service 不直接操作 HAL I2C,而是调用 platform_mcu_i2c;

  • 业务不直接知道某个屏幕复位脚,而是调用 platform_bsp_display_reset();

  • LVGL、日志库、安全库,也通过 port / adapter 接入。

这背后其实就是一个工程思想:

依赖倒置:上层不要依赖具体实现,上层只依赖抽象接口。

到了这一阶段,你会明显感觉工程能力变强了。因为你可以:

  • 替换 OS;

  • 替换传感器;

  • 替换板型;

  • 替换中间件;

  • 做 Mock 测试;

  • 做 CI / 单元测试;

  • 做 FCT 制造测试;

  • 做局部插桩;

  • 做日志、诊断、安全密钥等切面能力。

这时候系统已经不只是“能跑”。

它开始具备产品工程的味道。

第一阶段解决的是:

代码别写乱。

第二阶段解决的是:

变化别传导到上层。

05

Service 层到底是怎么来的?

很多人学分层架构的时候,会有一个疑问:

Service 层到底是什么?

是不是为了显得高级,硬加出来的一层?

不是。

Service 层不是凭空设计出来的,它往往是从 App 中沉淀出来的。

比如一开始你在 App 里面写:

  • 电池采集;

  • 低功耗管理;

  • 背光控制;

  • OTA 升级;

  • 存储管理;

  • 诊断日志;

  • BLE 通信;

  • 传感器融合。

刚开始没问题。

但写着写着你会发现,这些逻辑不属于某一个具体业务页面。

它们更像是系统能力。

比如 OTA,不是某一个页面的能力,而是整个设备的升级能力。 比如 battery,不是某一个任务的能力,而是整个系统都需要知道的电源状态。 比如 diagnosis,不是某一个模块的能力,而是产品长期维护必须具备的诊断能力。

所以这些能力就会逐渐从 App 中沉淀出来,形成 Service。

Service 的本质,是把 App 中可复用、可迁移、可长期沉淀的系统能力抽出来。

这一步非常重要。

因为从这个时候开始,你的项目就不再只是“写业务代码”。

你开始建设自己的平台能力。

06

第三阶段:从平台抽象,走向对象模型

第二阶段已经能隔离底层变化了。

但它还不够。

因为系统继续复杂以后,你会遇到另一个问题:

代码层面的隔离够了,但语义层面的管理不够。

举个简单例子。

如果你有 1 个 LED,随便写都行。 如果你有 3 个 LED,封几个函数也能凑合。 但如果你有 100 个设备呢?

有显示屏、触摸、IMU、温湿度、电池、Flash、RTC、蜂鸣器、马达、蓝牙、4G、定位模块……

你不可能靠人脑去记:

  • 哪些设备需要初始化?

  • 哪些设备需要启动?

  • 哪些设备支持读取?

  • 哪些设备需要注入到 Service?

  • 哪些设备依赖 I2C?

  • 哪些设备依赖 SPI?

  • 哪些设备有自己的上下文?

  • 哪些设备有自己的操作接口?

这时候就必须进入第三阶段:

plf_object

├─ plf_device

└─ plf_service

每个对象统一具备:

cfg - 静态配置

ctx - 运行时上下文

data - 当前数据

ops - 行为接口

也就是说,你开始把系统中的设备和服务统一建模。

Display 是一个 device。 Touch 是一个 device。 IMU 是一个 device。 Battery Service 是一个 service。 OTA Service 是一个 service。 Diagnosis Service 也是一个 service。

它们都来自统一的对象基座。

这样做的好处是什么?

系统终于可以被统一管理了。

你可以设计:

device_manager

service_manager

board_manager

然后统一处理生命周期:

register

init

start

process

stop

deinit

这时候工程能力又上了一个台阶。

以前你是“人肉管理模块”。 现在是“框架管理对象”。

以前你是“每个模块自己玩自己的”。 现在是“所有设备和服务都有统一协议”。

所以第三阶段解决的问题是:

系统别靠人脑硬记。

这也是很多嵌入式同学真正缺的能力。

你不只是会写一个驱动,而是能设计一套让很多驱动、很多服务、很多业务长期演进的系统结构。

07

总结

https://www.bilibili.com/video/BV1y4yJBrEok/?spm_id_from=333.1387.search.video_card.click

现在重点来了。

很多同学一看 Linux 驱动,觉得非常抽象:

device

driver

bus

probe

remove

device tree

file_operations

i2c_client

i2c_driver

i2c_adapter

但如果你已经理解了前面的对象模型和管理模型,你会发现:

Linux 并不是突然冒出来的一套天书。

它只是把这些思想做得更成熟、更彻底、更通用。

我们可以做一个对应:

你看,本质是不是一样的?

都是在解决几个问题:

  • 设备怎么描述?

  • 驱动怎么注册?

  • 设备和驱动怎么匹配?

  • 生命周期由谁调用?

  • 硬件资源怎么和驱动解耦?

  • 上层怎么用统一接口访问不同设备?

这就是为什么我一直强调:

你在 MCU / RTOS 阶段把平台化、对象模型、生命周期理解透了,再去看 Linux 驱动,就不是硬背 API,而是在看一套更成熟的工业级答案。

08

以 I2C 为例,Linux 的桥模式其实并不神秘

我们拿 I2C 举例。

在 MCU / RTOS 平台里,你可能是这样设计的:

Service(使用者)

↓

IMU Device(从设备对象,比如 MPU6050)

↓

MPU6050 Driver(BSP 驱动)

↓

I2C Impl(MCU I2C 控制器实现)

↓

I2C Master 硬件控制器

到了 Linux 里面,本质上变成:

User Space APP

↓

i2c_client(从设备对象)

↓

i2c_driver(具体设备驱动,比如 MPU6050)

↓

i2c_adapter(I2C 控制器)

↓

I2C 硬件控制器

再加上 Device Tree 来描述硬件资源。

你会发现,这里面的思想其实是一样的:

  • i2c_client 描述从设备;

  • i2c_driver 描述怎么驱动这个设备;

  • i2c_adapter 描述 I2C 控制器;

  • Device Tree 描述板子上到底挂了什么设备;

  • bus core 负责把 device 和 driver 匹配起来;

  • 匹配成功后调用 probe。

这就是桥模式思想在 Linux 中的体现。

很多人看 Linux 看不懂,不是因为 i2c_driver 太难,而是因为他没有在 MCU 阶段建立过这种“设备对象 - 驱动实现 - 总线控制器”的抽象关系。

所以他只能背模板。

模板一变,就懵了。

09

真正的学习路线,不是从 API 到 API

很多人学嵌入式的路线是这样的:

STM32 HAL

FreeRTOS API

LVGL API

Linux Driver API

Zephyr API

AUTOSAR API

这条路不是不能学。

但如果只沿着 API 学,会很痛苦。

因为每换一个平台,你就像重新开始。

更好的路线应该是:

功能分层

↓

平台抽象

↓

对象模型

↓

生命周期管理

↓

总线模型 / 驱动模型

↓

Linux / Zephyr / AUTOSAR

也就是说,不是从一个 API 跳到另一个 API。

而是从一个架构思想,迁移到另一个更成熟的平台。

你会发现,Linux 有 device model、driver model、bus model。 Zephyr 也有 device model、driver model、devicetree、subsystem、Kconfig、CMake。 AUTOSAR 也有 SWC、RTE、BSW、MCAL、CDD、Complex Driver。

名字不一样,但背后都在解决类似的问题:

如何描述资源?如何隔离变化?如何统一接口?如何管理生命周期?如何让团队协作?如何让系统长期演进?

这才是架构学习真正有价值的地方。

10

架构不是为了炫技,而是为了让系统能长大

我一直不太喜欢把架构讲成一种很虚的东西。

架构不是 PPT 上画几个框。 架构也不是把目录拆得很漂亮。 架构更不是为了显得自己很高级。

架构真正解决的是工程现实问题。

当你只有一个人、一个板子、一个传感器的时候,架构可以很简单。

但当你面对的是:

  • 多板型;

  • 多型号;

  • 多团队;

  • 多业务线;

  • 长期维护;

  • 量产测试;

  • 远程升级;

  • 日志诊断;

  • 安全加密;

  • 供应商替换;

  • 后续 Linux / Zephyr / AUTOSAR 迁移;

你就会发现,没有架构,系统根本长不大。

小项目靠经验,大项目靠结构。  Demo 靠手速,产品靠架构。

真正好的架构,不是一步到位设计出来的。

它一定是随着需求,一层一层长出来的。

第一阶段,不让代码乱。 第二阶段,不让变化往上传。 第三阶段,不让系统靠人脑记。 再往后,才能自然进入 Linux、Zephyr、AUTOSAR 这些成熟平台。

11

最后:为什么高手的架构设计既是哲学,也是艺术?

因为工程设计到最后,不只是写代码。

它是在复杂约束下做取舍。

分几层? 抽象到什么程度? 哪些能力沉淀成 Service? 哪些设备抽象成 Device? 生命周期由谁管? 配置放在哪里? 上层能不能直接碰底层? 底层变化要不要影响业务?

这些问题没有唯一答案。

但高手的设计,往往有一种共同特征:

该隔离的地方隔离,该收敛的地方收敛,该开放的地方开放,该约束的地方约束。

它不是为了复杂而复杂。

它是恰到好处。

这就是为什么我说:

高手在架构设计上总是趋同的。

因为背后是哲学。

同时它也是艺术。

因为每一次分层、每一次抽象、每一次边界收敛,都要刚刚好。

12

写在最后

如果你现在还处在“会写驱动,但看不懂复杂工程”的阶段,不要急。

这不是你不够努力。

很可能只是你的学习路线还停留在 API 层面。

从今天开始,你可以换一个视角:

不要只问“这个函数怎么用”。 要问“这一层为什么存在”。

不要只问“这个驱动怎么写”。 要问“这个设备在系统对象模型里是什么角色”。

不要只问“Linux 的 probe 什么时候调用”。 要问“为什么生命周期要由框架来驱动”。

当你能从 分层、抽象、对象、生命周期、总线模型 这条路线一路看过去,Linux 驱动就不再是天书。

它只是一个更大的、更成熟的、更工业化的嵌入式系统。

而这,才是嵌入式工程师真正应该补上的架构课。

加我V,发你架构循序渐进学习手册。

https://www.bilibili.com/video/BV16ENzz3Ea6/?spm_id_from=333.1387.search.video_card.click

立芯嵌入式  专注嵌入式工程化、平台化架构与企业级项目实战。  让普通工程师不只会写代码,更能看懂系统、设计系统、驾驭系统。

最新文章

随机文章