2016-08-19 144 views
1

在Keil RTX RTOS配置文件中,用戶可以配置默認的用戶線程堆棧大小。 通常,堆棧包含自動/本地變量。 「ZI數據」部分保存未初始化的全局變量。Keil RTX RTOS線程堆棧大小

因此,如果我更改RTX配置文件中的用戶線程堆棧大小,堆棧大小將增加,並且「ZI數據」節大小不會增加。

我測試一下,測試結果顯示如果我增加用戶線程堆棧大小。 「ZI數據」部分的大小將以相同大小同步增加。

在我的測試程序中,有6個線程,每個線程有600個字節的堆棧。我使用Keil來構建程序,它告訴我:

 
     Code (inc. data) RO Data RW Data ZI Data  Debug 

    36810  4052  1226  380  6484  518461 Grand Totals 
    36810  4052  1226  132  6484  518461 ELF Image Totals (compressed) 
    36810  4052  1226  132   0   0 ROM Totals 

============================================================================== 

    Total RO Size (Code + RO Data)    38036 ( 37.14kB) 
    Total RW Size (RW Data + ZI Data)    6864 ( 6.70kB) 
    Total ROM Size (Code + RO Data + RW Data)  38168 ( 37.27kB) 

但是,如果我將每個線程堆棧大小更改爲800字節。 Keil顯示如下:

 
============================================================================== 


     Code (inc. data) RO Data RW Data ZI Data  Debug 

    36810  4052  1226  380  7684  518461 Grand Totals 
    36810  4052  1226  132  7684  518461 ELF Image Totals (compressed) 
    36810  4052  1226  132   0   0 ROM Totals 

============================================================================== 

    Total RO Size (Code + RO Data)    38036 ( 37.14kB) 
    Total RW Size (RW Data + ZI Data)    8064 ( 7.88kB) 
    Total ROM Size (Code + RO Data + RW Data)  38168 ( 37.27kB) 

============================================================================== 

「ZI數據」部分的大小從6484增加到7684字節。 7684 - 6484 = 1200 = 6 * 200和800 - 600 = 200。 所以我看到線程堆棧放在「ZI數據」部分。

我的問題是: 這是否意味着汽車/在線程局部變量將被放置在「ZI數據」部分,當線程棧放在「ZI數據」一節中RAM? 如果這是真的,那意味着根本沒有堆疊部分。根本只有「RO/RW/ZI數據」和堆段。

這篇文章給了我不同的答案。我現在對此有點困惑。 https://developer.mbed.org/handbook/RTOS-Memory-Model

+0

_「堆棧保存自動/本地變量」_ - 從正在運行的線程的角度來看,當然是「該」堆棧。儘管如此,我沒有理由認爲這些堆棧不能從操作系統的角度來看是靜態分配的變量。你只是在這裏提出一個觀察;具體的問題是什麼? – Notlikethat

回答

1

鏈接器確定存在哪些內存段。鏈接器默認創建一些內存段。在您的情況下,其中三個默認部分顯然被命名爲「RO數據」,「RW數據」和「ZI數據」。如果您沒有明確指定變量應該位於哪個部分,則鏈接器將根據變量是否聲明爲const,初始化或未初始化將它分配給這些默認部分之一。

鏈接器不會自動意識到您正在使用RTOS。並且它沒有關於你打算用作線程堆棧的變量的專門知識。所以鏈接器不會爲你的線程堆棧自動創建獨立的內存段。相反,鏈接器會像處理任何其他變量一樣處理堆棧變量,並將它們包含在其中一個缺省內存段中。在你的情況下,線程堆棧顯然被鏈接器放入ZI Data部分。

如果您希望鏈接器爲您的線程堆棧創建特殊的獨立內存段,那麼您必須通過鏈接器命令文件明確告訴鏈接器。然後您還必須指定堆棧變量應該位於您的自定義部分中。有關如何執行此操作的詳細信息,請參閱鏈接器手冊。

+0

謝謝。通常有一些缺省部分:「RO數據」,「RW數據」和「ZI數據」,「堆棧」,「堆」。鏈接器確定閃存和RAM內存佈局。如果將線程堆棧放入「ZI Data」中,是否表示線程中調用的所有函數的自動變量將位於「ZI Data」部分?那麼在「堆棧」部分有什麼? –

+0

主程序有一個堆棧。這是當調用main()時以及在RTOS啓動之前正在使用的堆棧。您的鏈接器命令文件可以爲主堆棧顯式指定一個內存部分。每個線程都有獨立於主堆棧的堆棧。您的鏈接器正在ZI Data部分找到這些線程堆棧。一旦RTOS正在運行,將在線程堆棧上創建線程局部變量。是的,線程局部變量將位於ZI Data中,因爲線程堆棧位於ZI Data中。主棧是RTOS運行之前本地變量的位置。 – kkrambo

+0

RTOS運行後,「主函數」永遠不會再被調用。所以一旦RTOS破壞,主堆棧就不會被使用。爲了節省內存,這意味着主堆棧和線程堆棧的內存空間將被重疊。 –

0

任務堆棧必須來自某個地方 - 默認情況下,RTX會靜態分配並且大小固定。

os_tsk_create_user()允許調用者提供可以以任何方式分配的堆棧(靜態地或從堆中分配;從調用者堆棧分配是可能的,但是不尋常的,可能毫無意義且當然是危險的),只要它具有8字節對齊。我發現RTX的自動堆棧分配幾乎沒有用,除了最瑣碎的應用程序之外幾乎都不適用。