1. 确定硬件连接
打开OK6410底板电路图,找到LED,可以发现NLEDx为0时LED点亮。
找到LED的控制引脚,发现LED控制引脚通过连接器连到了核心板:
打开核心板电路图,找到对应的连接器中相同位置下的引脚,发现核心板上的命名与底板相同。
注意:设计者为了方便会将核心板与底板连接处的端口命名为相同的名字,但判断两者的连接位置与端口名其实是没有关系的。从底板上可以看出4个LED所在的连接器引脚编号分别为47,49,46和39,因此在核心板上应该找连接器上这几个编号的引脚,核心板连接器上47,49,46和39号引脚才是与底板LED相连的引脚,只不过设计者为了方便,将核心板上这几个引脚也命名为NLED1~4。
继续在核心板上寻找,能找到NLEDx控制的引脚为GPM0~3
2. 确定GPM相关寄存器的地址和要写入的值
打开6410的芯片手册,找到GPM相关寄存器
可以发现有3个寄存器与GPM相关,三个寄存器的地址分别为0x7F008820、0x7F008824、0x7F008828,其中GPMCON用于配置引脚功能
我们要控制LED需要把GPM0~3都配置成输出模式,因此GPMCON的位[15:0]应为0x1111。GPMDAT用于控制引脚输出电平
如果要控制LED全亮,则GPMDAT位[3:0]应为0x0,全灭则为0xF。GPMPUD用于使能引脚的上下拉,一般会将LED控制引脚配置为上拉模式(注意区分信号的输入输出和电流的流入流出,GPMCON配置输出指的是信号从6410输出到外部,当输出信号为0的时候电流会流入6410芯片)。因此GPMPUD的位[7:0]应为0xAA。
3. 编写汇编代码
编写led.s
1 .section .text 2 .global _start 3 _start: 4 LDR R0, =0x7F008820 @GPMCON,也可以认为是GPM寄存器基地值 5 6 LDR R1, [R0] @取出GPMCON的值 7 LDR R2, =0xFFFF 8 BIC R1, R1, R2 9 LDR R2, =0x1111 10 ORR R1, R1, R2 11 STR R1, [R0] @配置GPM0~3为输出模式 12 13 LDR R1, [R0, #4] @取出GPMDAT的值 14 ORR R1, R1, #0xF 15 STR R1, [R0, #4] @GPMDAT低4位置1,所有LED关闭 16 17 LDR R1, [R0, #8] @取出GPMPUD的值 18 BIC R1, R1, #0xFF 19 ORR R1, R1, #0xAA 20 STR R1, [R0, #8] @GPM0~3使能上拉 21 loop: 22 LDR R1, [R0, #4] 23 BIC R1, R1, #0xF 24 ORR R1, R1, #0xE 25 STR R1, [R0, #4] @点亮第一个LED 26 BL delay 27 28 LDR R1, [R0, #4] 29 BIC R1, R1, #0xF 30 ORR R1, R1, #0xD 31 STR R1, [R0, #4] @点亮第二个LED 32 BL delay 33 34 LDR R1, [R0, #4] 35 BIC R1, R1, #0xF 36 ORR R1, R1, #0xB 37 STR R1, [R0, #4] @点亮第三个LED 38 BL delay 39 40 LDR R1, [R0, #4] 41 BIC R1, R1, #0xF 42 ORR R1, R1, #0x7 43 STR R1, [R0, #4] @点亮第四个LED 44 BL delay 45 B loop 46 delay: 47 LDR R2, =0x1000000 48 delay_loop: 49 SUB R2, R2, #1 50 CMP R2, #0 51 BNE delay_loop 52 MOV PC, LR 53 54 .end
输入命令:
arm-none-linux-gnueabi-gcc -c led.s -o led.o
arm-none-linux-gnueabi-ld -Ttext 0 led.o -o led.elf
arm-none-linux-gnueabi-objcopy -O binary led.elf led.bin
此时生成了可执行文件led.bin
4. 下载文件
连接minicom,重启后进入U-boot,输入dnw 50008000
在虚拟机中输入:sudo dnw led.bin
下载成功后在开发板中输入:go 50008000
此时可以看到4个LED呈流水灯效果。
注意:我是利用U-boot下载程序,此时U-boot已经运行起来了,而U-boot已经做了很多初始化工作了,如设置堆栈指针、关闭看门狗、指定外设基地址等,如果想要将程序烧写进Nandflash的0地址,则这些初始化工作必须自己做。