一、简介

WSF(wireless software foundation)是对操作系统的一个简单的封装,提供对操作系统的简单编程,提供简单的系统服务

功能简介:

  1. 事件、消息传递和处理。
  2. 定时器功能。
  3. 队列和缓存管理功能。
  4. 可编程的数据类型。
  5. 关键部分和任务锁定。
  6. 调试输出和断言诊断。
  7. 用于加密和随机数生成的安全接口

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操作系统抽象层学习笔记 (一) ---简介和内存管理相关推荐

  1. WSF操作系统抽象层学习笔记 (五)---事件处理及运行方式

    事件处理 事件管理会创建一个OS的事件,用于进行WSF无运行需求时任务的阻塞. //事件管理结构 typedef struct {uint16_t param; //参数uint8_t event; ...

  2. WSF操作系统抽象层学习笔记(三)---消息列队

    消息 WSF的消息服务用于传递消息到对应的事件处理句柄. 实现机制和使用方法 基于内存管理,从内存中申请sizeof(wsfMsg_t) + 消息长度的内存.添加头部描述,返回给申请者除去头部的指针位 ...

  3. WSF操作系统抽象层学习笔记(四)---定时器

    定时器 定时器的实现方式: 使用OS自带的定时器模块,建立一个定时器,定时间隔为自定义TICKS,定时器的回调函数中设置定时器到时的事件. 定时器模块定义了一个定时器的链表,用于定时器的管理. 操作定 ...

  4. WSF操作系统抽象层学习笔记(二)---列队(单向链表)

    队列 队列的管理使用单向链表结构.个人认为使用双向链表更易于维护. 注意: 每个以列队为基础管理的结构都必须将第一个元素设定为列队元件的指针. 进行列队操作时都需要关闭任务调度,防止多线程操作的信息同 ...

  5. Linux操作系统学习笔记(十)内存管理之内存映射

    一. 前言   本文为内存部分最后一篇,介绍内存映射.内存映射不仅是物理内存和虚拟内存间的映射,也包括将文件中的内容映射到虚拟内存空间.这个时候,访问内存空间就能够访问到文件里面的数据.而仅有物理内存 ...

  6. JVM学习笔记(三)------内存管理和垃圾回收

    JVM内存组成结构 JVM栈由堆.栈.本地方法栈.方法区等部分组成,结构图如下所示: 1)堆 所有通过new创建的对象的内存都在堆中分配,其大小可以通过-Xmx和-Xms来控制.堆被划分为新生代和旧生 ...

  7. Objective-C基础教程学习笔记(九)内存管理

    每个对象都维护一个保留计数器.对象被创建时,其保留计数器值1:对象被保留时,保留计数器值加1:对象被释放时,保留计数器值减1:当保留计数器值归0时,对象被销毁.在销毁对象时,首先调用对象的deallo ...

  8. C++学习笔记-DLL中动态内存管理

    动态内存管理 在dll中malloc的内存,必须在dll中free 注:这是由Windows自己的特点决定! 如果 a 编译成静态库,有下面两种解决方法: 1.b.dll 和 c.dll 使用同一个款 ...

  9. JVM学习笔记(四)------内存调优

    首先需要注意的是在对JVM内存调优的时候不能只看操作系统级别Java进程所占用的内存,这个数值不能准确的反应堆内存的真实占用情况,因为GC过后这个值是不会变化的,因此内存调优的时候要更多地使用JDK提 ...

最新文章

  1. 掌握这35 个小细节,助你有效提升 Java 代码的执行效率!
  2. 重庆大学光电工程学院 贾旭滨 对 “句柄” “指针” 有下面的描述(AfxGetMainWnd GetSafeHwnd() AfxGetAppName() AfxGetThread)...
  3. js date转string_JS之你到底是什么类型?
  4. c语言作业答案N个公约数公倍数,c语言程序题,输入两个正整数m和n,求其最大公约数和最小公倍数。...
  5. Unix环境高级编程学习笔记(五)
  6. 使用自动补全功能- MATLAB
  7. [BZOJ1030][JSOI2007]文本生成器
  8. mysql学习day02
  9. 解决Debug certificate expired的问题 - 转
  10. 【LeetCode】【字符串】题号:*12. 整数转罗马数字
  11. 微信小程序转码机器人
  12. cartographer基于3d地图的纯定位模式
  13. Web渗透测试工程师:入门知识
  14. 怎么使用播放麦克风输入的音频呢
  15. 读书笔记(六)--成交
  16. 全国大学的ftp及部分免费ftp地址
  17. 微信小程序 车轮之 滑动删除
  18. windows下mysql免安装配置
  19. 导图解文 从梦想到财富(02)你拥有最宝贵的财富是什么?
  20. Vue 项目中实现的微信、微博、QQ空间分享功能(亲测有效)

热门文章

  1. 威联通nas百度网盘
  2. 【K8S运维知识汇总】第4天7: dashboard小彩蛋–heapster
  3. UnlockerX macOS蓝牙近距离解锁软件
  4. TiKV源码略读-Server Start
  5. 保安日记Hadoop 8.29
  6. git pull --rebase PK git pull
  7. BERT论文翻译:用于语言理解的深度双向Transformer的预训练
  8. JLink原厂固件集合共计52个
  9. 零基础学Python,机械成功转行,血泪干货的总结
  10. org.apache.jasper.JasperException: The absolute uri: http://java.sun.com/jsp/jstl/core