目录
基于A9的流水灯试验:
Makefile:
test.lds:
makefile初步制作,arm-linux- (gcc/ld/objcopy/objdump)详解:makefile初步制作,arm-linux- (gcc/ld/objcopy/objdump)详解 - 腾讯云开发者社区-腾讯云 (tencent.com)
arm位清零bic指令:http://t.csdn.cn/q2bMo
ARM指令集详解:http://t.csdn.cn/KIXMX
联合 c 和 汇编的流水灯实现:
基于A9的流水灯试验:
+GPF3CON 配置寄存器 0x1140 01E0 [23:20] 0x1 Output
+GPF3DAT 辅助输入输出pin 0x1140 01E4 [ 5: 0] 0x1 LED5 亮+GPX1CON 配置寄存器 0x1100 0C20 [ 3: 0] 0x1 Output
+GPX1DAT 辅助输入输出pin 0x1100 0C24 [ 7: 0] 0x1 LED3 亮+GPX2CON 配置寄存器 0x1100 0C40 [31:28] 0x1 Output
+GPX2DAT 辅助输入输出pin 0x1100 0C44 [ 7: 0] 0x1 LED2 亮+GPX3CON 配置寄存器 0x1100 0C60 [19:16] 0x1 Output
+GPX3DAT 辅助输入输出pin 0x1100 0C64 [ 7: 0] 0x1 LED4 亮.global _start _start: b reset ldr pc,_undefined_instruction ldr pc,_software_interrupt ldr pc,_prefetch_about ldr pc,_data_about ldr pc,_not_used ldr pc,_irq ldr pc,_fiq _undefined_instruction: .word _undefined_instruction _software_interrupt: .word _software_interrupt _prefetch_about: .word _prefetch_about _data_about: .word _data_about _not_used: .word _not_used _irq: .word _irq _fiq: .word _fiq reset: /*设置cpu模式为svc模式*/ mrs r0,cpsr bic r0,r0,#0x1f /*清除cpsr的模式位*/ orr r0,r0,#0xd3 /*让处理器处于ARM状态、禁用irq、fiq,并将模式设置为svc模式*/ msr cpsr,r0 /*设置异常向量表起始地址*/ ldr r0, =_start mcr p15,0,r0,c12,c0,0 /*这里需要是 c12,不能是 c15,还是不太明白*/ /*用户初始化*/ ldr sp,stacktop /*设置svc的栈顶*/ sub r6,sp,#64 /*计算user需要指向的栈顶位置/ /*切换到用户模式*/ mrs r0,cpsr bic r0,r0,#0x1f orr r0,r0,#0x10 /*处理器状态不变,启用irq、fiq,模式设置为user*/ msr cpsr,r0 mov sp,r6 /*设置user模式的栈顶*/ bl _main _main: ldr r0,=0x114001E0 /*led5 GPF3CON*/ ldr r1,=0x114001E4 /*led5 GPF3DAT*/ ldr r2,=0x11000c20 /*led3 GPX1CON*/ ldr r3,=0x11000c24 /*led3 GPX1DAT*/ ldr r4,=0x11000c40 /*led2 GPX2CON*/ ldr r5,=0x11000c44 /*led2 GPX2DAT*/ ldr r6,=0x11000c60 /*led4 GPX3CON*/ ldr r7,=0x11000c64 /*led4 GPX3DAT*/ /*led5 配置输出pin*/ ldr r8,[r0] bic r8,r8,#0x00f00000 orr r8,r8,#0x00100000 str r8,[r0] /*led3 配置输出pin*/ ldr r8,[r2] bic r8,r8,#0xf orr r8,r8,#0x1 str r8,[r2] /*led4 配置输出pin*/ ldr r8,[r6] bic r8,r8,#0x000f0000 orr r8,r8,#0x00010000 str r8,[r6] /*led2 配置输出pin*/ ldr r8,[r4] bic r8,r8,#0xf0000000 orr r8,r8,#0x10000000 str r8,[r4] loop: /*led5 亮*/ ldr r9,[r1] orr r9,r8,#0x20 str r9,[r1] bl delay bic r9,r8,#0x20 str r9,[r1] /*led3 亮*/ ldr r9,[r3] orr r9,r8,#0x1 str r9,[r3] bl delay bic r9,r8,#0x1 str r9,[r3] /*led4 亮*/ ldr r9,[r7] orr r9,r8,#0xf0 str r9,[r7] bic r9,r8,#0xf0 str r9,[r3] /*led2 灭*/ /*清除输出pin,不建议*/ /* ldr r8,[r4] bic r8,r8,#0xf0000000 str r8,[r4] */ /*清除 led2 数据位*/ ldr r9,[r5] bic r9,r8,#0x1 str r9,[r5] bl loop delay: stmfd sp!,{r0-r12,lr} mov r10,#1 lop1: add r10,r10,#1 cmp r10,#0xf000000 blt lop1 ldmfd sp!,{r0-r12,pc} stack: .space 64*8 stacktop: .word stack+64*8
在ARM 处理器中,只有MRS 指令可以状态寄存器CPSR或SPSR读出到通用寄存器中
【mrs r0,cpsr; 将 cpsr 状态寄存器的值读到 r0 中】
msr:写状态寄存器指令
在ARM 处理器中。只有MSR 指令可以直接设置状态寄存器CPSR或SPSR
【msr cpsr,r0; 将 r0 的值写到 cpsr 寄存器中】Makefile:
all: arm-linux-gcc 3.s -o start.o -c -g arm-linux-ld start.o -o start.elf -Ttest.lds arm-linux-objcopy start.elf start.bin -O binary clean: rm *.o *.elf *.bin
test.lds:
ENTRY(_start) SECTIONS{ . = 0x41000000; .text : { start.o(.text) *(.text) } .data : { *(.data) } .bss : { *(.bss) } }
makefile初步制作,arm-linux- (gcc/ld/objcopy/objdump)详解:makefile初步制作,arm-linux- (gcc/ld/objcopy/objdump)详解 - 腾讯云开发者社区-腾讯云 (tencent.com)
-------------------------------------------------------------------------------------------------------------------------
arm位清零bic指令:http://t.csdn.cn/q2bMo
ARM指令集详解:http://t.csdn.cn/KIXMX
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
联合 c 和 汇编的流水灯实现:
main.c:
#define GPF3CON *(unsigned int volatile*)0x114001E0 #define GPF3DAT *(unsigned int volatile*)0x114001E4 #define GPX1CON *(unsigned int volatile*)0x11000c20 #define GPX1DAT *(unsigned int volatile*)0x11000c24 #define GPX2CON *(unsigned int volatile*)0x11000c40 #define GPX2DAT *(unsigned int volatile*)0x11000c44 #define GPX3CON *(unsigned int volatile*)0x11000c60 #define GPX3DAT *(unsigned int volatile*)0x11000c64 /*自定义睡眠函数*/ void delay() { int t = 0xf0000000; while(t--); } int main(int argc, char *argv[]) { //配置输出 pin ,基本准则:先清后或 GPF3CON = GPF3CON & ( ~(0xf<<20) ) | (0x1<<20); GPX1CON = GPX1CON & ( ~(0xf<< 0) ) | (0x1<< 0); GPX2CON = GPX2CON & ( ~(0xf<<28) ) | (0x1<< 0); GPX3CON = GPX3CON & ( ~(0xf<<16) ) | (0x1<<16); while(1){ GPF3DAT = GPF3DAT | (0x1<<5); delay(); GPF3DAT = GPF3DAT | ~(0x1<<5); delay(); GPX1DAT = GPX1DAT | (0x1<<0); delay(); GPX1DAT = GPX1DAT | ~(0x1<<0); delay(); GPX2DAT = GPX2DAT | (0x1<<0); delay(); GPX2DAT = GPX2DAT | ~(0x1<<0); delay(); GPX3DAT = GPX3DAT | (0x1<<16); delay(); GPX3DAT = GPX3DAT | ~(0x1<<16); delay(); } return 0; }
Makefile:
all: arm-linux-gcc 3.s -o start.o -c -g arm-linux-gcc main.c -o main.o -c -g arm-linux-ld start.o main.o -o start.elf -Ttest.lds arm-linux-objcopy start.elf start.bin -O binary clean: rm *.o *.elf *.bin
汇编:
.global _start _start: b reset ldr pc,_undefined_instruction ldr pc,_software_interrupt ldr pc,_prefetch_about ldr pc,_data_about ldr pc,_not_used ldr pc,_irq ldr pc,_fiq _undefined_instruction: .word _undefined_instruction _software_interrupt: .word _software_interrupt _prefetch_about: .word _prefetch_about _data_about: .word _data_about _not_used: .word _not_used _irq: .word _irq _fiq: .word _fiq reset: /*设置cpu模式为svc模式*/ mrs r0,cpsr bic r0,r0,#0x1f /*清除cpsr的模式位*/ orr r0,r0,#0xd3 /*让处理器处于ARM状态、禁用irq、fiq,并将模式设置为svc模式*/ msr cpsr,r0 /*设置异常向量表起始地址*/ ldr r0, =_start mcr p15,0,r0,c12,c0,0 /*这里需要是 c12,不能是 c15,还是不太明白*/ /*用户初始化*/ ldr sp,stacktop /*设置svc的栈顶*/ sub r6,sp,#64 /*计算user需要指向的栈顶位置/ /*切换到用户模式*/ mrs r0,cpsr bic r0,r0,#0x1f orr r0,r0,#0x10 /*处理器状态不变,启用irq、fiq,模式设置为user*/ msr cpsr,r0 mov sp,r6 /*设置user模式的栈顶*/ /*跳转到用户程序*/ bl main stack: .space 64*8 stacktop: .word stack+64*8