stm32之Bootloader

利用bootloader代碼能夠實現遠程代碼更新。

要清楚的認識bootloader,我們就要先了解stm32正常程序運行流程。

 

 

在stm32中將所有的中斷做成了一張中斷向量表(其實就像是一張表格),由上圖可知由棧頂地址向下,我們可以大致分爲三個部分。

1、中斷向量表

2、各個中斷程序入口。

3、main函數入口。

整個單片機上電運行的流程爲:

上電------復位(從中斷向量表中找到復位中斷向量)-----執行復位中斷服務程序-----執行main函數程序-----main函數中發生中斷內請求----PC指針強制跳轉到中斷向量表處找到相應的中斷向量-------執行對應的中斷服務程序------返回mian函數

以上就是整個stm32上電運行main函數的流程。

當我們加入bootloader程序之後,在我們單片機的flush裏面實際有兩個或者多個程序(程序個數取決於flush大小),每個程序有着自己的mian函數,我們的多個程序分別放在flush的不同位置,我們的bootloader放在0X08000000(即是首地址處),其餘的程序(app)緊隨bootloader之後。

加入bootloader之後的啓動流程如下圖:

由圖我們可以看出每個程序都有着自己的中斷向量表等等。。。多個程序的驅動流程和單個的大致相似。。只是在app中發生中斷時PC指針指向的是0X08000004這個位置的中斷向量表,而非app本身的中斷向量表處,,這裏的注意,,在執行相應的中斷程序時是跳轉到app自己的中斷程序表位置,,,這裏的注意。。。

由此,我們利用bootloader實現代碼的更新無非就是在bootloader裏面將接受到的代碼下載到指定的flush區域替換掉原先的代碼,然後將PC指針強制指向app棧頂地址處即可實現代碼的跟新。。。。。

同理我也嘗試過在app中強制的將pc指針指向另外的app也能實現兩個應用程序之間的切換。。。。

bootloader中主要代碼爲跳轉程序:

//跳轉到應用程序段
//appxaddr:用戶代碼起始地址.
void iap_load_app(u32 appxaddr)
{
	if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)	//檢查棧頂地址是否合法.  
	{ 
		jump2app=(iapfun)*(vu32*)(appxaddr+4);		//用戶代碼區第二個字爲程序開始地址(復位地址)		
		MSR_MSP(*(vu32*)appxaddr);					//初始化APP堆棧指針(用戶代碼區的第一個字用於存放棧頂地址)
		jump2app();									//跳轉到APP.
	}
}		

注意:

if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)   :判斷棧頂值是否合法,若沒有這一句的話,即使沒有下載程序也會進入而導致跑飛。

其中appxaddr表示棧頂地址中的值是棧頂地址中的值而非地址。 棧頂合法值爲0x20000000--0x20020000

如何查看一個程序的棧頂值,可以在工程中查看map文件至於怎麼查看map文件自行百度。。。。

這是我們app項目生成的map文件可以看到我們的棧頂值爲0x2000b360,是一個合法的棧頂值。

    jump2app=(iapfun)*(vu32*)(appxaddr+4);        //用戶代碼區第二個字爲程序開始地址(復位地址)        

appxaddr:棧頂地址+4表示的是指向中斷向量表位置(也是復位地址)處。

其中iapfun,jump2app都是一個函數指針

typedef  void (*iapfun)(void);                //定義一個函數類型的參數.

彙編 初始化堆棧指針  MSR_MSP(*(vu32*)appxaddr);                    //初始化APP堆棧指針(用戶代碼區的第一個字用於存放棧頂地址)

樓主實力有限。。。不懂彙編所以這裏也不做解釋了。。。。照搬

 

 

jump2app():把用戶代碼的復位地址付給PC指針,我看到jump2app()這句代碼debug的時候對應的彙編代碼是

LDR r0,[pc,#12] ;相對PC的數據加載到函數指針的地址
LDR r0,[r0,#00] ;R0做索引,無偏移,數據裝載到R0,這個內容就是函數指針指向的內容,也就是函數的地址了,用戶程序的起始地址;
BLX r0              ;這個不解釋,說了是跳轉
 

到此整個bootloader的開發流程大致清楚,就可以利用bootloader實現app更新等一系列項目開發。。。

除了使用按鍵跟新程序,,我們也可以通過標誌位等其他方式更新app。。。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章