1. 什么是 IOMUXC?
IOMUXC 全称 I/O Multiplexer Controller(输入输出复用控制器)。
它的功能就是:把一个物理管脚(pad)切换到不同的功能。
因为 i.MX6ULL 的管脚非常多,但封装数量有限,所以同一个管脚可以复用成 GPIO / UART / I2C / SPI / ENET / LCD 等多种功能。
你写裸机代码要点亮 LED,首先要通过 IOMUXC 把 LED 所在的引脚复用成 GPIO 功能,否则它可能还在默认的其它外设模式下。
2. IOMUXC 的三个核心寄存器
每个引脚在 IOMUXC 里通常有三类寄存器来配置:
MUX Control 寄存器 (
IOMUXC_SW_MUX_CTL_PAD_xxx
)决定这个 PAD 的功能复用。
常见写法:
ALT0
~ALTn
表示不同外设功能,比如 ALT0=UART,ALT5=GPIO。
举例:
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 = 0x05; // ALT5 表示 GPIO
PAD Control 寄存器 (
IOMUXC_SW_PAD_CTL_PAD_xxx
)配置电气属性,例如:上下拉、驱动能力、速度、开漏等。
常用配置项:
PKE/PUE → 是否使能上下拉
PUS → 上拉/下拉强度
DSE → 驱动能力(2/4/8/12/16mA)
SPEED → 信号切换速度(低、中、高)
举例(常见的 0x10B0 配置):
IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03 = 0x10B0;
Select Input 寄存器 (
IOMUXC_xxx_SELECT_INPUT
)用于输入信号的路径选择。
有些 PAD 有多个输入路径,可以通过这个寄存器选择信号来源。
点亮 LED 用不到,一般在配置外设(比如 UART_RX 来源选择)才需要。
3. 使用流程(以 GPIO 点灯为例)
假设 LED 接在 GPIO1_IO03
:
开 GPIO1 模块时钟
CCM_CCGR1 |= (3 << 26); // 打开 GPIO1 时钟
设置 PAD 复用
IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 = 0x05; // ALT5 = GPIO
配置 PAD 电气属性
IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03 = 0x10B0; // 常用配置:上拉+中驱动
GPIO 配置为输出并控制
GPIO1_GDIR |= (1 << 3); // 设置 GPIO1_IO03 为输出 GPIO1_DR &= ~(1 << 3); // 输出低电平 → LED 亮(低有效)
4. IOMUXC 的重要性
复用配置是裸机开发的第一步,不管是 LED、串口、I2C、SPI 还是 LCD,都必须通过 IOMUXC 把 PAD 映射到对应外设。
配置正确 → 外设才能工作;配置错误 → 信号根本出不来,怎么写驱动都没用。
PAD 电气属性 影响信号质量,驱动能力不够可能带不动外设或 LED 电流。
一、LED 实验中对 SoC 引脚的配置步骤
IO 复用(IOMUX)
将物理引脚的功能切换为 GPIO,而不是其他外设功能(如 UART、I²C 等)。
电气特性配置(PAD Control)
设置引脚的上下拉电阻、驱动能力、信号上升沿速度、是否开漏或推挽输出。
这些参数确保引脚能稳定驱动 LED,同时满足电气特性要求。
引脚方向(GPIO Direction)
将该 GPIO 配置为“输出模式”,准备向外提供高/低电平信号。
数据输出控制(GPIO Data)
通过写数据寄存器的某一位,控制引脚输出高电平或低电平,从而实现 LED 的点亮与熄灭。
实际点亮方式取决于硬件电路的接法(低电平有效或高电平有效)。
实验效果
在完成以上配置后,通过不断改变输出电平并加入延时,LED 会实现闪烁效果。
led_init:
//IO复用功能配置
ldr r0, =0x020E0068
ldr r1, =0x05
str r1, [r0]
//引脚电器特性配置
ldr r0, =0x020E02F4
ldr r1, =0x10B0
str r1, [r0]
//引脚方向
ldr r0, =0x0209C004
ldr r1, [r0]
orr r1, r1, #(1 << 3)
str r1, [r0]
bx lr
led_on:
ldr r0, =0x0209C000
ldr r1, [r0]
bic r1, r1, #(1 << 3)
str r1, [r0]
bx lr
led_off:
ldr r0, =0x0209C000
ldr r1, [r0]
orr r1, r1, #(1 << 3)
str r1, [r0]
bx lr
二、工具链关键组件的作用
编译器(Compiler)
将高级语言(C/C++)源代码翻译为目标文件或机器指令。
包含语法分析、优化和指令生成等步骤。
连接器 / 链接器(Linker)
将多个目标文件和库合并,解析符号引用,分配存储地址。
生成最终的可执行文件或带符号的映像文件(如 ELF)。
格式转换器(Object/Format Converter)
在不同文件格式之间进行转换。
常见用途是将 ELF 文件转换成 BIN/HEX 格式,以便烧录到开发板或 Flash。
反汇编器(Disassembler)
将二进制机器码还原为汇编指令,方便阅读和调试。
结果通常不包含变量名和注释,只提供指令层面的信息。
(1)使用arm-linux-gnueabihf-gcc只汇编不链接
arm-linux-gnueabihf-gcc -c start.S -o start.o -g
(2)使用arm-linux-gnueabihf-ld链接代码到特定地址(得到可执行,可连接程序linux executable linkable file)
arm-linux-gnueabihf-ld -Ttext 0x87800000 start.o -o start.elf
(3)使用arm-linux-gnueabihf-objcopy 格式转换
arm-linux-gnueabihf-objcopy -O binary -S(去符号信息) -g(去调试信息) start.elf start.bin
(4)使用arm-linux-gnueabihf-objdump 反汇编(此处只是为了阅读代码,非必要步骤)
arm-linux-gnueabihf-objdump -D start.elf > start.dis
三、从源代码到点亮 LED 的完整流程
编写源码(C 或汇编)。
编译:由编译器生成目标文件。
链接:由链接器将多个目标文件与库整合,输出 ELF 文件。
格式转换:由工具将 ELF 转为 BIN 或 HEX 文件。
烧录执行:单片机上电后运行初始化代码 → 配置 MUX、PAD、方向、数据寄存器 → LED 被点亮。