|i.MX6ULL 汇编点灯全流程(附避坑指南))
开发板IMX6ULL Alpha/Mini环境Windows VSCode Ubuntu 虚拟机目标从零实现汇编点亮 LED一、开发环境准备1.1 Windows 端 VSCode 插件必备插件清单少一个都可能难受插件名称作用ARM AssemblyARM 汇编语法高亮C/C Extension PackC/ASM 智能提示Makefile ToolsMakefile 工程管理Chinese (Simplified)汉化界面代码编写在 Windows编译在 Ubuntu这是嵌入式开发的经典组合。二、i.MX6ULL 核心知识铺垫在点灯之前必须搞清楚三个硬件模块这也是 NXP 官方手册的核心逻辑。2.1 IOMUXC —— 引脚复用控制i.MX6ULL 的引脚几乎都是复用的比如同一个引脚可以是GPIOUARTI2CSPI所以我们需要手动指定用途。两个关键寄存器寄存器作用IOMUXC_SW_MUX_CTL_PAD_XXX配置引脚复用功能IOMUXC_SW_PAD_CTL_PAD_XXX配置电气属性上下拉、驱动能力等例如本次使用的GPIO1_IO03MUX0x020E0068PAD0x020E02F42.2 GPIO —— 通用输入输出配置完复用后才真正进入 GPIO 控制。寄存器作用GPIO1_GDIR方向寄存器输入/输出GPIO1_DR数据寄存器高低电平DDR 起始地址0x800000002.3 CCM —— 时钟控制这是最容易忽略的一步NXP 芯片默认外设时钟是关闭的不打开时钟GPIO 永远不工作。寄存器作用CCM_CCGR0 ~ CCGR6外设时钟门控教学阶段最简单粗暴的方式ldr r1, 0xFFFFFFFF str r1, [ccgrx]一次性打开所有外设时钟 ✅三、汇编点灯完整代码下面是经过验证、可直接运行的版本已修复新手高频 Bug。3.1 启动文件start.S.global _start _start: ldr pc, _reset_handler ldr pc, _undef_handler ldr pc, _svc_handler ldr pc, _prefetch_abort_handler ldr pc, _data_abort_handler ldr pc, _reserved_handler ldr pc, _irq_handler ldr pc, _fiq_handler /* 异常入口死循环教学用 */ _fiq_handler: ldr pc, _fiq_handler _irq_handler: ldr pc, _irq_handler _reserved_handler: ldr pc, _reserved_handler _data_abort_handler: ldr pc, _data_abort_handler _prefetch_abort_handler: ldr pc, _prefetch_abort_handler _svc_handler: ldr pc, _svc_handler _undef_handler: ldr pc, _undef_handler /* 复位入口 */ _reset_handler: /* 切换到 IRQ 模式设置 IRQ 栈 */ mrs r0, cpsr bic r0, r0, #0x1F orr r0, r0, #0x12 msr cpsr, r0 ldr sp, 0x86000000 /* 切换到 SYS 模式设置系统栈 */ mrs r0, cpsr bic r0, r0, #0x1F orr r0, r0, #0x1F msr cpsr, r0 ldr sp, 0x84000000 bl _enable_clocks bl _led_init bl _led_on loop: b loop /* 打开所有外设时钟 */ _enable_clocks: ldr r0, 0x020C4068 ldr r1, 0xFFFFFFFF str r1, [r0] ldr r0, 0x020C406C /* ⚠️ 新手常漏 CCGR1 */ str r1, [r0] ldr r0, 0x020C4070 str r1, [r0] ldr r0, 0x020C4074 str r1, [r0] ldr r0, 0x020C4078 str r1, [r0] ldr r0, 0x020C407C str r1, [r0] ldr r0, 0x020C4080 str r1, [r0] bx lr /* LED GPIO 初始化 */ _led_init: /* 引脚复用GPIO1_IO03 */ ldr r0, 0x020E0068 mov 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 点亮低电平点亮 */ _led_on: ldr r0, 0x0209C000 ldr r1, [r0] bic r1, r1, #(1 3) str r1, [r0] bx lr四、编译 烧写4.1 Makefile简化版led.bin: start.o arm-linux-gnueabihf-ld -Ttext 0x87800000 -o led.elf $^ arm-linux-gnueabihf-objcopy -O binary led.elf led.bin start.o: start.S arm-linux-gnueabihf-gcc -c $ -o $ clean: rm -f *.o *.elf *.bin4.2 烧写到 SD 卡imxdownload在上一级目录时sudo ../imxdownload led.bin /dev/sdb⚠️千万确认不是/dev/sda烧写成功后插入 SD 卡开发板拨到 SD 启动上电✅ LED 亮起五、新手必踩的三个坑血泪总结❌ 坑 1漏开 CCGR1 时钟 现象代码跑通LED 就是不亮❌ 坑 2MUX 写成 PAD 值 现象GPIO 没生效❌ 坑 3SD 卡设备认错 后果系统盘直接报废 六、下一步计划本系列后续文章将覆盖✅ 汇编 → C 语言点灯✅ NXP 官方固件库点灯✅ 中断IRQ实战✅ 从 SD 卡启动原理IVT / DCD✅ 手写简易 Bootloader七、总结一句话ARM 裸机开发 寄存器 时钟 耐心只要你能点亮第一个 LED后面的一切都只是复杂度叠加不再是门槛。如果你觉得这篇博客对你有帮助欢迎点赞 收藏后续我会持续更新 IMX6ULL 裸机与驱动系列文章。