云计算百科
云计算领域专业知识百科平台

IMX6ULL 裸机工程化改造:从手动 Makefile 到全自动编译

一、今日整体目标

本次学习围绕 IMX6ULL 裸机开发,完成从老旧手动 Makefile 到工程化自动扫描 Makefile 的升级改造,核心目标如下:

  • 搭建工程化自动扫描 Makefile 裸机工程,替代老旧手动写 obj 的简单 Makefile。
  • 掌握标准工程目录结构,学会分层管理代码。
  • 掌握链接脚本 .lds 完整写法、作用、BSS 段清零原理。
  • 掌握芯片手册查寄存器的标准驱动开发流程。
  • 完成完整编译、链接、生成 bin、SD 卡烧录、开发板运行全流程。

二、最终标准工程目录(固定规范)

工程根目录结构如下,后续所有裸机工程均按此规范组织:

工程根目录
├─ Makefile # 自动化编译脚本
├─ imx6ull.lds # 链接脚本
├─ bsp/ # 板级驱动包(所有外设代码、底层头文件)
│ ├─ start.S # 启动汇编(栈初始化、BSS清零、跳转main)
│ ├─ beep.c/h
│ ├─ led.c/h
│ ├─ MCIMX6Y2.h
│ └─ cc.h
├─ project/ # 应用层代码(主函数)
│ └─ main.c
└─ obj/ # make自动生成,存放所有.o文件

目录分层职责清晰:bsp 存放所有底层驱动、寄存器头文件和启动汇编;project 存放应用层主函数;根目录只保留 Makefile 和链接脚本;obj 目录由 make 自动生成,统一存放编译产物。

三、新旧 Makefile 对比(核心知识点)

1)旧版(初学简单版)

手动写死所有 .o 文件,新增驱动必须手动修改 Makefile,文件散乱、不规范,维护成本高。

2)新版(今日工程版)

完全自动工程化,具备以下能力:

  • 自动扫描 bsp、project 下所有 .c .S 文件。
  • 自动生成 obj 目录,所有 .o 统一存放,目录整洁。
  • 自动添加 -I 头文件路径,解决头文件找不到问题。
  • 新增外设驱动不用改 Makefile,直接丢进 bsp 即可编译。

常用命令:

  • make clean:清理所有编译产物。
  • make:全自动编译、链接、生成 bin。
  • make load:烧录 SD 卡。

四、链接脚本 imx6ull.lds 完整作用

今天编写的链接脚本版本如下:

SECTIONS
{
. = 0x87800000; // 程序链接起始地址(DDR地址)
.text :
{
obj/start.o // 强制启动汇编放在最开头
*(.text) // 其余所有代码
}
.rodata ALIGN(4) : {*(.rodata*)} // 只读常量,4字节对齐
.data ALIGN(4) : {*(.data)} // 已初始化全局变量
__bss_start = .; // 记录BSS起始地址
.bss ALIGN(4) : {*(.bss) *(.COMMON)} // 未初始化变量
__bss_end = .; // 记录BSS结束地址
}

链接脚本的关键作用:

  • 指定程序运行地址 0x87800000。
  • 保证 start.o 启动代码最先执行。
  • 4 字节对齐满足 ARM 架构要求。
  • 导出 __bss_start、__bss_end 给汇编清零 BSS 段。

五、启动文件 start.S 核心功能

启动文件承担三项核心任务:

  • 设置栈指针(DDR 顶端)。
  • 手动清零 BSS 段(必须做,否则全局变量乱值)。
  • 跳转到 C 语言 main 函数。
  • 后缀必须使用大写 .S:支持预处理、兼容 Makefile 规则。小写 .s 不会被当前 Makefile 识别,也无法预处理。

    六、头文件查找原理(今天最大坑点总结)

    报错现象:文件明明存在,却提示找不到。根本原因是 gcc 不会自动遍历文件夹,只找 Makefile 里通过 -I 指定的目录。

    解决规范(最终标准):所有芯片寄存器头文件、底层头文件全部放入 bsp 目录。因为 Makefile 默认带 -Ibsp,永远能找到,无需修改 Makefile。

    七、芯片手册标准查找流程(驱动开发核心)

    写任何外设驱动,不能死记地址,必须查手册,固定流程如下:

  • 看原理图:确定外设使用的引脚(如 GPIO1_IO08)。
  • 查手册引脚复用:找到该引脚的 IOMUX 寄存器,设为 GPIO 模式。
  • 查 GPIO 寄存器:GDIR 方向寄存器(1=输出 0=输入)、DR 数据寄存器(控制高低电平)。
  • 将寄存器地址写入头文件,在 C 代码中操作。
  • 八、今日所有报错 + 终极原因(全套复盘)

    报错信息原因解决方案
    MCIMX6Y2.h 找不到文件 文件在根目录,但 Makefile 没有 -I.,编译器不搜索根目录 移入 bsp 文件夹
    cc.h 找不到 MCIMX6Y2.h 内部依赖 cc.h,链式头文件缺失 所有依赖头文件统一放 bsp
    cannot find obj/start.o start.S 放在根目录,不在 Makefile 的扫描目录(bsp/project) start.S 放入 bsp
    必须用大写 .S 小写 .s 不会被当前 Makefile 识别,也无法预处理 统一使用大写 .S 后缀

    九、完整工程运行流程

  • start.S 初始化栈、清 BSS,跳转 main。
  • main.c 调用 beep 驱动,循环翻转 IO 电平。
  • Makefile 自动编译 bsp/project 所有文件生成 .o。
  • ld 根据 lds 链接脚本链接成 elf。
  • objcopy 转换成可烧录 bin 文件。
  • make load 烧录 SD 卡,开发板运行。
  • 十、今日学到的工程规范(长期通用)

    • bsp:放所有底层驱动、寄存器头文件、启动汇编。
    • project:放 main 主程序。
    • 根目录:只放 Makefile、lds 脚本。
    • 所有寄存器地址必须来自手册。
    • 工程化 Makefile:一次写完,永久不用改,只管加代码。
    赞(0)
    未经允许不得转载:网硕互联帮助中心 » IMX6ULL 裸机工程化改造:从手动 Makefile 到全自动编译
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!