5

LLVM を使用して、ベアメタル ARM Cortex M4 開発用のコードを生成しようとしています。IR の作成は順調に進んでおり、LLVM は (私の意見では) 正しい ARM Thumb ASM を生成しています。

テストを行うために Arm 開発キットを購入しました: Atmel SAM4L-EK http://www.atmel.com/tools/SAM4L-EK.aspx

開発ボードの黄色の LED を点灯させるアプリケーションを作成しました。(ボードから何かを取得したいだけです) Atmel Studio で付属のアプリを実行したところ、LED は正常に動作しました。しかし、私のアプリケーションは何もしないようです...

マニュアルによると、LED は PC10 に接続されています。ATSAM4LC4C MCU のデータシートでは、GPIO ポートのアドレスは 0x400E1000 であり、1 つのポートが 0x0200 バイトのアドレス空間を必要とするため、ポート C は 0x400E1000 + 0x0400 にあると記載されています。

これは私が持っているプログラム出力です(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

このコードは、GPIOEnableRegister のビット 10 を 1 に設定します。

次に、OutputDriverEnableRegister のビット 10 を 1 にします。

次に、OutputValueRegister のビット 10 を 1 にします。

その時点で、LEDが点灯するはずです...

これは私が使用した起動コードです:

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

両方のアセンブラー ファイルは、次のようにオブジェクト ファイルにコンパイルされました。

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

GNU ARM アセンブラの使用

これは私が使用したリンカースクリプトです:

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

次に、オブジェクト ファイルは次のように ELF バイナリにリンクされました。

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

GNU Arm リンカの使用

次に、Atmel Studio を使用して ELF バイナリをボードにアップロードしました。

ボットは何も起こりません (リセット後も)

どんな洞察も大歓迎です!

4

1 に答える 1

5

cortex-m シリーズは、cortex-m シリーズ以外のアームのようには起動しません。cortex-m には、フルサイズのアームのような命令テーブルではなく、(非アーム) 従来の割り込みベクトル テーブル アプローチがあります。

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

プロセッサ固有の最初の項目として、スタック トップ アドレスを設定する必要があります。また、llvm を使用すると、ここでいくつかのディレクティブを微調整する必要がある場合があります。上記は gnu 用です。

于 2013-06-15T13:16:36.170 に答える