目录
题目
赛题
格式说明
计分规则
评分步骤
题目解析
右上角节点代码解析
其余11个节点代码解析
比赛时的思考
具体解析
核心代码
右上角节点代码
其余11个节点代码
正文
题目
赛题
数据广播节点—>
如图所示,平台节点不安装天线,12 个节点 ID 号随机,左上角的节点作为数据广播节
点,每隔 1 秒往外重复广播负载为 1 个字节的数据包(该广播代码由组委会提供),参赛队
需编写其他 11 个节点的代码,在考虑多跳传输的情况下,获取到该广播包的负载,最终 11
个节点通过 printf 语句将该负载打印到平台,从而表明任务的完成。
1) 11 个节点只允许编写一份代码,代码中可通过宏 TOS_NODE_ID 获取自身 ID 号;
2)本题开销指的是除左上角节点外的另外 11 个节点无线通信发送数据包的总和;
3)左上角节点代码由组委会提供,参赛队可自行查阅和修改负载内容(不可修改格式)
以验证代码;
4)左上角节点烧录完成 10 秒后停止评分,参赛队需在 10 秒内完成数据包的发送;
5)广播的数据为同一数据,参赛队无需多次接收并转发,多次转发时需考虑其造成的
网络开销;
6)参赛队编写的和结果无关的 printf 调试语句,必须在最终代码中注释掉,以免造成
最终结果输出错误。
格式说明
1)左上角广播的数据包的负载为一个字节,示例如下:
00 FF FF 00 00 01 00 06 12
前 8 个字节 00 FF FF 00 00 01 00 06 固定,后 1 个字节 12 为随机的某字节,参赛队
需编写代码接收此结构的数据包;
2) Printf 输出的格式为:标志位(Data)+1 个字节负载(十进制,并以空格隔开,结
尾应加上换行符“In”以表明语句的完结)
广播数据包:00 FF FF 00 00 01 00 06 12
正确的输出结果:Data 18
注意:输出的结果应完整正确,数据必须以十进制输出,例如上述示例的 0x12 的
十进制为 18;
3)每个节点的结果可重复输出,计分时只会以每个节点最后一组含有标志位 Data 的
行作为判分依据;
计分规则
本赛题满分为 30 分,其中正确性得分 22 分,开销得分 8分;
1)正确性得分:共 22 分,正确性得分不少于 14 分才可以获得开销分;
正确性得分 (m≥7)
m 为 11 个节点正确输出结果的数量
2)开销得分:共 8 分,开销超过 50 得分 0 分,小于 50 按如下公式如下:
开销得分 (0<n<50)
n 为 11 个节点的开销总和
评分步骤
1)烧录 Null程序,清空节点状态;
2)编译烧录参赛队代码(参赛队的 11 个节点);
3)对 11 个节点进行 printf 监听;
4)烧录左上角数据广播节点代码,烧录完成后,开始计时;
5) 10 秒后停止监听,核实各节点的输出结果和开销量,计算出得分;
题目解析
由题目可知,右上角的节点是由主委会给出的,但因为我们这是平时练习,所以右上角节点的无线发送数据的代码,也由我们自己来写吧。
右上角节点代码解析
由题意可知,右上角这个节点,是个工具节点,其目的就是给其余11个节点每隔一秒发一个固定数据包,所以我们只需要用到无线通信的发包函数就可,再用一个定时器每隔1000毫秒调用以下无线发包函数,就完成啦。
其余11个节点代码解析
比赛时的思考
这11个节点的代码也很简单,但我们比赛更要注意分数,在每个节点都完成任务的同时,要使发包数达到最小,才算胜利。而这道题目,这11个节点根本不用发包,也能完成任务。
具体解析
只需要用到无线接收函数即可。先定义一个与右上角发送数据包同类型的结构体,这个结构体在收包的时候进行判断是否是我们需要的数据包,判断成功后,printf打印出来即可。这里不用限制打印次数,反正发包数还是为0。
核心代码
右上角节点代码
event void MilliTimer.fired() { if (locked) { //锁机制的实现AMSend.sendDone判断发包正确后,会解除锁机制 return; } else { radio_count_msg_t* rcm = (radio_count_msg_t*)call Packet.getPayload(&packet, sizeof(radio_count_msg_t)); //rcm指向packet的负载 if (rcm == NULL) { return; } //如果负载不为空,就将counter的值赋值给rcm->counter rcm->counter = 0x16; //定义发包的内容 //AM_BROADCAST_ADDR:无线通信中,代表广播 //如果改成 0x01,那就是向1号节点发送单播 if (call AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(radio_count_msg_t)) == SUCCESS) { //无线发包 locked = TRUE; //打开锁机制 ,锁住后,转到senddone } } }
其余11个节点代码
event message_t* Receive.receive(message_t* bufPtr, void* payload, uint8_t len) { //节点接收数据,无线收包 if (len != sizeof(radio_count_msg_t)) {return bufPtr;} //判断是否是我想要的包 else { //如果是我想要的包 radio_count_msg_t* rcm = (radio_count_msg_t*)payload; //rcm指向包的负载 //如果rcm->counter == 1,那么 1 & 0x1 == 0x1,所以LED0会亮,以下同理 printf("Data %d",rcm->counter); printfflush(); return bufPtr; } }