DynamicLoad - プログラムの動的読み込み
.
DynamicLoad - プログラムの動的読み込み
バイナリファイルを読み込んで、Flashへ自己書き込みし、そのコードを実行するテストです。
Load the binary file, and then programming the Flash, then run the code.
Import programDynamicLoad
dynamic load and run users binary file. self write the flash memory.
how to make binary
読み込むバイナリファイルは mbed 環境では作ることができないので、 Sourcery G++ Lite でコンパイルします。
コンパイルしてできた.binファイルを、ファイル名 "test.dat" として mbedのUSBストレージ(USBメモリ)へ保存しておきます。
compiled.bin rename to "test.dat", and save to mbed USB strage (USB memory).
リンカースクリプトを編集しFlashの 0x00040000 番地からコードが始まるようにします。 (このサンプルではファイルを読み込むアドレスを 0x00040000 としているため)
Linker script:
lpc17xx.ld
IROM (rx) : ORIGIN = 0x00040000, LENGTH = 256k IRAM0 (rwx) : ORIGIN = 0x10002000, LENGTH = 24k
or
ldscript_gnu.ld
rom (rx) : ORIGIN = 0x00040000, LENGTH = 256K ram (rwx) : ORIGIN = 0x10002000, LENGTH = 24K
Information
メモリーマップに注意! mbedの Heap はRAMの先頭アドレスから、Stack は最後尾アドレスから。 読み込むプログラムがRAMの内容を破壊しないよう .heap や .stack の定義を確認してください。
スタートアップのコードを編集し、リセットハンドラを割り込みではなく単なる関数にします。 そしてシステムの初期化ルーチンを再実行しないようにします。
Startup file:
startup_LPC17xx.c
//void Reset_Handler(void) __attribute__((__interrupt__)); void Reset_Handler(void); // SystemInit();
or
startup_LPC17xx.s
/* LDR R0, =SystemInit */ /* BLX R0 */
Sample:
LED1 を点滅するサンプル。
sample.c
#include "LPC17xx.h" volatile uint32_t TimeTick = 0; void SysTick_Handler(void) { if (TimeTick) TimeTick --; } int main (void) { int i; LPC_PINCON->PINSEL3 &= (~(3 << 4)); // P1_18 GPIO LPC_GPIO1->FIODIR |= (1 << 18); // P1_18 Output SysTick_Config(SystemCoreClock / 1000); // SysTick Timer 1ms for (;;) { for (i = 0; i < 5; i ++) { LPC_GPIO1->FIOSET = (1 << 18); // LED ON TimeTick = 500; while (TimeTick); LPC_GPIO1->FIOCLR = (1 << 18); // LED OFF TimeTick = 500; while (TimeTick); } } return 0; }
make して、mbedのUSBストレージへ "test.dat" というファイル名で保存します。
DynamicLoad もmbed環境でコンパイルし、mbedへ書き込みます。
mbedをリセットし、DynamicLoad が実行されると、test.dat を読み込み、プログラムの実行が test.dat に移ります。
参考
3 comments on DynamicLoad - プログラムの動的読み込み:
Please log in to post comments.
とても有用なプログラムを公開していただき、ありがとうございます。 2つ質問をさせてください。 ロードされる側のプログラムのリンカスクリプトで、RAM領域を0x10002000から24KB、と定義していて、 これによってHeap領域が0x10002000から後が使われますが、ロードする側のプログラムのHeap領域は0x10000000からで、それとは重ならないように後にずらしている、という理解でよろしいでしょうか。
またStack領域は、そもそもRAM領域の最後尾アドレスから使われるので、両プログラムとも共通にしてもよい(StackへのPush/Popは(両プログラムで共通の)スタックポインタを使って行われるため、両プログラムでスタックされるデータが重なることはない)、という理解でよろしいでしょうか。