WSF操作系统抽象层学习笔记 (一) ---简介和内存管理

一、简介

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 == TRUE
  uint32_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 == TRUE
    pPool->numAlloc = 0;
    pPool->maxAlloc = 0;
    pPool->maxReqLen = 0;
#endif

    WSF_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 == TRUE
        pBuf->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 == TRUE
        if (++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 == TRUE
      WSF_ASSERT(FALSE);
#endif
    }
  }

  /* 申请失败,若使能了回调函数,调用回调通知 */
#if WSF_OS_DIAG == TRUE
  if (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());
  }
#else
  WSF_TRACE_WARN1("WsfBufAlloc failed len:%u", len);
#endif

#if WSF_BUF_ALLOC_FAIL_ASSERT == TRUE
  WSF_ASSERT(FALSE);
#endif

  return NULL;
}

内存释放

        从缓冲区的尾部开始查询,根据每个mempool的起始地址找到被释放内存在内存池中的位置,将内存重新释放到内存池中,并重新定义内存头部信息。

void WsfBufFree(void *pBuf)
{
  wsfBufPool_t  *pPool;
  wsfBufMem_t   *p = pBuf;

  WSF_CS_INIT(cs);

  /* 判断指针范围 */
#if WSF_BUF_FREE_CHECK == TRUE
  WSF_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 == TRUE
      WSF_ASSERT(p->free != WSF_BUF_FREE_NUM);
      p->free = WSF_BUF_FREE_NUM;
#endif
#if WSF_BUF_STATS == TRUE
      pPool->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;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值