嵌入式汇编 linux,嵌入式Linux之汇编LED

参考文档 【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.2

一、汇编LED原理分析

为什么要学习Cortex-A汇编:

①、需要用汇编初始化一些SOC外设。

②、使用汇编初始化DDR,I.MX6U不需要。

③、设置sp指针,一般指向DDR,设置好C语言运行环境。

1、ALPHA开发板LED灯硬件原理分析:

STM32 IO初始化流程:

①、使能GPIO时钟。

②、设置IO复用,将其复用为GPIO

③、配置GPIO的电气属性。

④、使用GPIO,输出高/低电平。

I.MX6ULL IO初始化:

①、使能时钟,CCGR0~CCGR6这7个寄存器控制着6ULL所有外设时钟的使能。为了简单,设置CCGR0~CCGR6这7个寄存器全部为0XFFFFFFFF,相当于使能所有外设时钟。

②、IO复用,将寄存器IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03的bit3~0设置为0101=5,这样GPIO1_IO03就复用为GPIO。

③、寄存器IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03是设置GPIO1_IO03的电气属性。包括压摆率、速度、驱动能力、开漏、上下拉等。

④、配置GPIO功能,设置输入输出。设置GPIO1_DR寄存器bit3为1,也就是设置为输出模式。设置GPIO1_DR寄存器的bit3,为1表示输出高电平,为0表示输出低电平。

二、源码分析

.global _start /* 全局标号 */

/*

* 描述:_start函数,程序从此函数开始执行此函数完成时钟使能、

* GPIO初始化、最终控制GPIO输出低电平来点亮LED灯。

*/

_start:

/* 关闭I,DCache和MMU 重点:关于到是否能用uboot启动

* 采取读-改-写的方式。

*/

mrc p15, 0, r0, c1, c0, 0 /* 读取CP15的C1寄存器到R0中 */

bic r0, r0, #(0x1 << 12) /* 清除C1寄存器的bit12位(I位),关闭I Cache */

bic r0, r0, #(0x1 << 2) /* 清除C1寄存器的bit2(C位),关闭D Cache */

bic r0, r0, #0x2 /* 清除C1寄存器的bit1(A位),关闭对齐*/

bic r0, r0, #(0x1 << 11) /* 清除C1寄存器的bit11(Z位),关闭分支预测*/

bic r0, r0, #0x1 /* 清除C1寄存器的bit0(M位),关闭MMU */

mcr p15, 0, r0, c1, c0, 0 /* 将r0寄存器中的值写入到CP15的C1寄存器中 */

/* 1、使能所有时钟 */

ldr r0, =0X020C4068 /* CCGR0 */

ldr r1, =0XFFFFFFFF

str r1, [r0]

ldr r0, =0X020C406C /* CCGR1 */

str r1, [r0]

ldr r0, =0X020C4070 /* CCGR2 */

str r1, [r0]

ldr r0, =0X020C4074 /* CCGR3 */

str r1, [r0]

ldr r0, =0X020C4078 /* CCGR4 */

str r1, [r0]

ldr r0, =0X020C407C /* CCGR5 */

str r1, [r0]

ldr r0, =0X020C4080 /* CCGR6 */

str r1, [r0]

/* 2、设置GPIO1_IO03复用为GPIO1_IO03 */

ldr r0, =0X020E0068/* 将寄存器SW_MUX_GPIO1_IO03_BASE加载到r0中 */

ldr r1, =0X5/* 设置寄存器SW_MUX_GPIO1_IO03_BASE的MUX_MODE为5 */

str r1,[r0]

/* 3、配置GPIO1_IO03的IO属性

*bit 16:0 HYS关闭

*bit [15:14]: 00 默认下拉

*bit [13]: 0 kepper功能

*bit [12]: 1 pull/keeper使能

*bit [11]: 0 关闭开路输出

*bit [7:6]: 10 速度100Mhz

*bit [5:3]: 110 R0/6驱动能力

*bit [0]: 0 低转换率

*/

ldr r0, =0X020E02F4/*寄存器SW_PAD_GPIO1_IO03_BASE */

ldr r1, =0X10B0

str r1,[r0]

/* 4、设置GPIO1_IO03为输出 */

ldr r0, =0X0209C004/*寄存器GPIO1_GDIR */

ldr r1, =0X0000008

str r1,[r0]

/* 5、关闭LED0

* 设置GPIO1_IO03输出低电平

*/

ldr r0, =0X0209C000/*寄存器GPIO1_DR */

ldr r1, =0x8

str r1,[r0]

ldr r3, =0xfffff/*延时时间*/

/*

* 描述:loop死循环

*/

loop:

ldr r0, =0X0209C000/*LED 关 寄存器GPIO1_DR */

ldr r1, =0x8

str r1,[r0]

mov r2,#0

delay0:/*延时1*/

add r2, r2, #0x1/*r2=r2+1*/

cmp r2, r3/*如果r2

ble delay0

ldr r0, =0X0209C000/*LED 开 寄存器GPIO1_DR */

ldr r1, =0x0

str r1,[r0]

mov r2,#0

delay1:/*延时1*/

add r2, r2, #0x1

cmp r2, r3

ble delay1

b loop /*跳转到loop*/

三、编译程序

arm-linux-gnueabihf-gcc -g -c led.s -o led.o

arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf

arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin

arm-linux-gnueabihf-objdump -D led.elf > led.dis

1、

arm-linux-gnueabihf-gcc -g -c led.s -o led.o

上述命令就是将 led.s 编译为 led.o,其中“-g”选项是产生调试信息,GDB 能够使用这些 调试信息进行代码调试。“-c”选项是编译源文件,但是不链接。“-o”选项是指定编译产生的文 件名字,这里我们指定 led.s 编译完成以后的文件名字为 led.o。执行上述命令以后就会编译生 成一个 led.o 文件

2、

arm-linux-gnueabihf-ld -Ttext 0X87800000 led.o -o led.elf

上述命令中-Ttext 就是指定链接地址,“-o”选项指定链接生成的 elf 文件名,这里我们命名 为 led.elf。上述命令执行完以后就会在工程目录下多一个 led.elf 文件

链接:

链接就是将所有.o文件链接在一起,并且链接到指定的地方。本实验链接的时候要指定链接起始地址。链接起始地址就是代码运行的起始地址。

对于6ULL来说,链接起始地址应该指向RAM地址。RAM分为内部RAM和外部RAM,也就是 DDR。6ULL内部RAM地址范围0X900000-0X91FFFF。也可以放到外部DDR中,对于I.MX6U-ALPHA开发板,512MB字节DDR版本的核心板,DDR范围就是0X80000000-0X9FFFFFFF。对于256MB的DDR来说,那就是0X80000000-0X8FFFFFFF。

裸机代码的链接起始地址为0X87800000。要使用DDR,那么必须要初始化DDR,对于I.MX来说bin文件不能直接运行,需要添加一个头部,这个头部信息包含了DDR的初始化参数,I.MX系列SOC内部boot rom会从SD卡,EMMC等外置存储中读取头部信息,然后初始化DDR,并且将bin文件拷贝到指定的地方。

Bin的运行地址一定要和链接起始地址一致。位置无关代码除外。

3、

arm-linux-gnueabihf-objcopy 更像一个格式转换工具,我们需要用它将 led.elf 文件转换为 led.bin 文件,命令如下:

arm-linux-gnueabihf-objcopy -O binary -S -g led.elf led.bin

上述命令中,“-O”选项指定以什么格式输出,后面的“binary”表示以二进制格式输出, 选项“-S”表示不要复制源文件中的重定位信息和符号信息,“-g”表示不复制源文件中的调试信息。

4、

大多数情况下我们都是用 C 语言写试验例程的,有时候需要查看其汇编代码来调试代码, 因此就需要进行反汇编,一般可以将 elf 文件反汇编,比如如下命令:

arm-linux-gnueabihf-objdump -D led.elf > led.dis

上述代码中的“-D”选项表示反汇编所有的段,反汇编完成以后就会在当前目录下出现一 个名为 led.dis 文件

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值