TinyOS 模块中 CTP 的功能

 TinyOS 模块化的结构使 CTP 功能分明,便于调用。Estimator 通过接口 LinkEstimator向 Router 提供邻居表的链路信息。Router 选择父节点,维护路由表。Forwarder 调用接口UnicastNameFreeRouting 获得当前的路由信息,然后转发数据到父节点,同时调用LinkEstimator 向 Estimator 反馈是否发送成功。1、链路估计LinkEstimatorP(Estimator)使用两种机制来估计链路质量:周期性的 LEEP 帧和数据包。LEEP帧由一个以指数级随机递增的定时器控制发送。 节点根据 LEEP帧的链路估计(B估计)始于事件 SubReceive.receive。添加LEEP帧头尾,更新邻居表,这些操作在函数 processReceiveMessage 中处理,该函数找到 LEEP 帧发送者对应的邻居表项,更新收到包数记数值和丢包数记数值。其中丢包数就是本次与上次LEEP帧中顺序号字段的差值。当收到包数达到一个固定值时,更新 B估计值。 节点根据数据包的链路估计(D 估计)以发送数据包的成功率来作 ETX 值的估计。Estimator 根据 ACK 判断数据包是否发送成功, 它提供两个命令 txAck和 txNoAck供上层组件调用。txAck 用于告知 Estimator 数据包发送成功,它将对应通信邻居的成功传输数据包计数值和总传输包计数值加

1。当总传输包数达到一个固定值时,更新D 估计值。 当 B估计或D 估计有更新时,均调用函数 updateETX 更新累积 ETX 值。公式如下: 累积ETX = (α*原ETX + (10-α)*newEst)/10 根据动态移动平均原理更新累积 ETX,TinyOS 2.x 中设 α值为 9,因此每次更新时,旧值占 9/10的权重,而新值占 1/10的权重。 

2、路由引擎CtpRoutingEngineP(Router)提供 RootControl 接口允许节点被动态地配置为根节点。Router 维护了一个路由表,里面存放了各邻居节点的路由信息,包括它们当前的父节点和路径 ETX,通过调用接口 LinkEstimator 来取得 LinkEstimatorP 维护的邻居表中信息,然后在定时器 RouteTimer 控制下周期地调用任务 UpdateRouteTask,计算以各个邻居节点为下一跳的路径 ETX,然后选择最小的路径 ETX 与当前路径ETX 比较,若最小 ETX 与当前 ETX 的差值大于一个阈值,则更换父节点,最小路径 ETX对应的邻居节点成为新的父节点。 Router 由定时器 BeaconTimer 控制周期地调用任务 sendBeaconTask 广播自己的路由信息,以路由帧的形式发送。当节点接收到一个邻居节点广播的路由帧后,则触发事件BeaconReceive.receive,然后调用函数routingTableUpdateEntry更新自己的路由表对应表项。  

3、转发引擎CtpForwardingEngineP(Forwarder)提供了顶层接口Packet、Send、Receive、Snoop等供应用程序调用。它管理了一个发送队列,采取先入先出(FIFO)策略。当节点收到来自子节点的数据包时,它首先对数据包 THL 字段加 1,然后检查发送队列和发送缓存确定是否是重复的包,如果是则丢弃它。在确定数据包不是重复包之后,若自身是根节点,则触发receive事件;若不是根节点,则调用函数 forward将数据包送入发送队列,然后检测路由循环,若为路由循环,则通知路由引擎立即广播路由帧,期望发送者收到后更新它的路由表,打破循环。若未检测到路由循环,则立即启动任务 sendTask。sendTask检查位于发送队列头部的包,请求路由信息,并提交到 AM 层进行发送。当发送完毕时,触发事件Subsend.sendDone 检查发送的结果。如果包收到 ACK 确认,则将包从发送队列中移出,若包是本地产生的,则向上触发 sendDone 事件,若包是转发的,则将包释放到消息缓冲区以备检查包重复之用。如果队列中还有剩余的包(比如没有被 ACK 确认的) ,它启动一个随机定时器以重新发布这个任务,若达到最大重传次数还未被确认,则将其移出发送队列并丢弃。 

posted @ 2011-04-22 13:56  仰视45°  阅读(245)  评论(0)    收藏  举报