20251125 - 韦东山Linux第三篇笔记【中】

韦东山Linux第三篇笔记 - 中

总结一:从 STM32F4 到 i.MX6ULL

有两个月的 STM32F407 基础,这是一个非常棒的起步

虽然自称是 Linux"零基础",但实际上已经掌握了最难啃的"硬件原理"部分(比如 I2C 时序、中断机制等)。这些物理层面的知识在 Linux 上是通用的,只是控制它们的方式变了。

从 STM32F4 到 i.MX6ULL,不仅仅是换了一块板子,而是从 MCU(微控制器) 跨越到了 MPU(微处理器)

1. 硬件架构的区别:从"单间"到"大厦"

STM32 像是一个精装修的单身公寓 ,资源紧凑但伸手可得;i.MX6ULL 像是一座现代化写字楼,资源丰富但结构复杂,需要有管理员(操作系统)。

维度 STM32F407 (MCU) i.MX6ULL (Linux MPU) 转换核心
核心架构 Cortex-M4 (168MHz) Cortex-A7 (528MHz) 性能更强,不仅仅跑控制,还能跑复杂的算法和界面,支持高级指令集。
内存 (RAM) 片内 SRAM (比如 192KB) 片外 DDR3L (我的板子是 512MB) 关键点: Linux 需要初始化外部 DDR 才能运行,这比 STM32 初始化复杂得多。
存储 (ROM) 片内 Flash (比如 1MB) 片外 eMMC/NAND (我的板子是 eMMC) 代码不是直接在芯片里运行,而是从外部存储加载到内存运行。
地址管理 物理地址 虚拟地址 (MMU) 在 Linux 里,不能直接往 0x40020000 写数据,必须先通过驱动映射成虚拟地址。
内存管理 无 MMU (内存管理单元) 有 MMU (内存管理单元) 最大的区别之一! MMU使得 Linux 能够运行,并实现虚拟内存和内存保护。
2. 学习内容的区别:从"裸奔"到"分层"

在 STM32 中,代码通常是一个 while(1) 循环包含了所有逻辑。在 Linux 中,软件被严格分层了。

要学的不再是"如何操作一个寄存器",而是"如何通过 Linux 框架与硬件通信"。

A. 软件层级的变化
  • STM32 开发:

    • 通常只写一个大程序(固件),烧进去就跑。
    • 既是驱动开发者,是应用开发者。
  • Linux 开发 (i.MX6ULL):

    系统被切分为四个完全独立的部分,需要分别学习:

    1. Bootloader (U-Boot): 相当于 STM32 的启动文件,负责初始化 DDR、Flash,启动内核。
    2. Linux Kernel (内核): 管理硬件资源。之前学的 RCC, GPIO, SPI 都在这里被封装成了驱动。
    3. Rootfs (根文件系统): 存放库文件、配置文件(类似在 Windows 上看到的 C 盘目录结构)。
    4. App (应用程序): 跑在最上层,不直接操作硬件,而是调用内核提供的接口。
B. 具体外设的映射 (学过的 vs 现在要学的)

在 STM32 中,通过操作寄存器(例如 GPIOA->ODR)直接控制硬件。在 Linux 中,需要通过内核提供的 API (应用程序接口) 来间接控制硬件。

STM32 概念 Linux 中的对应物 (韦东山教程重点) 区别
RCC (时钟) CCM + 设备树 (Device Tree) 不再需要手动 RCC_APB2PeriphClockCmd。通常在设备树 (.dts 文件) 里写好,内核自动开启。
GPIO Pinctrl 子系统 + GPIO 子系统 不再直接操作 ODR/IDR 寄存器。如果是写驱动,用 gpiod_set_value;如果是写应用,用 sysfs (/sys/class/gpio).
NVIC/EXTI GIC (通用中断控制器) + 中断子系统 Linux 处理中断分"上半部"和"下半部",不能在中断里做延时操作。
I2C/SPI I2C/SPI 核心驱动框架 这是重难点。 不需要模拟时序了!只需要按照 Linux 的标准框架,填入设备地址和数据,内核会帮发波形。
UART (串口) TTY 驱动 在应用层,串口就是一个文件 (/dev/ttymxc0),像读写 TXT 文件一样读写串口。
ADC IIO (工业 I/O) 子系统 学习通过统一的 IIO 框架来读取传感器数据,而不是直接操作 ADC 寄存器。
3. 学习方法与工具的区别:最不习惯的地方

这是初学者最痛苦的阶段,因为"舒适区"被打破了。

A. 开发环境
  • STM32: Windows + Keil/MDK。点一下按钮就编译下载。
  • i.MX6ULL: Linux 虚拟机 (Ubuntu) + 命令行 (GCC/Make) + 交叉编译。
B. 调试手段 (痛点!)
  • STM32: J-Link 插上,打个断点,单步执行,看寄存器值。爽!
  • i.MX6ULL:
    • 应用层: 可以用 GDB,但不如 Keil 直观。
    • 驱动/内核层: 基本告别单步调试 。主要靠 printk (打印日志)
    • 心态调整: 需要学会通过分析串口打印出来的 Log 来推测程序死在哪里,而不是依赖单步调试。
C. 编程思维
  • STM32: "我要把 PA5 拉高"。(直接控制)
  • Linux: "我要打开 LED 设备文件,写入 1"。(通过文件 IO)
    • 在 Linux 中,一切皆文件。之前的 STM32 经验通过"驱动程序"转化为了文件操作。
4. 新增的必学内容
领域 学习内容 难度和重要性
系统基础 U-Boot 启动流程、Linux Shell 脚本、文件系统结构、用户/内核空间。 理解整个系统如何运转的关键。
核心技术 设备树 (Device Tree):用于描述硬件连接的语言。 最重要的新概念,它将硬件信息与驱动程序解耦。
驱动开发 字符设备驱动、Platform 驱动、驱动的注册与注销。 从裸机代码到符合 Linux 规范的驱动代码。
网络应用 Socket 编程、TCP/IP 协议栈。 实现 I.MX6ULL 价值(网络通信)的核心技能。

总结二: 编译器 GCC,项目构建管理工具 Make

对于习惯了 Windows 下 Keil/IAR 等集成开发环境(IDE)的 STM32 开发者来说,初次面对 Linux 下的命令行开发,最不适应的就是 GCCMake

在 Keil 中,只需要点击一个"编译按钮 " (Build),所有的工作就自动完成了。但在 Linux 下,我们需要把这个"按钮"背后的工作拆解开来,由两个独立的工具来完成:GCCMake

我们可以用**"装修队"**来打比方:

1. GCC (编译器):具体的"干活工人"

GCC (GNU Compiler Collection) 是一套工具集,在的 i.MX6ULL 开发中,它的核心作用就是翻译

  • 它的角色: 它是瓦工/木工
  • 它的工作: 它把看得懂的 C 语言代码 (main.c),一行行翻译成 i.MX6ULL 芯片能看懂的机器码 (main.oapp)。
  • Keil 对比: 在 Keil MDK 里,其实也有一个编译器(叫 armccarmclang),只是 Keil 把它藏在了后台。当点"编译"时,Keil 会悄悄调用它。但在 Linux 下,需要显式地调用它。

举个例子:

假设有一个 hello.c 文件。

  • 在 Keil 里:把它加入工程,点按钮。

  • 在 Linux 命令行里:需要输入指令呼叫工人:

    Bash:

    bash 复制代码
    # 嘿!GCC工人(arm-linux-gnueabihf-gcc),请把 hello.c 编译(-o) 成可执行文件 hello
    arm-linux-gnueabihf-gcc hello.c -o hello
2. Make (构建工具):聪明的"包工头"

如果的项目只有一个 hello.c,那每次手动输上面的 GCC 命令还可以接受。

但是,Linux 内核或者大型项目通常有几千个 .c 文件。如果要一个一个手动输命令去编译,那得累死。

这时候就需要 Make

  • 它的角色: 它是包工头/项目经理
  • 它的工作:不干具体的活 (不编译代码),它的任务是指挥 GCC 去干活 。它根据一份图纸(叫 Makefile ),决定:
    1. 哪些文件需要编译?
    2. 哪些文件虽然在项目里,但这次不需要编译?
    3. 编译的顺序是什么?(先砌墙还是先刷漆?)
    4. 最厉害的一点: 如果只修改了一个文件,Make 会发现:"咦,其他 999 个文件没变,那我只指挥 GCC 编译这一个修改过的文件就好啦!"(这叫增量编译,极大节省时间)。
  • Keil 对比: Make + Makefile 就相当于 Keil 里的 "工程文件 (.uvprojx)" 加上 "Build/Rebuild 逻辑" 。Keil 帮我们记住了包含哪些文件、头文件路径在哪里;在 Linux 下,需要把这些写进 Makefile 里告诉 Make。
3. 它们如何配合工作?

在 Linux 开发中,流程通常是这样的:

  1. 编写代码: 我们写好了几百个 .c 文件。

  2. 编写规则 (Makefile): 我们写了一个叫 Makefile 的文本文件,里面写着:"GCC 啊,要先编译 A,再编译 B,最后把它们拼起来。"

  3. 执行构建 (Make):

    在命令行里只输入一个单词:

    Bash

    复制代码
    make
  4. 自动执行:

    Make 工具醒来,读取 Makefile,然后自动指挥 GCC 执行几百条编译指令:

    • Make: "GCC, 编译 main.c!"
    • GCC: "好勒!" (生成 main.o)
    • Make: "GCC, 编译 led.c!"
    • GCC: "好勒!" (生成 led.o)
    • ...
4. 什么是"交叉编译"?

最后解释一下"交叉"。

  • 普通编译: 在电脑(x86 架构)上编译,给电脑自己用。
  • 交叉编译 (Cross Compile):
    • GCC 分很多种。
    • 在 Ubuntu 上用的这个 GCC,它的全名通常叫 arm-linux-gnueabihf-gcc
    • 它的特殊技能是: 它运行在的电脑(x86)上,但它生成的机器码是专门给 ARM 架构 (i.MX6ULL) 吃的。
    • 这就好比:在中国 (PC环境),用英文 (ARM指令集)写了一本书,但这书是给美国人(开发板)看的。
GCC+Make总结
  • GCC手工工具(锤子),用来把代码变成程序。
  • Make自动化脚本(流水线控制器),用来批量、智能地调用 GCC。
  • 交叉编译 是因为的电脑 CPU 和开发板 CPU 语言不通,需要一个专门的翻译官。

总结三:详解 交叉编译 (Cross Compilation) 的前后因果

交叉编译 (Cross Compilation) 是所有嵌入式 Linux 开发的基石。

🔬 一、什么是交叉编译?(定义)
1. 核心概念

交叉编译 ,简而言之,就是在一个A 架构的平台 上,生成可以在另一个B 架构的平台上运行的程序的行为。

  • 宿主机 (Host Platform): 用于编译代码的机器。在的例子中是 Ubuntu 虚拟机 ,其 CPU 架构通常是 x86 或 x64
  • 目标机 (Target Platform): 最终运行程序的机器。在的例子中是 i.MX6ULL 开发板 ,其 CPU 架构是 ARM (具体是 Cortex-A7)。

定义: 交叉编译就是让 x86/x64 架构的机器,生成 ARM 架构的可执行代码。

2. 为什么要"交叉"?

不能直接在开发板上编译吗?理论上可以,但实践中不可行:

  • 性能瓶颈: i.MX6ULL (528MHz) 的计算性能远低于的电脑。编译 Linux 内核或大型应用(比如 LVGL 库)可能需要几个小时甚至一天。
  • 资源限制: 开发板的内存 (512MB DDR3L) 和存储 (eMMC) 相对紧张,不足以运行大型编译器和存放编译过程中产生的巨大临时文件。

因此,我们利用高性能的 PC 电脑作为宿主机 来完成编译工作,然后将编译好的、体积更小的可执行文件传输到目标机(i.MX6ULL)上运行。

⚙️ 二、交叉编译在嵌入式 Linux 中的体现
1. 交叉编译工具链 (Cross Toolchain)

实现交叉编译的关键是使用一套特殊的工具:交叉编译工具链

工具名称 的系统名称示例 作用
交叉编译器 arm-linux-gnueabihf-gcc 将 C 语言翻译成 ARM 机器码。
交叉链接器 arm-linux-gnueabihf-ld 将编译好的模块和库链接成最终的可执行文件。
交叉调试器 arm-linux-gnueabihf-gdb 用于远程调试开发板上的程序。

命名规则: 交叉工具链的名称通常遵循:目标架构-目标操作系统-ABI-工具

2. 编译整个 Linux 系统

在 i.MX6ULL 的开发中,进行的每一次编译都是交叉编译,包括:

  • Bootloader (U-Boot): 必须被交叉编译成 ARM 架构的引导代码。
  • Linux 内核 (Kernel): 整个内核源码会被交叉编译成 zImageuImage 文件,包含了针对 ARM Cortex-A7 的指令。
  • 驱动模块 (Drivers): 编写的 Linux 驱动 .ko 文件。
  • 应用程序 (Applications): 在用户空间运行的 C/C++ 程序,如 LVGL 示例。
➡️ 三、从 STM32 到 i.MX6ULL 的思维转变

在 STM32 裸机开发中,可能使用的是 Arm M4 GCCArm M4 Clang,它们也是一种交叉编译,但通常是在 IDE 中完成了。

维度 STM32 编译 (广义交叉编译) i.MX6ULL 编译 (嵌入式 Linux 交叉编译)
目标 STM32F407 (裸机/RTOS) Linux 操作系统下的 i.MX6ULL
输出格式 一个完整的固件 (.hex.bin),直接写入 Flash。 多种文件: Bootloader, Kernel (zImage), 文件系统, 应用程序。
宿主环境 IDE 隐藏了编译过程。 命令行主导 ,需要手动配置环境变量 $PATH,确保 make 命令找到正确的交叉编译器。

总结: 当在 Ubuntu 虚拟机中输入 make 编译韦东山 i.MX6ULL 的任何代码时,正在启动一个由 make 管理、由 arm-linux-gnueabihf-gcc 执行的交叉编译过程,其最终目的是为远端的 ARM 芯片生产可执行代码。

我们把这条长长的命令拆开,你会发现它非常有逻辑:

arm-buildroot-linux-gnueabihf-gcc (翻译官的名字)

这是最长、最容易让人晕的部分。这个文件名并不是随便起的,它遵循了标准的命名规则:

Arch-Vendor-OS-ABI(架构-厂商-系统-二进制接口)。

我们把它大卸八块来看:

  • arm : 目标架构
    • 这表明编译器生成出来的代码是给 ARM 处理器 跑的,而不是给你的电脑(x86/Intel)跑的。这是最关键的一点。
  • buildroot : 厂商/构建者
    • 这表明这个工具链是由 Buildroot 这个工具构建出来的。有时候你也会看到 none 或者 fsl(Freescale),这只是个标签,说明谁制作了这个工具。
  • linux : 目标操作系统
    • 这表明编译出来的程序是运行在 Linux 操作系统之上的(会调用 Linux 的库),而不是运行在裸机(没有操作系统的环境)上的。
  • gnueabihf : 应用二进制接口 (ABI) 与浮点策略 。这一串字符包含的信息量最大:
    • gnu: 表示它使用 GNU C 标准库(glibc),这是 Linux 上最标准的库。
    • eabi: Embedded Application Binary Interface(嵌入式应用二进制接口)。这是一种标准,规定了 ARM 程序之间如何传递参数、如何调用函数。
    • hf : Hard Float(硬件浮点)这一点对你的 I.MX6ULL 很重要!
      • I.MX6ULL 芯片内部有一个专门做小数运算的硬件单元(FPU)。
      • hf 告诉编译器:"遇到小数运算时,直接生成指令让芯片里的 FPU 硬件去算,不要用软件模拟。"
      • 结果: 程序的浮点运算速度会快几十倍。
  • gcc : 工具本身
    • 这就是大名鼎鼎的 GNU C Compiler(C语言编译器)。

总结这个名字:

"这是一个由 Buildroot 制作的、用于 ARM 架构、运行在 Linux 系统上、使用 GNU 标准库、并开启了硬件浮点加速GCC 编译器。"

总结四:详解 Board Support Package(板级支持包)

BSP 全称是 Board Support Package(板级支持包)。

简单来说,BSP 就是让 i.MX6ULL 开发板能"活"起来、能跑 Linux 系统所需的全部软件代码包。

1. 🍔 形象的比喻:BSP 是什么?

想象一下我们买了一台组装电脑(PC):

  • 硬件: 主板、CPU、显卡、硬盘。
  • 操作系统: Windows 10。
  • 缺失的环节: 如果我们直接装 Windows,可能显卡不亮、声卡没声音、网卡连不上。我们需要安装主板驱动、显卡驱动等。

在嵌入式 Linux 中:

  • Linux 内核 就像是一个通用的 Windows(全球通用)。

  • i.MX6ULL 开发板 就像那台组装电脑(硬件各不相同)。

  • BSP 就是**"驱动光盘 + BIOS + 定制好的 Windows"**的打包集合。它负责告诉通用的 Linux 内核:"嘿,这块板子上有个网卡在地址 A,有个屏幕在地址 B,请把它们驱动起来。"

    也就是所谓的板级支持包,板级指开发板级别,支持包指打包好了的各种驱动。

2. 📦 BSP 里面具体有什么?

在韦东山的 i.MX6ULL 开发包中,所谓的"编译 BSP",实际上是指编译以下三个核心部分:

A. Bootloader (引导加载程序)

  • 对应文件: 通常是 U-Boot
  • 作用: 相当于电脑的 BIOS。它是板子上电后运行的第一个程序,负责初始化最基本的硬件(如 DDR 内存),然后把 Linux 内核从存储器中读出来并启动它。

B. Linux Kernel (内核)

  • 对应文件: zImage (内核镜像) 和 .dtb (设备树二进制文件)。
  • 作用: 这是操作系统的核心。
    • 关键点: BSP 里的内核源码不是 Linux 官方的原版,而是经过 NXP 原厂或韦东山团队修改、配置、打补丁后的版本,专门为了适配这块板子的硬件。
    • 设备树 (Device Tree): BSP 中包含了描述这块板子硬件连接情况的代码(.dts 文件),这是 STM32 中没有的概念。

C. Root Filesystem (根文件系统)

  • 对应文件: 包含 /bin, /etc, /usr 等目录的文件夹或压缩包。
  • 作用: 相当于 Windows 的 C 盘。它包含了 Linux 运行所需的库文件、配置文件以及您编写的应用程序。
3. 🔄 BSP 与 GCC/Make 的关系

现在把所有概念串起来:

  1. 源代码: 韦东山提供的 BSP 源码包(包含 U-Boot 源码、Linux 内核源码)。
  2. 工具: 在 Ubuntu 上安装的 GCC 交叉编译器
  3. 指挥官: 源码里自带的 Make 工具和 Makefile
  4. 动作: 您在命令行输入 make
  5. 结果: GCC 把 BSP 源码编译成了可以在 i.MX6ULL 上运行的二进制文件(U-Boot、zImage、设备树)。
4. 🆚 STM32 vs. i.MX6ULL:BSP 的角色变化
维度 STM32 (裸机/RTOS) i.MX6ULL (Linux)
谁写底层驱动? 通常是您自己 。您基于官方库(HAL库)配置引脚、初始化时钟、写 while(1) BSP 已经写好了。NXP 原厂和开发板厂商(韦东山)已经把底层的 UART、网卡、LCD 驱动写好了。
您的工作重心 造轮子。从底层硬件配置开始,一直写到上层逻辑。 用轮子。您的主要工作是在 BSP 的基础上,开发上层的应用程序(APP),或者微调 BSP(比如换了个不一样型号的屏幕)。
代码量 几百行到几万行。 BSP 源码(内核+U-Boot)有几百万行代码(不用怕,不需要全读懂)。

BSP 就是"地基"。

韦东山老师提供给您的 BSP ,就是把地基打好了(U-Boot 能启动、Linux 能跑、屏幕能亮、网口能通)。作为初学者,第一步通常是学会编译和烧录这个 BSP,确保板子能正常运行,然后再在这个坚实的地基上盖房子(写应用程序)。

总结五:什么是设备树(Device Tree)

理解了设备树,你就理解了 Linux 驱动开发的半壁江山。

🌳 一、什么是设备树?(通俗解释)

设备树 (Device Tree),顾名思义,就是一棵描述硬件信息的"树"。

1. 核心理念:代码与硬件分离
  • 以前 (STM32 模式):

    你在写代码时,会把硬件信息直接写在 .c 代码里。

    • 代码里写死: "我要操作 GPIOA 的第 5 个引脚,它的物理地址是 0x40020000。"
    • 缺点: 如果你换了一块板子,LED 接到了 GPIOA_6,你就必须修改 C 代码,重新编译整个程序
  • 现在 (Linux 设备树模式):

    Linux 社区的大佬们觉得这样太蠢了。驱动代码应该是通用的(逻辑),不应该包含具体的硬件信息(数据)。

    • 驱动代码 (.c): "我要操作一个叫 user-led 的设备,我不管它接在哪,我只负责控制它的亮灭逻辑。"
    • 设备树文件 (.dts): "嗨,内核!这块板子上有一个 LED,名字叫 user-led,它接在 GPIO1_3 引脚上,高电平有效。"

总结:设备树就是一份"硬件说明书",它独立于内核源代码之外,专门告诉 Linux 内核当前板子上有哪些硬件,以及它们是如何连接的。

🆚 二、STM32 与 Linux 的具体对比

为了让你更有代入感,我们来看一个点亮 LED 的例子

1. STM32 的做法 (Hardcode)

在 STM32 中,硬件信息和驱动逻辑是混在一起的:

c 复制代码
// main.c 或 led.c
void LED_Init(void) {
    // 硬件信息直接写在代码里
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    GPIO_Init(GPIOA, &GPIO_InitStructure); // 指定了具体的 GPIOA
}

痛点: 如果硬件改版,LED 换到了 GPIOB,你必须修改这份 C 代码。

2. Linux 设备树的做法 (Decoupling)

在 Linux 中,这件事情被拆成了两半:

A. 设备树文件 (imx6ull-100ask.dts): 负责描述硬件。

c++ 复制代码
// 这是一个文本文件,描述硬件
led_device {
    compatible = "gpio-led";   // 告诉内核:用那个叫 "gpio-led" 的驱动来控制我
    gpios = <&gpio1 3 0>;      // 告诉内核:我接在 GPIO1 的第3号引脚
    status = "okay";           // 我是可用的
};

B. 驱动代码 (led_driver.c): 负责逻辑。

c++ 复制代码
// 这是一个 C 文件,只写逻辑
probe() {
    // 代码里完全没有 "GPIO1_3" 这种字眼
    // 而是问内核:设备树里有没有那个叫 "gpio-led" 的设备?
    // 如果有,把它的 GPIO 信息给我,我来操作。
    get_gpio_from_device_tree(); 
}

优势: 如果硬件改版,LED 换到了 GPIO5,你完全不需要动 C 语言驱动代码 ,只需要去修改设备树文本文件,把 <&gpio1 3> 改成 <&gpio5 3>,然后重新编译设备树即可。

🛠️ 三、设备树的"三剑客" (.dts, .dtsi, .dtb)

在韦东山的 SDK 中,你会经常看到这三种文件后缀:

  1. DTS (.dts) - Device Tree Source
    • 源代码。 这是给人看的文本文件。
    • 通常对应具体的某一块开发板 (例如 100ask_imx6ull_pro.dts)。
    • 里面描述了这块板子特有的硬件(比如这块板子接了 7 寸屏,那块板子接了 HDMI)。
  2. DTSI (.dtsi) - Device Tree Source Include
    • 头文件。 类似于 C 语言的 .h 文件。
    • 通常对应芯片级的信息 (例如 imx6ull.dtsi)。
    • 作用: 因为所有用 i.MX6ULL 芯片的板子,其 CPU 内部的 UART、I2C 控制器地址都是一样的。这些通用的信息写在 .dtsi 里,所有的 .dts 都可以引用它,避免重复写。
  3. DTB (.dtb) - Device Tree Binary
    • 二进制文件。 这是给机器(内核)看的。
    • DTC (Compiler): 我们使用设备树编译器 (DTC) 将 .dts 编译成 .dtb
    • 最终产物: 这个 .dtb 文件会被烧录到板子上,U-Boot 启动时会把它读入内存传给 Linux 内核。
⚙️ 四、内核是如何使用设备树的?

这个过程非常精妙,被称为 "匹配 (Match)"

  1. 启动: Linux 内核启动。
  2. 解析: 内核读取 .dtb 文件,解析出里面所有的硬件节点。
  3. 加载驱动: 内核遍历所有已加载的驱动程序。
  4. 相亲 (Match):
    • 设备树节点说: "我的 compatible 属性是 韦东山,led"。
    • 驱动程序 A 说: "我能支持的 compatible 名字是 韦东山,beep"。(匹配失败)
    • 驱动程序 B 说: "我能支持的 compatible 名字是 韦东山,led"。(匹配成功!
  5. 工作: 既然匹配上了,内核就调用驱动程序 B 的初始化函数 (probe),并把设备树里的 GPIO 信息传给它,驱动就开始工作了。
🎯 总结:这意味着什么?

作为 i.MX6ULL 的初学者,你在学习驱动开发时:

  1. 你不再需要在 C 代码里查手册找寄存器地址了。
  2. 你需要学习一种新的语法(DTS 语法)。 你需要学会如何去修改 .dts 文件,告诉内核:"我新接了一个传感器,挂在 I2C1 上,地址是 0x50"。
  3. 核心工作流变了:
    • STM32: 改代码 -> 编译 -> 烧录。
    • Linux: 改设备树 -> 编译 DTB -> 替换 DTB -> 重启板子 -> (驱动程序可能完全不用改)。
相关推荐
不过普通话一乙不改名41 分钟前
Linux 网络收包的进阶之路:从普通 socket 到 AF_XDP 零拷贝
linux·运维·网络
在路上@Amos1 小时前
Linux 命令行查看 串口hex数据
linux·运维·服务器
人工智能训练1 小时前
Linux 系统核心快捷键表(可打印版)
linux·运维·服务器·人工智能·ubuntu·容器·openeuler
大聪明-PLUS1 小时前
C++ 中的引用和引用类型
linux·嵌入式·arm·smarc
赖small强3 小时前
【Linux驱动开发】ESP-Hosted-FG 深度解析指南
linux·驱动开发·esp32·esp-hosted-fg
大聪明-PLUS3 小时前
C++中的恒定性
linux·嵌入式·arm·smarc
信工 18023 小时前
Linux驱动开发——SPI
linux·驱动开发
b***59433 小时前
在 Ubuntu 22.04 上安装和配置 Nginx 的完整指南
linux·nginx·ubuntu