IMX6ULL嵌入式裸机开发|GPIO点灯、编译链接、GIC中断、协处理器完整笔记

📝摘要:本文基于IMX6ULL Cortex‑A7裸机开发,梳理DDR内存映射、GPIO点灯三模块(IOMUXC引脚复用、GPIO寄存器、CCM时钟)、SVC软中断、编译工具链Makefile、ELF/bin链接、段分布、GIC通用中断控制器、CP15协处理器、内联函数等核心知识点,附带实操代码片段。


1. IMX6ULL内存布局

IMX6ULL搭载512MB DDR3

  • DDR物理起始地址:0x80000000
  • DDR结束地址:0xA00000000x80000000 + 0x20000000

裸机开发链接脚本常用入口地址:‑Ttext 0x87800000,把程序运行加载到DDR内存中间区域。

栈空间分配

地址区间 用途
0x80000000 ~ 0x84000000 系统模式栈 sp_system
0x84000000 ~ 0x86000000 IRQ中断模式栈 sp_irq,大小32MB
0x86000000 ~ 0xA0000000 其余DDR内存,供用户程序、堆使用

ARM32不同处理器模式拥有独立栈指针sp;裸机初始化必须为每一种模式设置单独SP,防止栈冲突。

存储介质差异

  1. NOR‑Flash :可以按字节随机寻址,支持XIP原地执行代码;S3C2440 NOR Flash:0x0 ~ 0x200000
  2. NAND‑Flash / eMMC(IMX6ULL)不能直接寻址执行;程序必须拷贝到DDR内存中再运行。

2. GPIO点灯三大核心模块

IMX6ULL一共有5组GPIO:GPIO1 ~ GPIO5

想要驱动GPIO引脚输出高低电平点亮LED,必须配置3大模块,缺一不可

模块1:IOMUXC 引脚复用与电气属性

芯片引脚可以复用为GPIO、UART、SPI等多种功能,需要IOMUXC寄存器切换。

  1. IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03引脚复用选择寄存器,选择该PAD作为GPIO功能。
  2. IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03PAD电气属性寄存器 ,配置上下拉、摆率、驱动能力。
    • 高压摆率:信号边沿陡峭,适合高速外设;
    • 低压摆率:信号变化平缓,EMI电磁干扰更小。

模块2:GPIO模块寄存器

寄存器 功能描述
GPIOx_GDIR 方向寄存器,bit=1输出模式;bit=0输入模式
GPIOx_DR 数据寄存器,写1输出高电平,写0输出低电平
GPIOx_PSR 引脚状态只读寄存器,读取外部引脚实际电平
GPIOx_ICR 中断触发配置:高电平/低电平/上升沿/下降沿
GPIOx_IMR 中断掩码,1开启该引脚中断,0屏蔽中断
GPIOx_ISR 中断状态,发生中断对应bit置1;写1清除该中断标志位
GPIOx_EDGE_SEL 双边沿中断选择,置1开启双边沿检测

注意:GPIOx_ISR写1清0,不是写0清标志。

模块3:CCM时钟控制模块

外设默认时钟关闭,必须打开时钟门控,外设寄存器才可以正常工作。

CCM_CCGR0 ~ CCM_CCGR6:时钟门控寄存器;写入0xFFFFFFFF打开全部外设时钟。

C语言裸机点灯示例(寄存器直接操作)

复制代码
#include <stdio.h>
//volatile 阻止编译器优化硬件寄存器访问
#define CCM_CCGR0  (*((volatile unsigned int *)0x020C4068))
#define GPIO1_GDIR (*((volatile unsigned int *)0x0209C004))
#define GPIO1_DR   (*((volatile unsigned int *)0x0209C000))

int main(void)
{
    CCM_CCGR0 = 0xFFFFFFFF;   //打开所有外设时钟
    GPIO1_GDIR |= (1 << 3);    //GPIO1_IO03 设置输出模式
    GPIO1_DR &= ~(1 <<3);      //输出低电平,点亮LED
    while(1);
    return 0;
}

3. SVC软中断指令

SVC(Supervisor Call)软中断,触发异常,进入异常向量表SVC入口。

汇编格式:

复制代码
SVC{<cond>} #<imm24>
svc #7    ;触发软中断,携带立即数7作为中断号

应用场景:用户模式触发SVC异常,切换进入特权模式,实现系统调用。

异常向量表中SVC对应偏移地址0x08

4. 开发环境:VSCode远程开发

开发工作流:Windows安装VSCode,通过FTP(FileZilla)连接Ubuntu服务器。

需要安装VSCode插件:

  1. C/C++
  2. C/C++ Extension Pack
  3. ARM Assembly 汇编语法高亮
  4. Makefile Tools Makefile语法与调试工具

文件传输:FileZilla FTP客户端,Windows ↔ Ubuntu互传源码。

5. 编译、链接、objcopy工具与程序段

完整裸机编译流水线

复制代码
#1.编译:源文件编译为.o目标文件,-g加入调试信息
arm‑linux‑gnueabihf‑gcc -g -c start.S -o start.o
arm‑linux‑gnueabihf‑gcc -g -c main.c -o main.o

#2.链接:将多个.o合并elf可执行,‑Ttext指定代码段起始地址
arm‑linux‑gnueabihf‑ld -Ttext 0x87800000 start.o main.o -o start.elf

#3.objcopy:把elf转为二进制bin镜像,烧写到Flash/eMMC
arm‑linux‑gnueabihf‑objcopy -O binary -S -g start.elf start.bin
  • elf:带调试信息、段表的可执行格式,不能直接烧写Flash;
  • bin:纯粹二进制机器码,无头部,适合烧录存储介质。

ELF中五大段

段名 作用
.text 存放程序代码、汇编指令,‑Ttext指定该段链接基地址
.data 已经初始化的全局/静态变量
.bss 初始化为0的全局、静态变量;加载时不占用bin文件空间,运行时清零
.common 未初始化的全局变量
.rodata 只读常量字符串,常量数据

编译链接参数

  • -I:指定头文件搜索路径
  • -L:指定库文件搜索路径

工具链程序:

gcc编译、ld链接、objcopy格式转换、objdump反汇编查看elf。

6. Makefile基础三要素

Makefile核心三要素:目标、依赖、执行规则(命令)

复制代码
目标:依赖
	命令

⚠️命令行前面必须是Tab制表符,不能用空格。

简单示例:

复制代码
start.bin:start.o main.o
	arm‑linux‑gnueabihf‑ld -Ttext 0x87800000 start.o main.o -o start.elf
	arm‑linux‑gnueabihf‑objcopy -O binary -S -g start.elf start.bin

start.o:start.S
	arm‑linux‑gnueabihf‑gcc -g -c start.S -o start.o

main.o:main.c
	arm‑linux‑gnueabihf‑gcc -g -c main.c -o main.c

7. IMX6ULL中断体系与GIC通用中断控制器

IMX6ULL Cortex‑A7使用 GIC‑V2 中断控制器,ARM官方外设,最多支持1020路中断;IMX6ULL实际使用160个中断源。

GIC中断三大分类

  1. SPI 共享外设中断:来自片内外设GPIO、UART、TIMER;多核环境每个CPU都可以接收该中断。
  2. PPI私有外设中断:每个CPU私有,核间信号,和外部硬件外设无关。
  3. SGI软件触发中断:软件指令产生,多用于多核CPU之间通信。

完整中断处理流程

  1. 外设侧:配置GPIO/定时器等外设,设置中断触发方式,使能外设中断输出;
  2. GIC控制器侧
    1. 设置中断使能/屏蔽;
    2. 设置中断优先级;
    3. GIC对比优先级,分发中断到对应CPU核;
  3. CPU内核侧
    1. CPSR打开IRQ总中断开关;
    2. CPU跳转到异常向量表IRQ入口
    3. 中断服务函数中读取GIC C_IAR寄存器,获取中断号;
    4. 根据中断号,执行对应外设中断业务处理;
    5. 处理完毕向C_EOIR写入中断号,通知GIC中断处理结束;
    6. 恢复现场,返回被打断的程序。

关键寄存器:

  • C_IAR:中断确认寄存器,只读,获取发生的中断号;
  • C_EOIR:中断结束寄存器,只写,处理完必须写回中断号。

GIC版本迭代:

  • GIC V1:Cortex‑A5老芯片;
  • GIC V2:IMX6ULL,树莓派,支持虚拟化,最多1020中断;
  • GIC V3/V4:64位多核手机芯片;
  • GIC V5:大型服务器、车载大算力芯片。

8. CP15协处理器 mrc/mcr指令

CP15是Cortex‑A7最重要系统协处理器,控制MMU、Cache、向量表基地址等系统配置。

  • MRC:把协处理器寄存器读取到ARM通用寄存器
  • MCR:把通用寄存器写入协处理器寄存器

指令格式

复制代码
mrc <coproc>, <opc1>, <Rt>, <CRn>, <CRm>{, <opc2>}

示例:操作SCTLR系统控制寄存器,开启I‑Cache

复制代码
;读取cp15 c1(SCTLR)到r0
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #(1 <<13)
orr r0, r0, #(1 <<12)    ;打开I‑Cache
mcr p15, 0, r0, c1, c0, 0 ;写回cp15

设置异常向量表基地址:

复制代码
mcr p15,0,r0,c12,c0,0

9. volatile关键字作用

裸机操作硬件寄存器必须加volatile修饰。

  1. 修饰变量:告诉编译器,该内存内容可能被硬件意外修改,禁止编译器做读写优化,每次都真实访问内存

  2. 硬件寄存器指针:

    #define CCM_CCGR0 (*((volatile unsigned int *)0x020C4068))

如果去掉volatile,编译器会优化,寄存器读写被直接删掉,外设完全无法工作。

10. 内联函数 inline

inline内联函数:编译阶段,把函数代码直接展开到调用位置,消除函数调用压栈跳转开销,提升运行效率。

注意:编译时必须可以看见函数定义,只声明不定义无法内联。

复制代码
inline void delay(unsigned int t)
{
    while(t--);
}

11. 英文缩写全称对照表

缩写 英文全称 中文释义
IOMUXC Input Output Multiplexer Controller 输入输出多路复用控制器
CCM Clock Control Module 时钟控制模块
GIC Generic Interrupt Controller 通用中断控制器
SPI Shared Peripheral Interrupt 共享外设中断(GIC中断类型)
PPI Private Peripheral Interrupt 私有外设中断(GIC中断类型)
SGI Software Generated Interrupt 软件产生中断(GIC中断类型)
SVC Supervisor Call 管理调用,软中断指令
XIP Execute‑In‑Place 原地执行
ELF Executable and Linkable Format 可执行可链接文件格式
BIN Binary 原始二进制镜像文件
CP15 Coprocessor‑15 15号系统协处理器
MRC Move from Coprocessor 从协处理器读数据到通用寄存器
MCR Move to Coprocessor 通用寄存器写入协处理器
DDR Double‑Data‑Rate 双倍速率同步内存
FTP File Transfer Protocol 文件传输协议

💡裸机开发踩坑总结

  1. IMX6ULL操作GPIO三件套:时钟CCM、IOMUXC引脚复用、GPIO方向数据寄存器,缺一不可。
  2. 硬件寄存器指针一定要volatile,防止编译器优化。
  3. GIC中断处理完成必须写C_EOIR,否则会重复触发中断。
  4. NAND/eMMC不能XIP,程序必须加载到DDR运行;NOR可以直接原地执行。
  5. Makefile规则行必须是Tab,不能使用空格。
相关推荐
一直C3 小时前
ARM裸机开发|IMX6ULL GIC中断详解,中断流程、GIC版本分类、CP15协处理器
arm·imx6ull·寄存器
sunoo-2295 小时前
【ARM嵌入式学习笔记Day5】一文打通GPIO中断全链路:从硬件引脚→GIC→汇编入口→C语言处理
arm开发·笔记·学习·中断·gic·裸机开发
祖力556 小时前
ARM中断(IMX6ULL中断、GIC通用中断控制器)
嵌入式硬件·arm·imx6ull·中断·gic·通用中断控制器
susplus1 天前
【ARM 裸机开发 (IMX6ULL-mini)】GNU工具、Makefile 工程构建、链接脚本详解|C 语言点灯 + 蜂鸣器驱动
linux·arm·makefile·imx6ull
晊晌_h2 天前
ARM 学习 |ARM 汇编指令实战笔记
嵌入式·arm·arm汇编
G.E.M.小白2 天前
【IMX6ULL裸机LED开发全程解析】存储架构 + 编译链接 + 内存段 + Makefile
嵌入式·imx6ull·裸机开发
一直C2 天前
ARM裸机开发Day04|IMX6ULL汇编&C点灯实操,Makefile、链接脚本、段解析
嵌入式硬件·imx6ull·交叉编译
AAA代码批发商3 天前
Days 46 i.MX6ULL 裸机开发|从内核切入外设,汇编点亮 LED(补充)
arm开发·嵌入式·裸机开发
祖力553 天前
ARM汇编LED实验
汇编·arm·imx6ull