SNOS是实验室的一个项目,传感器节点的微操作系统。周一软件项目验收,周末突击加班。。主要的验收指标是20个节点自组织组网,以及多跳的UDP6?
协议栈最初采用最简单的路由策略,事实证明“简单”确实非常坑爹:
- 源节点Flooding路由包:
- 其他节点收到路由包,进行一系列逻辑判断,即如果是新的或者原路由信息超期,则更新本节点并reFlooding。
这个策略简单,容易实现,并且在节点数目较少的情况下,容易达到全网路由同步,但当节点数目较多时,容易出现如下问题:
- 当通信链路不对称时,该路由策略失效;
- 节点数目较多时,路由开销太大。
原本以为,对一个演示性的小网络,这个路由算法足够了,但下面的问题几乎让人抓狂了:
节点收到数据包,统一产生硬件中断,并逐层调用到协议栈上层;这个策略本身无可厚非,但跟上述路由策略结合就出现了很大的问题(当然,其实是底层的发送过程写的坑爹):
节点收到广播的路由包,一般需要进行reFlooding,并且,这个过程实际是在中断处理函数中进行的;同时,在reFlooding的时候,一般很多个节点都在reFlooding,考虑到Mac层是CSMA/CA,那么就需要在中断中进行回退和等待!这样,节点基本就限于死亡了。
如何来解决这个问题呢?主要的方法有二:
- 借鉴PC上的非阻塞式处理方式,收到数据包后扔到一个队列,然后由Timer经过调度来处理这些数据包。我个人相信这是王道。
- 换个路由策略吧。。。
晚上8点,开始考虑更换路由算法。很多Paper中的算法基本不能使用,只有4K Ram,情何以堪~~ 最后还是决定借鉴下Internet的RIP协议,也很简单,很符合小规模网络、跳数少的网络使用。
- 节点广播已知的各节点hops array;
- 收到广播包后,不立即reBroadcast,而是在下一个定时时刻广播;
- 可选的,可以根据邻居节点发送的路由包情况,判断是否为单向链路,也解决了硬件收发不对称带来的问题。
这样,即便在中断内部处理,也稳定了很多,基本不会出现节点跑死的情况。
重新写了网关的循环数组,更新UDP6等等东西,耗费了大半个晚上。
最终的效果还比较让人满意,只是功率设的太大,拓扑不是很给力,基本上都是单跳的方式。。
唯一的后遗症是:一晚上通宵,眼睛血丝不少。


