• <track id="eh8v2"></track>
  • <td id="eh8v2"></td><track id="eh8v2"></track>
    <object id="eh8v2"><strong id="eh8v2"></strong></object>
    <td id="eh8v2"></td>
      <pre id="eh8v2"><label id="eh8v2"></label></pre><acronym id="eh8v2"><strong id="eh8v2"></strong></acronym>

        stm32L0無用戶bootloader完成IAP

        2020-03-23 07:19:16  瀏覽:-  來歷:

        DK45

        甚么是IAP

        IAP-in application programming,便是在利用中編程的意義,在產物宣布今后,不論是增添功效啊,或對bug修復啊,都能夠對本來固件停止更新進級。

        傳統IAP思緒

        基于stm32做的iap大大都的思緒都是先設想一個bootloader,若是須要進級呢就跳轉到bootloader用來更新后面的利用法式。利用法式的余暇呢能夠是一個或兩個。以下圖所示,兩個app必定就要限制每一個app的巨細,可是它比擬一個app空間會更寧靜,由于它隨時城市存在一個能夠任務的app。

        這類體例用的比擬多,可是也會存在一些題目:

        • 須要保護bootloader和app兩套代碼
        • bootloader沒法更新,以是要確保bootloader完整不bug
        • 像單APP空間若是更新失利了,那末只能逗留在bootloader地區

        雙bank IAP道理

        而stm32L0系列呢(局部型號)供給了一套雙BANK機制能夠用來做雙存儲區在線進級。基于該雙bank體例便能夠夠夠丟棄bootloader,保護起來更便利。不過要懂得雙bank仍是略微有那末一點龐雜,好的成果是用來卻很便利。

        咱們先從微觀上懂得一下雙bank的道理:

        如圖所示,它的flash被均勻分為兩塊,一起為bank1,一起為bank2。當在bank1中運轉app時便能夠夠夠把新更新的固件寫入到bank2,寫完今后就切換到從bank2啟動運轉新的app。若是今后在bank2運轉就把新固件寫入bank1,寫完今后切換從bank1啟動。

        道理便是如許很簡略,可是這外面有個關頭的題目點,在不bootloader的環境下若何完成從bank1或bank2啟動。這便是stm32L071cb自帶的一個首要特征(其余型號是不是有請自查手冊,今朝只要stm32L0、stm32L4、stm32G4中的某些型號有這個特征)。下面以stm32L071cb為例來闡發若何完成切換。

        起首進場的是UFB。what is UFB?

        這是存在于SYSCFG寄放器中的一個位,它有兩個值:0或1,功效是:

        • 0:FLASH bank1 被映照在0x8000000地點上
        • 1:FLASH bank2 被映照在0x8000000地點上

        用過stm32的同窗能夠思惟外面有一個牢固的概念:stm32的flash都是從0x8000000起頭的。換句話說,我從0x8000000讀掏出來的數據必定都是同一片flash地區。可是,在stm32L071CB下面并不是。你從0x8000000讀出來一個數據能夠是BANK1開首的數據也能夠是BANK2開首的數據。究竟是哪一個取決于UFB這個位今后的值是0仍是1。

        這個UFB先記著,期待后面綜合起來懂得。

        雙BANK啟動才能

        這個能夠一下抖出來的內容有點多,請打起精力。

        這又要從ARM的啟動體例提及了,能夠看我上一篇文章有具體的總結:STM32在線進級間斷向量重定向深度分解。要記著關頭的一點便是ARM是從0x00000000取的第一條指令。而STM32一般環境下之以是從用戶flash起頭運轉,是由于用戶flash被映照到了0x00000000地點上。0x8000000和0x00000000都能拜候到flash同一個地區,以是才讓看起來貌似是從0x8000000運轉起來的一樣。

        當從bank1啟動時,現實上便是通俗的啟動形式。上電后用戶flash最底部(BANK1地區)被映照到0x00000000地點,而后CPU間接從這里取指令起頭履行。

        那重點便是從BANK2啟動的流程是若何的,這里要給大師再先容個新的設置裝備擺設選項:BFB2,存在于option bytes外面的一個位。這個位呢便能夠夠夠用來挑選從bank2啟動。由于在option bytes外面,以是掉電是不會喪失的。

        當boot0=0的時辰,stm32默許就會從用戶flash啟動。也便是用戶flash被映照到0x0地點。可是當boot0=0并且BFB2=1的時辰,體系flash會被映照到0x0地點,體系flash也便是stm32內置的bootloader。

        這時辰進內置bootloader今后呢就會去查抄BANK2有不有用代碼(當在bank的第一個數據所指向的地點是有用的(指向棧頂地點),則以為代碼便是有用的),若是有就會把UFB設置為1(UFB后面先容過,忘了往上翻再看一遍),bank2被映照到0x8000000地點,而后跳轉到BANK2起頭運轉。以是從BANK2啟動和從BANK1啟動是不一樣的,也比從bank1啟動流程龐雜一些。bank2啟動流程以下:

        以是我這里畫了一張stm32L071cb上電到從bank1或bank2起頭運轉的流程圖:

        雙BANK進級中的間斷向量表該怎樣辦

        從bank1啟動時的間斷向量表

        細心再看下面的流程圖,若是從bank1啟動,bank1是被映照到0x0地點的,而ARM內核默許也是從0x0處讀取間斷向量表。以是不必做任何設置都能夠一般的運轉。

        從bank2啟動時的間斷向量表

        可是從BANK2啟動就沒那末簡略了,假設BFB2=1時,CPU并不是間接跳轉到bank2運轉,而是進步前輩入了體系flash地區(內置bootloader)。這時辰現實上是stm32內置bootloader被映照到了0x0地點。今后流程只是把bank2映照到了0x8000000,而后就從BANK2啟動了。

        如許若是不論間斷向量表地位會產生甚么景象呢?當間斷產生了,ARM內核會跳轉到0x0地點處(跳回了內置bootloader)找到間斷向量。那如許法式豈不亂套了,咱們本身編寫的間斷辦事函數將永久不會被履行到。

        以是進入到BANK2今后必然要做間斷向量表的重定位。這里我列出來三種是被我在stm32L071cb下面考證過的思緒:(對更多若何定位間斷向量表仍是看我上一篇文章:STM32在線進級間斷向量重定向深度分解)

        1. 從bank2啟動今后就點竄VTOR為0x8000000
        2. 從bank2啟動今后點竄MEM_MODE,從頭把用戶flash定位到0x0地點
        3. 從bank2啟動今后把flash中間斷向量表拷貝到RAM中,并點竄VTOR重定位間斷向量到RAM區

        終究我感覺最簡略的是第一種,便是上電今后就點竄VTOR到0x8000000。固然另有別的一個益處便是不論從bank1或bank2啟動都能夠履行這一條。固然對bank1啟動來講這個設置不是必須的,可是履行了也有害。如許便能夠夠做到bank1和bank2的app代碼處置流程盡能夠同一。

        別的另有便是現實上若是你利用的是STM32 HAL庫,在SystemInit()中現實上已幫咱們從頭設置VTOR到0x8000000。以是咱們就無需再次增加點竄VTOR的代碼了。

        雙bank切換的方式

        對IAP把代碼新固件寫到別的一片bank今后,就要切換到從別的一個bank啟動。雖然后面流程道理有點龐雜,可是完成它的也比擬簡略,首要履行以下步驟:

        • 先查抄BFB2位必定今后處于哪一個bank
        • 若是在BANK1就設置BFB2=1,如過在BANK2就設置BFB2=0
        • 履行HAL_FLASH_OB_Launch()。履行完該步驟今后體系會主動復位

        從BANK2啟動時沒法呼應間斷

        厥后顛末各方排查,定位到ARM內核的一個寄放器:PRIMASK。這個寄放器從stm32參考手冊上是查不到的,若是領會概況能夠去看arm-cortex M0+編程手冊。

        在切換到從bank2啟動今后,間斷向量表偏移我也從頭設置,可是仍是呈現了間斷沒法呼應的題目。systick間斷進不去,如許就致使HAL庫運轉會一向期待systick計不時間到的處所。

        說這個寄放器你能夠不熟習,可是__enable_irq()和__disable_irq()現實上操縱的便是這個寄放器的值。默許這個值是0,是不屏障任何間斷的。可是從bank2啟動時辰發明這個值變成了1。如許便能夠夠詮釋為甚么間斷進不去了,它為1的時辰除不可屏障間斷,其余的間斷都一概屏障不呼應。

        而為甚么從bank2啟動才變成1,從bank1啟動就一般。再看下后面bank2啟動的流程是先從外部bootloader跳轉過去的,以是必定是外部bootloader把PRIMASK給設置裝備擺設成1了。

        以是終究處理起來就簡略了,便是從bank2啟動今后,就挪用一條__enable_irq()從頭點竄PRIMASK值變成0便能夠夠夠了。

        AV天堂永久资源网 2021AV天堂网手机版 影音先锋2020色资源网 国产精品自在线拍国产手机版 日本高清一区和二区三区免费 影音先锋2020色资源网 99自在现线免费 久久国内精品自在自线 亚洲国产在线精品国自产拍愿 精品伊人久久久大香线蕉 亚洲国产在线精品 亚洲精品久久久久中文字幕一区 99精品国产自在现线