日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

bootloader学习笔记---第二篇

發布時間:2024/1/8 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 bootloader学习笔记---第二篇 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

一、鏈接地址與跳轉

二、bootloader疑難問題

1、應用程序中使用中斷導致程序跑飛或者不能重新下載程序?

2、中斷向量表具體是怎么重映射?

3、bootloader更新app過程中意外斷電,怎么處理?流程是先備份后擦出然后燒寫嗎?

4、botloader燒寫app程序過程中突然斷電或者斷開連接導致bootloader無法使用,必須重新燒寫,這是什么原因呢?

5、怎么將BOOT程序和APP程序一起燒進板子?

6、第一,多核芯片是否給每個核編寫一個bootloader,并分別放在每個核相應的flash里?第二,上位機軟件下發的信息是否可以通過ID來區分送到哪個核里?第三,上位機軟件是不是必須和CAN盒子配套?

?7、bootloader升級過程很慢,100k左右的s19文件需要十多分鐘?

8、boot程序,對于app的跳轉地址有什么要求?boot程序比較大,跳轉地址是0x25000,跳轉總是失敗?

9、可以直接從APP區域跳轉到到BOOT區域直接升級,而不用經過一個重啟的過程嗎?正常項目都是APP啟動升級的

10、boot 更新app的時候,將flash drv(擦除,寫入等風險操作函數)臨時通過can從上位機下載到ram中并運行,通過修改鏈接文件指定自定義的一塊ram,可以把收到的flash drv的數據放到這塊地址,在執行擦除或者寫入操作時,1.怎么找到擦除或寫入函數的ram地址并執行?2.如果可以找到地址,怎么往擦除或寫入函數傳遞參數(這兩個函數知道ram地址,不是函數,怎么傳遞參數)?

11、將地址強制轉換為函數指針調用,會造成hard fault interrupt?

三、備注


一、鏈接地址與跳轉

這里討論第一篇文章中提到的第二種情況,即第二種常見的情況就是app燒寫在flash上,app應該在ram內存里運行,app或者是bootloader需要把app拷貝到內存ram中去,1、如果是bootloader拷貝的,那么bootloader要跳轉到內存ram中去執行app;2、如果是app自己把自己復制到內存中去的,那么bootloader直接跳轉到app的位置就可以了。

這里有三個問題,1、誰把app從flash復制到ram中去?2、具體是復制到哪里?3、如果bootloader要跳轉到ram中去怎么跳?

第一個問題,app自我復制,bootloader幫忙復制;第二個問題,這個地址我們可以預先設置好;第三個問題,用函數指針跳轉。

下面介紹兩種跳轉方式
第一、相對跳轉,BL main; 這是條匯編語句,這條語句會讓pc=當前pc+相對位移。不管我們程序放在哪里,相對跳轉都能成功。編譯器是默認優先使用相對跳轉。

?

第二、絕對跳轉,是讓pc=要跳轉的地址。比如,LDR r5 , [pc, #24]? ? ?BLX r5。函數指針的方式也是絕對跳轉的方式。對于絕對跳轉,在對應的地址上面必須有對應的代碼。stm32上電后第二件事情就是跳轉到Reset_Handler中去,這也是絕對跳轉。如果是長距離調用,也會使用絕對跳轉。如果是絕對跳轉,我們程序燒錄的位置如果發生變化,即我們燒錄的地址和鏈接文件(散列文件)中指定的地址不一致,那么跳轉過去的地址就會出現錯誤,因為跳轉的絕對地址的那塊內存可能沒有初始化,程序會崩潰。

散列文件

?

如果我們如上圖那樣使用散列文件修改了app程序的鏈接地址,那么app程序會把指令和數據放在0x20000000。那么這相當于,bootloader跳轉到app中,app自己把自己復制到0x20000000。可以看到散列文件中,鏈接地址和加載地址都是同一個地址,鏈接地址就是運行時的地址,我們可以使用燒錄工具來決定程序的燒錄地址,在這里加載地址沒有用,只有鏈接地址有用。

?上面的代碼是app自己復制自己到內存的

第二種情況,需要bootloader把app復制到內存中去時,app文件的頭部一般會包含以下幾種信息,1、加載地址:即要拷貝到內存的那個地址,2、入口地址:即第一條指令地址,3、長度,4、CRC。

這就需要bootloader啟動后需要去app的燒錄地址讀取這些頭部信息,接著解析這些頭部信息,然后讀取app.bin存入內存,最后跳轉到內存中去執行app程序。

解析頭部信息,需要注意的是,存儲方式是大字節序還是小字節序,

這里我補充一個知識點:我們在對flash進行讀寫操作時,flash中對應的應用程序文件將不能運行,所以必須將flash driver拷貝到ram區域,這是由flash的硬件性質決定的,為什么呢?

因為,flash只有一套自己的crossbar(類似交叉開關,同一時刻只能執行一種操作)訪問總線,當其被用作寫數據時,不能同時讀取數據(譬如CPU取指執行程序)。但在支持RWW partition的flash中是不必如此操作的,它支持在不同flash分區同時進行讀和寫。

二、bootloader疑難問題

1、應用程序中使用中斷導致程序跑飛或者不能重新下載程序?

這個要看具體的MCU(內核),一個原則是使能中斷和異常發生之前必須確保其中斷向量表和中斷/異常ISR已經ready。

2、中斷向量表具體是怎么重映射?

更改向量表基地址寄存器,也叫中斷向量表偏移量寄存器,中斷向量表的重定向可以是在bootloader進入用戶程序之前改,也可以在用戶程序里面改,對于在Cortex-M3內核的MCU上可以通過設置SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET,關于這個寄存器的描述可以見下圖;該寄存器的值來實現中斷向量表的重定義。如果沒有這類的寄存器可以參考這位博主的辦法嘗試解決STM32F0芯片IAP實現之中斷向量表重映射(沒有中斷向量表偏移寄存器SCB->VTOR的應對方法)_a只如初見的博客-CSDN博客_中斷重映射

3、bootloader更新app過程中意外斷電,怎么處理?流程是先備份后擦出然后燒寫嗎?

一般是雙應用程序分區,更新完新的應用程序之后才擦除老的應用程序分區并設置跳轉標志,以保證時鐘有一個分區中的應用程序正確可用。

4、botloader燒寫app程序過程中突然斷電或者斷開連接導致bootloader無法使用,必須重新燒寫,這是什么原因呢?

如果應用程序新過程中斷電或者意外復位,則應用程序更新失敗,相應的應用程序完整性校驗通不過,當然得重新下載,為了避免這種情況下應用程序丟失,常常BootLoader需要對應用程序進行雙備份,即使用兩個不同的NVM分區來保存應用程序,只有新的應用程序更新成功之后,才擦除老的應用程序。

5、怎么將BOOT程序和APP程序一起燒進板子?

用任意文本編輯器打開bootloader和app工程生成的S19文件拷貝即可合并,然后使用調試器通過SWD/JTAG接口下載即可。

6、第一,多核芯片是否給每個核編寫一個bootloader,并分別放在每個核相應的flash里?第二,上位機軟件下發的信息是否可以通過ID來區分送到哪個核里?第三,上位機軟件是不是必須和CAN盒子配套?

多核MCU只需要為其boot CPU core開發一個bootloader就可以了,可以通過ID或者地址來判斷,可以復用我們的上位機軟件,但其只有簡單功能,要用這個上位機軟件需要使用匹配的CAN適配器,否則需要修改底層dll以適用于其他CAN適配器

?7、bootloader升級過程很慢,100k左右的s19文件需要十多分鐘?

Flash擦除本身很耗時間,另外,可以在將S19文件每行的數據設置為更長(比如128字節或者512字節)或者把bootloader里面改為接收10行s19再燒寫,提高Flash燒寫效率,再或者就是提高通信速率

8、boot程序,對于app的跳轉地址有什么要求?boot程序比較大,跳轉地址是0x25000,跳轉總是失敗?

這個要看跳轉具體是如何實現的?要反匯編看看具體的匯編跳轉指令,不同的匯編跳轉指令支持的跳轉地址范圍不同。

9、可以直接從APP區域跳轉到到BOOT區域直接升級,而不用經過一個重啟的過程嗎?正常項目都是APP啟動升級的

可以在APP中接收到boot請求后使用函數指針直接跳轉到bootloader的reset_handler,但需要在跳轉之前反初始化/復位APP使用的所有時鐘和外設,以避免APP與bootloader的相互影響。當然,我們推薦的方式還是軟件復位或者看門狗溢出復位進入bootloader。

10、boot 更新app的時候,將flash drv(擦除,寫入等風險操作函數)臨時通過can從上位機下載到ram中并運行,通過修改鏈接文件指定自定義的一塊ram,可以把收到的flash drv的數據放到這塊地址,在執行擦除或者寫入操作時,1.怎么找到擦除或寫入函數的ram地址并執行?2.如果可以找到地址,怎么往擦除或寫入函數傳遞參數(這兩個函數知道ram地址,不是函數,怎么傳遞參數)?

第1個問題,使用函數查找表,類似中斷向量表的工作原理;第2個問題使用函數指針,因為函數名本身就是地址,我們可以定義一個和flash drv相同格式的函數指針,然后向這個函數指針傳遞的參數就是傳遞給了flash drv函數;

11、將地址強制轉換為函數指針調用,會造成hard fault interrupt?

typedef void(*pfun_t)(void);pfun_t pfun = (pfun_t)0x00500000; pfun();

注意是把中斷向量(中斷ISR函數地址,存在中斷向量表地址的內容)而不是中斷向量地址本身轉換成函數指針執行。

三、備注

本文部分內容是根據韋東山老師的視頻整理編寫的筆記從0寫BootLoader(適用于單片機),還有部分公眾號中汽車電子expert成長之路的文章評論,部分圖片來自于cortex-m3權威指南。

=文檔信息=
本學習筆記由博主整理編輯,僅供非商用學習交流使用
由于水平有限,錯誤和紕漏之處在所難免,歡迎大家交流指正
如本文涉及侵權,請隨時留言博主,必妥善處置
版權聲明:非商用自由轉載-保持署名-注明出處

總結

以上是生活随笔為你收集整理的bootloader学习笔记---第二篇的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。