當前位置:編程學習大全網 - 編程語言 - stm32 學習困惑

stm32 學習困惑

因為STM32設計的Flash起始地址是在0x0800 0000位置開始的。全部代碼都只能在從這裏開始存儲。詳見STM32 referenc manual手冊第54頁。

那既然從這裏才能存儲代碼,就必須在MDK裏設置Flash地址為0x0800 0000,下面是MDK設置頁面,這個應該都看到過:

這樣就還有壹個問題,理論上,CM3中規定上電後CPU是從0地址開始執行,但是這裏中斷向量表卻被燒寫在0x0800 0000地址裏,這是因為STM32的Flash是從0x0800 0000開始才有。但SMT32也不能破壞ARM定下的“規矩”,所以它做了壹個啟動映射的過程,就是和芯片上總能見到的BOOT0和BOOT1有關了,當選擇從主Flash啟動模式後,芯片壹上電,Flash的0x0800 0000地址被映射到0地址處,不影響CM3內核的讀取,所以這時的CM3既可以在0地址處訪問中斷向量表,也可以在0x0800 0000地址處訪問中斷向量表,而代碼還是在0x0800 0000地址處存儲的。這就是最難理解的地方,其實,這是基本上所有ARM芯片采用的啟動映射方法。ARM7,ARM9沒有內部Flash的通常都是這樣做的。這個過程出自STM32 referenc manual手冊,裏面是有說明的:

還要註意,這個中斷向量表是可以在程序中再次被映射的。控制它的就是CM3已經規定的NVIC寄存器SCB->VTOR。在STM32庫中給出的啟動代碼裏,startup_stm32f10x_hd.s文件裏,第146行,是上電後讀取中斷向量表中的復位中斷位置,並執行復位中斷處理代碼,代碼如下:

; Reset handler

Reset_Handler? PROC

EXPORT? Reset_Handler [WEAK]

IMPORT? __main

IMPORT? SystemInit

LDR R0, =SystemInit

BLX R0?

LDR R0, =__main

BX? R0

ENDP

註意復位後第壹個被執行的是SystemInit代碼,這個代碼在庫目錄下的system_stm32f10x.c文件裏,它初始化了時鐘,NVIC等壹系列操作,這裏摘要與中斷向量有關的代碼:

void SystemInit (void)

{

......

#ifdef VECT_TAB_SRAM

SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */

#else

SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */

#endif

}

可以看出中斷向量重映射是壹個選擇性編譯,通常宏定義VECT_TAB_SRAM都沒有被定義,所以這裏執行結束後,SCB->VTOR就是FLASH_BASE了,值為0x0800 0000。以後CM3再取中斷向量裏,就會根據SCB->VTOR的設置,從這裏取向量執行了。中斷向量自此終於轉正。

註意這時連__main函數都還沒進,看起來中斷向量的重映射位置還是夠早的。

  • 上一篇:智慧消防工程師是幹什麽的
  • 下一篇:《通天塔》中的浮屍案
  • copyright 2024編程學習大全網