美文网首页
Contiki memb

Contiki memb

作者: LittleEndian | 来源:发表于2018-08-08 23:30 被阅读0次

Contiki提供了三种内存分配机制:memb机制、mmem机制和标准C语言库中的堆内存分配机制。memb最常使用,mmem极少使用,而使用堆内存分配是一件危险的事情。这篇日志讲解memb

memb库提供了一系列内存块管理函数。内存块在静态内存区中被分配为具有固定尺寸的数组。
先把里面的例子搬出来

 #include "contiki.h"
 #include "lib/memb.h"

struct connection {
   int socket;
 };
 MEMB(connections, struct connection, 16);

struct connection *
open_connection(int socket)
 {
   struct connection *conn;

   conn = memb_alloc(&connections);
   if(conn == NULL) {
     return NULL;
   }
   conn->socket = socket;
   return conn;
 }

 void
 close_connection(struct connection *conn)
 {
   memb_free(&connections, conn);
 }

先来看看MEMB()宏源码:

#define MEMB(name, structure, num)\ 
        static char CC_CONCAT(name,_memb_count)[num]; \
        static structure CC_CONCAT(name,_memb_mem)[num]; \
        static struct memb name = {sizeof(structure), num, \
                        CC_CONCAT(name,_memb_count), \
                        (void *) CC_CONCAT(name,_memb_mem)}
struct memb {
    unsigned short size;
    //num表示可以存放的结构体个数,由于用short声明,表明最多只能控制127个结构体
    unsigned short num;
    char *count;
    void *mem;
};

先借用上例中的代码把这个宏展开来看看:

struct connection {
   int socket;
 };
 MEMB(connections, struct connection, 16);

展开后的代码:

//char数组,估计用于指向实际内存地址 
static char connections_memb_count[16];
//结构体数组,结构体实际存放的地方 
static struct connection connections_memb_mem[16];
static struct memb connections =
{
  sizeof(struct connection), //这里可以假设为2,一个int的大小 
  16, //结构体总个数 
  connections_memb_count, //指向指针数组
  (void *)connections_memb_mem //指向结构体实际存放的地方
 }

这个东西讲出来挺拗口,来张图就一目了然了:

内存分配---memb

小结一下:有一个结构体connection,我们需要分配一段内存存放16个connection。使用MEMB实际上已经分配了这16个空间了,需要注意的是static关键字表明,它们被分配到了静态内存区。那么现在还有一个疑问,connections_memb_count[16]里面存放什么东西?有何用,得继续往下研究。

下面来看下memb_init原型:

void memb_init(struct memb *m)
{ 
  //把char数组里面的元素全部初始化为0
  memset(m->count, 0, m->num);
  //把结构体所占内存全部初始化为0    
  memset(m->mem, 0, m->size * m->num);
}

memset()函数是C语言标准库函数,memb_init函数就是把所占内存全部清0。

memb_alloc原型:

void *memb_alloc(struct memb *m)
{
      int i;
      for(i = 0; i < m->num; ++i)
      {
            if(m->count[i] == 0)   //为0表示此空间并未使用
           {
                  ++(m->count[i]); //等同于m->count[i]=1;                  
             //返回分配的结构体空间首地址                  
             return (void *)((char *)m->mem + (i * m->size));
            }
      }
      /* 能走到这里说明没有多余空间,分配失败了,标志为返回NULL */
      return NULL;
}

现在终于明白connections_memb_count[16]的作用了,可以把它理解为标志位。某段结构体空间已用则标上1,某段结构体空间空闲则标上0。如果象C#那样有BitArray这样的数据结构,完全可以用一个位来存放这样的标志,现在用8个位存放一个标志,有点浪费空间了。不过如果用位运算,访问的时候需要另外声明函数返回标志,有些麻烦。

char[16]实际上和struct[16]一一对应,在char[16]中只要找到一个为0的元素,就说明它所对应的struct空间空闲,这时返回struct空间首地址作为memb_alloc函数的返回值。

memb_free原型:

char memb_free(struct memb *m, void *ptr)
{
      int i;
      char *ptr2;
      ptr2 = (char *)m->mem;
      for(i = 0; i < m->num; ++i)
      {
            if(ptr2 == (char *)ptr)   //找到释放的空间             
            {
                  if(m->count[i] > 0)
                  {
                        --(m->count[i]); //设标志位为0 
                 }
                  return m->count[i]; //返回0             
            }
            ptr2 += m->size; //指向下一块空间      
      }
      return -1; //没找到相应空间返回-1 
}

memb_free用于释放空间,实际上只是把相应的标志位设为0,结构体空间原来的数据并未清除,这是不是有些危险?所以在使用memb的时候一定要注意,里面的结构体每个成员在使用前必须要全部赋值,否则会有出错的可能。

**int memb_inmemb(struct memb m, void ptr)

求证一个指针是否在memb之中

*int memb_numfree(struct memb m)

返回memb的空余空间的个数

最后来个总结吧,memb这东西我个人感觉更象是一个线程池之类的东西。例如我们在写程序时,需要多次同时用到一个结构体类型,每个结构体每次用的时间都不确定,这篇文章开头用的socket就是个很典型的例子。这时就可以使用memb进行统一管理。memb的作用可以作个比喻:学校有个体育馆,里面有6个羽毛球场地,学生要打羽毛球就必须到体育馆去,打完球后,空出来的场地可以让别的同学继续打,如果没有场地了则必须等到有人打完后才能轮到你。

相关文章

  • Contiki memb

    Contiki提供了三种内存分配机制:memb机制、mmem机制和标准C语言库中的堆内存分配机制。memb最常使用...

  • Contiki-NG中定制MODULE

    开发基于Contiki-NG的应用,通常需要编写特有的服务或者功能或者模块。 首先介绍一下Contiki-NG的基...

  • consul

    agent---An agent is the long running daemon on every memb...

  • contiki--process详解

    Contiki内核结构 嵌入式系统可以看作是一个运行着死循环主函数系统,Contiki内核是基于事件驱动的,系统运...

  • contiki协议总结

    之前做传感网一直在tinyOS系统下,contiki只是稍微了解,近来实验室突然接到contiki下的一个项目,所...

  • BEC listen and translation exerc

    能听懂自己的录音,说明发音还行,可惜听不懂。。。 Another problem is that the memb...

  • Contiki边界路由

    导语 边界路由器位于网络的边沿,可以通过使用其内建的网络接口与外界交流,这些网络接口如wifi,以太网,串口等。 ...

  • Python 报错:Module xx has no xx m

    问题描述 使用 visual studio code,引用时报错 Module xx has no xx memb...

  • contiki--etimer详解

    Contiki内核是基于事件驱动和Protothreads机制,事件既可以是外部事件(比如按键,数据到达),也可以...

  • Contiki学习笔记(一)

    笔者初步学习Contiki,本文暂只堆砌学习过程中做的笔记,一段时间后有所积累再做整理,方便大家参考阅读。 线程 ...

网友评论

      本文标题:Contiki memb

      本文链接:https://www.haomeiwen.com/subject/eppfbftx.html