先想到哪,写到哪。以后再整理。
================
网络层的主要任务是消息转发(Forwarding),转发的基础是路由(Routing)。
转发:节点收到消息后,若消息不是给本节点的,根据消息中的目的地址(网络层)和路由表决定下一跳的对端节点和发送端口,然后将消息送往链路层。
路由:按路由算法和路由协议更新路由表。
在网络层,多种原因决定需要对消息进行缓冲和排队:
1、待发送消息的消息来源:有从RF接口收到的(链路层上传),有从本节点应用层下发的;
2、路由未知:在某些动态路由机制中,如果目的地址没有在路由表中,则发起路由发现(Route Discovery),在此过程中须缓存消息,等待路由发现结果;
3、处理速度:网络层对消息的处理过程变复杂,不适合全部在消息接收中断服务程序内完成,所以需要对刚收到的消息进行缓存;
实现过程中包含两个消息队列,接收队列和发送队列。
接收1:链路层消息接收中断服务程序调用网络层的消息处理回调函数,将收到的消息放入接收队列中,不作处理立即返回。
其它方式1:回调函数对目的地址进行判断,如果是给本节点应用层的消息,调用应用提供的回调函数,否则将消息加入接收队列中。(这种方式对本地消息的处理时延最小)
接收2:主程序循环执行协议栈处理函数,其中对接收队列中的消息进行分析:
* 如果是给网络层的命令消息,执行相应处理;
* 如果是给应用层的本地消息,调用应用提供的回调函数;
* 如果可以确定下一跳(链路层)的对端节点地址,将消息转入发送队列;
* 如果不能确定,可以:1)丢弃;2)转发给父节点;3)启动路由发现程序;
发送1:应用层调用消息发送API,如果可以确定下一跳的对端节点地址,送入发送队列;否则1)返回错误;2)转发给父节点;3)送入接收队列,启动路由发现程序;
发送2:由网络层命令处理过程产生的消息,送入发送队列;
发送3:路由发现程序在收到消息建立路由后,扫描接收队列中的消息,将等待结果的消息送入发送队列;
发送4:协议栈处理函数中的一个子功能是判断芯片是否可以发送消息,若可则从发送队列取消息,调用链路层消息发送函数进行发送。
消息缓冲机制
消息发送队列和接收队列中保存的只是消息的指针和相关属性及标志字段,消息体本身保存在消息缓冲区。
从链路层接收到的消息指针指向的是链路层代码中的一个消息缓冲区,当回调函数返回后其内容会被新消息覆盖,因此在回调函数中需要将收到的消息内容复制到网络层的消息缓冲区中。若该消息提供给应用层使用,则在应用提供的回调函数返回后,会释放该消息(将来如果有特定应用是需要转发该消息的,可通过回调函数的返回参数或其它手段通知网络层对消息进行处理)。若该消息是需要转发的消息,则由转发程序处理,修改其参数送入发送队列。如果是网络层指令消息,则由相应程序在处理完成后释放。
发送4的处理过程是根据发送队列将缓冲区的消息数据送到链路层,链路层会将消息数据压入芯片的FIFO,然后发送。该过程不需要对消息内容进行复制。发送4处理完成后,将缓冲区中的消息数据释放。
消息缓冲区的内存分配可以采用以字节为单位的动态内存分配方式(类似于malloc和free,利用率高,但是分配速度不平均,要进行碎片整理),如果空间足够的话也可以采用固定长度消息数组的方式(利用率低,操作速度快,简单)。
存在缓冲队列,自然就会有队列满的可能性,尤其在WSN芯片内存十分有限的情形下。
当消息缓冲区满,有新消息来的时候怎么办?
注意到消息接收申请缓冲区的操作是在接收中断服务程序线程中,发送消息申请缓冲区的操作是在主程序线程中,释放缓冲区的操作(发送完成、收到的消息处理完成)是在主程序线程中。需要分析是否有可能产生并发冲突。
消息在重要程度上有区别吗?看看消息的分类:
* 给本地应用的用户消息;
* 本地应用发送的用户消息;
* 跟用户有关的命令消息;
* 网管相关的命令消息;
* 转发给其它节点的用户消息;
* 等待路由发现的用户消息;
* 路由相关的命令消息;
用户447635 2013-8-22 16:13