S32k144 簡易 Bootloader

TOPS

原創版權,轉載請注明出處!

內容目錄

一、理論
1、 復位流程
2、 內存分布
二、 實戰 — boot
1、 工具:keil JLINK
2、 新建工程
3、 修改腳本
4、 修改代碼
5、 編譯下載
6、現象
三、 實戰 — app
1、 新建工程
2、 修改腳本
3、 修改代碼
4、 編譯下載
5、 在線仿真
注意:
問題:
總結
參考文獻:

一、理論

1、 復位流程

在離開復位狀態后,Cortex-M 做的第一件事就是讀取下列兩個 32 位整數的值:
1、從地址 0x0000,0000 處取出 MSP 的初始值。</li>
2、從地址 0x0000,0004 處取出 PC 的初始值——這個值是復位向量,LSB 必須是1,然后從這個值所對應的地址處取指。

圖 1.1 復位序列.jpg

在 0 地址處提供 MSP 的初始值,然后緊跟著就是向量表。向量表中的數值是 32位的地址,而不是跳轉指令。向量表的第一個條目指向復位后應執行的第一條指令。

圖 1.2 初始化MSP及PC初始化一個范例.jpg

因為 Cortex-M 使用的是向下生長的滿棧,所以 MSP 的初始值必須是堆棧內存的末地址加1。舉例來說,如果你的堆棧區域在 0x20007C00-0x20007FFF 之間,那么 MSP 的初始值就必須是 0x20008000。
向量表跟隨在 MSP 的初始值之后——也就是第 2 個表目。要注意因為 cortex-m 是在Thumb 態下執行,所以向量表中的每個數值都必須把 LSB 置1(也就是奇數)。正是因為這個原因,圖 3.18 中使用 0x101 來表達地址 0x100。當 0x100 處的指令得到執行后,就正式開始了程序的執行。在此之前初始化 MSP 是必需的,因為可能第1條指令還沒來得及執行,就發生了 NMI 或是其它 fault。MSP 初始化好后就已經為它們的服務例程準備好了堆棧。

2、 內存分布

圖 1.3 flash 內存分配圖.jpg

需要修改工程中內存分配的腳本實現以上效果,這里是使用兩個工程設計,一個為 bootloader 工程,一個為 app 工程。

二、 實戰 — boot

1、 工具:keil JLINK

使用 S32DS 開發也可以,但是 S32DS 使用 jlink 下載程序的時候,芯片容易鎖死,而且飛思卡爾的芯片鎖死之后,解鎖都比較麻煩,所以暫時選擇 keil 開發。

2、 新建工程

使用 keil 建立 s32k144 工程并不難,只是 s32k144 與其他的芯片稍微有點不一樣,除了有一個匯編文件的啟動文件之外,還有幾個源文件,源文件的作用主要是從 flash 復制代碼到 ram 中,初始化 bss 段,關閉看門狗,配置時鐘等。

圖 2.1 新建工程.jpg
圖 2.2 保存工程.jpg
圖 2.3 選擇芯片類型.jpg
圖 2.4 選擇固件以及啟動代碼.jpg

上圖紅色部分務必勾選。

圖 2.5 工程目錄結構.jpg

紅色框部分即使內存分配腳本,這是待會兒需要修改的。工程建立好了之后,還需要進行一些配置。

圖 2.6 內存配置.jpg

在搞 STM32 的時候,有時候修改的就是這里,這里可以修改內存分配,但是我們這次使用的是用戶腳本,不是默認內存配置,所以這里不需要修改。當然還有生成 hex 文件、調試工具的選擇、輸出目錄等配置也需要進行,這里就不一一列舉了,

圖 2.7 用戶腳本選擇.jpg

紅色部分不要勾選,紫色部分需要手動找到這個腳本,我們把代碼下載到 flash 就選擇 flash 腳本,下載到 ram 就選擇 ram 腳本。

圖 2.8 下載配置.jpg

紅色部分最好不勾選,因為如果直接使用在 keil 下載的話,這個選項在下載 app 代碼的時候,會全部擦除 flash,這時候 boot 會遭殃,會導致起不來,配置基本配置好了,接下來就是修改腳本了。

3、 修改腳本

Boot 的腳本基本不用怎么修改,就是修改一下 Boot 結束地址,這里開辟給 boot 的大小是 0x4000,相當于 16K 的大小。

#if (defined(__ram_vector_table__))
#define __ram_vector_table_size__    0x00000400
#else
#define __ram_vector_table_size__    0x00000000
#endif

#define m_interrupts_start             0x00000000
#define m_interrupts_size              0x00000400

#define m_flash_config_start           0x00000400
#define m_flash_config_size            0x00000010

#define m_text_start                   0x00000410
//#define m_text_size                    0x0007FBF0
#define m_text_size                    0x00002000

#define m_interrupts_ram_start         0x1FFF8000
#define m_interrupts_ram_size          __ram_vector_table_size__
#define m_data_start       (m_interrupts_ram_start+m_interrupts_ram_size)
#define m_data_size                  (0x00008000 - m_interrupts_ram_size)
#define m_data_2_start                 0x20000000
#define m_data_2_size                  0x00007000

4、 修改代碼

代碼的修改主要是集中在,跳轉函數,需要定義一個函數指針類型,還要注意 Cortex-m 復位跳轉序列。

#include "S32K144.h" /* include peripheral declarations S32K144 */
#include "clocks_and_modes.h"
#include "gpio_led.h"



#define APP_ADDR  0x00004000

/******************************************************************************
*Local variables
******************************************************************************/
typedef void (*bootloader_fun)(void);
bootloader_fun jump2app;


void delay(volatile int cycles)
{
    /* Delay function - do nothing for a number of cycles */
    while(cycles--);
}


int main(void)
{
    
      SOSC_init_8MHz();       /* Initialize system oscilator for 8 MHz xtal */
      SPLL_init_160MHz();     /* Initialize SPLL to 160 MHz with 8 MHz SOSC */
      NormalRUNmode_80MHz();  /* Init clocks: 80 MHz sysclk & core, 40 MHz bus, 20 MHz flash */
    
      LED_PORT_init();
    
    for(;;){

        for(int i = 0;i < 5;i++){
        led_triggle(2,1);              /* turn on red LED */
        led_triggle(1,0);              /* turn on green LED */
        led_triggle(0,0);              /* turn on blue LED */       

            delay(720000);
            delay(720000);
        
        led_triggle(2,0);              /* turn on red LED */
        led_triggle(1,0);              /* turn on green LED */
        led_triggle(0,0);              /* turn on blue LED */   
            delay(720000);
            delay(720000);
        }
        
        
        jump2app = (bootloader_fun)*(uint32_t*)(APP_ADDR + 4);
        jump2app();
            
    }
    
    
    return 0;
}

重點應該就是這句話:
jump2app = (bootloader_fun)(uint32_t)(APP_ADDR + 4);
APP 地址加上 4 ,就是因為 CORTEX-M 復位序列的 PC 指針位置的偏移量就是偏移 4,(uint32_t)(APP_ADDR + 4) 進行強制類型轉換,(bootloader_fun)(uint32_t*)(APP_ADDR+4) 取址,相當于取 0x4004 地址的值,放到 PC 指針,可能需要主義的還有一個就是 C 語言的語法,C 語言里面,函數名稱就是函數的入口地址,也就是說函數名稱其實也是一個指針,所以后面一句:jump2app();就是相當于執行一個函數。這樣就可以跳轉了。

5、 編譯下載

編譯就沒啥問題,下載就有兩種方式,一種是直接在keil 上下載,這個很簡單了,例外一個就是單獨打開 segger 下載,這時候需要配置一下這個軟件:

圖 2.9 segger 配置.jpg
圖 2.10 選擇芯片.jpg

然后把編譯生成的 hex 文件,直接拖到頁面里面就可以了,按 F5 就可以下載了,boot的下載沒有什么特別的要求,兩個都可以下載。

圖 2.11 編譯完成.jpg

6、現象

下載之后,可以看到小燈閃了 5 下就不閃了,說明執行到了后面的跳轉程序。

三、 實戰 — app

1、 新建工程

建立工程和 boot 一樣的過程,這里就不再贅述了。

圖 3.1 app 目錄結構.jpg

2、 修改腳本

腳本位置:$(工程目錄)144_app\RTE\Device\S32K144UAxxxLLx 下

#if (defined(__ram_vector_table__))
#define __ram_vector_table_size__    0x00000400
#else
#define __ram_vector_table_size__    0x00000000
#endif

//#define m_interrupts_start             0x00000000
#define m_interrupts_start             0x00004000
#define m_interrupts_size              0x00000400

//#define m_flash_config_start           0x00000400
#define m_flash_config_start           0x00004400
#define m_flash_config_size            0x00000010

//#define m_text_start                   0x00000410
#define m_text_start                   0x00004410
//#define m_text_size                    0x0007FBF0
#define m_text_size                    0x0002FBF0

#define m_interrupts_ram_start         0x1FFF8000
#define m_interrupts_ram_size          __ram_vector_table_size__

#define m_data_start            (m_interrupts_ram_start + m_interrupts_ram_size)
#define m_data_size                    (0x00008000 - m_interrupts_ram_size)

#define m_data_2_start                 0x20000000
#define m_data_2_size                  0x00007000

App 腳本的修改稍微多一點,每個對應的偏移地址都需要改,向量表的地址,text 段的地址等。

3、 修改代碼

代碼基本就是正常的代碼,不用做任何的操作就可以了。

4、 編譯下載

編譯和 boot 一樣,下載的話,如果沒勾選 erase full chip ,可以直接下載,也可以使用 segger 下載。

5、 在線仿真

如果 app 的代碼只是下載,那每次調試都會比較麻煩,都得編譯成 hex 文件再下載才能驗證,因為腳本修改了向量表的地址,直接在線調試是不行的,這樣就很不方便開發了,網路上有網友通過修改一個腳本,讓 keil 識別到我們已經修改過的向量表的地址,在工程目錄新建 flashoffset.ini 文件,內容如下:

圖 3.2 app 在線調試腳本.jpg

在 keil 配置里面導入這個文件

圖 3.3 導入在線調試腳本.jpg

這樣就可以就行在線調試了,就和正常開發一樣方便了。

注意:

每個工程編譯完了之后,最好是查看 .map 文件,看一下內存分配是否都在劃定的內存里面

圖 3.4 app 工程的 .map 文件.jpg

也算是一種調試信息手段吧。

問題:

這個 bootloader 整個流程雖然可以走通,但是還有問題,如果 app 工程開啟了中斷,app 的程序會跑飛。原因是什么呢?這個就是第一節說的 cortex-m 復位序列。

1、 boot 中斷未關;
2、接收升級文件驅動未提供;
3、Flash 驅動未提供;
4、App 程序重新定位向量表的基地址未修改。

總結

雖然上述通過 keil 軟件,以及它的分散腳本實現了簡單的 bootloader 和 app 在線調試功能,這個只是一個簡易的 bootloader,還有很多功能未添加,也有很多地方還需要完善,目前這個只是能跑一個簡單的流程,只是幫助理解一下。

參考文獻:

《Cortex-M3 權威指南》

代碼下載:
https://pan.baidu.com/s/1fF3N_qpvMNtZOFGcB-HuIQ 密碼: 3ouv
https://pan.baidu.com/s/1TsZtd38C8hcLsVjJ113G5w 密碼:3tqg

微信公眾號:depthkernel
關注可了解更多嵌入式的教程。問題或建議,請公眾號留言;
QQ 群:135924744
如果你覺得對你有幫助,歡迎關注公眾號

微信公眾號
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,197評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,415評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,104評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,884評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,647評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,130評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,208評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,366評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,887評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,737評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,939評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,478評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,174評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,586評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,827評論 1 283
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,608評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,914評論 2 372

推薦閱讀更多精彩內容