WSF操作系统抽象层学习笔记 (一) ---简介和内存管理
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                WSF操作系统抽象层学习笔记 (一)  ---简介和内存管理
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                一、簡介
WSF(wireless software foundation)是對操作系統的一個簡單的封裝,提供對操作系統的簡單編程,提供簡單的系統服務
功能簡介:
WSF不定義任何任務,僅定義了一些給任務的接口。依賴于目標OS去實現任務和事件管理,定時器管理等。也可以在裸機環境中充當一個簡單的獨立操作系統。
?
二、組成介紹
數據類型
wsf_types.h
定義了后續軟件系統使用的常用數據類型。
/* 嵌入式常用數據類型 */ typedef signed char int8_t; typedef unsigned char uint8_t; typedef signed short int16_t; typedef unsigned short uint16_t; typedef signed long int32_t; typedef unsigned long uint32_t; typedef unsigned long long uint64_t;內存管理
WSF的內存管理是一個基于內存池的緩存管理方法。
//內存池緩存描述結構 typedef struct {uint16_t len; //內存池中單個緩存長度uint8_t num; //內存池中緩存個數 } wsfBufPoolDesc_t;//內存池管理結構 typedef struct {wsfBufPoolDesc_t desc; //內存池wsfBufMem_t *pStart; //內存池開始的指針wsfBufMem_t *pFree; //指向第一個可用的內存位置 #if WSF_BUF_STATS == TRUE //用于控制buf狀態信息的輸出和調試uint8_t numAlloc; //當前被申請的內存個數uint8_t maxAlloc; //使用最大個數uint16_t maxReqLen; //使用的最長的長度 #endif } wsfBufPool_t;//一個內存單位的描述結構,同時作為每個內存塊的頭部結構,屬于復用型結構 //這個地方定義為一個指針的大小,目的可能是為了做內存對齊。 typedef struct wsfBufMem_tag {struct wsfBufMem_tag? *pNext;???? //指向下一個內存塊的位置 #if WSF_BUF_FREE_CHECK == TRUEuint32_t????????????? free;?? ??? //表示該內存塊單元是否被使用 #endif } wsfBufMem_t;內存池分配的結構
?
內存的初始化
? ? ? ?內存的初始化是將傳遞進來的整塊內存,按照上圖所示,依次在頭部填充N個內存池的管理結構,然后將剩下的內存劃分為N個內存池,并根據內存池描述結構將每個內存池劃分為M塊實際內存。
? ? ? ?因此,傳遞內存的大小應該額外添加N個內存管理結構的大小。否則內存池將廚師胡失敗。產生斷言。
/**bufMemLen:傳入的緩沖區大小。*pBufMem:指向緩沖區的指針。*numPools:需要創建的內存池個數。*pDesc:每個內存池的描述結構。 */ uint16_t WsfBufInit(uint16_t bufMemLen, uint8_t *pBufMem, uint8_t numPools, wsfBufPoolDesc_t *pDesc) {wsfBufPool_t *pPool;wsfBufMem_t *pStart;uint16_t len;uint8_t i;wsfBufMem = (wsfBufMem_t *) pBufMem;pPool = (wsfBufPool_t *) wsfBufMem;/* 內存的頭部存放內存池管理結構 */pStart = (wsfBufMem_t *) (pPool + numPools);wsfBufNumPools = numPools;/* 循環創建內存池 */while (TRUE){/* 這里時檢測內存是否越限 *//* 這個位置最好在函數的入口進行總長度的計算,邊創建邊計算的方式稍微有點不合適 */if (pStart > &wsfBufMem[bufMemLen / sizeof(wsfBufMem_t)]){WSF_ASSERT(FALSE);return 0;}/* 創建完畢退出循環 */if (numPools-- == 0){break;}/* 對內存池進行對齊,這里是以一個指針的大小進行對齊 */if (pDesc->len < sizeof(wsfBufMem_t)){pPool->desc.len = sizeof(wsfBufMem_t);}else if ((pDesc->len % sizeof(wsfBufMem_t)) != 0){pPool->desc.len = pDesc->len + sizeof(wsfBufMem_t) - (pDesc->len % sizeof(wsfBufMem_t));}else{pPool->desc.len = pDesc->len;}pPool->desc.num = pDesc->num; //記錄內存池中內存塊的個數。pDesc++;pPool->pStart = pStart; //記錄內存其實位置pPool->pFree = pStart; //記錄下一個可用的位置 #if WSF_BUF_STATS == TRUEpPool->numAlloc = 0;pPool->maxAlloc = 0;pPool->maxReqLen = 0; #endifWSF_TRACE_INFO2("Creating pool len=%u num=%u", pPool->desc.len, pPool->desc.num);WSF_TRACE_INFO1(" pStart=0x%x", (uint32_t)pPool->pStart);/* 循環創建內存塊,設置可用鏈表 */len = pPool->desc.len / sizeof(wsfBufMem_t);for (i = pPool->desc.num; i > 1; i--){/* 越界檢測,若開始做了檢查則此處不在需要檢查 */if (pStart > &wsfBufMem[bufMemLen / sizeof(wsfBufMem_t)]){WSF_ASSERT(FALSE);return 0;}/* 記錄下一個空閑的位置 */pStart->pNext = pStart + len;pStart += len;}/* 越界檢測,同上 */if (pStart > &wsfBufMem[bufMemLen / sizeof(wsfBufMem_t)]){WSF_ASSERT(FALSE);return 0;}/* 最后一個內存塊的下一個指向空 */pStart->pNext = NULL;pStart += len;/* 進行下一個內存池的創建 */pPool++;}wsfBufMemLen = (uint8_t *) pStart - (uint8_t *) wsfBufMem;WSF_TRACE_INFO1("Created buffer pools; using %u bytes", wsfBufMemLen);return wsfBufMemLen; }?
內存申請
? ? ? ?使用輪詢的方式依次檢查每個內存池支持的長度以及,是否有剩余空間,然后取其中一個將內存起始地址返回,并重新設置free指針。
/**len:申請內存的長度*/ void *WsfBufAlloc(uint16_t len) {wsfBufPool_t *pPool;wsfBufMem_t *pBuf;uint8_t i;WSF_CS_INIT(cs);WSF_ASSERT(len > 0);pPool = (wsfBufPool_t *) wsfBufMem;/* 輪詢每個mempool,找到空閑和合適大小的內存池 */for (i = wsfBufNumPools; i > 0; i--, pPool++){/* 判斷當前內存池塊大小是否滿足需求 */if (len <= pPool->desc.len){/* enter critical section */WSF_CS_ENTER(cs);/* 判斷當前內存池是都有空余內存塊 */if (pPool->pFree != NULL){/* pbuf指向可用內存 */pBuf = pPool->pFree;/* 將FREE指針指向下一個內存塊的位置 */pPool->pFree = pBuf->pNext;#if WSF_BUF_FREE_CHECK == TRUEpBuf->free = 0; #endif #if WSF_BUF_STATS_HIST == TRUE/* increment count for buffers of this length */if (len < WSF_BUF_STATS_MAX_LEN){wsfBufAllocCount[len]++;}else{wsfBufAllocCount[0]++;} #endif #if WSF_BUF_STATS == TRUEif (++pPool->numAlloc > pPool->maxAlloc){pPool->maxAlloc = pPool->numAlloc;}pPool->maxReqLen = WSF_MAX(pPool->maxReqLen, len); #endif/* exit critical section */WSF_CS_EXIT(cs);WSF_TRACE_ALLOC2("WsfBufAlloc len:%u pBuf:%08x", pPool->desc.len, pBuf);return pBuf;}/* exit critical section */WSF_CS_EXIT(cs);#if WSF_BUF_ALLOC_BEST_FIT_FAIL_ASSERT == TRUEWSF_ASSERT(FALSE); #endif}}/* 申請失敗,若使能了回調函數,調用回調通知 */ #if WSF_OS_DIAG == TRUEif (wsfBufDiagCback != NULL){WsfBufDiag_t info;info.type = WSF_BUF_ALLOC_FAILED;info.param.alloc.taskId = WSF_OS_GET_ACTIVE_HANDLER_ID();info.param.alloc.len = len;wsfBufDiagCback(&info);}else{WSF_TRACE_WARN2("WsfBufAlloc failed len:%u - task:%u", len, WSF_OS_GET_ACTIVE_HANDLER_ID());} #elseWSF_TRACE_WARN1("WsfBufAlloc failed len:%u", len); #endif#if WSF_BUF_ALLOC_FAIL_ASSERT == TRUEWSF_ASSERT(FALSE); #endifreturn NULL; }內存釋放
? ? ? ? 從緩沖區的尾部開始查詢,根據每個mempool的起始地址找到被釋放內存在內存池中的位置,將內存重新釋放到內存池中,并重新定義內存頭部信息。
void WsfBufFree(void *pBuf) {wsfBufPool_t *pPool;wsfBufMem_t *p = pBuf;WSF_CS_INIT(cs);/* 判斷指針范圍 */ #if WSF_BUF_FREE_CHECK == TRUEWSF_ASSERT(p >= ((wsfBufPool_t *) wsfBufMem)->pStart);WSF_ASSERT(p < (wsfBufMem_t *)(((uint8_t *) wsfBufMem) + wsfBufMemLen)); #endif/* 從最后一個內存池開始查找 */pPool = (wsfBufPool_t *) wsfBufMem + (wsfBufNumPools - 1);while (pPool >= (wsfBufPool_t *) wsfBufMem){/* 如果在當前內存池的范圍內 */if (p >= pPool->pStart){/* enter critical section */WSF_CS_ENTER(cs);#if WSF_BUF_FREE_CHECK == TRUEWSF_ASSERT(p->free != WSF_BUF_FREE_NUM);p->free = WSF_BUF_FREE_NUM; #endif #if WSF_BUF_STATS == TRUEpPool->numAlloc--; #endif/* 重新將內存塊放入內存池中,并將free指針指向當前的內存位置 */p->pNext = pPool->pFree;pPool->pFree = p;/* exit critical section */WSF_CS_EXIT(cs);WSF_TRACE_FREE2("WsfBufFree len:%u pBuf:%08x", pPool->desc.len, pBuf);return;}/* 不在當前內存池,查找下一個 */pPool--;}/* should never get here */WSF_ASSERT(FALSE);return; }總結
以上是生活随笔為你收集整理的WSF操作系统抽象层学习笔记 (一) ---简介和内存管理的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 鼠标悬浮样式
- 下一篇: avada打开速度慢怎么办?
