Contiki常用数据结构

来源:互联网 发布:天猫魔盒看美剧的软件 编辑:程序博客网 时间:2024/05/10 17:21

Contiki常用数据结构

1.     Packetbuf

得益于Contiki进程是非抢占的特性,Rime缓冲区将接收与发送的数据包存储在一个单一的缓冲区packetbuf,它的管理结构如图1.1所示,结合该图与源代码packetbuf.c可以很好地理解和使用缓冲区。

特别注意packetbufptr,该指针可以指向外部引用的内存,这样就带来很大的灵活性(如:实现“零拷贝”,访问只读数据区等)。

1.1  Rime缓冲区管理示意图

为了有效利用底层MAC和链接层协议,rime buffer使用数据包属性取代数据包头,即图1.2所示的packetbuf_attrs。另外,记录了接收与发送数据包的地址信息,即packetbuf_addrs

1.2  Rime数据包属性与地址示意图

2.     RimeQueueBuf

上节描述可知Packetbuf简单实用,但它只能保存一个数据包,如果协议需要缓存发送数据包(例如:排队发送)就需要队列性质的数据结构。图2.1所示,左图存储“非引用类型”的packetbuf,包括:数据包、属性和地址;右图存储“引用类型”的packetbuf,包括:数据包头部、引用内存的指针。

2.1非引用和引用类型的queuebuf数据结构

Contiki内存管理是基于预先分配,queuebuf的大小由以下宏定义控制:QUEUEBUF_NUM对应struct queuebuf的个数、QUEUEBUF_RAM_NUM对应struct queuebuf_data的个数、QUEUEBUF_REF_NUM对应struct queuebuf_ref的个数,一般说来前2个宏定义个数相等。

2.2可配置个数的queuebuf

RimeQueueBuf保存与恢复“非引用内存”packetbuf的原理如图2.3所示。

2.3保存与恢复“非引用内存”packetbuf

RimeQueueBuf保存与恢复“引用内存”的packetbuf的原理如图2.4所示。

2.4保存与恢复引用内存

3.     LIST

Contiki遵循Linux的“万能链表”设计思想,即LIST数据结构。只要将实际链表对象的第一个域配置成void *next,即可使用LIST的常见操作:开辟链表头空间、插入节点和删除节点,即图3.1所示。

3.1  LIST常见操作

4.     MEMB

Contiki的内存分配采用预先设置的方式,当申明一块内存MEMB(name, structure, num)时,即开辟如图4.1所示的内存空间,其中name_memb_count[]记录该内存块引用的次数,name_memb_mem[]num个大小为sizeof(structure)的静态内存。

4.1开辟内存空间

4.2分配内存

当执行memb_alloc()成功分配内存时,该内存的引用次数加一,返回该内存的指针,如图4.2所示。回收内存是分配内存的逆过程,memb_free()会将该内存的引用次数减一。

4.3回收内存

5.     ctimer

ctimer的主要用途是为contiki的协议栈提供定时器,从图5.1所示的ctimer数据结构可知,它的定时功能是通过etimer来实现的。

5.1  ctimer数据结构

当用户调用ctimer_set()函数插入一个ctimer后,ctimer_list结构如图5.2所示,当该定时器到期后会被系统自动从链表中摘除,即图5.3效果,如果用户需要继续定时则要再次调用ctimer_set()添加该定时器。

5.2添加一个ctimer定时器

5.3  ctimer定时器到期后从链表中摘除

5.4显示了一个ctimer定时器的调用时序,当call_process调用ctimer_set()后,经过interval时长后etimer_process检测到该定时器超时并发送消息给ctimer_processctimer_process调用该定时器注册的回调函数。这里有一个小技巧:在回调函数执行前会将process_current赋值为ctimer_i->p,这样做保持了进程轨迹的一致性。

5.4  ctimer定时器调用时序

6.     etimer

6.1显示了一个etimer定时器插入前、插入后和超时调用后,这三种情况下etimer链表数据结构。很容易看出,当一个etimer超时并处理后它将从链表中摘除,如果用户需要再次使用该定时器则需要继续调用etimer_set()函数。

6.1  etimer链表结构

Etimer的调用时序如图6.2所示,call_process调用etimer_set()添加一个etimer定时器后,经过interval时长该定时器超时,这里etimer_processcall_process发送超时消息,当call_process接收到超时消息后执行对应的逻辑动作。

6.2  etimer调用时序


免费快速下载链接:http://www.rimelink.com/nd.jsp?id=31&_np=105_315 

0 0
原创粉丝点击