本实验选择的是正点原子I.MX6U阿尔法开发板。
交叉编译器
交叉编译器:开发指南对应:4.3节
当今CPU架构只剩两种:X86架构和ARM架构
X86主要追求性能,但会导致功耗大,不节能
ARM则是追求节能,低功耗,但和X86相比性能较差
X86采用CISC复杂指令集计算机,而ARM采用的是RISC精简指令集计算机。
So?
ARM 裸机、Uboot 移植、Linux 移植这些都需要在 Ubuntu 下进行编译。但是 Ubuntu 自带的 gcc 编译器是针对 X86 架构的。而我们现在要编译的是 ARM 架构的代码,所以我们需要一个在 X86 架构的 PC 上运行,可以编译 ARM 架构代码的 GCC 编译器,这个编译器就叫做交叉编译器。
汇编语法
汇编语法:对应开发指南:7.1节
.global _start
_start:
LDR R0, =0X0209C004 @将寄存器地址 0X0209C004 加载到 R0 中,即 R0=0X0209C004
LDR R1, [R0] @读取地址 0X0209C004 中的数据到 R1 寄存器中
STR R1, [R0] @将 R1 中的值写入到 R0 中所保存的地址中
b main @跳转到 main 函数
点灯
点灯:对应开发指南:第八章
这里的GPIO_3实际上是GPIO1_03, 当GPIO1_03输出低电平时,灯亮。
对比STM32点灯:
1.使能GPIO时钟
2.设置io复用为GPIO
3.配置GPIO 属性
4.输出高低电平
I.MX6UL 点灯:
1.使能时钟:
CCGR0~CCGR6,七个寄存器控制所有的外设时钟的使能。32位寄存器,即0xFFFFFFFF。相当于使能所有外设。(F=1111)
2.复用:
寄存器:IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03设置为0x5 (0101).
3.配置属性:
寄存器:IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03
重点是压摆率,速度,驱动能力,开漏,上下拉等。
4.配置GPIO功能,设置输入输出和高低电平。
寄存器:GPIOx_DR控制位,设置GPIO1_DR bit3为0,表示低电平。
GPIOx_GDIR方向位,设置GPIO1_GDIR bit3为1,表示输出。
编程
1.编写led.s
.global _start @全局标号
_start:
/*使能外设时钟*/
ldr r0, =0x020c4068 @CCGR0地址
ldr r1, =0xffffffff
str r1,[r0] @将0xffffffff写进CCGR0中
ldr r0, =0x020c406c @CCGR1地址
str r1,[r0] @将0xffffffff写进CCGR1中
ldr r0, =0x020c4070 @CCGR2地址
str r1,[r0] @将0xffffffff写进CCGR2中
ldr r0, =0x020c4074 @CCGR3地址
str r1,[r0] @将0xffffffff写进CCGR3中
ldr r0, =0x020c4078 @CCGR4地址
str r1,[r0] @将0xffffffff写进CCGR4中
ldr r0, =0x020c407c @CCGR5地址
str r1,[r0] @将0xffffffff写进CCGR5中
ldr r0, =0x020c4080 @CCGR6地址
str r1,[r0] @将0xffffffff写进CCGR6中
/* 配置IO复用功能*/
/* IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03 = 0x5 */
ldr r0, =0x020e0068 @IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03地址
ldr r1, =0x5
str r1,[r0]
/* 配置属性*/
/* IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03地址0x020e02f4*/
ldr r0, =0x020e02f4
ldr r1, =0x10b0
str r1,[r0]
/* 配置GPIO输入输出,高低电平*/
/*GPIO_DR和GPIO_GDIR*/
ldr r0, =0x0209c004 @GDIR
ldr r1, =0x8
str r1,[r0]
ldr r0, =0x0209c000 @DR
ldr r1, =0
str r1,[r0]
/*死循环*/
loop:
b loop
2.将所有的.s和.c文件变成.o文件
arm-linux-gnueabihf-gcc -g -c led.s -o led.o
3.将所有的.o文件链接为.elf格式的可执行文件
链接就是将所有的.o文件链接在一起,并且指定到链接的地方,也就是要指定起始地址,也就是代码开始运行的地址。
对于6UL来说,链接起始地址应该指向RAM地址。因为内部ROM用不了,基本上所有的corxA芯片都没有内部flash。RAM又分为内部RAM和外部RAM (DDR)。
内部RAM 地址范围0x900000~0x91FFFF,只有128KB(0x20000)(128*1024)。
512MB的DDR地址范围从0x80000000~0x9FFFFFFF
256MB的DDR地址范围从0x80000000~0x8FFFFFFF
这里选用DDR。链接地址设为0x87800000
对于imx来说,bin文件不能直接运行,需要添加一个头部,这个头包含了DDR 的初始化参数。
arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf
4.将.elf文件转为bin文件
arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin
5.将.elf文件转为汇编,反汇编
arm-linux-gnueabihf-objdump -D led.elf > led.dis
烧写
stm32是烧写到内部flash
6UL烧写到SD卡里面,但是不能直接烧写bin文件,需要在bin前面添加头部,使用imxdownload软件。
ls /dev/sd* -l 查看读卡器信息
chmod 777 imxdownload 开通权限
./imxdownload led.bin /dev/sda 烧写