2011-06-16 40 views
9

當我給Keil編譯器提供「--callgraph」選項, 它靜態地爲我計算確切的「最大堆棧使用情況」。唉,今天它給了我一個「最大堆棧使用率= 284字節+未知(沒有堆棧大小的函數...)」消息,以及「沒有堆棧信息的函數」列表。如何確定嵌入式系統中的最大堆棧使用情況?

尼格爾瓊斯說,遞歸是在嵌入式系統 ("Computing your stack size" 2009年)一個非常糟糕的主意, 所以我一直注意不要使任何相互遞歸函數的代碼。另外,我確定我的中斷處理程序都不會重新啓用中斷,直到它們的最終中斷返回指令爲止,所以我不必擔心重新進入的中斷處理程序。

沒有遞歸或重入中斷處理程序,它應該能夠靜態確定最大堆棧使用情況。 (所以大多數的答案不適用於 How to determine maximum stack usage? )。 我的理解是,處理「--callgraph」選項 的軟件首先查找每個中斷處理程序未被高優先級中斷中斷時的最大堆棧深度,以及main()函數的最大堆棧深度它不會中斷。 然後它們將它們全部加起來找到最大堆棧深度的總數(最壞情況)。 當main()後臺任務在被最低優先級中斷中斷時處於其最大深度並且該中斷在被下一個最低優先級中斷中斷時處於其最大深度時發生,以此類推。

我懷疑處理--callgraph的軟件對「無堆棧信息的函數」列表中的小彙編語言函數感到困惑。 --callgraph documentation似乎暗示我需要手動計算(或做出保守估計)他們使用了多少堆棧 - 它們非常短,所以應該很簡單 - 然後「在彙編語言代碼中使用幀指令描述你的代碼如何使用堆棧。「 其中之一是在跳轉到main()之前將堆棧重置爲零的初始啓動代碼 - 實際上,這會消耗零堆棧。 另一個是「故障」中斷處理程序,它在無限循環中鎖定,直到我重新啓動電源 - 假設這消耗零堆棧是安全的。

我正在使用Keil uVision V4.20.03.0編譯LM3S1968 ARM Cortex-M3的代碼。

那麼我該如何使用「frame directives」來告訴處理「--callgraph」的軟件這些函數使用了多少堆棧呢? 還是有一些更好的方法來確定最大堆棧使用情況?

(幾乎有針對性地gcc編譯器同樣的問題見How to determine maximum stack usage in embedded system with gcc?。)

+2

也許你可以編譯裝配模塊的虛擬C等效物(從堆棧使用的角度來看)並運用你的分析。 – 2011-06-16 22:14:55

+0

我添加了'keil'標籤,因爲這是一個特定於編譯器的問題。希望這會吸引更多專業人士關注這個問題。 – bta 2011-06-16 22:53:52

+0

我不知道你是否在問如何讓GCC做類似的分析,或者如何擺脫Keil的「+未知」的消息(或者你正在尋找兩者,在這種情況下應該有兩個單獨的問題)。由於您已經確定「+未知」來自使用零堆棧的函數,因此您似乎基本上可以忽略它。 – 2011-06-17 04:33:58

回答

3

使用--info =堆在連接選項。然後,映射文件將包含所有具有外部鏈接功能的堆棧使用情況。

在一個單一的任務環境中,main()的堆棧使用會給你總的需求。如果您正在使用諸如RTX之類的RTOS,其中每個任務都有自己的堆棧,那麼您需要查看所有任務入口點的堆棧使用情況,然後爲任務上下文添加更多(RTX情況下爲64個字節)存儲。

這適用於Keil和更普遍的描述猶他州大學的here

3

約翰·雷吉漢弗具有http://www.embedded.com/design/prototyping-and-development/4025013/Say-no-to-stack-overflow測量嵌入式系統堆棧使用商量好了其他的技術,但要注意的是,連接到FTP。 embedded.com是陳舊的,並且「沒有中斷禁用」的一個事件應該有否定的第一個或最後一個單詞。在商業世界中,Coverity有一個可配置的堆棧溢出檢查器,並且某些版本的CodeWarrior有一個半記錄的warn_stack_usage編譯指示。 (在我的編譯器文檔版本中沒有提到它,但是在MetroWerks的「Targeting Palm OS」文檔中)。

+0

偉大的鏈接,我希望爲我正在做的一些飛思卡爾HCS08工作使用這些技術(2KB RAM,因此每個字節都很重要,您不想在未使用的堆棧上浪費時間)。小世界:早在90年代,您爲牛頓創建了Kagi註冊應用程序,並創建了order.kagi.com網站。 – tomlogic 2011-06-23 16:48:54

相關問題