IMX6ULL裸机开发从零开始:VS Code搭建环境+汇编点灯实战

一、开发环境准备

1. 宿主机与工具链

  • Windows端:安装VS Code,装这几个必备扩展:

    • Chinese (Simplified):汉化包,看着舒服

    • C/C++ Extension Pack:C/C++语法支持

    • Arm Assembly:ARM汇编语法高亮、补全

    • Makefile Tools:Makefile工程管理

  • 编译环境:Ubuntu系统(可以是WSL2或者虚拟机),用来交叉编译代码,毕竟最终跑在ARM架构的IMX6ULL上。

2. 核心硬件资源先搞懂

IMX6ULL的外设操作主要和三个模块打交道,先把这几个基础概念记牢:

模块 核心寄存器 作用
IOMUXC(引脚复用) IOMUXC_SW_MUX_CTL_PAD_xxx 配置引脚复用功能,比如把某个IO设为GPIO模式
IOMUXC_SW_PAD_CTL_PAD_xxx 配置引脚电气属性:上下拉、驱动能力、速度等
GPIO GPIOx_DR GPIO数据寄存器,控制引脚输出高低电平
GPIOx_GDIR GPIO方向寄存器,配置引脚是输入还是输出
CCM(时钟控制) CCM_CCGR0 ~ CCM_CCGR6 外设时钟门控,给对应位写0xFFFFFFFF就能打开所有外设时钟

另外要记住一个关键地址:IMX6ULL的DDR起始地址是0x80000000,后面链接脚本会用到。


二、汇编点灯实战(以GPIO1_IO03为例)

点灯是所有嵌入式开发的"Hello World",咱们先从最底层的汇编实现,搞清楚每一步硬件操作的原理。

1. 整体流程

汇编点灯一共4步:

  1. 开启GPIO外设时钟

  2. 配置引脚复用为GPIO功能

  3. 配置引脚电气属性

  4. 设置GPIO为输出模式,并输出低电平点亮LED

2. 完整汇编代码(start.S)

复制代码
.global _start

_start:
    /* 1. 开启GPIO1时钟(CCM_CCGR1控制GPIO1时钟,bit27:26置11即可) */
    ldr r0, =0x20C406C   /* CCM_CCGR1寄存器地址 */
    ldr r1, =0xFFFFFFFF  /* 打开所有外设时钟,偷懒直接全开 */
    str r1, [r0]

    /* 2. 配置引脚复用:将GPIO1_IO03复用为GPIO功能 */
    ldr r0, =0x20E0068   /* IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03寄存器地址 */
    ldr r1, =0x5         /* ALT5模式就是GPIO */
    str r1, [r0]

    /* 3. 配置引脚电气属性 */
    ldr r0, =0x20E02F4   /* IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03寄存器地址 */
    ldr r1, =0x10B0      /* 配置:下拉、100MHz速度、驱动能力R0/6等 */
    str r1, [r0]

    /* 4. 配置GPIO1_IO03为输出模式 */
    ldr r0, =0x209C004   /* GPIO1_GDIR寄存器地址 */
    ldr r1, =0x8         /* bit3置1,对应GPIO1_IO03为输出 */
    str r1, [r0]

    /* 5. 输出低电平,点亮LED(假设LED共阳极接法) */
    ldr r0, =0x209C000   /* GPIO1_DR寄存器地址 */
    ldr r1, =0x0         /* bit3清零,输出低电平 */
    str r1, [r0]

loop:
    b loop               /* 死循环,防止程序跑飞 */

3. 配套Makefile

复制代码
CROSS_COMPILE ?= arm-linux-gnueabihf-
TARGET = led_asm

$(TARGET).bin: $(TARGET).elf
	$(CROSS_COMPILE)objcopy -O binary -S $^ $@

$(TARGET).elf: start.o
	$(CROSS_COMPILE)ld -Ttext 0x80000000 -o $@ $^

start.o: start.S
	$(CROSS_COMPILE)gcc -Wall -nostdlib -c $^ -o $@

clean:
	rm -rf *.o *.elf *.bin

注意链接地址-Ttext 0x80000000,就是我们前面说的DDR起始地址,代码会被加载到这里运行。

4. 编译烧录

  1. 把代码放到Ubuntu里,执行make生成led_asm.bin

  2. 通过imxdownload工具把bin文件烧写到SD卡:

    复制代码
    ./imxdownload led_asm.bin /dev/sdb  # 注意sdb是你的SD卡设备名,别写错!
  3. 把SD卡插到开发板,拨码开关设为SD卡启动,上电就能看到LED亮起来~


三、后续进阶方向

这次只是最基础的汇编点灯,后面还会更新:

  • C语言点灯:用C封装寄存器操作,更符合工程习惯

  • NXP官方固件库点灯:学习工业级代码的写法

  • 中断、定时器、串口等外设的裸机驱动


常见问题Q&A

  1. LED不亮怎么办?

    先检查LED的硬件接法(共阳/共阴),再核对寄存器地址是否正确,最后看SD卡烧录有没有报错。

  2. 为什么要用汇编开头?

    裸机程序没有引导程序帮我们做初始化,汇编负责最底层的CPU初始化、栈设置等,后面C语言运行环境准备好了就可以跳转到C代码。

如果这篇博客对你有帮助,别忘了点赞收藏~ 有问题欢迎在评论区交流!

相关推荐
码上上岸3 小时前
基于单片机的老人跌倒监测报警器设计与实现
stm32·嵌入式硬件·物联网·智能硬件·硬件
恒锐丰科技林技术员3 小时前
SS6209 半桥驱动器:小型半桥电源方案的优选器件
经验分享·嵌入式硬件
别催小唐敲代码6 小时前
Pixhawk 6C — Mission Planner 烧录 & 全套校准教程
stm32·单片机·嵌入式硬件
wuyk5557 小时前
从零吃透Modbus通信|第7章:终极工程整合(模块化架构、双模式主机从机、RTOS适配、量产级模板)
c语言·stm32·学习·架构
Freak嵌入式8 小时前
Pico UART 数据收发实战:硬件配置、MicroPython 编程
java·开发语言·单片机·嵌入式硬件·生活
一条破秋裤8 小时前
STM32 学习笔记:PWM 驱动 LED 呼吸灯与舵机代码
笔记·stm32·学习
Freak嵌入式9 小时前
Pico PIO 汇编语法深度详解:标识符、指令、伪指令全解析
汇编·stm32·单片机·嵌入式硬件·fpga开发·硬件架构
自小吃多10 小时前
PCB Editor软件差分对添加与设置笔记
笔记·嵌入式硬件
逐步前行10 小时前
ESP32-S3-工程管理
单片机
智购科技无人售货机厂家12 小时前
2026自动售货机连接器选型指南:从IP等级到插拔寿命的工程实践~YH
单片机·嵌入式硬件