can總線實現stm32的IAP


使用stm32f105rct6的can通信做IAP,實現固件的遠程更新功能。IAP的實現包括兩個程序:BootLoader和應用程序。啟動過程先啟動BootLoader,等待1s,若接收到燒寫指令則開始更新程序,若無指令則啟動應用程序。應用程序接收到更新指令后,切換到BootLoader。
遠程程序更新需要防止更新失敗后,程序卡死,只能通過人工現場更新的情況。可以使用看門狗實現重啟返回BootLoader,給重新燒寫留出時間。
實現IAP流程,需要的工作包括:
1、規划單片機存儲區,設置中斷向量位置,生成應用程序bin文件
2、編寫BootLoader,實現應用程序切換
3、編寫遠程更新上位機,實現通信協議
4、插入看門狗程序,實現燒寫失敗后重啟
1、規划單片機存儲區,設置中斷向量位置,生成應用程序bin文件
stm32f105rct6的flash共256KB,規划flash空間:  
0x08000000~0x08004000 共16KB空間,給BootLoader  
0x08004000~0x08010000 共48KB空間,給應用程序
0x08010000~0x08014000 共16KB空間,保留
0x08014000~0x08018000 共16KB空間,給配置
單片機應用程序在起始地址中的結構,首先是中斷向量,然后是代碼。
中斷向量的結構:開頭4字節堆棧指針,接下來是4字節reset函數地址,之后是其他中斷函數的地址。
單片機開機后,從0x08000000處取得SP,然后從0x08000004處取得reset地址作為PC,在reset函數中調用main函數,進入C語言控制的程序中。
 
在keil中的options -> target -> IROM 填寫應用程序的起始和長度,並在linker -> use memory layout from target dialog中打鈎
在應用程序中,調用NVIC函數,設置中斷向量位置為0x08004000
生成應用程序的bin文件:
keil中,在options -> user -> after build -> run   中輸入指令 
    fromelf.exe --bin -o ..\w01sim\bin\mcubin\canext.bin .\obj\test.axf
2、編寫BootLoader,實現應用程序切換
建立一個普通的stm32工程,實現can通信和數據協議、flash燒寫等功能,當超時無指令,或燒寫成功后,需要進行程序切換。
程序切換時,首先應關閉設備時鍾、關閉中斷,避免應用程序中未對設備進行初始化,導致boot方式啟動與冷啟動有功能差別。
切換原理:模擬單片機上電過程,人工設置堆棧指針,調用應用程序入口函數。
切換代碼如下:
 1 void switch_2_addr(u32 *pc) //切換到指定的程序指針
 2 {
 3     u32 i = 0;
 4     RCC->APB1RSTR = 0x00000000;//復位結束
 5     RCC->APB2RSTR = 0x00000000;
 6 
 7     RCC->AHBENR = 0x00000014;  //睡眠模式閃存和SRAM時鍾使能.其他關閉.      
 8     RCC->APB2ENR = 0x00000000; //外設時鍾關閉.
 9     RCC->APB1ENR = 0x00000000;   
10     RCC->CR |= 0x00000001;     //使能內部高速時鍾HSION
11     RCC->CFGR &= 0xF8FF0000;   //復位SW[1:0],HPRE[3:0],PPRE1[2:0],PPRE2[2:0],ADCPRE[1:0],MCO[2:0]
12     RCC->CR &= 0xFEF6FFFF;     //復位HSEON,CSSON,PLLON
13     RCC->CR &= 0xFFFBFFFF;     //復位HSEBYP
14     RCC->CFGR &= 0xFF80FFFF;   //復位PLLSRC, PLLXTPRE, PLLMUL[3:0] and USBPRE
15     RCC->CIR = 0x00000000;     //關閉所有中斷
16 
17     NVIC->ICER[0] = 0xFFFFFFFF;
18     NVIC->ICER[1] = 0x000007FF;
19     NVIC->ICPR[0] = 0xFFFFFFFF;
20     NVIC->ICPR[1] = 0x000007FF;
21     for(i = 0; i < 0x0B; i++)
22     {
23         NVIC->IP[i] = 0x00000000;
24     }
25    __ASM volatile("cpsid i"); //關閉所有中斷
26 
27     MSR_MSP(*pc); //堆棧指針是應用程序起始的第一個u32
28     ((void (*)(void))*(pc+1))();//入口函數是應用程序起始的第二個u32
29 }

其中MSR_MSP函數如下:

1 __asm void MSR_MSP(u32 addr)
2 {
3     MSR MSP, r0             //set Main Stack value
4     BX r14
5 }
3、編寫遠程更新上位機,實現通信協議
上位機實現通信協議:
每個程序具有自己的version,16bit,高1字節為程序代號,低1字節為程序發布版本  
通信的過程:  
1. 控制方發送查詢指令,應用程序或BootLoader收到后發送自身version  
2. 控制方發送起始指令,指令中帶有長度和crc,應用程序收到后,若不准許,則發不准更新包,若准許,則不響應,直接切入BootLoader  
3. 控制方持續發送起始指令,BootLoader收到后,回復相同canid的包,准許更新  
4. 控制方得到准許后,發送id遞增的can包,將bin文件下載到MCU  
5. 發送完成后,控制方額外發送一個can id低16bit為0xffff的包,內容任意,表示結束。BootLoader收到后開始計算crc,若失敗,則發失敗包。若成功,則開始燒寫flash,若燒寫失敗,發送燒寫失敗包。  
6. 燒寫成功,BootLoader切換到應用程序,此時控制方一直發查詢指令,直到應用程序回復版本號正確。  
 4、插入看門狗程序,實現燒寫失敗后重啟
在BootLoader中開看門狗,切換到應用程序后喂狗。若程序燒寫失敗,則切換到應用程序后程序卡死,導致MCU重啟,又進入BootLoader,停留1s,等待下次燒寫。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM