欢迎光临
我们一直在努力

从零裸机开发 i.MX6ULL:点灯起步,搞定外部中断

i.MX 6ULL 裸机开发


一、点灯开发三阶段

1.1 三个核心模块

点灯涉及三个硬件模块,必须按顺序配置:

模块功能关键寄存器
CCM(时钟) 开启外设时钟门 CCM_CCGR0 ~ CCM_CCGR6
IOMUXC(引脚复用) 设置引脚复用功能 + 电气属性 SW_MUX_CTL_PAD_xxx、SW_PAD_CTL_PAD_xxx
GPIO(通用输入输出) 设置引脚方向、输出电平 GPIOx_GDIR、GPIOx_DR

1.2 阶段一:汇编点灯

直接操作寄存器地址,通过汇编指令完成配置。

配置步骤:

  • 开时钟:写 CCM_CCGR0 ~ CCM_CCGR6 为 0xFFFFFFFF

  • 引脚复用:配置 IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 为 GPIO 功能

  • 电气属性:配置 IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03

  • GPIO 方向:写 GPIO1_GDIR 设置为输出

  • 输出电平:写 GPIO1_DR 控制亮灭


  • 1.3 阶段二:C 语言点灯

    通过宏定义封装寄存器地址,用 C 语言操作。

    关键:volatile 关键字

    • 变量前加 volatile:编译器对该变量的操作不会被优化

    • 指针前加 volatile:通过该指针访问的内存空间不被优化

    寄存器地址宏定义示例:

    \\#define CCM\\_CCGR0 (\\*((volatile unsigned int \\*)(0x020C4068)))

    \\#define CCM\\_CCGR1 (\\*((volatile unsigned int \\*)(0x020C406C)))

    // … 其余 CCGR2 \\~ CCGR6

    \\#define SW\\_MUX\\_CTL\\_PAD\\_GPIO1\\_IO03 (\\*((volatile unsigned int \\*)(0x020E0068)))

    \\#define SW\\_PAD\\_CTL\\_PAD\\_GPIO1\\_IO03 (\\*((volatile unsigned int \\*)(0x020E02F4)))

    \\#define GPIO1\\_GDIR (\\*((volatile unsigned int \\*)(0x0209C004)))

    \\#define GPIO1\\_DR (\\*((volatile unsigned int \\*)(0x0209C000)))


    1.4 阶段三:NXP 固件库点灯

    使用 NXP 提供的 SDK 库函数,封装更简洁。

    代码示例:

    \\#include "MCIMX6Y2.h"

    \\#include "fsl\\_iomuxc.h"

    \\#include "led.h"

    // 开启所有外设时钟

    void enable\\_clocks(void)

    {

      CCM->CCGR0 = 0xFFFFFFFF;

      CCM->CCGR1 = 0xFFFFFFFF;

      CCM->CCGR2 = 0xFFFFFFFF;

      CCM->CCGR3 = 0xFFFFFFFF;

      CCM->CCGR4 = 0xFFFFFFFF;

      CCM->CCGR5 = 0xFFFFFFFF;

      CCM->CCGR6 = 0xFFFFFFFF;

    }

    // LED 初始化

    void led\\_init(void)

    {

      IOMUXC\\_SetPinMux(IOMUXC\\_GPIO1\\_IO03\\_GPIO1\\_IO03, 0); // 引脚复用

      IOMUXC\\_SetPinConfig(IOMUXC\\_GPIO1\\_IO03\\_GPIO1\\_IO03, 0x10B0); // 电气属性

    &#x20; GPIO1->GDIR |= (1 << 3); // 设置为输出

    }

    // 点亮 LED(低电平点亮)

    void led\\_on(void)

    {

    &#x20; GPIO1->DR &= \\~(1 << 3);

    }


    二、程序内存段

    段名存放内容
    .text 代码、指令(通过 -Ttext 指定起始地址)
    .data 已初始化的全局变量和静态变量
    .bss 初始化为 0 的全局变量和静态变量
    .common 未初始化的全局变量
    .rodata 只读常量

    三、交叉编译工具链(arm-linux-gnueabihf-)

    裸机开发完整流水线:

    start.S / main.c

    &#x20; ↓ arm-linux-gnueabihf-gcc -c

    start.o / main.o

    &#x20; ↓ arm-linux-gnueabihf-ld -Ttext 0x87800000

    led.elf

    &#x20; ↓ arm-linux-gnueabihf-objcopy -O binary

    led.bin ← 下载到开发板运行

    3.1 四个核心工具

    工具作用常用参数产物
    gcc 编译器:源码 → 目标文件 -c(只编译不链接) .o 目标文件
    ld 链接器:合并 .o,分配内存地址 -Ttext 0x87800000 .elf 可执行文件
    objcopy 格式转换:提取纯机器码 -O binary .bin 原始二进制(烧录用)
    objdump 反汇编:机器码 → 汇编代码 -D .dis 反汇编文件(调试用)

    区别

    .elf

    带符号表和调试信息,不能直接下载;

    .bin

    只有纯机器码,是最终烧录文件。


    四、GPIO 外设通用控制流程

    所有 GPIO 外设(LED、蜂鸣器等)都遵循统一的四步流程:

  • 开启时钟:配置 CCM 时钟门控寄存器

  • 查找引脚:查看底板原理图,找到对应外设的引脚

  • 引脚配置:设置引脚复用功能 + 电气属性

  • GPIO 配置:设置方向(输入 / 输出)、读写电平


  • 五、外部中断(按键 EINT)

    5.1 中断系统架构

    在这里插入图片描述

    外设中断源 → GPIO 中断 → GIC 中断控制器 → ARM 内核

    GIC(通用中断控制器):ARM 设计的专门管理 Cortex-A 系列处理器中断的外设。

    5.2 GIC 版本

    版本应用场景
    GIC V1 旧款嵌入式芯片(Cortex-A5)
    GIC V2 i.MX6ULL、树莓派(Cortex-A7,32 位),支持 1020 个中断
    GIC V3-V4 64 位处理器(手机芯片)
    GIC V5 大型服务器、车载算力芯片

    5.3 GIC 中断分类(共 1020 个)

    类型全称说明
    SPI Shared Peripheral Interrupt 共享中断,外设产生的中断,所有 CPU 核都可以处理
    PPI Private Peripheral Interrupt 私有中断,CPU 核与核之间的通信中断
    SGI Software Generated Interrupt 软件中断,由软件指令触发

    i.MX6ULL 实际支持

    160 个中断

    5.4 GPIO 外部中断配置

    以 GPIO1_IO18 按键中断为例:

    外设端(GPIO 寄存器)
    寄存器作用
    GPIO1_ICR2 配置中断触发方式(下降沿 / 上升沿)
    GPIO1_IMR 中断屏蔽寄存器,使能对应引脚的中断
    GPIO1_ISR 中断状态寄存器,查询是否产生中断(写 1 清零)
    GPIO1_EDGE_SEL 设置双边沿触发
    GIC 端寄存器
    寄存器作用
    C_IAR 中断通知寄存器(只读),读取中断号,确定中断源
    C_EOIR 中断结束寄存器(只写),处理完后写入中断号,通知 GIC 处理完毕

    5.5 启动代码中的中断相关配置

    在汇编启动代码中,通过 cp15 协处理器配置:

    mrc p15, 0, r0, c1, 0 // 读取 SCTLR 控制寄存器

    bic r0, r0, #(1 << 13) // 关闭异常向量表重映射

    orr r0, r0, #(1 << 12) // 打开 I-Cache

    mcr p15, 0, r0, c1, c0, 0 // 写回 SCTLR 寄存器

    5.6 内联函数 INLINE

    • 本质是函数,调用前必须有定义

    • 编译时在调用位置展开,不产生函数调用开销,提高效率

    • 适合短小、频繁调用的函数


    赞(0)
    未经允许不得转载:171主机测评 » 从零裸机开发 i.MX6ULL:点灯起步,搞定外部中断
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址