當(dāng)前位置:首頁 > 芯聞號 > 充電吧
[導(dǎo)讀]小弟近日看到一篇極好的文章,在此轉(zhuǎn)載分享給大家也是給自己做個備份吧?**********************************分割線*****************************

小弟近日看到一篇極好的文章,在此轉(zhuǎn)載分享給大家也是給自己做個備份吧?

**********************************分割線*************************************

--基于STM32F103ZET6的UART通訊實現(xiàn)

一、什么是IAP,為什么要IAP??????IAP即為In Application Programming(在應(yīng)用中編程),一般情況下,以STM32F10x系列芯片為主控制器的設(shè)備在出廠時就已經(jīng)使用J-Link仿真器將應(yīng)用代碼燒錄了,如果在設(shè)備使用過程中需要進行應(yīng)用代碼的更換、升級等操作的話,則可能需要將設(shè)備返回原廠并拆解出來再使用J-Link重新燒錄代碼,這就增加了很多不必要的麻煩。站在用戶的角度來說,就是能讓用戶自己來更換設(shè)備里邊的代碼程序而廠家這邊只需要提供給用戶一個代碼文件即可。??????而IAP卻能很好的解決掉這個難題,一片STM32芯片的Code(代碼)區(qū)內(nèi)一般只有一個用戶程序。而IAP方案則是將代碼區(qū)劃分為兩部分,兩部分區(qū)域各存放一個程序,一個叫bootloader(引導(dǎo)加載程序),另一個較user application(用戶應(yīng)用程序)。bootloader在出廠時就固定下來了,在需要變更user application時只需要通過觸發(fā)bootloader對userapplication的擦除和重新寫入即可完成用戶應(yīng)用的更換。如圖1-1所示圖 1-1??????在程序執(zhí)行初始進入bootloader,在bootloader里面檢測條件是否被觸發(fā)(可通過按鍵是否被按下、串口是否接收到特定的數(shù)據(jù)、U盤是否插入等等),如果有則進行對user application進行擦除和重新寫入操作,如果沒有則直接跳轉(zhuǎn)到user application執(zhí)行應(yīng)用;如果有則進行擦除用戶代碼并重新寫入新的用戶代碼。?二、STM32F103ZET6硬件條件??????STM32F103ZET6的啟動方式有三種:內(nèi)置FLASH啟動、內(nèi)置SRAM啟動、系統(tǒng)存儲器ROM啟動,通過BOOT0和BOOT1引腳的設(shè)置可以選擇從哪中方式啟動,這里選擇內(nèi)置的FLASH啟動。其FLASH的地址為0x08000000—0x0807ffff,共512KB,這些都能從芯片數(shù)據(jù)手冊中直接得到。而這里首要的一個問題是中斷的問題。正常情況下發(fā)生中斷的過程為:發(fā)生中斷(中斷請求)à到中斷向量表查找中斷函數(shù)入口地址à跳轉(zhuǎn)到中斷函數(shù)à執(zhí)行中斷函數(shù)à中斷返回。也就是說在STM32的內(nèi)置的Flash中有一個中斷向量表來存放各個中斷服務(wù)函數(shù)的入口地址,內(nèi)置Flash的分配情況大致如下圖2-1。圖2-1?在只有一個程序的情況下,程序執(zhí)行的走向應(yīng)該如圖2-2所示(借用網(wǎng)友的原圖)。圖2-2??????STM32F10x有一個中斷向量表,這個中斷向量表存放在代碼開始部分的后4個字節(jié)處(即0x08000004),代碼開始的4個字節(jié)存放的是堆棧棧頂?shù)牡刂?,?dāng)發(fā)生中斷后程序通過查找該表得到相應(yīng)的中斷服務(wù)程序入口地址,然后再跳到相應(yīng)的中斷服務(wù)程序中執(zhí)行。上電后從0x08000004處取出復(fù)位中斷向量的地址,然后跳轉(zhuǎn)到復(fù)位中斷程序的入口(標(biāo)號①所示),執(zhí)行結(jié)束后跳轉(zhuǎn)到main函數(shù)中(標(biāo)號②所示)。在執(zhí)行main函數(shù)的過程中發(fā)生中斷,則STM32強制將PC指針指回中斷向量表處(標(biāo)號③所示),從中斷向量表中找到相應(yīng)的中斷函數(shù)入口地址,跳轉(zhuǎn)到相應(yīng)的中斷服務(wù)函數(shù)(標(biāo)號④所示),執(zhí)行完中斷函數(shù)后再返回到main函數(shù)中來(標(biāo)號⑤所示)。??????若在STM32F103x中使用IAP方案,則內(nèi)置的Flash分配情況大致如下圖2-3。圖2-3在內(nèi)置的Flash里面添加一個BootLoader程序,BootLoader程序和user?application各有一個中斷向量表,假設(shè)BootLoader程序占用的空間為N+M字節(jié),則程序的走向應(yīng)該如圖2-2所示(借用網(wǎng)友的原圖并做改動,其中虛線部分為原圖步驟④⑤的走向,本人改為指向灰色部分)。圖2-2??????上電初始程序依然從0x08000004處取出復(fù)位中斷向量地址,執(zhí)行復(fù)位中斷函數(shù)后跳轉(zhuǎn)到IAP的main(標(biāo)號①所示),在IAP的main函數(shù)執(zhí)行完成后強制跳轉(zhuǎn)到0x08000004+N+M處(標(biāo)號②所示),最后跳轉(zhuǎn)到新的main函數(shù)中來(標(biāo)號③所示),當(dāng)發(fā)生中斷請求后,程序跳轉(zhuǎn)到新的中斷向量表中取出新的中斷函數(shù)入口地址,再跳轉(zhuǎn)到新的中斷服務(wù)函數(shù)中執(zhí)行(標(biāo)號④⑤所示),執(zhí)行完中斷函數(shù)后再返回到main函數(shù)中來(標(biāo)號⑥所示)。??????對于步驟④⑤,網(wǎng)友認為是:“在main執(zhí)行的過程中,如果CPU得到一個中斷請求,PC指針仍強制跳轉(zhuǎn)到地址0x08000004中斷向量表處,而不是新的中斷向量表,如圖標(biāo)號④所示,程序再根據(jù)我們設(shè)置的中斷向量表偏移量,跳轉(zhuǎn)到對應(yīng)中斷源新的中斷服務(wù)程序中,如圖標(biāo)號⑤所示”。我對此的理解是:“當(dāng)發(fā)生中斷后,程序從0x08000004(舊)處的中斷向量表中得到相應(yīng)的中斷服務(wù)函數(shù)入口地址,繼而跳轉(zhuǎn)到相應(yīng)的中斷服務(wù)程序”。但是舊的中斷向量列表里邊存放的是IAP程序中斷函數(shù)的入口地址,它是如何得到user程序中斷函數(shù)的入口地址呢?所以我覺得此種說法是錯誤的?!爱?dāng)發(fā)生中斷時PC指針強制會跳轉(zhuǎn)到0x08000004處”這種說法并沒有錯,只是忽略了后續(xù)的一些知識要點而導(dǎo)致這個說法出現(xiàn)矛盾。??????對于步驟④⑤我認為的是,在main函數(shù)的執(zhí)行過程中,如果CPU得到一個中斷請求,PC指針本來應(yīng)該跳轉(zhuǎn)到0x08000004處的中斷向量表,由于我們設(shè)置了中斷向量表偏移量為N+M,因此PC指針被強制跳轉(zhuǎn)到0x08000004+N+M處的中斷向量表中得到相應(yīng)的中斷函數(shù)地址(待求證),再跳轉(zhuǎn)到相應(yīng)新的中斷服務(wù)函數(shù),執(zhí)行結(jié)束后返回到main函數(shù)中來。?三、實現(xiàn)過程??????STM32F103ZET6的Flash地址為0x08000000—0x0807ffff共512KB,把這512KB的空間分為兩塊,第一塊大小為32KB存放BootLoader程序,剩余的空間存放用戶程序(根據(jù)實際情況分配這兩塊空間的大小,BootLoader程序占用的空間越小越好,則BootLoader地址為0x08000000—0x08007fff,用戶程序地址為0x08008000—0x0807ffff。BootLoader流程圖大致應(yīng)該如下:1、初始化時鐘。2、初始化中斷向量表地址。3、初始化按鍵。??????(使用按鍵觸發(fā)方式,上電時如果按鍵被按下則進行用戶程序更新操作)4、初始化串口。5、檢測按鍵是否被按下,是則執(zhí)行步驟6,否則執(zhí)行步驟10。6、擦除用戶程序(擦除0x08008000—0x0807ffff地址空間Flash)。7、從串口讀取新的用戶代碼數(shù)據(jù),把代碼寫入用戶程序空間。8、檢測串口數(shù)據(jù)接收完畢?是則執(zhí)行步驟9,否則跳回步驟7。9、用戶程序更新完畢,等待重新上電或硬件復(fù)位。10、跳轉(zhuǎn)到用戶程序(強制將PC指針跳轉(zhuǎn)到0x08008000+4處)。?????到這里首先要解決的問題就有:1、如何進行對STM32的Flash進行擦除和寫入操作。2、中斷向量表偏移如何設(shè)置。3、如何改變代碼存放的地址空間(因為BootLoader要存放在0x08000000處,用戶程序要存放在0x08008000處,而默認的代碼存放的地址空間為0x08000000)。4、怎么進行PC指針的強制跳轉(zhuǎn),跳轉(zhuǎn)時需要做些什么。5、串口接收的用戶代碼數(shù)據(jù)是什么樣的代碼數(shù)據(jù),是一種什么樣的文件。?問題的解決:1、使用STM32的固件庫函數(shù),只需調(diào)用幾個庫函數(shù)即可輕松解決,使用的固件庫為stm32f10x_flash.c文件,對Flash的操作過程簡要為:Flash解鎖àFlash擦除àFlash寫入àFlash上鎖。(對Flash編程的更詳細操作參考STM32F10xxx閃存編程手冊)①解鎖:FLASH_Unlock();????????????//解鎖FlashFLASH_SetLatency(FLASH_Latency_2);????????????//因為系統(tǒng)時鐘為72M所以要設(shè)置兩個時鐘周期的延時②擦除:for(i=0;i<240;i++){??if(FLASH_ErasePage(FLASH_ADDR+i*2048)?!= FLASH_COMPLETE)??????//一定要判斷是否擦除成功????return?ERROR;}說明:FLASH_ErasePage(uint32_t Page_Address)即為Flash擦除操作,按頁擦除,每頁2KB,Page_Address為頁的起始地址,如0x08000000是第一頁起始地址,0x08000800為第二頁起始地址,這里的操作擦除了0x08008000—0x0807ffff地址空間的Flash。③寫入:unsigned?char buf[1024];????????????//假設(shè)待寫入的代碼數(shù)據(jù)unsigned short temp;????????????//臨時數(shù)據(jù)for(i=0;i<512;i++){??????temp = (buf[2*i+1]<<8) | buf[2*i];????????????//2個字節(jié)整合為1個半字??????if(FLASH_ProgramHalfWord(ADDR,temp) != FLASH_COMPLETE)??????//判斷是否寫入成功??????{????????????Return ERROR;??????}ADDR +=2;??????//地址要加2,因為每次寫入的是2個字節(jié)(1個半字)}說明:因為STM32的Flash寫入為雙字節(jié)(1個半字)寫入,F(xiàn)LASH_ProgramHalfWord(uint32_t Address, uint16_t Data)函數(shù)即為對地址為Address寫入1個半字的Data,每次寫入完成后地址要加2。④上鎖:FLASH_Lock();??????//Flash?上鎖,一個固件庫函數(shù)即可實現(xiàn)。?2、關(guān)于中斷向量表的偏移設(shè)置,對于BootLoader程序只需設(shè)置中斷向量表的指向在0x08000000處,對于用戶程序需要設(shè)置中斷向量表的指向在0x08008000處即可。①在BootLoader程序的中斷向量表指向設(shè)置中應(yīng)有這么一句:NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);??????//設(shè)置中斷向量表指向其中NVIC_VectTab_FLASH是個宏定義,的值為0x08000000。②在用戶程序的中斷向量表指向設(shè)置用應(yīng)有這么一句:NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x8000);??????//設(shè)置中斷向量表指向?3、確認代碼存放的地址空間,在IAR和在Keil中的設(shè)置是不同的,網(wǎng)上有在Keil中設(shè)置的方法,設(shè)立介紹在IAR軟件環(huán)境下的設(shè)置方法。①在固件庫目錄STM32F10x_StdPeriph_Lib_V3.5.0ProjectSTM32F10x_StdPeriph_TemplateEWARM下找到一個stm32f10x_flash.icf文件,將其復(fù)制到工程目錄中來,在打開IAR工程,將配置文件添加到工程中,如下圖3-2所示圖3-1②在工程中打開stm32f10x_flash.icf該文件,修改兩個參數(shù)即可改變代碼存放的地址空間,圖下圖3-2所示。圖3-2?4、關(guān)于PC指針的強制跳轉(zhuǎn),想在BootLoader程序中將PC指針跳轉(zhuǎn)到用戶代碼處,可選擇下面的操作typedef????????void (*pFunction)(void);?????pFunction???????Jump_To_Application;uint32_t???????JumpAddress;#define???????ApplicationAddress???????0x08008000??if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000)???????//--------①{??JumpAddress?= *(__IO uint32_t*) (ApplicationAddress + 4);??????????????????//--------②??Jump_To_Application?= (pFunction) JumpAddress;??????????????????????????????//--------③??__set_MSP(*(__IO?uint32_t*) ApplicationAddress);?????????????????????????????//--------④??Jump_To_Application();?????????????????????????????????????????????????????????????????//--------⑤}①因為用戶程序開始位置(0x08008000處)的前4個字節(jié)存放的是堆棧的地址,堆棧地址必定是指向RAM空間的,而STM32的RAM空間起始地址為0x20000000,所以要進行判斷。②程序跳轉(zhuǎn)地址的確認,前面已經(jīng)說過0x08008004處的4個字節(jié)存放的是復(fù)位函數(shù)的入口地址,該句的意思為獲得(ApplicationAddress + 4)地址處的數(shù)據(jù),即為獲得新的復(fù)位函數(shù)入口地址。③令Jump_To_Application這個函數(shù)指針指向復(fù)位函數(shù)入口地址。④堆棧的初始化,重新設(shè)定棧頂代地址,把棧頂?shù)刂吩O(shè)置為用戶代碼指向的棧頂?shù)刂贰"萏D(zhuǎn)到新的復(fù)位函數(shù)。?5、通過串口來接收代碼數(shù)據(jù),就是PC機通過串口將代碼數(shù)據(jù)發(fā)送到STM32中去。這里就涉及到兩個問題:①數(shù)據(jù)怎么得來。②數(shù)據(jù)傳輸?shù)倪^程需要遵循的協(xié)議,什么時候開始,什么時候結(jié)束。解決①:一般我們就將*.hex文件使用JFlash-ARM打開再通過Jlink仿真器燒錄到STM32芯片中,但是*.hex文件里邊包含的數(shù)據(jù)不純粹是代碼數(shù)據(jù)還有一些別的東西,而*.bin文件數(shù)據(jù)就全部是代碼數(shù)據(jù)。在IAR軟件環(huán)境中打開一個用戶工程,先設(shè)置好中斷向量表偏移和代碼存放的地址空間后(前面已介紹過這兩種方法)。設(shè)置工程如下圖3-3所示,確認后重新編譯工程,在工程的DebugExe目錄下會相應(yīng)生成一個xxx.bin文件,這就是所需要的代碼文件。圖3-3②數(shù)據(jù)通過串口來傳輸文件常用的協(xié)議有XModem、YModem、ZModem這三種協(xié)議,在PC端使用這些協(xié)議傳輸文件只需要PC的超級終端或者終端工具SecureCRT即可,但是在STM32這邊的編程會增加一些困難(因為要先去讀懂、解析這些協(xié)議,在通過編程來實現(xiàn))。也可選擇自己定義一套簡單的傳輸協(xié)議,但同樣會有一些困難(因為要在PC端進行文件和串口編程)??傊还芡ㄟ^什么辦法都行,只要能將xxx.bin文件數(shù)據(jù)通過串口全部發(fā)送到STM32并且STM32能夠全部接收到這些數(shù)據(jù)并寫入Flash即可(我選擇后者,自定義傳輸協(xié)議并用VC進行文件和串口編程)。?四、結(jié)束語??????總的來說STM32的IAP方案實現(xiàn)需要在進行用戶程序之前加一段Bootloader程序,BootLoader程序的作用就是:①什么都不做,直接跳轉(zhuǎn)到用戶程序。②刪除原有的用戶程序,讀取*.bin文件數(shù)據(jù)并將數(shù)據(jù)重新寫入新的用戶程序。對于用戶程序相比普通的編程只需要做三步改動即可①改變中斷向量表。②改變代碼存放的地址空間③修改生成*.bin文件?????使用通過UART的IAP方案并不是很好的選擇,這只是IAP方案的一個機制,因為能使用PC機通過串口升級程序,同樣能通過Jlink燒寫程序,并且自定義的串口通訊協(xié)議在沒有校CRC校驗的情況下不能及時發(fā)現(xiàn)數(shù)據(jù)傳輸過程發(fā)生的錯誤。這里推薦使用SD卡(或U盤)進行用戶程序更新,將*.bin文件復(fù)制到SD卡(或U盤)中,STM32再通過讀取SD卡(或U盤)的*.bin文件進行用戶程序更新,這也避免了STM32與PC笨重的通訊,只需插一個SD卡(或U盤)更顯得人性化一些,但需要去弄懂STM32如何與SD卡(或U盤)的通訊。


本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉