<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

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

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

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

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

          本文引用地址:http://www.ex-cimer.com/article/201904/399825.htm

          1556075978925524.jpg

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

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

          這個函數(shù)實在也太顯眼了,因為這個函數(shù)不僅調用了好幾個函數(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é)了,要知道,在調用這個函數(shù)時,它里面的所有局部變量都是要放到堆棧上的,這樣的話,才可能會在中斷發(fā)生時保存現(xiàn)場,以在中斷服務程序完成后再度恢復現(xiàn)場。

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

          問題一目了然了,我輕輕地揮了揮手,把齊工提溜了過來,

          or

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

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

          1556076019727872.jpg

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

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

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

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

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

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

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

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

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


          上一頁 1 2 下一頁

          評論


          技術專區(qū)

          關閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();