新聞中心

EEPW首頁 > 牛人業(yè)話 > 任務(wù)堆棧不是系統(tǒng)堆棧 搞混了就會完蛋

任務(wù)堆棧不是系統(tǒng)堆棧 搞混了就會完蛋

作者:三昧道人 時間:2019-04-24 來源:電子產(chǎn)品世界 收藏

但是,代碼可不像大妹子那么好看。一眼望去,好幾個.c文件中密密麻麻的字符,簡直是老鼠拉烏龜,沒有下手的地方呀!

本文引用地址:http://butianyuan.cn/article/201904/399825.htm

1556075978925524.jpg

有些人總是有著鷹一般銳利的眼睛,比如他們會發(fā)現(xiàn),新版倚天屠龍記中張無忌和趙敏居然足足吻了25秒鐘,而且張無忌一邊吻還一邊貪婪地咽口水。好吧,我承認(rèn),我也發(fā)現(xiàn)了張無忌咽口水的猥瑣模樣,但是對于枯燥的代碼,我實在沒有這般銳利的眼睛,只好一行代碼一行代碼地硬著頭皮看。

I2C部分自然是不用看的。只看上層驅(qū)動就可以了,很快,我把目光放在了函數(shù)atsha204_mac身上,這正是我最終調(diào)用的那個函數(shù)。

這個函數(shù)實在也太顯眼了,因為這個函數(shù)不僅調(diào)用了好幾個函數(shù),里面還有三個大數(shù)組形式的局部變量:

uint8_t transmit_buffer[SHA204_CMD_SIZE_MAX];

uint8_t response_buffer[SHA204_RSP_SIZE_MAX];

uint8_t soft_digest[32];

單單是這三個局部變量就足足用掉了151個字節(jié)!再加上其他局部變量,快到200字節(jié)了,要知道,在調(diào)用這個函數(shù)時,它里面的所有局部變量都是要放到堆棧上的,這樣的話,才可能會在中斷發(fā)生時保存現(xiàn)場,以在中斷服務(wù)程序完成后再度恢復(fù)現(xiàn)場。

現(xiàn)場當(dāng)然不止包括局部變量,還要再加上調(diào)用的子函數(shù),這樣算下來,atsha204_mac這個函數(shù)運行時消耗掉的堆棧還不得快到300字節(jié)了?齊工調(diào)用這個函數(shù)的主程序是裸機形式,消耗的是,的默認(rèn)配置是512字節(jié),可是我是在帶有操作系統(tǒng)的任務(wù)里面調(diào)用這個函數(shù)的,消耗的是,我對的默認(rèn)配置是256字節(jié)??!

問題一目了然了,我輕輕地?fù)]了揮手,把齊工提溜了過來,

or

和齊工說完問題的原因之后,我心情大好,問起了齊工:“你知道不知道你的主程序設(shè)置的堆??臻g有多大?”根據(jù)我對齊工的了解,一心撲在炒股上面的他,應(yīng)該不知道在哪里設(shè)置堆棧空間,更遑論堆棧空間有多大了。

果然,他瞪著無辜的小眼神掃了我一眼,嘴角彎出一抹笑意,等著我的科普。

1556076019727872.jpg

我滿意地看著他的表情,鼓起腮幫子說了起來,“在prm文件里面,你看一下這個設(shè)置STACKSIZE 0x200,512個字節(jié)。你驗證加密認(rèn)證模塊時,用的就是這個堆棧,你可以看一下MCU初始化時對SP寄存器的設(shè)置和堆棧區(qū)域的初始化,SP寄存器設(shè)置堆棧棧頂,初始化程序里,從棧頂開始,根據(jù)STACKSIZE把用作堆棧的那部分RAM初始化為0。”

“哦,那按你的意思,如果Atmel的那個函數(shù)在裸機里面運行,消耗的就是系統(tǒng)堆棧,但是這個函數(shù)一旦在你的任務(wù)里面運行,消耗的就是任務(wù)堆棧了,為什么呢?”齊工精靈剔透,一下子就提問到了問題的本質(zhì)。

‘孺子可教也!’我一邊在心里嘀咕著,一邊組織著語言,回答他的問題。

“你來看一下在我用的這個ucos操作系統(tǒng)里,任務(wù)切換時到底執(zhí)行了什么就清楚了?!蔽乙贿厔澙髽?biāo)轉(zhuǎn)輪,一邊在屏幕上找著對SP指針進行操作的地方。嗯?那雙發(fā)現(xiàn)張無忌咽口水的鷹一般銳利的眼睛哪里去了?找了半天后,我突然意識到,應(yīng)該翻到匯編代碼里面去找,于是我翻到os_cpu_a.s文件里面,終于找到了下面這條語句:

lds 0,x ;  3~, Load the SP of the next task

這是任務(wù)切換時將SP寄存器設(shè)置為待切換任務(wù)結(jié)構(gòu)體中的堆棧指針內(nèi)容的地方,它和裸機形式里只初始化一次SP的方式不一樣,每次切換到新的任務(wù)時都要設(shè)置一次,所以如果任務(wù)堆棧設(shè)計地過小,就無法運行atsha204_mac這個消耗大量堆棧的函數(shù)。

“那怎么解決呢?”齊工怯怯地問,顯然,他不想改這個函數(shù)的實現(xiàn)方式。

從臉盲癥中恢復(fù)的我定定地看了一下齊工,想到他上次給我推薦了一只好股票的“恩惠”,大手一揮,朗然道:“你不用管了,我可以在創(chuàng)建任務(wù)之前調(diào)用這個函數(shù),這時它用的還是系統(tǒng)堆棧。也可以在任務(wù)中調(diào)用它,把調(diào)用位置所在的任務(wù)堆棧加大也可以?!?/p>

看到他漸漸輕松了的笑容,我又加上了一句科普:任務(wù)堆棧不是系統(tǒng)堆棧,搞混了就會完蛋??!


上一頁 1 2 下一頁

評論


技術(shù)專區(qū)

關(guān)閉