<var id="fnfpo"><source id="fnfpo"></source></var>
<rp id="fnfpo"></rp>

<em id="fnfpo"><object id="fnfpo"><input id="fnfpo"></input></object></em>
<em id="fnfpo"><acronym id="fnfpo"></acronym></em>
  • <th id="fnfpo"><track id="fnfpo"></track></th>
  • <progress id="fnfpo"><track id="fnfpo"></track></progress>
  • <tbody id="fnfpo"><pre id="fnfpo"></pre></tbody>

  • 【轉載】改進uC/OS II,減少內存使用量

    發布時間:2009-8-29 23:57    發布者:原野之狼
    關鍵詞: 改進 , 內存 , 使用量

    在以uC/OS為操作系統的項目中,系統可能要處理各種不同的中斷請求,如果某個中斷處理程序需要調用uC/OS的各種Post函數向任務發出消息,那么uC/OS建議中斷服務程序的寫法是:
    1、保存全部CPU寄存器
    2、調用OSIntEnter或OSIntNesting直接加1
    3、執行用戶代碼做中斷服務
    4、調用OSIntExit
    5、恢復所有CPU寄存器
    6、執行中斷返回指令
    暫且稱為“標準中斷”方式,這種方式實際上是將這個中斷處理加入了任務調度系統,也就是說這個中斷可以引起任務的切換。

    如果在中斷處理中沒有調用各種Post函數的話,則可以用一般的、象原來沒有操作系統時的寫法:
    1、保存中斷處理程序需要用到的CPU寄存器
    2、執行中斷處理
    3、恢復保存了的CPU寄存器
    4、執行中斷返回指令
    暫且稱為“快中斷”方式,按照這種方法定義的中斷永遠不會引起任務切換。

    在uC/OS系統中,每個任務都要定義獨立的?臻g,一個?臻g的使用包括5個部分:
    1、任務包括的各個函數的調用返回地址
    2、任務包括的各個函數中可能在棧上分配的局部變量
    3、發生了“標準中斷”方式定義的中斷或任務被掛起時,所要保存的任務上下文
    4、發生了“快中斷”方式定義的中斷時,中斷處理程序所需要的?臻g
    5、中斷嵌套時,所要保存的中斷嵌套上下文

    在這些使用的部分中,1,2,3,4的內存占用量是比較容易估算的,最精確和保險的確定方法是:查看由C生成的asm文件,并計算各個函數的棧使用量。但是第5部分的?臻g使用量是隨中斷嵌套的深度而不斷增加的,是不確定的,一般的方法只能定義一個充分大的?臻g,使之不會溢出。

    為每個任務都定義一個充分大的?臻g,這在某些內存稀缺的小項目中是非常痛苦的,有時不得不增擴內存,這就會使成本增加。

    我深入研究了uC/OS后,認為,可以將所有任務?臻g使用的第5部分合并,這樣將會大大的降低整個系統對內存的需求。

    uC/OS的任務調度是靠OS_Sched和OSIntExit來完成的,這兩個函數中都要先判斷一個叫 OSIntNesting的系統變量,如果OSIntNesting不為0,則不進行任務切換。也就是說:在OSIntNesting為1(當前只有一個中斷在處理中,并且沒有嵌套的中斷)時起,如果發生了嵌套的中斷(不管嵌套的層數有深),那么在所有嵌套的中斷一層一層地都返回直到 OSIntNesting再次為1時止,任務棧是不會切換的(棧指針都在一個任務的?臻g中變化)。

    據此,我們可以這樣改動:設置一個緩沖區OSInterruptStk,作為嵌套中斷的?臻g,由所有任務共享,中斷服務程序改為:
    1、保存全部CPU寄存器
    2、調用OSIntEnter或OSIntNesting直接加1
    增加:2.1、判斷OSIntNesting是否等于1,如果不是則轉到3
    增加:2.2、將棧指針SP保存到OSTCBCur->OSTCBStkPtr
    增加:2.3、將SP指向OSInterruptStk的棧頂(注意棧增長的方向)。
    3、執行用戶代碼做中斷服務
    4、調用OSIntExit
    增加:4.1、判斷OSIntNesting是否等于0,如果不是則轉到5
    增加:4.2、從OSTCBCur->OSTCBStkPtr中恢復棧指針SP
    5、恢復所有CPU寄存器
    6、執行中斷返回指令

    并且要修改OSIntCtxSw函數,原始的OSIntCtxSw函數的寫法是:
    1、調整棧指針來去掉在調用:OSIntExit,OSIntCtxSw過程中入棧的多余內容
    2、將當前任務棧指針保存到OSTCBCur中(OSTCBCur->OSTCBStkPtr = __SP__)
    3、如果需要則調用OSTaskSwHook
    4、OSTCBCur = OSTCBHighRdy
    5、OSPrio = OSPrioHighRdy
    6、從OSTCBCur中恢復棧指針(__SP__ = OSTCBCur->OSTCBStkPtr)
    7、恢復保存了的CPU寄存器
    8、執行中斷返回指令

    新的寫法只需將原寫法中的1,2去掉即可,因為1,2步只是保存舊任務的棧指針,而新的寫法中,這些步被移到了“中斷服務程序”中的2.2。

    以上的修改已在我的項目中驗證通過了

    本文地址:http://www.portaltwn.com/thread-3217-1-1.html     【打印本頁】

    本站部分文章為轉載或網友發布,目的在于傳遞和分享信息,并不代表本網贊同其觀點和對其真實性負責;文章版權歸原作者及原出處所有,如涉及作品內容、版權和其它問題,我們將根據著作權人的要求,第一時間更正或刪除。
    geyingzhen 發表于 2009-10-4 14:05:50
    wsjc1999 發表于 2009-10-17 22:35:58
    謝謝。
    jcwangzi 發表于 2010-10-2 19:40:03
    頂,謝謝。
    您需要登錄后才可以發表評論 登錄 | 立即注冊

    廠商推薦

    • Microchip視頻專區
    • Dev Tool Bits——使用MPLAB® Discover瀏覽資源
    • Dev Tool Bits——使用條件軟件斷點宏來節省時間和空間
    • Dev Tool Bits——使用DVRT協議查看項目中的數據
    • Dev Tool Bits——使用MPLAB® Data Visualizer進行功率監視
    • 貿澤電子(Mouser)專區

    相關視頻

    關于我們  -  服務條款  -  使用指南  -  站點地圖  -  友情鏈接  -  聯系我們
    電子工程網 © 版權所有   京ICP備16069177號 | 京公網安備11010502021702
    快速回復 返回頂部 返回列表
    精品一区二区三区自拍图片区_国产成人亚洲精品_亚洲Va欧美va国产综合888_久久亚洲国产精品五月天婷