GD32IAP升级(BootLoader)
生活随笔
收集整理的這篇文章主要介紹了
GD32IAP升级(BootLoader)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
這里寫自定義目錄標題
- GD32IAP升級---BootLoader
- IAP升級
- 重點部分
- 1.中斷向量設置
- 2.程序起始地址設置說明
- 升級出現的問題
- 判斷程序地址出錯
- 寫入Flash之后,跳轉失敗
- 寫在最后
GD32IAP升級—BootLoader
本文記錄并說明GD32使用IAP升級過程中,必要的操作和關鍵步驟。
IAP升級
IAP升級原理很簡單,簡要介紹如下:
先下載BootLoader程序,如果有需要對程序進行升級時,BootLoader通過串口或者其他接口接收升級程序,接收之后把接收到的文件放到指定位置,然后設置中斷向量,最后跳轉過去即可;
重點部分
1.中斷向量設置
代碼如下
// 設置偏移量 nvic_vector_table_set(FLASH_BASE,0x4000);//設置偏移量2.程序起始地址設置說明
BootLoader中不需要設置程序其實地址,可以設置長度;
APP程序中需要設置程序起始地址:設置如下
升級出現的問題
判斷程序地址出錯
在代碼中判斷出錯
f(((*(vu32*)(FLASH_APP1_ADDR+4))&0xFF000000)==0x08000000)//判斷是否為0X08XXXXXX. { iap_load_app(FLASH_APP1_ADDR);//執行FLASH APP代碼 }原因分析:
1、可能是接收數據出錯
2、可能是寫數據出錯
3、見下面分析
寫入Flash之后,跳轉失敗
調用GD32的提供的fmc.c文件時在寫數據到flash中時,fmc_write_32bit_data函數擦除數據的時候是一次性擦除需要用到的所有塊,而第二次寫入數據的時候會造成把剛剛寫進去的數據又進行擦除,所以會導致,上面提到的判斷程序地址出錯
void fmc_write_32bit_data(uint32_t address, uint16_t length, int32_t* data_32) {uint16_t StartSector, EndSector,i;/* unlock the flash program erase controller */fmc_unlock();/* clear pending flags */fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_OPERR | FMC_FLAG_WPERR | FMC_FLAG_PGMERR | FMC_FLAG_PGSERR);/* get the number of the start and end sectors */StartSector = fmc_sector_get(address);EndSector = fmc_sector_get(address + 4*length);/* each time the sector number increased by 8, refer to the sector definition */for(i = StartSector; i <= EndSector; i += 8){if(FMC_READY != fmc_sector_erase(i)){while(1);}}/* write data_32 to the corresponding address */for(i=0; i<length; i++){if(FMC_READY == fmc_word_program(address, data_32[i])){address = address + 4;}else{ while(1);}}/* lock the flash program erase controller */fmc_lock(); }修改方法:
void fmc_write_32bit_data(uint32_t address, uint16_t length, int32_t* data_32) {uint16_t StartSector, EndSector,i;/* unlock the flash program erase controller */fmc_unlock();/* clear pending flags */fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_OPERR | FMC_FLAG_WPERR | FMC_FLAG_PGMERR | FMC_FLAG_PGSERR);if(frist_flag == 0){frist_flag = 1;/* get the number of the start and end sectors */StartSector = fmc_sector_get(address);EndSector = fmc_sector_get(address + 4*length);/* each time the sector number increased by 8, refer to the sector definition */for(i = StartSector; i <= EndSector; i += 8){if(FMC_READY != fmc_sector_erase(i)){while(1);}}}/* write data_32 to the corresponding address */for(i=0; i<length; i++){if(FMC_READY == fmc_word_program(address, data_32[i])){address = address + 4;}else{ while(1);}}/* lock the flash program erase controller */fmc_lock(); }添加一個標志位,只需擦除一次即可,一次性擦除后面所有的塊;或者每次擦除需要用到的塊,但是要對地址進行計算和拼接;
GD32擦除是根據SECTOR擦除,地址分配如下
/* base address of the FMC sectors */ #define ADDR_FMC_SECTOR_0 ((uint32_t)0x08000000) /*!< base address of sector 0, 16 kbytes */ #define ADDR_FMC_SECTOR_1 ((uint32_t)0x08004000) /*!< base address of sector 1, 16 kbytes */ #define ADDR_FMC_SECTOR_2 ((uint32_t)0x08008000) /*!< base address of sector 2, 16 kbytes */ #define ADDR_FMC_SECTOR_3 ((uint32_t)0x0800C000) /*!< base address of sector 3, 16 kbytes */ #define ADDR_FMC_SECTOR_4 ((uint32_t)0x08010000) /*!< base address of sector 4, 64 kbytes */ #define ADDR_FMC_SECTOR_5 ((uint32_t)0x08020000) /*!< base address of sector 5, 64 kbytes */ #define ADDR_FMC_SECTOR_6 ((uint32_t)0x08040000) /*!< base address of sector 6, 64 kbytes */ #define ADDR_FMC_SECTOR_7 ((uint32_t)0x08060000) /*!< base address of sector 7, 64 kbytes */ #define ADDR_FMC_SECTOR_8 ((uint32_t)0x08080000) /*!< base address of sector 8, 64 kbytes */ #define ADDR_FMC_SECTOR_9 ((uint32_t)0x080A0000) /*!< base address of sector 9, 64 kbytes */ #define ADDR_FMC_SECTOR_10 ((uint32_t)0x080C0000) /*!< base address of sector 10, 64 kbytes */ #define ADDR_FMC_SECTOR_11 ((uint32_t)0x080E0000) /*!< base address of sector 11, 64 kbytes */寫在最后
IAP升級和STM32一樣,需要注意的是flash寫的操作,Demo中的flash寫,是只對塊進行擦除,沒有對原有的數據進行保護;
PS:當然,可能和我使用的版本不一樣。
總結
以上是生活随笔為你收集整理的GD32IAP升级(BootLoader)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 工作总结9:这一个月来犯的错
- 下一篇: 心态-《当下的力量》书中的精髓:了解我们