第三天的内容主要是IMX6ULL的GPIO点灯,从寄存器配置到开发环境走了一遍,整理下核心知识点。
一、硬件基础
IMX6ULL的GPIO一共分为5组:GPIO1~GPIO5。
DDR3起始地址为 0x80000000 ,总大小512MB,地址范围到 0xA0000000 。系统栈指针sp_system位于 0x80000000 ,中断栈sp_irq位于 0x84000000 。
二、GPIO配置三大核心模块
要点亮一个LED,本质是依次配置三个模块的寄存器:引脚复用、GPIO功能、外设时钟。
- 引脚复用与电气属性(IOMUXC)
每个GPIO引脚对应两个控制寄存器:
IOMUXC_SW_MUX_CTL_PAD_xxx :配置引脚复用功能,选择是GPIO还是其他外设模式
IOMUXC_SW_PAD_CTL_PAD_xxx :配置引脚电气属性
高压摆率:曲线陡,适配高速设备
低压摆率:曲线平缓,适配低速场景
- GPIO模块寄存器
每组GPIO都有独立的寄存器组,常用功能如下:
寄存器 作用
GPIOx_GDIR 设置引脚方向,0为输入,1为输出
GPIOx_DR 输出高低电平,写0为低,写1为高
GPIOx_PSR 只读,读取引脚当前状态
GPIOx_ICR 设置中断触发方式(高低电平/上下沿)
GPIOx_IMR 中断屏蔽开关,打开/关闭对应引脚中断
GPIOx_ISR 查询中断标志位,判断是否产生中断
GPIOx_EDGE_SEL 配置为双边沿触发中断
- 时钟模块(CCM)
外设默认时钟关闭,必须先开时钟才能工作。
CCM_CCGR0 ~ CCM_CCGR6 控制所有外设的时钟门,写入 0xFFFFFFFF 即可打开全部外设时钟。
三、中断基础
ARM通过异常向量表管理所有异常和中断:
软中断(SVC):由指令主动触发,格式为 SVC<c> #<imm24> ,比如 svc #7 ,常用于实现系统调用
硬中断:由外设硬件触发,通过GPIO的中断寄存器配置触发方式
四、点灯的三种实现方式
-
纯汇编点灯:直接用汇编指令操作寄存器,适合入门理解时序
-
C语言点灯:用C封装寄存器操作,逻辑更清晰,易维护
-
官方固件库点灯:调用NXP提供的固件库函数,不用手动计算寄存器地址
附一段汇编点灯的核心逻辑示例:
asm
- 打开外设时钟
ldr r0, =CCM_CCGR1
ldr r1, =0xFFFFFFFF
str r1, r0
- 引脚复用为GPIO
ldr r0, =IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03
mov r1, #0x05
str r1, r0
- 设置为输出模式
ldr r0, =GPIO1_GDIR
mov r1, #(1 << 3)
str r1, r0
- 输出低电平点亮LED
ldr r0, =GPIO1_DR
mov r1, #0
str r1, r0
五、开发环境
Windows端用VSCode编写代码,需要安装插件:
C/C++
C/C++ Extension Pack
ARM Assembly
Makefile Tools
编译在Ubuntu环境下完成,先解压ARM GCC编译链:
bash
sudo tar -xvf gcc
Windows和Ubuntu之间的文件传输用FileZilla通过FTP完成。