Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

XMC1000 ベクタ テーブルの再マップ – KBA235654

XMC1000 ベクタ テーブルの再マップ – KBA235654

Infineon_Team
Moderator
Moderator
Moderator
5 replies posted First solution authored First comment on KBA

XMC1000 ベクタ テーブルの再マップ – KBA235654

Translated by:  

Community Translation: XMC1000 Vector table remap – KBA235654

Version: **

Arm® Cortex® Coreは、NVIC(Nested vector interrrupt controller)を経由して例外割り込みを処理します。NVICは、ベクタテーブルと呼ばれるルックアップテーブルを使用し実行するコード(飛び先)を決定します。一部のCortex®アーキテクチャでは、プログラムがベクタテーブルを変更したい場合、ベクタテーブルオフセットレジスタ(VTOR)レジスタが使用されます。この仕組みは次のような場合に便利です。

・アプリケーションにブートローダがあり、ブートローダとアプリケーションがそれぞれ独自のベクタテーブルを持っている場合
・ユーザがRAMベースのベクタテーブルで動的に異なるハンドラを使用したい場合
・ユーザが外部RAMを使用している場合

ところが、XMC1000デバイス ファミリのCortex® M0コアは、この機能をサポートしていません。XMC1000デバイスでは、Daveスタートアップ コードによってこの問題を解決しています。

XMC1000デバイスのスタートアップの詳細については、アプリケーション ノートAP32326を参照してください。

ベクター テーブルのリマップについて

ベクター テーブルは、SRAM の位置にリマップされ、各ベクターには 4 バイトのサイズが割り当てられています。このサイズでは、例外や割り込みを発生させるのに十分ではありません。そのため、別の場所にある実際のハンドラにジャンプするための分岐命令が必要となる。これを実現するのが"割り込みベニア処理"であす。"割り込みベニア処理"は命令の中間ターゲットとして機能し、その後PC(プログラムカウンター)を飛び先へ設定します。以下は、"割り込みベニア処理"のコード例です。

.section “.XmcVeneerCode”,”ax”,%progbits

.align 1

.globl HardFault_Veneer

HardFault_Veneer:

LDR R0, =HardFault_Handler

MOV PC, R0

In the startup code you can see this being done by using the following Macro

.macro Insert_InterruptVeener Interrupt

.globl \Interrupt()_Veener

\Interrupt()_Veener:

LDR R0, =\Interrupt()_Handler

BX R0

.endm

これらは、コード中の以下のマクロを使用して、デフォルトハンドラにマッピングされます。

.macro Insert_InterruptHandler Interrupt

.weak \Interrupt()_Handler

#if defined(ENABLE_OWN_HANDLER)

.thumb_func

.type \Interrupt()_Handler, %function

\Interrupt()_Handler:

b .

.size \Interrupt()_Handler, . - \Interrupt()_Handler

#else

.thumb_set \Interrupt()_Handler, Default_Handler

#endif

.endm

ユーザーはこれを上書きするために独自のカスタムハンドラを定義することができます。また、リンカファイルで、"割り込みベニア処理"が最初のSRAM位置にマッピングされていることを確認することができます。

/* DSRAM layout (Lowest to highest)*/

/* Veneer <> Stack <> DATA <> BSS <> HEAP */

.VENEER_Code ABSOLUTE(0x2000000C):

{ . = ALIGN(4); /* section size must be multiply of 4. See startup.S file */ VeneerStart = .; KEEP(*(.XmcVeneerCode)); . = ALIGN(4); /* section size must be multiply of 4. See startup.S file */ VeneerEnd = .; }

> SRAM AT > FLASH

eROData = LOADADDR (.VENEER_Code);

VeneerSize = ABSOLUTE(VeneerEnd) - ABSOLUTE(VeneerStart);

0 Likes
32 Views