2013-06-15 7 views
5

Sto cercando di utilizzare LLVM per generare codice per lo sviluppo ARM Cortex M4 bare metal. La creazione dell'IR sta andando bene e LLVM sta generando (a mio parere) l'ARM Thumb ASM corretto.Problemi con l'avvio di un'applicazione ARM bare metal

ho acquistato un kit Braccio dev per fare qualche test: un Atmel SAM4L-EK http://www.atmel.com/tools/SAM4L-EK.aspx

ho creato un'applicazione che si accende il led giallo sulla scheda dev. (Voglio solo estrarre qualcosa dalla scheda) Ho eseguito un'app inclusa con Atmel Studio e il LED funziona correttamente. Ma la mia domanda sembra non fare nulla ...

di tronchi con il manuale, il LED è collegato al PC10 Nella scheda tecnica del ATSAM4LC4C MCU si dice che l'indirizzo delle porte GPIO è 0x400E1000, una porta prende 0x0200 addii di spazio indirizzo in modo che la porta C sia su 0x400E1000 + 0x0400.

Quindi questo è l'uscita programma che ho (uscita LLVM):

.syntax unified 
.eabi_attribute 6, 10 
.eabi_attribute 9, 2 
.eabi_attribute 20, 1 
.eabi_attribute 21, 1 
.eabi_attribute 23, 3 
.eabi_attribute 24, 1 
.eabi_attribute 25, 1 
.eabi_attribute 44, 1 
.file "" 
.text 
.globl main 
.align 2 
.type main,%function 
.code 16 
.thumb_func 
main: 
movw r0, #5120 
movw r2, #5184 
movw r3, #5200 
mov.w r1, #1024 
movt r0, #16398 
movt r2, #16398 
movt r3, #16398 
.LBB0_1: 
str r1, [r0] 
str r1, [r2] 
str r1, [r3] 
b .LBB0_1 
.Ltmp0: 
.size main, .Ltmp0-main 

Questo codice imposta il bit 10 in GPIOEnableRegister a 1

poi bit 10 in OutputDriverEnableRegister a 1

allora po ' 10 in OutputValueRegister a 1

A quel punto il LED deve accendersi ...

Questo è il codice di avvio che ho usato:

.section INTERRUPT_VECTOR, "x" 
.global _Reset 
_Reset: 
B Reset_Handler /* Reset */ 
B . /* Undefined */ 
B . /* SWI */ 
B . /* Prefetch Abort */ 
B . /* Data Abort */ 
B . /* reserved */ 
B . /* IRQ */ 
B . /* FIQ */ 

Reset_Handler: 
#mov r0, stack_top 
MOV sp,r0 
BL main 
B . 

Entrambi i file assembler sono stati compilati da obiettare file in questo modo:

as -mcpu=cortex-m4 -g startup.s -o startup.o 

Utilizzando l'assemblatore GNU ARM

Questo è lo script del linker I utilizzato:

ENTRY(_Reset) 
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") 
OUTPUT_ARCH(arm) 
SEARCH_DIR(.) 

/* Memory Spaces Definitions */ 
MEMORY 
{ 
    rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 /* flash, 256K */ 
    ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 /* sram, 32K */ 
} 

SECTIONS 
{ 
. = 0x0; 
.text : { 
startup.o (INTERRUPT_VECTOR) 
*(.text) 
} 
.data : { *(.data) } 
.bss : { *(.bss COMMON) } 
. = ALIGN(8);0 
. = . + 0x1000; /* 4kB of stack memory */ 
stack_top = .; 
} 

Quindi l'oggetto ect i file sono stati collegati a un binario ELF come questo:

ld -T linkerscript.ld armtest.o startup.o -o armtest.elf 

usando il GNU Braccio Linker

Poi ho caricato il file binario ELF alla scheda utilizzando Atmel Studio

Bot non succede nulla (anche non dopo un reset)

Qualsiasi approfondimento sarebbe molto apprezzato!

+0

Chiunque abbia votato per chiuderlo come "troppo localizzato", si prega di notare l'applicabilità a livello familiare del problema evidenziato nella risposta accettata! –

risposta

5

la serie cortex-m non si avvia come un braccio della serie non-cortex-m. la corteccia-m ha un approccio tradizionale a tabella vettoriale di interrupt (non armata) piuttosto che una tabella di istruzioni come le braccia di dimensioni normali.

/* vectors.s */ 
.thumb 

.word 0x20020000 /* stack top address */ 
.word _start  /* 1 Reset */ 
.word hang  /* 2 NMI */ 
.word hang  /* 3 HardFault */ 
.word hang  /* 4 MemManage */ 
.word hang  /* 5 BusFault */ 
.word hang  /* 6 UsageFault */ 
.word hang  /* 7 RESERVED */ 
.word hang  /* 8 RESERVED */ 
.word hang  /* 9 RESERVED*/ 
.word hang  /* 10 RESERVED */ 
.word hang  /* 11 SVCall */ 
.word hang  /* 12 Debug Monitor */ 
.word hang  /* 13 RESERVED */ 
.word hang  /* 14 PendSV */ 
.word hang  /* 15 SysTick */ 
.word hang  /* 16 External Interrupt(0) */ 
.word hang  /* 17 External Interrupt(1) */ 
.word hang  /* 18 External Interrupt(2) */ 
.word hang  /* 19 ... */ 

.thumb_func 
.global _start 
_start: 
    /*ldr r0,stacktop */ 
    /*mov sp,r0*/ 
    bl notmain 
    b hang 

.thumb_func 
hang: b . 

È necessario impostare l'indirizzo superiore dello stack come primo elemento specifico per il processore. E usando llvm potresti aver bisogno di modificare alcune direttive qui, la precedente era per gnu.

+0

Ho molti semplici esempi come questi su http://github.com/dwelch67 –

+0

Che ha fatto il lavoro! Grazie mille! – JeroenVandezande

Problemi correlati