Contiki的NETWORK层间数据传输流程
来源:互联网 发布:java全套视频教程下载 编辑:程序博客网 时间:2024/05/17 22:18
Contiki的NETWORK层之间的数据流路径:
Send:
Network->Mac->Rdc(->Frame802154)->Radio
Recv:
Radio->Rdc(->Frame802154)->Mac->Network
注:在此结构中,802154应该是属于RDC层的,
如果不将RDC算作一层,应该是介于Mac和Radio之间。是Mac层的出口。这也是Contiki的一项重要模块之一。在Contiki中ContikiMAC.c模块实现了RDC功能。论文《The ContikiMAC Radio Duty Cycling Protocol》详细描述了RDC的实现与理论基础。
在Contiki中接收采用事件驱动方式。接收通过一个PThread任务,等待数据到来事件,如果数据到来事件触发,则将数据则取出来。这个事件触发是在Radio的中断中设置的。
即:NETSTACK_RDC.input()的调用一般都是在Radio的一个PThread中,由于在Network.open的时候已经将每一层的回调函数设置完备,所以当接收到数据的时候,通过每一层的回调,将数据传递到Network_Network处,即协议栈的最顶部应用层处理。
以contiki\cpu\avr\radio\rf230bb\rf230bb.c文件为例
rf230_interrupt()函数中判断接收到数据, 调用process_poll(&rf230_process),发送PROCESS_EVENT_POLL事件:
intrf230_interrupt(void){ /* Poll the receive process, unless the stack thinks the radio is off */#if RADIOALWAYSONif (RF230_receive_on) { DEBUGFLOW('+');#endif#if RF230_CONF_TIMESTAMPS interrupt_time = timesynch_time(); interrupt_time_set = 1;#endif /* RF230_CONF_TIMESTAMPS */ process_poll(&rf230_process); rf230_pending = 1; #if RADIOSTATS //TODO:This will double count buffered packets RF230_receivepackets++;#endif RIMESTATS_ADD(llrx);#if RADIOALWAYSON} else { DEBUGFLOW('-'); rxframe[rxframe_head].length=0;}#endif return 1;}
在rf230_process PThread中收到PROCESS_EVENT_POLL,调用NETSTACK_RDC.input()进入数据接收处理流程。最后在Radio文件中,找到了调用process_poll()函数来,poll一个PROCESS_EVENT_POLL。
PROCESS_THREAD(rf230_process, ev, data){ int len; PROCESS_BEGIN(); RF230PROCESSFLAG(99); while(1) { PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); RF230PROCESSFLAG(42); packetbuf_clear(); /* Turn off interrupts to avoid ISR writing to the same buffers we are reading. */ HAL_ENTER_CRITICAL_REGION(); len = rf230_read(packetbuf_dataptr(), PACKETBUF_SIZE); /* Restore interrupts. */ HAL_LEAVE_CRITICAL_REGION(); PRINTF("rf230_read: %u bytes lqi %u\n",len,rf230_last_correlation);#if DEBUG>1 { uint8_t i; unsigned const char * rxdata = packetbuf_dataptr(); PRINTF("0000"); for (i=0;i<len+AUX_LEN;i++) PRINTF(" %02x",rxdata[i]); PRINTF("\n"); }#endif RF230PROCESSFLAG(1); if(len > 0) { packetbuf_set_datalen(len); RF230PROCESSFLAG(2); NETSTACK_RDC.input(); } else {#if RADIOSTATS RF230_receivefail++;#endif } } PROCESS_END();}
附1:
以Contiki中example-mesh.c历程为例:
examples/example-mesh.c/example_mesh_process/mesh_open
send:
(在rime中:
mesh.c/mesh_send()
multihop_send()
unicast_send()
broadcast_send()
abc_send()(abc_send中调用rime_output)
)
rime.c/rime_output()/NETSTACK_MAC.send
nullmac.c/NETSTACK_RDC.send
(NETSTACK_FRAMER.create 生成framer)
nullrdc.c/NET_RADIO.send
nullrdc.c/mac_call_sent_callback 处理发送结束后的状态。
recv:
tf230bb/fr230bb.c/rf230_interrupt 调用process_poll产生PROCESS_EVENT_POLL。
pthread
rf230bb.c/rf230_process任务/NETSTACK_RDC.input
(NETSTACK_FRAMER.parse解析收到的数据帧,是否符合MAC层要求)
nullrdc.c/NETSTACK_MAC.input
nullmac.c/NETSTACK_NETWORK.input 调用rime.c/input()/abc_input()
通过rime协议栈的回调传递给
mesh.c/data_packet_received()此函数回调应用层的接收处理函数
example-mesh.c/example_recv()处理接收数据。
附2:
stunicast.c中
对于重发的处理,由在发送过程中设置timer如果在规定的时间内,如果没有数据返回则通过timer调用回调处理函数,如果有数据返回则在在recv_from_stunicast()调用stunicast_cancel()取消timer,避免调用回调。
在Contiki中,数据的发送与接收分别使用一个任务,这样可以避免之间的冲突问题。
NETWORK协议栈层之间的数据交互,通过buf来实现。这一点与Linux的sk_buff很像,所以导致了很多不必要的内存拷贝,这也是为什么Contiki内存占用很小的原因之一。
0 0
- Contiki的NETWORK层间数据传输流程
- Contiki-NETWORK层:Rime与uIPv6(6loWPAN)的关系
- 数据链路层的数据传输
- 数据传输流程
- contiki -2.6中UDP数据包的发送流程
- contiki 中数据包的接收与发送流程
- contiki 中数据包的接收与发送流程
- 运输层可靠数据传输的原理
- 数据链路层 数据传输的问题
- 计算机网络运输层可靠数据传输的原理
- Stagefright中OMX的数据传输流程
- 登录界面的数据传输流程 AJax
- 数据传输协议的学习(应用层、传输层)
- Contiki OS 数据包发送流程
- Contiki中MAC层与RDC层
- JESD204B_SystemC_module 数据传输层(3)
- Messenger层数据传输协议
- Contiki:关于MAC和RDC层的关系、作用及其实现
- Android JSON 出现Caused by: java.lang.ClassNotFoundException: net.sf.json.JSONObject;
- 面象对象 自学一
- MMU工作原理
- sed用法——看shell脚本一页的内容,居然详细有这么多种用法。路漫漫~
- 【Android】神奇的android:clipChildren属性
- Contiki的NETWORK层间数据传输流程
- 关于自定义控件
- 1、后盾PHP豆瓣教程学习笔记:头部布局分析、切片技术、选择器命名规范
- java 插入排序
- Eclipse 安装最新SVN插件
- oracle修改scott密码与解锁的方法
- NSURLRequestCachePolicy 缓存策略
- 一台电脑双网卡同时上网
- ios面试攻略