一、存储介质对比:S3C2440 vs IMX6ULL
S3C2440 Nor Flash
-
NorFlash地址范围:0x0 ~ 0x200000
-
特点:可以直接寻址,CPU可以直接从NorFlash读取执行代码指令。
IMX6ULL NAND/EMMC
-
IMX6ULL使用EMMC(8GB),EMMC不能直接寻址,CPU不能直接在EMMC上面运行代码。
-
程序必须拷贝到DDR内存中运行。
-
DDR3物理地址空间:0x80000000 ~ 0xA0000000,总大小512MB。
链接时指定代码运行基址:ld -Ttext 0X87800000,.text代码段运行在DDR的0x87800000地址。
二、裸机点灯:汇编点灯 VS C语言点灯
2.1 寄存器访问方式
以CCM_CCGR0时钟寄存器地址 0x020C4068为例
-
汇编点灯:汇编指令直接操作寄存器地址。
-
C语言点灯:把地址强制转换成指针,解引用访问寄存器。
// C语言直接操作寄存器
define CCM_CCGR0 (((unsigned int )0x020C4068))
CCM_CCGR0 = 0xFFFFFFFF;
寄存器特点:写1清0,部分寄存器位写入1代表清除对应状态位。
2.2 volatile关键字
寄存器属于硬件内存,编译器会做优化,会把没有读取的读写操作直接删掉,导致寄存器配置失效。
-
volatile修饰变量:编译器不会对该变量的访问做任何优化。
-
volatile修饰指针:通过该指针访问的内存/寄存器,禁止编译器优化。
// 正确的寄存器指针写法
define CCM_CCGR0 ((volatile unsigned int )0x020C4068)
三、ARM交叉编译工具链完整流程
完整编译、链接、生成bin镜像四步命令:
1.汇编文件编译为目标文件
arm-linux-gnueabihf-gcc -g -c start.S -o start.o
2.C文件编译为目标文件
arm-linux-gnueabihf-gcc -g -c main.c -o main.o
3.链接:指定代码段起始地址,生成elf可执行文件
arm-linux-gnueabihf-ld -Ttext 0x87800000 start.o main.o -o start.elf
4.格式转换:elf转为二进制bin镜像,烧写到EMMC
arm-linux-gnueabihf-objcopy -O binary -S -g start.elf start.bin
工具说明:
-
gcc:编译汇编、C源码,输出.o目标文件
-
ld:链接器,把多个.o文件合并,分配内存地址,生成elf
-
objcopy:格式转换,elf转bin用于烧录
-
objdump:反汇编工具,用来调试分析elf文件
编译参数:
-I:指定头文件搜索路径
-L:指定库文件搜索路径
四、程序五大段详解
程序编译链接之后会划分多个段,每段存放不同内容:
|------------|----------------------------|
| 段名 | 存储内容 |
| .text 段 | 存放代码、程序指令,-Ttext就是指定该段起始地址 |
| .bss 段 | 存放初始化为 0 的全局变量、静态变量 |
| .common 段 | 存放未初始化的全局变量 |
| .data 段 | 存放已经初始化的全局变量、静态变量 |
| .rodata 段 | 存放只读常量,const 修饰数据 |
链接脚本:特殊语法的脚本文件,可以自定义各个段的地址分配,高级裸机工程必备。
五、Makefile三要素
Makefile用来自动化编译工程,避免重复敲长编译命令。
三大核心要素:
-
目标:想要生成的文件(elf、bin、.o目标文件)
-
依赖:生成目标需要的源文件(.c、.S)
-
规则:执行的shell命令,描述如何由依赖生成目标。
六、IMX6ULL裸机工程架构
工程模块划分:
-
project主目录:main.c业务C代码、start.S汇编启动文件
-
imx6ull库文件:芯片相关底层库
-
bsp板级外设驱动文件夹
-
led.c / led.h LED驱动
-
beep.c / beep.h蜂鸣器驱动
- obj目录:存放编译生成的.o中间目标文件
七、Day04学习总结
-
NorFlash可以直接寻址执行代码;IMX6ULL EMMC不能直接寻址,代码必须加载到DDR内存运行;
-
C语言操作硬件寄存器必须加volatile,防止编译器优化;
-
完整工具链流程:gcc编译→ld链接→objcopy生成bin;
-
理解.text/.data/.bss/.rodata/.common各个段的作用;
-
Makefile三要素:目标、依赖、规则;学会使用-I、-L指定头文件、库路径;
-
规范裸机工程目录,区分bsp驱动、主业务代码、obj中间文件。