一、今日整体目标
本次学习围绕 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 核心功能
启动文件承担三项核心任务:
后缀必须使用大写 .S:支持预处理、兼容 Makefile 规则。小写 .s 不会被当前 Makefile 识别,也无法预处理。
六、头文件查找原理(今天最大坑点总结)
报错现象:文件明明存在,却提示找不到。根本原因是 gcc 不会自动遍历文件夹,只找 Makefile 里通过 -I 指定的目录。
解决规范(最终标准):所有芯片寄存器头文件、底层头文件全部放入 bsp 目录。因为 Makefile 默认带 -Ibsp,永远能找到,无需修改 Makefile。
七、芯片手册标准查找流程(驱动开发核心)
写任何外设驱动,不能死记地址,必须查手册,固定流程如下:
八、今日所有报错 + 终极原因(全套复盘)
| 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 后缀 |
九、完整工程运行流程
十、今日学到的工程规范(长期通用)
- bsp:放所有底层驱动、寄存器头文件、启动汇编。
- project:放 main 主程序。
- 根目录:只放 Makefile、lds 脚本。
- 所有寄存器地址必须来自手册。
- 工程化 Makefile:一次写完,永久不用改,只管加代码。
网硕互联帮助中心




评论前必须登录!
注册