在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

本跳轉(zhuǎn)程序靠bug運(yùn)行,請(qǐng)不要優(yōu)化

魚(yú)鷹談單片機(jī) ? 來(lái)源:魚(yú)鷹談單片機(jī) ? 2023-07-11 14:59 ? 次閱讀

絕大多數(shù)產(chǎn)品開(kāi)發(fā),軟件一般都會(huì)設(shè)計(jì)成 boot + app 的形式,這是方便后續(xù)軟件更新,否則更新會(huì)變成一個(gè)很麻煩的事情。

網(wǎng)上隨處可見(jiàn)的跳轉(zhuǎn)程序大概如下:

#define APP_START_ADDR          0x08040000 


voidjump2app()
{
typedefvoid(*func_app_start)(void);
   
__disable_irq();

func_app_start app_start=(func_app_start)(*(__IOuint32_t*)(APP_START_ADDR+4));
  
__set_MSP(*(__IOuint32_t*)(APP_START_ADDR));//設(shè)置棧頂?shù)刂?/span>


app_start();
}

大多數(shù)情況下,該程序跳轉(zhuǎn)正常,但當(dāng)你改變了編譯器優(yōu)化級(jí)別時(shí),可能直接就 hardfault 了。

此時(shí)你會(huì)莫名其妙,為什么???

從魚(yú)鷹18接觸到 boot 知識(shí)以來(lái),都覺(jué)得這樣的跳轉(zhuǎn)程序理所當(dāng)然,并且也沒(méi)出現(xiàn)過(guò)問(wèn)題,直到最近修改了優(yōu)化級(jí)別,發(fā)現(xiàn)程序直接hardfault 了,根本沒(méi)跳轉(zhuǎn)到 app 中,才發(fā)現(xiàn)了這里隱藏的 bug。

調(diào)試發(fā)現(xiàn),app_start 這個(gè)函數(shù)指針變成了異常值,但魚(yú)鷹查看0x08040000 處的內(nèi)存空間值是正常的。那只能是代碼問(wèn)題了。

因此結(jié)合匯編和在線調(diào)試,終于發(fā)現(xiàn),執(zhí)行__set_MSP 這條語(yǔ)句前app_start 的值是正常的,執(zhí)行后,這個(gè)值就異常了。

再結(jié)合 C 語(yǔ)言關(guān)于棧、局部變量的知識(shí),立刻就知道是因?yàn)橹匦略O(shè)置棧頂?shù)刂罚珔R編代碼不變,但是從新棧位置偏移取函數(shù)地址,因此跳轉(zhuǎn)失敗。

如:

15bee072-1f9c-11ee-962d-dac502259ad0.png

新棧的位置,變量的值是未知的,用它進(jìn)行跳轉(zhuǎn),失敗是必然的。

但是為什么大部分情況下程序沒(méi)有問(wèn)題呢?

這是因?yàn)樘D(zhuǎn)程序很簡(jiǎn)單,局部變量少,那么這個(gè)app_start 局部變量編譯器可能就不會(huì)從棧中分配,而直接用一個(gè)寄存器存儲(chǔ)數(shù)據(jù),而寄存器是不受棧頂位置影響的,自然程序能跳轉(zhuǎn)了。

但我們不能讓程序運(yùn)行正常與否由編譯器隨機(jī)決定,因此我們要避免這個(gè) bug,讓程序不管在何種優(yōu)化級(jí)別函數(shù)多復(fù)雜的情況下,依然可以正常運(yùn)行,因此還是有必要進(jìn)行優(yōu)化的。

最簡(jiǎn)單的方法,就是把這個(gè)app_start 局部變量變成全局變量這樣變量就不會(huì)受到棧頂位置影響,自然可以避免了。

如:

#define APP_START_ADDR          0x08040000 


voidjump2app()
{
typedefvoid(*func_app_start)(void);
   
__disable_irq();

static func_app_start app_start=(func_app_start)(*(__IOuint32_t*)(APP_START_ADDR+4));
  
__set_MSP(*(__IOuint32_t*)(APP_START_ADDR));//設(shè)置棧頂?shù)刂?/span>


app_start();
}

如有更好的優(yōu)化方法,歡迎留言討論。




聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5401

    瀏覽量

    122805
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4365

    瀏覽量

    63870
  • 變量
    +關(guān)注

    關(guān)注

    0

    文章

    614

    瀏覽量

    28756

原文標(biāo)題:本跳轉(zhuǎn)程序靠bug運(yùn)行,請(qǐng)不要優(yōu)化

文章出處:【微信號(hào):emOsprey,微信公眾號(hào):魚(yú)鷹談單片機(jī)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    西門(mén)子S7-1200 PLC程序控制指令:跳轉(zhuǎn)與標(biāo)簽指令

    在S7-1200PLC中,程序控制指令主要包含兩部分:一是改變程序執(zhí)行順序的的跳轉(zhuǎn)指令;二是程序運(yùn)行過(guò)程中用于控制的指令;本節(jié)主要分享
    發(fā)表于 03-07 10:25 ?9078次閱讀

    與單片機(jī)Bug戰(zhàn)斗的那些經(jīng)歷

    時(shí)我們可以知道是在哪一個(gè)地方。這點(diǎn)是相當(dāng)?shù)膶?shí)用,對(duì)于無(wú)法仿真的51單片機(jī),要了解程序內(nèi)部運(yùn)行的狀態(tài)和變量現(xiàn)在的值,就顯得很無(wú)語(yǔ),簡(jiǎn)直束手無(wú)策。那么就請(qǐng)加入串口程序的代碼,利用串口將一些
    發(fā)表于 11-05 17:09

    與單片機(jī)Bug戰(zhàn)斗的那些經(jīng)歷

    可以知道是在哪一個(gè)地方。這點(diǎn)是相當(dāng)?shù)膶?shí)用,對(duì)于無(wú)法仿真的51單片機(jī),要了解程序內(nèi)部運(yùn)行的狀態(tài)和變量現(xiàn)在的值,就顯得很無(wú)語(yǔ),簡(jiǎn)直束手無(wú)策。那么就請(qǐng)加入串口程序的代碼,利用串口將一些重要變
    發(fā)表于 12-20 17:15

    IAP程序跳轉(zhuǎn)到APP只能運(yùn)行大約2秒

    );} 問(wèn)題:如果設(shè)置了" __MSR_MSP (AppSpInitVal);//設(shè)置SP.,則跳轉(zhuǎn)過(guò)去大約2秒就又回到IAP程序了;而不操作這個(gè)SP,則可以正常運(yùn)行,實(shí)際上就是在IAP與APP同時(shí)
    發(fā)表于 03-14 08:05

    關(guān)于程序跳轉(zhuǎn)的問(wèn)題如何解決

    你好,我是一個(gè)初學(xué)者,有個(gè)問(wèn)題想問(wèn)一下就是關(guān)于DSP6747的在FLASH的0地址處加載一個(gè)AIS格式的bin文件,在這個(gè)程序讀到RAM中運(yùn)行的時(shí)候,我想讓DSP跳轉(zhuǎn)到另一個(gè)程序入口處
    發(fā)表于 05-22 14:49

    為了心愛(ài)的本本,請(qǐng)不要吸煙

    為了心愛(ài)的本本,請(qǐng)不要吸煙  問(wèn)題:鍵盤(pán)里有很多煙灰,請(qǐng)問(wèn)如何拆下,該如何清洗,工具哪有買(mǎi),最好詳細(xì)點(diǎn),謝謝。我用的是COMPAQ的X1000   回答:
    發(fā)表于 01-25 13:04 ?403次閱讀

    ---GD32F450---bootloader跳轉(zhuǎn)到app無(wú)法運(yùn)行

    問(wèn)題描述:bootloader和app程序都能單獨(dú)正常運(yùn)行,但是在使用bootloader進(jìn)行跳轉(zhuǎn)時(shí),程序跑飛。原因:bootloader在運(yùn)行
    發(fā)表于 12-02 14:36 ?16次下載
    ---GD32F450---bootloader<b class='flag-5'>跳轉(zhuǎn)</b>到app無(wú)法<b class='flag-5'>運(yùn)行</b>

    KEIL上跳轉(zhuǎn)程序的起始地址(未完成)

    //有任何想法,請(qǐng)務(wù)必評(píng)論,共同進(jìn)步一、keil設(shè)置二、程序設(shè)置內(nèi)存上面做跳轉(zhuǎn),定義一個(gè)在此地址之后的量(數(shù)組函數(shù)都可以)三、程序起始運(yùn)行
    發(fā)表于 12-03 09:06 ?12次下載
    KEIL上<b class='flag-5'>跳轉(zhuǎn)</b><b class='flag-5'>程序</b>的起始地址(未完成)

    STM32 IAP - Boot跳轉(zhuǎn)到APP

    簡(jiǎn)單IAP設(shè)計(jì)思路:?jiǎn)纹瑱C(jī)上電首先運(yùn)行BootLoader程序; Bootloader如果檢測(cè)到需要更新APP,則首先進(jìn)行更新,更新完成后跳轉(zhuǎn)到APP并運(yùn)行; Bootloader如果
    發(fā)表于 12-03 14:21 ?12次下載
    STM32 IAP - Boot<b class='flag-5'>跳轉(zhuǎn)</b>到APP

    【單片機(jī)程序和RAM】程序在RAM中調(diào)試的運(yùn)行方式&程序固化后運(yùn)行方式

    程序固化后運(yùn)行方式: 程序開(kāi)始運(yùn)行后需要將RW 和ZI段搬移到RAM中去,程序下載進(jìn)Flash中以后,上電后是怎樣將RW ZI斷搬移到RA
    發(fā)表于 12-03 15:21 ?4次下載
    【單片機(jī)<b class='flag-5'>程序</b>和RAM】<b class='flag-5'>程序</b>在RAM中調(diào)試的<b class='flag-5'>運(yùn)行</b>方式&<b class='flag-5'>程序</b>固化后<b class='flag-5'>運(yùn)行</b>方式

    BL(B)和LDR跳轉(zhuǎn)范圍是如何規(guī)定的

    ??LDR和BL在啟動(dòng)程序中,都是可以負(fù)責(zé)pc跳轉(zhuǎn)的指令。 ??BL是地址無(wú)關(guān)指令,即和當(dāng)前的運(yùn)行地址無(wú)關(guān)。鏈接器腳本中標(biāo)明了一個(gè)運(yùn)行地址,但是arm中的代碼實(shí)際是從地址0開(kāi)始
    的頭像 發(fā)表于 07-03 10:29 ?2687次閱讀

    PLC跳轉(zhuǎn)/標(biāo)號(hào)指令的工作原理及應(yīng)用舉例

    跳轉(zhuǎn)/標(biāo)號(hào)執(zhí)行是用來(lái)跳過(guò)部分程序使其不執(zhí)行必須用在同一程序塊內(nèi)部實(shí)現(xiàn)跳轉(zhuǎn)跳轉(zhuǎn)/標(biāo)號(hào)指令有兩條,分別為
    的頭像 發(fā)表于 10-08 09:59 ?6502次閱讀

    SCL用GOTO語(yǔ)句執(zhí)行程序跳轉(zhuǎn)

    用GOTO語(yǔ)句能夠執(zhí)行程序跳轉(zhuǎn)。此引起立即跳轉(zhuǎn)到指定標(biāo)號(hào),為此而到同塊中不同的語(yǔ)句。
    的頭像 發(fā)表于 02-01 09:22 ?2956次閱讀

    AN040 IAP程序跳轉(zhuǎn)說(shuō)明

    AN040 IAP程序跳轉(zhuǎn)說(shuō)明
    發(fā)表于 02-23 19:11 ?0次下載
    AN040 IAP<b class='flag-5'>程序</b><b class='flag-5'>跳轉(zhuǎn)</b>說(shuō)明

    PLC的條件跳轉(zhuǎn)、子程序調(diào)用等

    當(dāng)我們按下X000后,程序跳轉(zhuǎn)指令開(kāi)始運(yùn)行程序跳轉(zhuǎn)的位置為程序指針?biāo)诘奈恢茫簿褪菢?biāo)號(hào)10
    的頭像 發(fā)表于 06-07 14:46 ?1512次閱讀
    PLC的條件<b class='flag-5'>跳轉(zhuǎn)</b>、子<b class='flag-5'>程序</b>調(diào)用等
    主站蜘蛛池模板: 久久天天躁狠狠躁狠狠躁 | 天堂精品在线 | 韩国xxxxxxxx69 | 久久精品伊人波多野结 | 亚洲人成电影在线观看网 | 国产欧美日韩视频免费61794 | 日韩色天使综合色视频 | 中文字幕日本一区波多野不卡 | 亚洲在线a | 色噜噜亚洲精品中文字幕 | 青楼社区51在线视频视频 | 午夜看片在线 | 欧美色天使 | 四虎最新影院 | 曰本在线| 丁香花五月婷婷开心 | 夜夜爽一区二区三区精品 | 人人插97| 久久草在线看 | 成人在线观看网站 | 又粗又硬又爽又黄毛片 | 8050午夜| 日本精品一卡二卡≡卡四卡 | 一级片aaaaaa| 97人人草| 欧美一卡二卡3卡4卡无卡六卡七卡科普 | 欧美18同性gay视频 | 2345成人高清毛片 | 久久综合五月开心婷婷深深爱 | 丁香午夜婷婷 | 男人操女人免费网站 | 亚洲男人的天堂在线观看 | 色婷婷一区二区三区四区成人 | 日本黄色影片在线观看 | 欧美freesex10一|3 | 免费人成年激情视频在线观看 | 美日韩一区二区 | 黄色免费网站在线观看 | 久久久久青草 | 视频在线免费看 | 欧美性猛交ⅹxxx乱大交免费 |