Estoy intentando hacer que parpadee un LED en el ensamblaje de mi Raspberry pi 2 modelo B para depurar el código de inicio. Sin embargo no veo nada parpadear. ¿Podría alguien decirme lo que estoy olvidando?
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;@ BLINK LED
;;
main:
@ Configure the LED GPIO pin for output
ldr r0,=0x3f200000 @ Load r0 with hexadecimal number: 0x3f200000 (Raspberry Pi 2)
mov r1,#1 @ Move decimal number 1 to r1
lsl r1,#21 @ Logical shift left the value in r1 by 21 places
str r1,[r0,#16] @ Store r1 in the address calculated by [r0 + 16] (Raspberry Pi 2)
@ Turn the LED on
mov r1, #1 @ Move decimal number 1 to r1
lsl r1, #15 @ Logical shift left the value in r1 by 15 places
str r1, [r0,#32] @ Store r1 in the address calculated by [r0 + 32] (Raspberry Pi 2).
@ Now on pull-high pin (47) instead of pull-low pin (16), so write
@ to GPSET register instead of GPCLR.
b main
loop$:
b loop$ @ Branch to loop$
Todo el código de inicio:
.extern system_init
.extern __bss_start
.extern __bss_end
.extern vFreeRTOS_ISR
.extern vPortYieldProcessor
.extern rpi_cpu_irq_disable
.extern main
.section .init
.globl _start
;;
_start:
;@ All the following instruction should be read as:
;@ Load the address at symbol into the program counter.
ldr pc,reset_handler ;@ Processor Reset handler -- we will have to force this on the raspi!
;@ Because this is the first instruction executed, of cause it causes an immediate branch into reset!
ldr pc,undefined_handler ;@ Undefined instruction handler -- processors that don't have thumb can emulate thumb!
ldr pc,swi_handler ;@ Software interrupt / TRAP (SVC) -- system SVC handler for switching to kernel mode.
ldr pc,prefetch_handler ;@ Prefetch/abort handler.
ldr pc,data_handler ;@ Data abort handler/
ldr pc,unused_handler ;@ -- Historical from 26-bit addressing ARMs -- was invalid address handler.
ldr pc,irq_handler ;@ IRQ handler
ldr pc,fiq_handler ;@ Fast interrupt handler.
;@ Here we create an exception address table! This means that reset/hang/irq can be absolute addresses
reset_handler: .word reset
undefined_handler: .word undefined_instruction
swi_handler: .word vPortYieldProcessor
prefetch_handler: .word prefetch_abort
data_handler: .word data_abort
unused_handler: .word unused
irq_handler: .word vFreeRTOS_ISR
fiq_handler: .word fiq
reset:
/* Disable IRQ & FIQ */
cpsid if
/* Check for HYP mode */
mrs r0, cpsr_all ;@move FROM coprocessor reg to ARM register Current Program Status Register
and r0, r0, #0x1F
mov r8, #0x1A
cmp r0, r8
beq overHyped ;@branch if equal als r0 en r8 gelijk zijn jump naar overHyped
b continueBoot ;@branch(=jump)
overHyped: /* Get out of HYP mode */ ;@HYP = is een modus voor virtualization
ldr r1, =continueBoot ;@load addres van continueBoot routine in R1
msr ELR_hyp, r1 ;@ move ARM register to coprocessor register
mrs r1, cpsr_all
and r1, r1, #0x1f ;@ CPSR_MODE_MASK
orr r1, r1, #0x13 ;@ CPSR_MODE_SUPERVISOR
msr SPSR_hyp, r1
eret ;@return
continueBoot:
;@ In the reset handler, we need to copy our interrupt vector table to 0x0000, its currently at 0x8000
mov r0,#0x8000 ;@ Store the source pointer
mov r1,#0x0000 ;@ Store the destination pointer.
;@ Here we copy the branching instructions
ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Load multiple values from indexed address. ; Auto-increment R0
stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Store multiple values from the indexed address. ; Auto-increment R1
;@ So the branches get the correct address we also need to copy our vector table!
ldmia r0!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Load from 4*n of regs (8) as R0 is now incremented.
stmia r1!,{r2,r3,r4,r5,r6,r7,r8,r9} ;@ Store this extra set of data.
;@ Set up the various STACK pointers for different CPU modes
;@ (PSR_IRQ_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS)
mov r0,#0xD2
msr cpsr_c,r0
mov sp,#0x8000
;@ (PSR_FIQ_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS)
mov r0,#0xD1
msr cpsr_c,r0
mov sp,#0x4000
;@ (PSR_SVC_MODE|PSR_FIQ_DIS|PSR_IRQ_DIS)
mov r0,#0xD3
msr cpsr_c,r0
mov sp,#0x8000000
ldr r0, =__bss_start
ldr r1, =__bss_end
mov r2, #0
zero_loop:
cmp r0,r1
it lt
strlt r2,[r0], #4
blt zero_loop
bl rpi_cpu_irq_disable
;@ mov sp,#0x1000000
b main ;@ We're ready?? Lets start main execution!
.section .text
undefined_instruction:
b undefined_instruction
prefetch_abort:
b prefetch_abort
data_abort:
b data_abort
unused:
b unused
fiq:
b fiq
hang:
b hang
.globl PUT32
PUT32:
str r1,[r0]
bx lr
.globl GET32
GET32:
ldr r0,[r0]
bx lr
.globl dummy
dummy:
bx lr
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;@ BLINK LED
;;
main:
@ Configure the LED GPIO pin for output
ldr r0,=0x3f200000 @ Load r0 with hexadecimal number: 0x3f200000 (Raspberry Pi 2)
mov r1,#1 @ Move decimal number 1 to r1
lsl r1,#21 @ Logical shift left the value in r1 by 21 places
str r1,[r0,#16] @ Store r1 in the address calculated by [r0 + 16] (Raspberry Pi 2)
@ Turn the LED on
mov r1, #1 @ Move decimal number 1 to r1
lsl r1, #15 @ Logical shift left the value in r1 by 15 places
str r1, [r0,#32] @ Store r1 in the address calculated by [r0 + 32] (Raspberry Pi 2).
@ Now on pull-high pin (47) instead of pull-low pin (16), so write
@ to GPSET register instead of GPCLR.
b main
loop$:
b loop$ @ Branch to loop$