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中间文件。

相关推荐
女神下凡1 小时前
端侧 AI 产品 有什么产品
人工智能·嵌入式硬件
pan0c232 小时前
什么是ESP8266-NodeMCU
嵌入式硬件·esp8266
Brilliantwxx2 小时前
【STM32】 SPI阻塞式通信与HAL源码(串口读ID实战)
开发语言·stm32·单片机·嵌入式硬件·ecmascript
t13970182 小时前
太阳能板与电池的电压匹配:别用开路电压 Voc,要用 Vmp
嵌入式硬件·物联网·硬件设计·电源管理·太阳能供电
老k一步步来2 小时前
鸣志驱动器 Alarm_CodeTypeDef 状态报警位详解
嵌入式硬件
星栖与芯3 小时前
LiteOS-M 切换汇编逐行图解(5):HalPendSV 任务切换的现场搬运(五阶段逐行)
汇编·stm32·嵌入式硬件·harmonyos
2601_958352903 小时前
不改PCB也能调拾音方向?真相在这。
前端·嵌入式硬件·回声消除·语音模块·降噪处理
M78佐菲3 小时前
ARM学习笔记(四)
linux·arm开发·笔记·嵌入式硬件·学习
半导体憨包3 小时前
光伏组件级MLPE功率优化器DCDC:25年寿命+IP67+雷击,怎么设计才不“翻车“?
嵌入式硬件·硬件工程·dc-dc·半导体芯片