LPC810マイコン実行の流れを確認する (LPCXpresso IDE上でソースの関連性を調べる)
debug/にあるmapファイルにメモリ配置の情報が書かれている。
リンカ実行時に、このファイルが参照されて、各オブジェクトのメモリ配置が決まり、実行バイナリが作成されるのだろう。
このmapファイルの以下の記述は、コンパイルされたcr_startup_lpc8xx.oのg_pfnVectorsをメモリマップのアドレス0x0000000に割り付けている、と思われる。
*(.isr_vector) .isr_vector 0x00000000 0xc0 ./src/cr_startup_lpc8xx.o 0x00000000 g_pfnVectors 0x000000c0 . = ALIGN (0x4) 0x000000c0 __section_table_start = . 0x000000c0 __data_section_table = . 0x000000c0 0x4 LONG 0x954 LOADADDR (.data)
これに該当するのは、startup_lpc8xxx.cの以下のところになる。
//***************************************************************************** // // The vector table. // This relies on the linker script to place at correct location in memory. // //***************************************************************************** extern void (* const g_pfnVectors[])(void); __attribute__ ((section(".isr_vector"))) void (* const g_pfnVectors[])(void) = { // Core Level - CM0plus &_vStackTop, // The initial stack pointer ResetISR, // The reset handler NMI_Handler, // The NMI handler HardFault_Handler,
g_pfnVectorsが関数ポインタの配列で定義されている。
この配列に格納されているもの(ResetISRやNMI_Handlerなど)は、()が略された関数名であり、つまり関数のエントリポイント(先頭アドレス)を示している。
なので、ここでは割り込みベクタアドレスの定義を行っていて、これを0x00000000から順番にマッピングしている、ということになる。
さて、一番最初にマイコンが起動した場合(もしくはリセット有効でリセットがアサートされた場合)は、リセット割り込みベクタにより0x00000000のResetISR関数が呼ばれる。ResetISR()は、cr_startup_lpc8xx.cに定義されている。
//***************************************************************************** // Reset entry point for your code. // Sets up a simple runtime environment and initializes the C/C++ // library. //***************************************************************************** __attribute__ ((section(".after_vectors"))) void ResetISR(void) { // // Copy the data sections from flash to SRAM. //
ResetISRでやっていることは...
・4kBのフラッシュから1kBのSRAMへデータをコピー、初期化 (容量はLPC810の場合)
・bssセクション 0埋め
・systemInit()の呼び出し … systemInit関数はsystem_LPC8xx.cに定義されている。クロックの設定
・main()の呼び出し … main()はみんなのよく知っているmain関数。main.cに定義されている
以上、mainまでの流れ。