如何在Contiki网络的不同节点间实现共享数据的读写操作?
核心问题
- Contiki中的每个节点(含COOJA仿真节点、实际硬件节点)都拥有完全独立的内存地址空间,不存在跨节点的内存共享能力,指针仅在当前节点内部有效,你尝试用指针跨节点传值的思路本身不可行。你目前看到的现象是每个节点各自维护了独立的变量副本,自然不会同步更新,这和protothreads无关,是节点运行架构的特性。
- 你的sink节点代码存在野指针问题:
sendNumber函数中int *val未初始化就直接赋值*val = 12,属于非法内存访问,运行结果属于未定义行为,随时可能触发崩溃。
你看到其他节点display输出1,是因为这些节点的ptr默认指向了本地初始值为1的内存区域,从未接收到sink节点的更新值。
实现方案
要实现全节点共享可读写的整型变量,需要通过网络广播同步所有节点的本地变量副本,可用Contiki自带的Rime广播模块实现,示例代码如下:
公共定义(所有节点都引用)
// 共享变量的初始值 #define INIT_SHARED_VAL 1 // 广播通道号 #define BROADCAST_CHANNEL 128 // 广播数据包结构 struct broadcast_msg { int new_val; };
所有节点通用逻辑(sender和sink都包含)
#include "contiki.h" #include "net/rime/broadcast.h" // 本地存储的共享变量副本 int shared_val = INIT_SHARED_VAL; static struct broadcast_conn bc; // 收到广播后的回调函数,更新本地共享值 static void bc_recv(struct broadcast_conn *c, const linkaddr_t *from) { struct broadcast_msg *msg = packetbuf_dataptr(); shared_val = msg->new_val; printf("共享值已更新为:%d\n", shared_val); } static const struct broadcast_callbacks bc_cb = {bc_recv}; /* 节点初始化时注册广播回调 */ // 在你的节点PROCESS启动时调用以下代码: broadcast_open(&bc, BROADCAST_CHANNEL, &bc_cb);
更新共享值的通用接口(所有节点都可调用)
void update_shared_val(int new_val) { struct broadcast_msg msg; // 先更新本地副本 shared_val = new_val; // 封装广播包发送到全网 msg.new_val = new_val; packetbuf_copyfrom(&msg, sizeof(msg)); broadcast_send(&bc); } // 读取共享值的接口 int get_shared_val() { return shared_val; }
sink节点触发更新的逻辑
void sendNumber() { // 直接调用更新接口即可同步全节点 update_shared_val(12); }
原display逻辑替换为
void display() { printf("the number is %d ", get_shared_val()); }
内容的提问来源于stack exchange,提问作者Ron Nen
相关产品推荐
相关产品推荐

