一、汇编指令学习
ldr r0, [r1]
:假设 r1 的值是 x,读取 地址 x 上 数据 (4 字节) 到 r0 中 str r0, [r1]
:假设 r1 的值是 x,把 r0 的值(4 字节) 写到 地址 x 上mov r0, r1
:把 r1 的值赋给 r0,相当于 c 语言 r0=r1mov r0, #0x100
:直接赋值操作 r0=0x100ldr r0, =0x12345678
:伪指令,最后会实现 r0=0x12345678。因为 arm 一条指令是 32 位除了包含数据本身还要包含指令,一条命令无法操作太长的数据sub r0, r1, #4/ 寄存器
:减法意思就是 r0=r1-4/ 寄存器值add r0, r1, #4/ 寄存器
:加法意思就是 r0=r1+4/ 寄存器值bl xxx
:执行两部操作 1. 跳转到 xxx 2. 返回地址(下一条指令地址)保存到 lr 寄存器中
二、代码编写
硬件连接(低电平点亮)
寄存器
-
寄存器地址
-
PBCON
-
GPBDAT
说明
- 需要把 PBCON 配置为 output,GPBDAT 对应位置设置输出 0 / 1 电平
- 配置 GPB5、6、7、8 为 输出PBCON 写入0x00015400
+ 配置 GPB5、6、7、8 输出 0100 值0x00000040
代码
编译环境
代码量较小使用 Nas 上的 docker 版 ubuntu 编译运行/etc/init.d/ssh start
:开启 sshssh -p 1922 root@10.0.0.2
:ssh 指定端口
汇编
.text
.global _start
_start:
ldr r0, =0x56000010
mov r1, #0x00015400
str r1, [r0]
ldr r0, =0x56000014
ldr r1, =0x00000040
str r1, [r0]
halt:
b halt
Makefile
all:
arm-linux-gcc -c -o led_on.o led_on.s
arm-linux-ld -Ttext 0x00000000 led_on.o -o led_on_elf
arm-linux-objcopy -O binary -S led_on_elf led_on.bin
clean:
rm -f led_on.bin led_on_elf *.o
c 语言
- 指针
指针的类型决定了写入的字节数
- C 代码(点亮 0010)
int main(){unsigned int *pGPBCON = (unsigned int *)0x56000010;
unsigned int *pGPBDAT = (unsigned int *)0x56000014;
*pGPBCON = 0x00015400;
*pGPBDAT = 0x00000080;
return 0;
}
- 汇编代码(引导 C 函数)
.text
.global _start
_start:
/* 设置栈 */
ldr sp, =4096 /*nand 启动 设置在 4k 顶部 */
//ldr sp, =0x4000000 + 4096 /*nor 启动 */
/* 调用 main*/
bl main
halt:
b halt
- Makefile
all:
arm-linux-gcc -c -o led.o led.c
arm-linux-gcc -c -o start.o start.S
arm-linux-ld -Ttext 0x00000000 start.o led.o -o led_elf
arm-linux-objcopy -O binary -S led_elf led.bin
clean:
rm -f led_on.bin led_on_elf *.o
二、程序下载
因为目前使用的是 64M 版本不支持 minitools 工具所以用 supervivi 结合 DNW 的办法
- win10 可用 DNW 说明
- supervivi 截图,选择 v 下载到 nand flash