S32k144 簡易 Bootloader

TOPS

原創(chuàng)版權(quán),轉(zhuǎn)載請注明出處!

內(nèi)容目錄

一伯诬、理論
1商源、 復(fù)位流程
2、 內(nèi)存分布
二鸯旁、 實戰(zhàn) — boot
1、 工具:keil JLINK
2、 新建工程
3泣港、 修改腳本
4暂殖、 修改代碼
5、 編譯下載
6爷速、現(xiàn)象
三央星、 實戰(zhàn) — app
1、 新建工程
2惫东、 修改腳本
3莉给、 修改代碼
4、 編譯下載
5廉沮、 在線仿真
注意:
問題:
總結(jié)
參考文獻:

一颓遏、理論

1、 復(fù)位流程

在離開復(fù)位狀態(tài)后滞时,Cortex-M 做的第一件事就是讀取下列兩個 32 位整數(shù)的值:
1叁幢、從地址 0x0000,0000 處取出 MSP 的初始值。</li>
2坪稽、從地址 0x0000,0004 處取出 PC 的初始值——這個值是復(fù)位向量曼玩,LSB 必須是1,然后從這個值所對應(yīng)的地址處取指窒百。

圖 1.1 復(fù)位序列.jpg

在 0 地址處提供 MSP 的初始值黍判,然后緊跟著就是向量表。向量表中的數(shù)值是 32位的地址篙梢,而不是跳轉(zhuǎn)指令顷帖。向量表的第一個條目指向復(fù)位后應(yīng)執(zhí)行的第一條指令。

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

因為 Cortex-M 使用的是向下生長的滿棧渤滞,所以 MSP 的初始值必須是堆棧內(nèi)存的末地址加1贬墩。舉例來說,如果你的堆棧區(qū)域在 0x20007C00-0x20007FFF 之間妄呕,那么 MSP 的初始值就必須是 0x20008000陶舞。
向量表跟隨在 MSP 的初始值之后——也就是第 2 個表目。要注意因為 cortex-m 是在Thumb 態(tài)下執(zhí)行趴腋,所以向量表中的每個數(shù)值都必須把 LSB 置1(也就是奇數(shù))吊说。正是因為這個原因,圖 3.18 中使用 0x101 來表達(dá)地址 0x100优炬。當(dāng) 0x100 處的指令得到執(zhí)行后颁井,就正式開始了程序的執(zhí)行。在此之前初始化 MSP 是必需的蠢护,因為可能第1條指令還沒來得及執(zhí)行雅宾,就發(fā)生了 NMI 或是其它 fault。MSP 初始化好后就已經(jīng)為它們的服務(wù)例程準(zhǔn)備好了堆棧葵硕。

2眉抬、 內(nèi)存分布

圖 1.3 flash 內(nèi)存分配圖.jpg

需要修改工程中內(nèi)存分配的腳本實現(xiàn)以上效果贯吓,這里是使用兩個工程設(shè)計,一個為 bootloader 工程蜀变,一個為 app 工程悄谐。

二、 實戰(zhàn) — boot

1库北、 工具:keil JLINK

使用 S32DS 開發(fā)也可以爬舰,但是 S32DS 使用 jlink 下載程序的時候,芯片容易鎖死寒瓦,而且飛思卡爾的芯片鎖死之后情屹,解鎖都比較麻煩,所以暫時選擇 keil 開發(fā)杂腰。

2垃你、 新建工程

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

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

上圖紅色部分務(wù)必勾選。

圖 2.5 工程目錄結(jié)構(gòu).jpg

紅色框部分即使內(nèi)存分配腳本林说,這是待會兒需要修改的煎殷。工程建立好了之后,還需要進行一些配置腿箩。

圖 2.6 內(nèi)存配置.jpg

在搞 STM32 的時候豪直,有時候修改的就是這里,這里可以修改內(nèi)存分配珠移,但是我們這次使用的是用戶腳本弓乙,不是默認(rèn)內(nèi)存配置,所以這里不需要修改钧惧。當(dāng)然還有生成 hex 文件暇韧、調(diào)試工具的選擇、輸出目錄等配置也需要進行浓瞪,這里就不一一列舉了懈玻,

圖 2.7 用戶腳本選擇.jpg

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

圖 2.8 下載配置.jpg

紅色部分最好不勾選,因為如果直接使用在 keil 下載的話湾盒,這個選項在下載 app 代碼的時候湿右,會全部擦除 flash,這時候 boot 會遭殃罚勾,會導(dǎo)致起不來毅人,配置基本配置好了,接下來就是修改腳本了荧库。

3堰塌、 修改腳本

Boot 的腳本基本不用怎么修改,就是修改一下 Boot 結(jié)束地址分衫,這里開辟給 boot 的大小是 0x4000场刑,相當(dāng)于 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蚪战、 修改代碼

代碼的修改主要是集中在牵现,跳轉(zhuǎn)函數(shù),需要定義一個函數(shù)指針類型邀桑,還要注意 Cortex-m 復(fù)位跳轉(zhuǎn)序列瞎疼。

#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;
}

重點應(yīng)該就是這句話:
jump2app = (bootloader_fun)(uint32_t)(APP_ADDR + 4);
APP 地址加上 4 ,就是因為 CORTEX-M 復(fù)位序列的 PC 指針位置的偏移量就是偏移 4壁畸,(uint32_t)(APP_ADDR + 4) 進行強制類型轉(zhuǎn)換贼急,(bootloader_fun)(uint32_t*)(APP_ADDR+4) 取址,相當(dāng)于取 0x4004 地址的值捏萍,放到 PC 指針太抓,可能需要主義的還有一個就是 C 語言的語法,C 語言里面令杈,函數(shù)名稱就是函數(shù)的入口地址走敌,也就是說函數(shù)名稱其實也是一個指針,所以后面一句:jump2app();就是相當(dāng)于執(zhí)行一個函數(shù)逗噩。這樣就可以跳轉(zhuǎn)了掉丽。

5、 編譯下載

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

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

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

圖 2.11 編譯完成.jpg

6空免、現(xiàn)象

下載之后空另,可以看到小燈閃了 5 下就不閃了,說明執(zhí)行到了后面的跳轉(zhuǎn)程序蹋砚。

三扼菠、 實戰(zhàn) — app

1、 新建工程

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

圖 3.1 app 目錄結(jié)構(gòu).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 腳本的修改稍微多一點墨坚,每個對應(yīng)的偏移地址都需要改秧饮,向量表的地址,text 段的地址等泽篮。

3盗尸、 修改代碼

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

4泼各、 編譯下載

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

5弱贼、 在線仿真

如果 app 的代碼只是下載,那每次調(diào)試都會比較麻煩磷蛹,都得編譯成 hex 文件再下載才能驗證,因為腳本修改了向量表的地址溪烤,直接在線調(diào)試是不行的味咳,這樣就很不方便開發(fā)了,網(wǎng)路上有網(wǎng)友通過修改一個腳本檬嘀,讓 keil 識別到我們已經(jīng)修改過的向量表的地址槽驶,在工程目錄新建 flashoffset.ini 文件,內(nèi)容如下:

圖 3.2 app 在線調(diào)試腳本.jpg

在 keil 配置里面導(dǎo)入這個文件

圖 3.3 導(dǎo)入在線調(diào)試腳本.jpg

這樣就可以就行在線調(diào)試了鸳兽,就和正常開發(fā)一樣方便了掂铐。

注意:

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

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

也算是一種調(diào)試信息手段吧全陨。

問題:

這個 bootloader 整個流程雖然可以走通爆班,但是還有問題,如果 app 工程開啟了中斷辱姨,app 的程序會跑飛柿菩。原因是什么呢?這個就是第一節(jié)說的 cortex-m 復(fù)位序列雨涛。

1枢舶、 boot 中斷未關(guān);
2替久、接收升級文件驅(qū)動未提供凉泄;
3、Flash 驅(qū)動未提供蚯根;
4后众、App 程序重新定位向量表的基地址未修改。

總結(jié)

雖然上述通過 keil 軟件稼锅,以及它的分散腳本實現(xiàn)了簡單的 bootloader 和 app 在線調(diào)試功能吼具,這個只是一個簡易的 bootloader,還有很多功能未添加矩距,也有很多地方還需要完善拗盒,目前這個只是能跑一個簡單的流程,只是幫助理解一下锥债。

參考文獻:

《Cortex-M3 權(quán)威指南》

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

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

微信公眾號
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末登夫,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子允趟,更是在濱河造成了極大的恐慌恼策,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件潮剪,死亡現(xiàn)場離奇詭異涣楷,居然都是意外死亡,警方通過查閱死者的電腦和手機抗碰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門狮斗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人弧蝇,你說我怎么就攤上這事碳褒≌墼遥” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵沙峻,是天一觀的道長睦授。 經(jīng)常有香客問我,道長专酗,這世上最難降的妖魔是什么睹逃? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮祷肯,結(jié)果婚禮上沉填,老公的妹妹穿的比我還像新娘。我一直安慰自己佑笋,他們只是感情好翼闹,可當(dāng)我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蒋纬,像睡著了一般猎荠。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蜀备,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天关摇,我揣著相機與錄音,去河邊找鬼碾阁。 笑死输虱,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的脂凶。 我是一名探鬼主播宪睹,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蚕钦!你這毒婦竟也來了亭病?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤嘶居,失蹤者是張志新(化名)和其女友劉穎罪帖,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體邮屁,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡整袁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了樱报。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡泞当,死狀恐怖迹蛤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤盗飒,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布嚷量,位于F島的核電站,受9級特大地震影響逆趣,放射性物質(zhì)發(fā)生泄漏蝶溶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一宣渗、第九天 我趴在偏房一處隱蔽的房頂上張望抖所。 院中可真熱鬧,春花似錦痕囱、人聲如沸田轧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽傻粘。三九已至,卻和暖如春帮掉,著一層夾襖步出監(jiān)牢的瞬間弦悉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工蟆炊, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留稽莉,地道東北人。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓盅称,卻偏偏與公主長得像肩祥,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子缩膝,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容