You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 04:12:02