2013-06-15 8 views
5

Próbuję użyć LLVM do wygenerowania kodu dla baremetal ARM Cortex M4 development. Tworzenie IR idzie dobrze, a LLVM generuje (w mojej oppinion) prawidłowe ARM Thumb ASM.Problemy z pobieraniem gołej metalowej aplikacji ARM do startu

Kupiłem zestawu Arm dev zrobić kilka testów: AN Atmel SAM4L-EK http://www.atmel.com/tools/SAM4L-EK.aspx

I stworzył aplikację, która włącza się żółta dioda na płycie dev. (Chcę tylko coś wyciągnąć z tablicy) Uruchomiłem aplikację z Atmel Studio i dioda LED działa dobrze. Ale moja aplikacja wydaje się nie robić nic ...

Acording do instrukcji dioda jest podłączona do PC10 w arkuszu z ATSAM4LC4C MCU mówi, że adres portów GPIO jest 0x400E1000, jeden port zajmuje 0x0200 byes przestrzeni adresowej, więc port C ma wartość 0x400E1000 + 0x0400.

Więc to jest wyjście programu Mam (LLVM Output):

.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 

Ten kod ustawia bit 10 w GPIOEnableRegister do 1

wówczas bit 10 w OutputDriverEnableRegister do 1

następnie nieco 10 w OutputValueZarejestruj się na 1

W tym momencie dioda LED powinna się włączyć ...

Jest to kod startowy użyłem:

.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 . 

Oba pliki asemblera były kompilowane do obiektu plików tak:

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

Korzystanie z asemblera GNU ARM

Jest to skrypt linkera I używany:

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 = .; 
} 

Następnie obj ect pliki zostały połączone z elfem binarny tak:

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

pomocą GNU Arm Linker

Potem dodał binarnego ELF do płyty przy użyciu Atmel Studio

Bot nic się nie dzieje (również nie po reset)

Wszelkie spostrzeżenia są mile widziane!

+0

Ktokolwiek zagłosował, aby zamknąć to jako "zbyt zlokalizowane", proszę zwrócić uwagę na ogólnoeuropejską możliwość zastosowania problemu wskazanego w zaakceptowanej odpowiedzi! –

Odpowiedz

5

Seria cortex-m nie uruchamia się jak ramię inne niż kortex-m. kortex-m ma tradycyjne podejście do tablicy przerwań (bez ramienia), a nie tabelę instrukcji, taką jak ramiona o pełnej wielkości.

/* 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 . 

Musisz ustawić górny adres stosu jako pierwszy element charakterystyczny dla twojego procesora. I przy użyciu llvm możesz potrzebować ulepszyć kilka dyrektyw tutaj, powyższy był dla gnu.

+0

Mam wiele prostych przykładów takich jak na http://github.com/dwelch67 –

+0

To wykonało zadanie! Dziękuję Ci bardzo! – JeroenVandezande

Powiązane problemy