目标:点亮LED
1、查数据手册
硬件图中,找到LED灯对应的GPIO
从二极管方向看出,端口输出低电平时,电流经过,LED点亮。
再到数据手册查找对应的寄存器
GPBCON:模式选择,GPIO配置可以有3中模式,输入、输出、DAC
GPBDAT:数据位
GPBUP:上拉禁能标志
2、纯汇编程序
LED1对应的是GPB5
(1)配置GPB5为输出引脚,给GPBCON寄存器写入(1 << 10)
(2)设置GPB5输出低电平,给GPBDAT寄存器写入(1 << 5)
(3)GPBUP保持默认
.text
.global _start
_start:
ldr r1, =0x56000010
ldr r0, =0x400
str r0, [r1]
ldr r1, =0x56000014
ldr r0, =0
str r0, [r1]
halt:
b halt
3、编译程序
编译常用的命令在gcc/ld/objcopy/objdump命令中整理。
在终端中输入命令:
jw@pc:~/w/02-led$ arm-linux-gcc -c -o led_on.o LED.S
jw@pc:~/w/02-led$ arm-linux-ld -Ttext 0 led_on.o -o led_on.elf
jw@pc:~/w/02-led$ arm-linux-objcopy -O binary -S led_on.elf led_on.bin
jw@pc:~/w/02-led$ ls -l
总用量 20
-rwxrwxr-x 1 jw jw 36 5月 18 22:06 led_on.bin
-rwxrwxr-x 1 jw jw 33502 5月 18 22:05 led_on.elf
-rw-rw-r-- 1 jw jw 671 5月 18 22:05 led_on.o
-rwxrw-rw- 1 jw jw 522 5月 18 22:00 LED.S
也可以使用makefile:
all:
arm-linux-gcc -c -o led_on.o LED.S
arm-linux-ld -Ttext 0 led_on.o -o led_on.elf
arm-linux-objcopy -O binary -S led_on.elf led_on.bin
arm-linux-objdump -D led_on.elf > led_on.dis
clean:
rm *.bin *.o *.elf
4、烧写程序
使用JLink往开发板的NOR FLASH中烧写这个程序
烧写过程与上一篇文章(一)MINI2440–恢复出厂相同。
烧写成功后,重启,led1被点亮了。
5、常用的汇编指令小结
ARM是RISC结构,在ARM架构下, 数据从内存到CPU之间的移动只能通过LDR/STR指令来完成. 而MOV只能在寄存器之间移动数据,或者把立即数移动到寄存器中,并且数据的长度不能超过8位
比如想把数据从RAM中某处读取到CPU寄存器中,只能使用ldr
ldr(load)
ldr r0,=label 用于加载立即数或一个地址值到指定寄存器中
-
如果label是立即数: ldr r0,=0X123 ;将0X123存入r0中
-
如果name是个标识符: ldr r0,=label_1 ;将label_1所指向的地址值存入r0中
ldr r0,[r1] ;将R1地址中的值存到r0中
ldr r1,[r2,#16] ;将(r2+16)地址中的内容存到r1中
ldr r1,[r2],#4 ;将r2地址中的内容存到r1中,同时r2=r2+4
str(store)
str r1,[r2] ; 将r1中的值存到r2所指定的地址中
str r1,[r2,#4] ;将r1中的值存到r2+4所指定的地址中
str r1,[r2],#4 ;将r1中的值存到r2所指定的地址中, 同时r2=r2+4
6、汇编+C
如果要使用C语言,则需要为C程序搭建环境,主要是配置堆栈,然后调用main函数。
而堆栈的栈顶位置随着Nand启动、非Nand启动而有所不同,对于MINI2440的内存空间,可以参考:
s3c2440启动过程分析
s3c2440启动过程详解 (主要讲启动时nand nor的地址映射)
- 为什栈顶是4096而不是4095?
可用栈空间大小是4096字节,sp始终指向最后一个进入堆栈的信息所在的单元。
那么,入栈时,SP先减,再拷贝数据入栈;出栈时,先拷贝数据出栈,SP再加。栈空时,有SP=Stack.size;栈满时,有SP=0。 - 为什么栈顶是4096而不是0?
因为栈是从高地址向低地址生长
汇编程序,主要为C程序搭建运行环境和调用C:
.text
.global _start
_start:
ldr r0, =0x53000000
ldr r1, =0
str r1, [r0]
mov r1, #0
ldr r0, [r1]
str r1, [r1]
ldr r2, [r1]
cmp r1, r2
ldr sp, =0x40000000+4096
moveq sp, #4096
streq r0, [r1]
bl main
halt:
b halt
C程序操作寄存器:
int main()
{
unsigned int *pGPBCON = (unsigned int *)0x56000010;
unsigned int *pGPBDAT = (unsigned int *)0x56000014;
*pGPFCON = 0x400;
*pGPFDAT = 0;
return 0;
}
Makefile
all:
arm-linux-gcc -c -o led.o led.c
arm-linux-gcc -c -o start.o start.S
arm-linux-ld -Ttext 0 start.o led.o -o led.elf
arm-linux-objcopy -O binary -S led.elf led.bin
arm-linux-objdump -D led.elf > led.dis
clean:
rm *.bin *.o *.elf *.dis
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)