STM8L IAP升級
芯片:STM8LXXX
通訊方式:SPI
IDE: IAR for STM8
工作需求,需要實現(xiàn)基于SPI通信的IAP升級,百度了一些資料,爬過了一些坑,現(xiàn)在測試升級ok,因此寫篇筆記記錄一下整個過程,以下便是整個過程,純屬個人記錄,難免有不到的地方,如有錯誤,麻煩指出。
一、介紹
1) IAP簡介
所謂的IAP即應(yīng)用程序中編程(In-application programming),即可以在產(chǎn)品出廠后,更新程序。既然可以更新程序,那么就要有程序負責這部分功能,這個程序就叫做BootLoader,而被更新的程序就叫做Application.
2)官方BooLoader
如果只是想使用這個功能,而不用自己編寫B(tài)ootLoader,ST官方已經(jīng)內(nèi)置了Bootloader,參考文檔《AN2659.pdf》中:點擊下載
根據(jù)上面的文檔,可以了解,ST官方已經(jīng)在STM8中內(nèi)置了Bootloader,然后參考文檔《UM0560.pdf》,點擊下載,可以查看自己要使用的MCU是否支持內(nèi)置的Bootloader,還有支持什么通信方式。
我使用的這顆MCU官方的Bootloader只支持USART方式通信,而我們的項目需求是使用SPI方式通信,因此需要自己開發(fā)Bootloader。
如果使用官方的Bootloader,則《UM0560.pdf》文檔里面有詳細的升級協(xié)議,可以根據(jù)協(xié)議進行對接。
3)自己編寫B(tài)ootLoader注意點
如果自己編寫B(tài)ootloader,則需要注意幾個方面:
1.中斷向量表的重定向
參考文檔《STM8L IAP 應(yīng)用程序中編程指導(dǎo).pdf》中的說明,點擊下載,如下圖
可以看到,當Application中發(fā)生中斷的時候,會跳轉(zhuǎn)到0x8000地址處,因此在Bootloader中需要將中斷進行重定向,使之能夠跳轉(zhuǎn)到Application中的中斷向量表中去。
2.Bootloader與Application的大小以及數(shù)據(jù)的寫入
這個要根據(jù)自己的項目實際情況來確定大小以及區(qū)塊位置,下面將會詳細說明。
3.程序跳轉(zhuǎn)
程序跳轉(zhuǎn)可以分為Bootloader跳轉(zhuǎn)到Application, Application跳轉(zhuǎn)到Bootloader.下面將會詳細說明。
二、功能實現(xiàn)
根據(jù)上面的說明,自己編寫B(tài)ootLoader需要實現(xiàn)以下幾個方面:中斷向量表、分區(qū)大小、數(shù)據(jù)寫入、程序跳轉(zhuǎn)
1)中斷向量表
中斷向量表的重定向,需要根據(jù)自己的Bootloader大小進行設(shè)置,例如,大小為4KB,則Bootloader地址范圍為0x8000 ~ 0x8FFF,則可以中斷向量表可以重定向如下:
/* interrupt vetor redirected app addres is 0x9000
* bld size is 4kb
*/
__root const long reintvec[]@".intvec"=
{
0x82008080,0x82009004,0x82009008,0x8200900c,
0x82009010,0x82009014,0x82009018,0x8200901c,
0x82009020,0x82009024,0x82009028,0x8200902c,
0x82009030,0x82009034,0x82009038,0x8200903c,
0x82009040,0x82009044,0x82009048,0x8200904c,
0x82009050,0x82009054,0x82009058,0x8200905c,
0x82009060,0x82009064,0x82009068,0x8200906c,
0x82009070,0x82009074,0x82009078,0x8200907c,
};
如果大小為5KB,則Bootloader地址范圍為0x8000 ~ 0x93FF,則可以中斷向量表可以重定向如下:
/* interrupt vetor redirected app addres is 0x9400
* bld size is 5kb
*/
__root const long reintvec[]@".intvec"=
{
0x82008080,0x82009404,0x82009408,0x8200940c,
0x82009410,0x82009414,0x82009418,0x8200941c,
0x82009420,0x82009424,0x82009428,0x8200942c,
0x82009430,0x82009434,0x82009438,0x8200943c,
0x82009440,0x82009444,0x82009448,0x8200944c,
0x82009450,0x82009454,0x82009458,0x8200945c,
0x82009460,0x82009464,0x82009468,0x8200946c,
0x82009470,0x82009474,0x82009478,0x8200947c,
};
2)分區(qū)設(shè)置
如果確定自己的BooLoader大小,然后就可以設(shè)置對應(yīng)的icf文件已經(jīng)flash的大小。
例如,現(xiàn)在使用的MCU flash地址空間為 0x8000 ~ 0xBFFF, 并且確定Bootloader的大小為5KB,則Bootloader地址為 0x8000 ~ 0x93FFF, Application地址為0x94000 ~ 0xBFFF.
首先需要找到對應(yīng)MCU的icf文件,具體路徑為C:\Program Files\IAR Systems\Embedded Workbench 8.0_2\stm8\config 這個要根據(jù)你自己的IAR軟件安裝位置來確定。
找到對應(yīng)的MCU icf文件后,創(chuàng)建Bootloader和Application兩份工程,然后將每一份工程的icf中,根據(jù)自己的分區(qū)的大小進行修改:
Bootloader修改如下:
Application中修改如下:
修改完畢后,還需要將此文件載入工程,直接在IAR中點擊創(chuàng)建的過程,右鍵options —> Linker —> Configuration, 選擇自己修改好的icf文件然后載入,如下:
3)數(shù)據(jù)寫入
數(shù)據(jù)的寫入,根據(jù)MCU的datasheeet有幾種寫入方式,因為是大數(shù)據(jù)寫入,所以采用了塊寫入的方式,即每次直接寫入一個塊,每個塊128Bytes則需要計算寫入塊的位置。
(0xbfff - 0x8000) / 128 = 128block 可知一共有128個塊
而Application的地址范圍為 0x9400 ~ 0xbfff, 則Application的起始位置是(0x9400 - 0x8000) / 128 = 40 block
也就是,Bootloader的位置為block0 ~ block 39, Application的位置為block40 ~ block127
數(shù)據(jù)的寫入和擦除使用的是IN_RAM方式,代碼如下:
/*
Block programming, also called standard block programming: The block is automatically erased before being programmed.
Fast block programming: No previous erase operation is performed.
Block erase
*/
IN_RAM(void bld_flash_write_block(uint16_t BlockNum,FLASH_MemType_TypeDef FLASH_MemType,uint8_t *Buffer))
//void Write_Flash_Block(uint16_t BlockNum,FLASH_MemType_TypeDef FLASH_MemType,uint8_t *Buffer)
{
FLASH_Unlock(FLASH_MemType);
//FLASH_EraseBlock(BlockNum,FLASH_MemType);
FLASH_ProgramBlock(BlockNum, FLASH_MemType,FLASH_ProgramMode_Fast,Buffer);
FLASH_WaitForLastOperation(FLASH_MemType);
FLASH_Lock(FLASH_MemType);
}
IN_RAM(void bld_flash_erase_block(FLASH_MemType_TypeDef FLASH_MemType))
{
uint8_t i = 0;
FLASH_Unlock(FLASH_MemType);
for (i = FLASH_START_BLOCK; i <= FLASH_END_BLOCK; i++)
{
FLASH_EraseBlock(i, FLASH_MemType);
FLASH_WaitForLastOperation(FLASH_MemType);
}
FLASH_Lock(FLASH_MemType);
}
代碼中寫入的時候采用的是FLASH_ProgramMode_Fast方式,即直接寫入,F(xiàn)LASH_ProgramMode_Standard模式則是寫入前先自動擦除,速度較慢??梢愿鶕?jù)自己的需求進行選擇。
4)程序跳轉(zhuǎn)
Bootloadre — > Application
跳轉(zhuǎn)直接采用匯編的方式,這里不再說明
void bld_goto_app()
{
asm("LDW X, SP");
asm("LD A, $FF");
asm("LD XL, A");
asm("LDW SP, X");
asm("JPF $9400");
}
Application —> Bootloader
當需要升級的時候,需要進入到Bootloader狀態(tài),此時可以通過一些方法,例如外部電源reset、看門狗超時復(fù)位、或者直接采用匯編的方式跳轉(zhuǎn),如下:
void app_goto_bld()
{
asm("LDW X, SP");
asm("LD A, $FF");
asm("LD XL, A");
asm("LDW SP, X");
asm("JPF $8000");
}
不過,在使用這種方式之前,最好要 enableInterrupts();,否則會有一些有趣的事情發(fā)生。。。
5)BootLoader如何確定要升級?
這個各有各的方法,目前簡單采用向EEPROM中寫入特殊字符來判斷。
以上是全部的過程,如有錯誤的地方,麻煩指出。
上一篇:STM8S105 SPI 初始化
下一篇:關(guān)于STM8S使用硬件SPI收發(fā)問題
推薦閱讀
史海拾趣
設(shè)計資源 培訓(xùn) 開發(fā)板 精華推薦
- 2025 是德科技數(shù)字月:圍觀拆解百萬示波器!注冊可參與幸運抽獎!
- Microchip直播|如何在ADAS系統(tǒng)中解決精密授時挑戰(zhàn)
- 【EEWORLD第三十一屆】2011年10月社區(qū)明星人物揭曉!
- 免費樣片申請、技術(shù)干貨|Littelfuse數(shù)據(jù)中心解決方案專區(qū)
- 學知識,贏好禮|泰克半導(dǎo)體材料與器件測試技術(shù)電源特性篇!
- 新年芯幣競價第二期——開發(fā)板競價
- Quartus Prime設(shè)計軟件15.1版 帶你體驗革命性的設(shè)計生涯
- TI嵌入式直播月:深入探究嵌入式產(chǎn)品在工業(yè)和汽車中的新應(yīng)用
- 【1月14日 技術(shù)直播】工程師請就位,Keysight計量專家開講啦 ~電子儀器計量校準基礎(chǔ)知識與校準周期探討