ARM裸机开发Day04|IMX6ULL汇编&C点灯实操,Makefile、链接脚本、段解析

一、存储介质对比: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为例

  1. 汇编点灯:汇编指令直接操作寄存器地址。

  2. 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用来自动化编译工程,避免重复敲长编译命令。

三大核心要素:

  1. 目标:想要生成的文件(elf、bin、.o目标文件)

  2. 依赖:生成目标需要的源文件(.c、.S)

  3. 规则:执行的shell命令,描述如何由依赖生成目标。

六、IMX6ULL裸机工程架构

工程模块划分:

  1. project主目录:main.c业务C代码、start.S汇编启动文件

  2. imx6ull库文件:芯片相关底层库

  3. bsp板级外设驱动文件夹

  • led.c / led.h LED驱动

  • beep.c / beep.h蜂鸣器驱动

  1. obj目录:存放编译生成的.o中间目标文件

七、Day04学习总结

  1. NorFlash可以直接寻址执行代码;IMX6ULL EMMC不能直接寻址,代码必须加载到DDR内存运行;

  2. C语言操作硬件寄存器必须加volatile,防止编译器优化;

  3. 完整工具链流程:gcc编译→ld链接→objcopy生成bin;

  4. 理解.text/.data/.bss/.rodata/.common各个段的作用;

  5. Makefile三要素:目标、依赖、规则;学会使用-I、-L指定头文件、库路径;

  6. 规范裸机工程目录,区分bsp驱动、主业务代码、obj中间文件。

相关推荐
fly_sunnn2 小时前
STM32-GPIO
stm32·单片机·嵌入式硬件
宵时待雨5 小时前
STM32基础1:嵌入式历史与生态
stm32·单片机·嵌入式硬件
不会代码的小猴6 小时前
启动文件
stm32·嵌入式硬件
G.E.M.小白7 小时前
【Linux嵌入式蜂鸣器驱动开发】原理图分析、寄存器寻址、完整驱动+应用+Makefile
嵌入式·imx6ull·linux驱动开发·蜂鸣器驱动
2401_862880827 小时前
iMX6ULL 驱动工程搭建 + LED 灯驱动
c语言·驱动开发·嵌入式硬件
hahaha60167 小时前
FPGA+ARM实现AWB的全流程
人工智能·嵌入式硬件·算法·计算机视觉·fpga开发
老孟说禅8 小时前
硬件测试 - 测试用例设计:测试需求分析、测试点提取、测试用例编写方法
单片机·嵌入式硬件·智能硬件
逐光者9338 小时前
STM32通信协议——I2C
stm32·单片机·嵌入式硬件
千秋岁rr8 小时前
15.PWR电源控制
单片机·嵌入式硬件
额额额对了8 小时前
嵌入式 Linux 启动程序文件
开发语言·嵌入式硬件·php