1 嵌入å¼ç³»çµ±ä¸å°å…§å˜åˆ†é…çš„è¦æ±‚
①快速性。
嵌入å¼ç³»çµ±ä¸å°å¯¦æ™‚性的ä¿è‰ï¼Œè¦æ±‚å…§å˜åˆ†é…éŽç¨‹è¦ç›¡å¯èƒ½åœ°å¿«ã€‚å› æ¤åœ¨åµŒå…¥å¼ç³»çµ±ä¸ï¼Œä¸å¯èƒ½é‡‡ç”¨é€šç”¨æ“作系統ä¸å¾©é›œè€Œå®Œå–„的內å˜åˆ†é…ç–略,一般都采用簡單ã€å¿«é€Ÿçš„å…§å˜åˆ†é…方案。當然,å°å¯¦æ€§è¦æ±‚的程åºä¸åŒï¼Œåˆ†é…方案也有所ä¸åŒã€‚例如,VxWorks采用簡單的最先匹é…如立å³èšåˆæ–¹æ³•ï¼›VRTXä¸é‡‡ç”¨å¤šå€‹å›ºå®šå°ºå¯¸çš„binning方案。
â‘¡å¯é 性。
也就是內å˜åˆ†é…çš„è«‹æ±‚å¿…é ˆå¾—åˆ°æ»¿è¶³ï¼Œå¦‚æžœåˆ†é…失敗å¯èƒ½æœƒå¸¶ä¾†ç½é›£æ€§çš„åŽæžœã€‚嵌入å¼ç³»çµ±æ‡‰ç”¨çš„環境åƒè®Šè¬åŒ–ï¼Œå…¶ä¸æœ‰ä¸€äº›æ˜¯å°å¯é æ€§è¦æ±‚極高的。比如,汽車的自動駕駛系統ä¸ï¼Œç³»çµ±æª¢æ¸¬åˆ°å³å°‡æ’žè»Šï¼Œå¦‚æžœå› ç‚ºå…§å˜åˆ†é…失敗而ä¸èƒ½ç›¸æ‡‰çš„æ“ä½œï¼Œå°±æœƒç™¼ç”Ÿè»Šæ¯€äººäº¡çš„äº‹æ•…ï¼Œé€™æ˜¯ä¸èƒ½å®¹å¿çš„。
③高效性。
å…§å˜åˆ†é…è¦ç›¡å¯èƒ½åœ°å°‘浪費。ä¸å¯èƒ½ç‚ºäº†ä¿è‰æ»¿è¶³æ‰€æœ‰çš„å…§å˜åˆ†é…請求而將內å˜é…置得無é™å¤§ã€‚一方é¢ï¼ŒåµŒå…¥å¼ç³»çµ±å°æˆæœ¬çš„è¦æ±‚使得內å˜åœ¨å…¶ä¸åªæ˜¯ä¸€ç¨®å¾ˆæœ‰é™çš„資æºï¼›å¦ä¸€æ–¹é¢ï¼Œå³ä½¿ä¸è€ƒæ…®æˆæœ¬çš„å› ç´ ï¼Œç³»çµ±æœ‰é™çš„空間和有é™çš„æ¿é¢ç©æ±ºå®šäº†å¯é…置的內å˜å®¹é‡æ˜¯å¾ˆé™çš„。
2 éœæ…‹åˆ†é…與動態分é…
ç©¶ç«Ÿæ‡‰ç”¨ä½¿ç”¨éœæ…‹åˆ†é…還是動態分é…,一直是嵌入å¼ç³»çµ±è¨è¨ˆä¸ä¸€å€‹çˆè«–ä¸ä¼‘的。當然,最åˆé©çš„ç”æ¡ˆæ˜¯å°äºŽä¸åŒçš„系統采用ä¸åŒçš„æ–¹æ¡ˆã€‚如果是系統å°äºŽå¯¦æ™‚性和å¯é æ€§çš„è¦æ±‚極高(硬實時系統),ä¸èƒ½å®¹å¿ä¸€é»žå»¶æ™‚或者一次分é…失敗,當然需è¦é‡‡ç”¨éœæ…‹åˆ†é…方案,也就是在程åºç·¨è¯æ™‚所需è¦çš„å…§å˜éƒ½å·²ç¶“分é…好了。
ä¾‹å¦‚ï¼Œç«æ˜ŸæŽ¢æ¸¬å™¨ä¸Šé¢çš„嵌入å¼ç³»çµ±å°±å¿…é ˆé‡‡ç”¨éœæ…‹åˆ†é…的方案。å¦å¤–,WindRiverå…¬å¸çš„一款專門用于汽車電å和工æ¥è‡ªå‹•åŒ–é ˜åŸŸçš„å¯¦æ™‚æ“作系統OSEKWorksä¸å°±ä¸æ”¯æŒå…§å˜çš„動態分é…ã€‚åœ¨é€™æ¨£çš„æ‡‰ç”¨å ´åˆï¼Œæˆæœ¬ä¸æ”¯æŒå…§å˜çš„動態分é…ã€‚åœ¨é€™æ¨£çš„æ‡‰ç”¨å ´åˆï¼Œæˆæœ¬ä¸æ˜¯å„ªå…ˆè€ƒæ…®çš„å°è±¡ï¼Œå¯¦æ™‚性和å¯é æ€§æ‰æ˜¯å¿…é ˆä¿è‰çš„。
ç•¶ç„¶ï¼Œé‡‡ç”¨éœæ…‹åˆ†é…一個ä¸å¯é¿å…çš„ç¸½æ˜¯å°±æ˜¯ç³»çµ±å¤±åŽ»äº†éˆæ´»æ€§ï¼Œå¿…é ˆåœ¨è¨è¨ˆéšŽæ®µå°±é å…ˆçŸ¥é“æ‰€éœ€è¦çš„å…§å˜å¹¶å°ä¹‹ä½œå‡ºåˆ†é…ï¼›å¿…é ˆåœ¨è¨è¨ˆéšŽæ®µå°±é 先考慮到所有å¯èƒ½çš„æƒ…æ³ï¼Œå› ç‚ºä¸€æ—¦å‡ºç¾æ²’有考慮到的情æ³ï¼Œç³»çµ±å°±ç„¡æ³•處ç†ã€‚é€™æ¨£çš„åˆ†é…æ–¹æ¡ˆå¿…é ˆå°Žè‡´å¾ˆå¤§çš„æµªè²»ï¼Œå› ç‚ºå…§å˜åˆ†é…å¿…é ˆæŒ‰ç…§æœ€å£žæƒ…æ³é€²è¡Œæœ€å¤§çš„é…置,而實際上在é‹è¡Œä¸å¯èƒ½ä½¿ç”¨çš„åªæ˜¯å…¶ä¸çš„一å°éƒ¨åˆ†ï¼›è€Œä¸”在硬件平臺ä¸è®Šçš„æƒ…æ³ä¸‹ï¼Œä¸å¯èƒ½éˆæ´»åœ°ç‚ºç³»çµ±æ·»åŠ åŠŸèƒ½ï¼Œå¾žè€Œä½¿å¾—ç³»çµ±çš„å‡ç´šè®Šå¾—困難。
大多數的系統是硬實時系統和軟實時系統的綜åˆã€‚也就是說,系統ä¸çš„ä¸€éƒ¨åˆ†ä»»å‹™æœ‰åš´æ ¼çš„æ™‚é™è¦æ±‚,而å¦ä¸€éƒ¨åˆ†åªæ˜¯è¦æ±‚完æˆå¾—越快越好。按照RMS(RateMonotoinScheduling)ç†è«–ï¼Œé€™æ¨£çš„ç³»çµ±å¿…é ˆé‡‡ç”¨æ¶å…ˆå¼ä»»å‹™èª¿åº¦ï¼›è€Œåœ¨é€™æ¨£çš„系統ä¸ï¼Œå°±å¯ä»¥é‡‡ç”¨å‹•æ…‹å…§å˜åˆ†é…來滿足那一部分å¯é æ€§å’Œå¯¦æ™‚æ€§è¦æ±‚ä¸é‚£ä¹ˆé«˜çš„任務。
采用動態內å˜åˆ†é…的好處就是給è¨è¨ˆè€…å¾ˆå¤§çš„éˆæ´»æ€§ï¼Œå¯ä»¥æ–¹ä¾¿åœ°å°‡åŽŸä¾†é‹è¡ŒäºŽéžåµŒå…¥å¼æ“作系統的程åºç§»æ¤åˆ°åµŒå…¥å¼ç³»çµ±ä¸ï¼Œæ¯”如,許多嵌入å¼ç³»çµ±ä¸ä½¿ç”¨çš„網絡å”è°æ£§ã€‚å¦‚æžœå¿…é ˆé‡‡ç”¨éœæ…‹å…§å˜åˆ†é…,移æ¤é€™æ¨£çš„å”è°æ£§å°±æœƒå›°é›£å¾—多。
å¦å¤–,采用動態內å˜åˆ†é…å¯ä»¥ä½¿è¨è¨ˆè€…åœ¨ä¸æ”¹è®ŠåŸºæœ¬çš„硬件平臺的情æ³ä¸‹ï¼Œæ¯”è¼ƒéˆæ´»åœ°èª¿æ•´ç³»çµ±çš„功能,在系統ä¸å„個功能之間作出權衡。例如,å¯ä»¥åœ¨æ”¯æŒçš„VLAN數和支æŒçš„路由æ¢ç›®æ•¸ä¹‹é–“作出調整,或者ä¸åŒçš„版本支æŒä¸åŒçš„å”è°ã€‚說到底,動態內å˜åˆ†é…給了嵌入å¼ç³»çµ±çš„程åºè¨è¨ˆè€…在比較少的é™åˆ¶å’Œè¼ƒå¤§çš„è‡ªç”±ã€‚å› æ¤ï¼Œå¤§å¤šæ•¸å¯¦æ™‚æ“作系統æä¾›äº†å‹•æ…‹å…§å˜åˆ†é…接å£ï¼Œä¾‹å¦‚mallocå’Œfree函數。
3 RTOSæä¾›çš„å…§å˜åˆ†é…接å£
ä¸åŒçš„RTOS由于其ä¸åŒçš„定ä½ï¼Œé‡‡ç”¨ä¸åŒçš„å…§å˜åˆ†é…ç–略。例如VRTXä¸ï¼Œé‡‡ç”¨é¡žä¼¼äºŽGNUCä¸ç”±DougLea開發的內å˜åˆ†é…方案,å³Binning算法,系統內å˜è¢«åˆ†æˆäº†ä¸€äº›å›ºå®šå°ºå¯¸çš„å…§å˜å¡Šçš„算法,系統內å˜è¢«åˆ†æˆäº†ä¸€äº›å›ºå®šå°ºå¯¸çš„å…§å˜å¡Šçš„集åˆã€‚é€™ç¨®æ–¹æ³•çš„å„ªé»žæ˜¯æŸ¥æ‰¾é€Ÿåº¦å¿«è€Œä¸”ä¸æœƒç”¢ç”Ÿå…§å˜ç¢Žç‰‡ã€‚ä½†æ˜¯ï¼Œå®ƒçš„ç¼ºé»žä¹Ÿå¾ˆæ˜Žé¡¯ï¼Œå°±æ˜¯å®¹æ˜“é€ æˆæµªè²»ï¼Œå› 為內å˜å¡Šçš„å°ºå¯¸åªæœ‰æœ‰é™å€‹ï¼Œåˆ†é…時åªèƒ½å–較大的內å˜å¡Šä¾†æ»¿è¶³ä¸€å€‹è¼ƒå°çš„需求,累ç©èµ·ä¾†ï¼Œæµªè²»å°±å¾ˆå¤§äº†ï¼›è€Œä¸”æ“作系統管ç†é€™æ¨£ä¸€å€‹å…§å˜åˆ†é…è¡¨ä¹Ÿæ˜¯ä¸€å€‹å¾ˆå¤§çš„è² æ“”ã€‚
下é¢è©³ç´°ä»‹ç´¹ä¸€ä¸‹æˆ‘們常用的RTOS——美國風河公å¸ï¼ˆWindRiver)的VxWorksä¸é‡‡ç”¨çš„å…§å˜åˆ†é…ç–略。VxWorksçš„å‰èº«å°±æ˜¯VRTX,據說VxWorksçš„å稱來自makevrtxwork。VxWorks的內å˜ç®¡ç†å‡½æ•¸å˜åœ¨äºŽ2個庫ä¸ï¼›memPartLib(緊湊的內å˜åˆ†å€ç®¡ç†å™¨ï¼‰å’ŒmemLib(完整的內å˜åˆ†å€ç®¡ç†å™¨ï¼‰ã€‚å‰è€…(memPartLib)æä¾›çš„工具用于從內å˜åˆ†å€ä¸åˆ†é…å…§å˜å¡Šã€‚該庫包å«å…©é¡žç¨‹åºï¼Œä¸€é¡žæ˜¯é€šç”¨å·¥å…·å‰µå»ºå’Œç®¡ç†å…§å˜åˆ†å€å¹¶å¾žé€™äº›åˆ†å€ä¸åˆ†é…和管ç†å…§å˜å¡Šï¼›å¦ä¸€é¡žæ˜¯æ¨™æº–çš„malloc/freeç¨‹åºæä¾›èˆ‡å…§å˜åˆ†å€çš„æŽ¥å£ã€‚
系統內å˜åˆ†å€ï¼ˆå…¶ID為memSysPartId是一個全局變é‡ï¼‰åœ¨å…§æ ¸åˆå§‹åŒ–時由usrRoot調用memInit創建。其開始地å€ç‚ºRAMä¸ç·ŠæŽ¥è‘—VxWorksçš„BSS段之åŽï¼Œå¤§å°ç‚ºæ‰€æœ‰ç©ºé–‘å…§å˜ï¼Œå¦‚圖1所示。

ç•¶å‰µå»ºå…¶å®ƒåˆ†å€æ™‚,一般需è¦å…ˆèª¿ç”¨malloc從系統內å˜åˆ†å€ä¸åˆ†é…ä¸€æ®µå…§å˜æ‰èƒ½å‰µå»ºã€‚
å…§å˜åˆ†å€çš„çµæ§‹å®šç¾©ç‚ºmem_part,包å«1個å°è±¡æ¨™è¨˜ï¼Œ1個雙å‘éˆè¡¨ç®¡ç†ç©ºé–‘塊,1個信號é‡ä¿è·è©²åˆ†å€åŠä¸€äº›çµ±è¨ˆä¿¡æ¯ï¼Œå¦‚ç¸½å°ºå¯¸ã€æœ€å¤§å¡Šå°ºå¯¸ã€èª¿è©¦é¸é …ã€å·²åˆ†é…的塊數ã€å·²åˆ†é…的尺寸ç‰ã€‚其語å¥å¦‚下:
typedefstructmem_part
ï½›OBJ_COREobjCore;/*å°è±¡æ¨™å¿—*/
DL-LISTfreeListï¼›/*空閑éˆè¡¨ï¼Š/
SEMAPHOREsem;/*ä¿è·åˆ†å€çš„信號é‡ï¼Š/
UnsignedtotalWordsï¼›/*分å€ä¸å—(WORD)數*/
UnsignedminBlockWords;/*以å—為單ä½çš„æœ€å°å¡Šå°ºå¯¸ï¼Š/
Unsignedoptions;/*é¸é …,用于調試或統計*//*分é…統計*/
unsignedcurBlocksAllocated;/*當å‰åˆ†é…的塊數*/
unsignedcurWorkdAllocated;/*當å‰åˆ†é…çš„å—æ•¸ï¼Š/
unsignedcumBlockAllocatedï¼›/*累ç©åˆ†é…的塊數*/
unsignedcumWordsAllocatedï¼›/*累ç©åˆ†é…çš„å—æ•¸ï¼Š/
ï½PARTITIONï¼›
一般系統ä¸åªæœ‰1個內å˜åˆ†å€ï¼Œå³ç³»çµ±åˆ†å€ï¼Œæ‰€æœ‰ä»»å‹™æ‰€éœ€è¦çš„å…§å˜ç›´æŽ¥èª¿ç”¨malloc從其ä¸åˆ†é…。分é…采用First-Fit算法(注æ„這種算法容易導致大é‡ç¢Žç‰‡ï¼‰ï¼Œé€šéŽfree釋放的內å˜å°‡è¢«èšåˆä»¥å½¢æˆæ›´å¤§çš„空閑塊。
這就是VxWorks的內å˜åˆ†é…機ç†ã€‚åˆ†é…æ™‚å¯ä»¥è¦æ±‚一定的å°é½Šæ ¼å¼ã€‚注æ„,ä¸åŒçš„CPU架構有ä¸åŒçš„å°é½Šè¦æ±‚。為了優化性能,mallocè¿”å›žçš„æŒ‡é‡æ˜¯ç¶“éŽå°é½Šçš„,為æ¤çš„開銷隨構ä¸åŒè€Œä¸åŒã€‚
例如,68K為4å—節å°é½Šï¼Œé–‹éŠ·8å—節;SPARC為8å—節å°é½Šï¼Œé–‹éŠ·12å—節;MIPS為16å—節å°é½Šï¼Œé–‹éŠ·12å—節;I960為16å—節å°é½Šï¼Œé–‹éŠ·16å—節。MemLibåº«ä¸æä¾›äº†å¢žå¼·çš„å…§å˜åˆ†å€ç®¡ç†å·¥å…·ï¼Œå¹¶ä¸”å¢žåŠ äº†ä¸€äº›æŽ¥å£ï¼Œè€Œä¸”å¯ä»¥è¨ç½®èª¿è©¦é¸é …。
å¯ä»¥æª¢æ¸¬2類錯誤:①嘗試分é…太大的內å˜ï¼›â‘¡é‡‹æ”¾å…§å˜æ™‚發ç¾å£žå¡Šã€‚有4種錯誤處ç†é¸é …ï¼Œç•¶ç™¼ç”ŸéŒ¯èª¤æ™‚è¨˜éŒ„æ¶ˆæ¯æˆ–掛起任務。
但是,使用動態內å˜åˆ†é…malloc/freeæ™‚è¦æ³¨æ„到以下幾方é¢çš„é™åˆ¶ã€‚â‘ å› ç‚ºç³»çµ±å…§å˜åˆ†å€æ˜¯ä¸€ç¨®è‡¨ç•Œè³‡æºï¼Œç”±ä¿¡è™Ÿé‡ä¿è·ï¼Œä½¿ç”¨malloc會導致當å‰èª¿ç”¨æŽ›èµ·ï¼Œå› æ¤å®ƒä¸èƒ½ç”¨äºŽä¸æ–·æœå‹™ç¨‹åºï¼›â‘¡å› 為進行內å˜åˆ†é…需è¦åŸ·è¡ŒæŸ¥æ‰¾ç®—法,其執行時間與系統當å‰çš„å…§å˜ä½¿ç”¨æƒ…æ³ç›¸é—œï¼Œæ˜¯ä¸ç¢ºå®šçš„ï¼Œå› æ¤å°äºŽæœ‰è¦å®šæ™‚é™çš„æ“ä½œå®ƒæ˜¯ä¸é©å®œçš„;③由于采用簡單的最先匹é…算法,容易導致系統ä¸å˜åœ¨å¤§é‡çš„å…§å˜ç¢Žç‰‡ï¼Œé™ä½Žå…§å˜ä½¿ç”¨æ•ˆçŽ‡å’Œç³»çµ±æ€§èƒ½ã€‚
é‡å°é€™ç¨®æƒ…æ³ï¼Œä¸€èˆ¬åœ¨ç³»çµ±è¨è¨ˆæ™‚é‡‡ç”¨éœæ…‹åˆ†é…與動態分é…相çµåˆçš„æ–¹æ³•。也就是å°äºŽé‡è¦çš„æ‡‰ç”¨ï¼Œåœ¨ç³»çµ±åˆå§‹åŒ–時分é…好所需è¦çš„å…§å˜ã€‚在系統é‹è¡ŒéŽç¨‹ä¸ä¸å†é€²è¡Œå…§å˜çš„分é…/釋放,這樣就é¿å…äº†å› å…§å˜çš„分é…釋放帶來的總是。而且在系統åˆå§‹åŒ–ï¼Œå› ç‚ºæ²’æœ‰å…§å˜ç¢Žç‰‡ï¼Œå°äºŽå¤§çš„å…§å˜å¡Šçš„需求容易滿足。å°äºŽå…¶å®ƒçš„æ‡‰ç”¨ï¼Œåœ¨é‹è¡Œæ™‚進行動態內å˜åˆ†é…。尤其是æŸäº›æ‡‰ç”¨æ‰€è¦æ±‚的大é‡å›ºå®šå°ºå¯¸çš„å°å…§å˜å¡Šï¼Œé€™æ™‚å°±å¯ä»¥é‡‡ç”¨ä¸€æ¬¡åˆ†é…多次使用的內å˜åˆ†é…方案。下é¢è©³ç´°ä»‹ç´¹é€™ç¨®å…§å˜åˆ†é…方案åŠå…¶æ‡‰ç”¨å ´åˆã€‚
4 一次分é…多次使用的內å˜åˆ†é…方案
在嵌入å¼ç³»çµ±è¨è¨ˆä¸ï¼Œç¶“å¸¸æœ‰ä¸€äº›é¡žä¼¼äºŽå…§å˜æ•¸æ“šåº«çš„æ‡‰ç”¨ã€‚這些應用的特點是在內å˜ä¸ç®¡ç†ä¸€äº›æ¨¹ï¼Œæ¯”å¦‚ä»¥å¤ªç¶²äº¤æ›æ©Ÿä¸çš„MAC地å€è¡¨ã€VLAN表ç‰ï¼Œæˆ–者路由器ä¸çš„路由表。這些樹是由許多相åŒå°ºå¯¸çš„節點組æˆçš„。這樣,就å¯ä»¥æ¯æ¬¡åˆ†é…ä¸€å€‹å¤§çš„ç·©æ²–æ± ï¼Œæ¯”å¦‚åŒ…å«å¤šå€‹å…§å˜å–®å…ƒçš„æ•¸çµ„,æ¯å€‹å…§å˜å–®å…ƒç”¨äºŽ1個節點。我們用一個空閑éˆè¡¨ä¾†ç®¡ç†è©²æ•¸çµ„ä¸çš„空閑內å˜å–®å…ƒã€‚æ¯æ¬¡ç¨‹åºéœ€è¦åˆ†é…å…§å˜ä»¥å‰µå»º1個新的節點時,就從空閑éˆè¡¨ä¸å–1個單元給調用者。程åºåˆªé™¤ç¯€é»žå¹¶é‡‹æ”¾å…§å˜æ™‚,將釋放的內å˜å–®å…ƒè¿”還給空閑éˆè¡¨ã€‚如果éˆè¡¨ä¸çš„空閑內å˜å–®å…ƒå–ç©ºäº†ï¼Œå°±å†æ¬¡èª¿ç”¨malloc從系統內å˜ä¸åˆ†é…一個大的內å˜å¡Šä½œç‚ºæ–°çš„ç·©æ²–æ± ã€‚
é‡‡ç”¨é€™æ¨£ä¸€ç¨®æ–¹æ¡ˆä¸»è¦æœ‰å¦‚下優點:①減少了malloc/free的調用次數,從而é™ä½Žäº†é¢¨éšªï¼Œæ¸›å°‘äº†ç¢Žç‰‡ï¼›â‘¡å› ç‚ºå¾žç·©æ²–æ± ä¸å–一個內å˜å–®å…ƒæ˜¯æ™‚é–“ç¢ºå®šçš„ï¼ˆç•¶ç„¶ï¼Œå¦‚æžœç·©æ²–æ± è€—ç›¡å¾žè€Œéœ€è¦é‡æ–°èª¿ç”¨malloc分é…é™¤å¤–ï¼‰ï¼Œå› æ¤å®ƒå¯ä»¥ç”¨äºŽåš´æ ¼æ™‚é™çš„å ´åˆå¾žè€Œä¿è‰å¯¦æ™‚æ€§ï¼›â‘¢å®ƒçµ¦ç”¨æˆ¶ä»¥è‡ªç”±ä¾†æ·»åŠ ä¸€äº›ç”¨äºŽå…§å˜åˆ†é…和釋放的調試函數以åŠä¸€äº›çµ±è¨ˆåŠŸèƒ½ï¼Œæ›´å¥½åœ°ç›£æ¸¬ç³»çµ±ä¸å…§å˜çš„使用情æ³ã€‚這種方案必然涉åŠåˆ°ä¸€å€‹ç·©æ²–æ± çš„çµæ§‹ã€‚ä¸€èˆ¬ç·©æ²–æ± çš„çµæ§‹ç”±ä»¥ä¸‹å¹¾éƒ¨åˆ†çµ„æˆï¼šå–®å…ƒå°ºå¯¸ã€å¡Šå°ºå¯¸ï¼ˆæˆ–者單元數目)ã€ç·©æ²–æ± æŒ‡é‡ã€ç©ºé–‘éˆè¡¨ã€ç”¨äºŽçµ±è¨ˆå’Œèª¿è©¦çš„åƒæ•¸ç‰ã€‚å°ç·©æ²–æ± çš„æ“ä½œåŒ…æ‹¬å‰µå»ºç·©æ²–æ± ã€é‡‹æ”¾ç·©æ²–æ± ã€å¾žç·©æ²–æ± ä¸åˆ†é…1個內å˜å–®å…ƒã€é‡‹æ”¾å…§å˜å–®å…ƒå›žç·©æ²–æ± ç‰ã€‚下é¢èˆ‰2個例å說明一下該方案的具體使用情æ³ã€‚
4.1 Inteläº¤æ›æ©Ÿé©…動程åºä¸å…§å˜åˆ†é…
在以Intel的交æ›èŠ¯ç‰‡ç‚ºåŸºç¤Žçš„äº¤æ›æ©Ÿæ–¹æ¡ˆä¸ï¼Œå› 為采用的是軟件地å€å¸ç¿’的方å¼ï¼Œéœ€è¦åœ¨å…§å˜ä¸ç¶è·è¨±å¤šæ•¸æ“šï¼Œå¦‚MAC地å€è¡¨çš„軟拷è²ã€VLAN表ã€éœæ…‹å–®æ’地å€è¡¨ã€çµ„æ’地å€è¡¨ç‰ã€‚這些表都是由一些樹組æˆï¼Œæ¯å€‹æ¨¹ç”±ä¸€äº›å›ºå®šå°ºå¯¸çš„節點組æˆã€‚一般æ¯å€‹ç¯€é»žå¹¾å個å—ç¯€ï¼Œæ¯æ£µæ¨¹çš„節點數是å¯å¢žé•·çš„,少則幾å,最多å¯åˆ°16Kå€‹ç¯€é»žã€‚å› æ¤ï¼Œå¾ˆé©åˆäºŽé‡‡ç”¨è©²æ–¹æ¡ˆï¼Œå…·é«”的實ç¾å¦‚下:
(1ï¼‰ç·©æ²–æ± çµæ§‹
BlockMemMgrtypedefstruct{MemSizedata_cell_size;/*數據單元的尺寸*/MemSizeblock_size;/*塊尺寸*/
/*下é¢çš„變é‡ç‚ºé 定義的æ¯å€‹ç®¡ç†å™¨æœ€å¤šåŒ…å«çš„塊數,如64MAX_BLOCKS_OF_MEM_SIZE*/Unsignedshortblocks_being_used;/*已使用的塊數*/
Voidmem_ptr[PAX_BLOCKS_OF_MEM_SIZE];/*塊數組*/
SLListfree_data_cells_list;/*空閑éˆè¡¨ï¼Š/
ï½BlockMemMgr;
çµæ§‹ä¸çš„åƒæ•¸åŒ…括:單元尺寸ã€å¡Šå°ºå¯¸ã€å·²ç”¨å¡Šæ•¸ã€æ‰€æœ‰å¡Šçš„地å€ã€ç©ºé–‘éˆè¡¨ï¼ˆå–®å‘éˆè¡¨ï¼‰ã€‚
(2ï¼‰ç·©æ²–æ± çš„ç®¡ç†å‡½æ•¸
â—†block_mem_create:創建塊內å˜ç®¡ç†å™¨ï¼Œåƒæ•¸åŒ…æ‹¬å…§å˜æŒ‡é‡ï¼ˆå¦‚為NULL,表示自己分é…)ã€å¡Šå°ºå¯¸ã€å–®å…ƒå°ºå¯¸ã€è¿”回管ç†å™¨æŒ‡é‡ã€‚éŽç¨‹å¦‚下:
â‘ æª¢é©—åƒæ•¸åˆæ³•性。
②單元尺寸4å—節å°é½Šï¼Œè¨ˆç®—æ¯å€‹å¡Šä¸çš„單元數。å°å…§å˜æŒ‡é‡é€²è¡Œ4å—節å°é½Šæˆ–者分é…å…§å˜æŒ‡é‡ã€‚
â‘¢åˆå§‹åŒ–çµæ§‹BlockMemMgr,包括單元尺寸和塊尺寸。è¨ç½®ç¬¬1個內å˜å¡Šçš„æŒ‡é‡ã€‚å¦‚æžœå…§å˜æ˜¯å¤–來的,è¨ç½®å¡Šå·²ç”¨æ¨™å¿—(已用為0),表示ä¸èƒ½å¢žåŠ å¡Šï¼›å¦å‰‡ï¼Œå·²ç”¨å¡Šæ•¸è¨ç‚º1。
④創建空閑éˆè¡¨ï¼Œå°‡å¡Šå…§æ‰€æœ‰å–®å…ƒæ·»åŠ åˆ°éˆè¡¨ä¸ï¼Œæœ€åŽä¸€å€‹å–®å…ƒè™•于éˆè¡¨çš„æœ€å‰é¢ã€‚
⑤返回BlockMemMgr。
â—†block_mem_destroy:解構一個塊內å˜ç®¡ç†å™¨ï¼Œé‡‹æ”¾å®ƒæ‰€åˆ†é…的所有內å˜ï¼Œèª¿ç”¨è€…è² è²¬å¤–éƒ¨å…§å˜çš„é‡‹æ”¾ã€‚åƒæ•¸ç‚ºBlockMemMgr。返回æˆåŠŸå¤±æ•—æ¨™å¿—ã€‚
â‘ åƒæ•¸åˆæ³•性檢測。
②刪除單å‘éˆè¡¨ï¼ˆè¨éˆè¡¨æŒ‡é‡ç‚ºNULL)。
③如果塊是動態分é…的,釋放它們。
â‘£é‡‹æ”¾çµæ§‹BlockMemMgr。
â—†block_malloc:從塊內å˜ç®¡ç†å™¨ä¸åˆ†é…1å€‹å–®å…ƒâ‘¤é‡‹æ”¾çµæ§‹BlockMemMgr
â—†block_malloc:從塊內å˜ç®¡ç†å™¨ä¸åˆ†é…1å€‹å–®å…ƒã€‚åƒæ•¸ç‚ºBlockMemMgr,返回數據單元指é‡ã€‚
â‘ åƒæ•¸åˆæ³•性檢測。
②判斷空閑éˆè¡¨æ˜¯å¦ç‚ºç©ºï¼ˆæ˜¯å¦ç‚ºNULL)。如果為空,判斷是å¦å¯ä»¥å‹•態分é…塊,如果ä¸èƒ½ï¼Œè¿”回失敗;如果å¯ä»¥å‹•態分é…塊,則分é…1個塊,執行與block_mem_create一樣的æ“作。
③從空閑éˆè¡¨ä¸åˆ†é…第1個單元,返回其指é‡ã€‚注æ„é€™é‡Œæœ‰ä¸€å€‹å°æŠ€å·§ï¼Œå³æ•¸æ“šå–®å…ƒåœ¨ç©ºé–‘時其ä¸å˜æ”¾ç©ºé–‘éˆè¡¨çš„節點信æ¯ï¼Œè€Œåˆ†é…åŽå‰‡å˜æ”¾æ•¸æ“šå…§å®¹ã€‚
â—†block_free:釋放1個數據單元,返回塊內å˜ç®¡ç†å™¨ã€‚å°å¿ƒä¸è¦å°1個單元釋放2æ¬¡ã€‚åƒæ•¸ç‚ºBlockMemMgr和單元指é‡ã€‚
â‘ åƒæ•¸åˆæ³•性檢測。
â‘¡åœ°å€æ¯”較,判斷數據單元屬于哪個塊。
③判斷數據單元的內容是å¦ç‚ºç©ºé–‘éˆè¡¨ç¯€é»žä¿¡æ¯ï¼ˆä¹Ÿå°±æ˜¯å¡Šå…§æŸå–®å…ƒçš„地å€ï¼‰ï¼Œå¾žè€Œç¢ºå®šæ˜¯å¦ç‚º2次釋放。
④將該數據單元æ’入到空閑éˆè¡¨çš„å‰é¢ã€‚
⑤引用該單元的指é‡è¨ç‚ºNULL。
å…§å˜ç®¡ç†ä»£ç¢¼éµå®ˆå¦‚下約定:
①管ç†çš„å…§å˜æ˜¯å¯¦éš›å¯å¯«çš„å…§å˜ï¼›
②分é…å…§å˜æ˜¯4å—節或32ä½å°é½Šï¼›
â‘¢block_mallocã€bloc
k_freeåœ¨ä¸æ–·ç´šèª¿ç”¨æ˜¯éƒ¨åˆ†å®‰å…¨çš„,除éžBLOCKä¸å·²ç¶“沒有空閑CELL,需è¦é‡æ–°èª¿ç”¨mallocåˆ†é…æ–°çš„BLOCK(而mallocå’Œfree就䏿˜¯å®‰å…¨çš„ï¼Œå› ç‚ºå…¶ä¸ä½¿ç”¨äº†ä¿¡è™Ÿé‡å’Œæœç´¢ç®—æ³•ï¼Œå®¹æ˜“å¼•èµ·ä¸æ–·æœå‹™ç¨‹åºé˜»å¡žï¼‰ã€‚當然,block_mem_createå’Œblock_mem_destroyå¿…é ˆåœ¨é€²ç¨‹ç´šèª¿ç”¨ã€‚
4.2 TMSä¸çš„å…§å˜åˆ†é…
TMS是WindRiverå…¬å¸ç‚ºå¯ç®¡ç†å¼äº¤æ›æ©ŸæŽ¨å‡ºçš„開發包。它用用IDB來管ç†å„種å”è°çš„æ•¸æ“šï¼Œæ¯”如STPå’ŒGVRPç‰ã€‚為了支æŒIDBï¼Œå®ƒå»ºç«‹äº†è‡ªå·±çš„ç·©æ²–æ± ç®¡ç†æ–¹æ¡ˆï¼Œç¨‹åºåœ¨bufPoolLib.cä¸ã€‚該程åºåŒ…å«ç”¨äºŽç·©æ²–æ± ç®¡ç†çš„函數,這些函數å…許從1å€‹æ± ä¸åˆ†é…固定數目和大å°çš„ç·©æ²–å€ã€‚通éŽé 先分é…一定數目固定大å°çš„ç·©æ²–å€ï¼Œé¿å…了å復的å°çš„å…§å˜å¡Šåˆ†é…/釋放相關è¯çš„å…§å˜ç¢Žç‰‡å’Œæµªè²»ã€‚既然它從1個單一的塊ä¸åˆ†é…ç·©æ²–æ± ï¼Œä¹Ÿæ¯”å°æ¯ä¸€å€‹ç·©æ²–å€åŸ·è¡Œ1æ¬¡åˆ†é…æœ‰æ›´é«˜çš„ç©ºé–“æ•ˆçŽ‡ã€‚æ¨¡å¡Šå°æ¯å€‹ç·©æ²–å€åŠ ä¸Š1個標記(MAGIC),釋放時會檢查標記。模塊給用戶æä¾›åˆ†é…和釋放æ“作定義回調函數的能力。這樣å¯ä»¥åšåˆ°è‡ªå‹•çš„å°è±¡å‰µå»ºå’Œè§£æ§‹ï¼ŒåŒæ™‚å…è¨±ç”±å¤šå€‹ç·©æ²–æ± åˆ†é…çš„æˆå“¡çµ„æˆçš„å°è±¡åšç‚º1個單一的實體刪除。這類似于C++ä¸è‡ªå‹•çš„å°è±¡æ§‹å»ºå’Œè§£æ§‹ï¼Œä¸éŽæ˜¯ç”¨Cèªžè¨€å¹¶ä¸”æ²’æœ‰å †æ£§åˆ†é…çš„è² æ“”ã€‚æ¨¡å¡Šæ—¢å…è¨±å¾žå †æ£§ä¸åˆ†é…ç·©æ²–æ± ï¼ˆé€šéŽcalloc),也å¯ä»¥åœ¨ç”¨æˆ¶åˆ†é…的空間ä¸å‰µå»ºå®ƒå€‘。模塊用1個單å‘éˆè¡¨ä¾†ç¶è·æœªåˆ†é…的緩沖å€ï¼Œä½†ä¸è·Ÿè¹¤å·²åˆ†é…的緩沖å€ã€‚æ¨¡å¡Šå¹¶ä¸æ˜¯ä»»å‹™å®‰å…¨çš„,用戶需è¦ç”¨ä¿¡è™Ÿæ™‚來ä¿è·ç·©æ²–æ± ã€‚
(1ï¼‰ç·©æ²–æ± çµæ§‹
typedefstruct{ulong_tmagic;/*用于一致性檢測的特殊標記*/
BooleanlocalAlloc;/ï¼Šå…§å˜æ˜¯å¦åœ¨å‰µå»ºç·©æ²–倿™‚分é…*/
SL_LISTfreeList;/*空閑éˆè¡¨ï¼Š/
Voidstore;/ï¼Šç·©æ²–å€æŒ‡å‘çš„å…§å˜æŒ‡é‡ï¼Š/
STATUS(*createFn)(void*,ulong_targl);/ï¼Šå‰µå»ºç·©æ²–å€æ™‚的回調函數指é‡ï¼Š/STATUS(*destroyFn)(void*,ulong_targl);/ï¼Šé‡‹æ”¾ç·©æ²–å€æ™‚的回調函數指é‡ï¼Š/Ulong_targVal;/ï¼Šå›žèª¿å‡½æ•¸çš„åƒæ•¸ï¼Š/
ï½buf_pool_t;
çµæ§‹ä¸çš„åƒæ•¸åŒ…括檢查標記MAGICã€æ˜¯å¦æœ¬åœ°åˆ†é…ã€ç©ºé–‘éˆè¡¨ã€å…§å˜æŒ‡é‡ã€å‰µå»ºç·©æ²–æ± çš„å›žèª¿å‡½æ•¸æŒ‡é‡ã€é‡‹æ”¾æ™‚的回調函數指é‡ã€å›žèª¿å‡½æ•¸åƒæ•¸ã€‚
(2)相關函數
â—†BufPoolInitializeStorage:分é…å’Œåˆå§‹åŒ–å˜å„²å€ã€‚åƒæ•¸åŒ…括å˜å„²å€åœ°å€ï¼ˆå¦‚為NULL,則本地分é…)ã€ç·©æ²–å€å¤§å°ã€ç·©æ²–å€å€‹æ•¸ã€‚
â‘ æ ¹æ“šç·©æ²–å€å¤§å°å’Œå€‹æ•¸ç²å¾—所需的內å˜å¤§å°ã€‚
②如果指é‡ç‚ºNULL,則調用calloc分é…å…§å˜ã€‚è¨ç½®æœ¬åœ°åˆ†é…標志。
â‘¢åˆå§‹åŒ–å…§å˜ç‚º0。
â‘£åˆå§‹åŒ–指é‡ã€‚分é…的內å˜å¡Šæœ€å‰é¢ç‚ºç·©æ²–æ± çµæ§‹buf_pool_t。實際的å˜å„²å€ç·Šéš¨å…¶åŽã€‚Buf_pool_t包å«åƒæ•¸æª¢æŸ¥æ¨™è¨˜ã€æ˜¯å¦æœ¬åœ°åˆ†é…ã€å˜å„²å€åœ°å€ã€åˆ†é…時回調函數ã€é‡‹æ”¾æ™‚回調函數ã€å›žèª¿å‡½æ•¸è®Šé‡ã€‚æ¤æ™‚åªè¨ç½®å˜å„²å€æŒ‡é‡ã€‚
â—†BufPoolCreateï¼šå‰µå»ºç·©æ²–æ± ã€‚åƒæ•¸ç‚ºå…§å˜åˆ¶æ¢ã€‚ç·©æ²–å€å°ºå¯¸å’Œå€‹æ•¸ï¼Œå‰µå»ºæ™‚回調函數ã€é‡‹æ”¾æ™‚回調函數ã€å›žèª¿å‡½æ•¸åƒæ•¸ã€‚①尺寸å°é½Šã€‚②調用bufPoolInitializeStorageåˆå§‹åŒ–å…§å˜å€å’Œbuf_pool_tçµæ§‹ã€‚â‘¢ç”¨å‚³å…¥åƒæ•¸å¡«å……buf_pool_tçµæ§‹ã€‚â‘£å°‡ç·©æ²–å€æ·»åŠ åˆ°ç©ºé–‘éˆè¡¨ä¸ï¼Œæœ€åŽçš„ç·©æ²–å€åœ¨æœ€å‰é¢ã€‚
â—†BufPoolDestroyï¼šåˆªé™¤ç·©æ²–æ± ã€‚åƒæ•¸ç‚ºbuf_pool_t指é‡ã€‚â‘ æª¢æŸ¥ç·©æ²–æ± çµæ§‹ä¸çš„MAGICå—æ®µæ˜¯å¦è¢«å€‹æ€§ã€‚②如果是本地分é…的則翻放內å˜å€ã€‚
â—†BufPoolAllocï¼šå¾žç·©æ²–æ± ä¸åˆ†é…一個緩沖å€ï¼Œåƒæ•¸ç‚ºç·©æ²–æ± çµæ§‹æŒ‡é‡ã€‚如果å˜åœ¨ç©ºé–‘ç·©æ²–å€ï¼Œå‰‡å¾žç©ºé–‘éˆè¡¨ä¸é™¤å¹¶æä¾›çµ¦èª¿ç”¨è€…,執行創建時回調函數。如果回調函數返回錯誤,則將緩沖å€è¿”還給空閑éˆè¡¨ã€‚â‘ æª¢æŸ¥ç·©æ²–æ± çµæ§‹ä¸çš„MAGIC標記是å¦å®Œå¥½ã€‚②從空閑éˆè¡¨ä¸å–出é 一個節點。③如果節點ä¸ç‚ºç©ºï¼Œæ¸…空節點,以其地å€ç‚ºåƒæ•¸èª¿ç”¨å›žèª¿å‡½æ•¸ã€‚④如果回調函數返回錯誤,則將節點還給空閑éˆè¡¨ã€‚⑤返回得到空閑緩沖å€åœ°å€ã€‚
â—†BufPoolFree:將緩沖å€è¿”å›žçµ¦ç·©æ²–æ± ã€‚å¦‚æžœå®šç¾©äº†å›žèª¿å‡½æ•¸ï¼Œå°‡åœ¨æ¸é‚„ç·©æ²–ä¹‹é–“èª¿ç”¨å›žèª¿å‡½æ•¸ã€‚åƒæ•¸ç‚ºç·©æ²–æ± çµæ§‹å’Œç·©æ²–倿Œ‡é‡ã€‚â‘ ç·©æ²–æ± MAGIC標記是å¦å®Œå¥½ã€‚②如果定義回調函數ã€èª¿ç”¨ä¹‹ã€‚如果返回錯誤,則è¨ç½®éŒ¯èª¤è™Ÿã€‚â‘¢å°‡ç·©æ²–å€æ·»åŠ åˆ°ç©ºé–‘éˆè¡¨ä¸é 部。注æ„該函數有2點:①回調函數返回錯誤,照樣æ¸é‚„ç·©æ²–å€ã€‚â‘¡æ²’æœ‰æª¢æŸ¥ç·©æ²–å€æ˜¯å¦äºŒæ¬¡é‡‹æ”¾ï¼Œé€™ä¸€é»žèˆ‡Intel的驅動程åºä¸åŒã€‚å¦å¤–,TMSçš„ç·©æ²–æ± æ²’æœ‰BLOCKè¦é ˜ï¼Œä¸éœ€è¦åˆ¤æ–·å“ªå€‹CELL屬于哪個BLOCK,簡化了æ“作。
5 å°çµ
è¨±å¤šåµŒå…¥å¼æ‡‰ç”¨åœ¨RTOSæä¾›çš„malloc/free的基礎上編寫自己的內å˜ç®¡ç†æ–¹æ¡ˆã€‚編寫這樣的內å˜ç®¡ç†æ–¹æ¡ˆï¼Œç›®çš„ç„¡éžæœ‰å…©å€‹ï¼šä¸€æ˜¯æ¸›å°‘å°malloc/freeçš„ä¾è³´ï¼Œå¾žè€Œé¿å…由之帶來的內å˜ç¢Žç‰‡ã€æ™‚é–“ä¸ç¢ºå®šç‰ç¸½æ˜¯ï¼›å¦ä¸€å€‹æ˜¯å¢žå¼·ç¨‹åºçš„æŸ¥éŒ¯èƒ½åŠ›ï¼Œé€é‚„å…§å˜ä½¿ç”¨éŒ¯èª¤ã€‚å°äºŽåœ¨åµŒå…¥å¼ç³»çµ±ä¸å»£æ³›å˜åœ¨çš„æ•¸æ“šåº«é¡žåž‹çš„å…§å˜éœ€æ±‚,å³åˆ†é…多個固定尺寸的內å˜å–®å…ƒçš„è¦æ±‚,“一閃分é…,多次使用â€çš„æ–¹æ¡ˆç„¡ç–‘是一種很好的解決之é“。文ä¸ä»‹ç´¹çš„2個例å很好地體ç¾äº†å®ƒçš„優越性。