注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
dan158185的个人空间 https://home.eeworld.com.cn/space-uid-349284.html [收藏] [复制] [分享] [RSS]
日志

CC2538之TinyOS例程实验:7-blip实验 开始zigbee通信

已有 1300 次阅读2016-1-5 16:09 |个人分类:CC2538之TinyOS例程| 通信

前面的6部实验为基本的驱动外设实验,是学习使用基础,实验设备只需要一个cc2538cb节点;从这一部开始实验开始需要两个cc2538cb节点,开始zigbee的无线通信;

此次例程为TinyOS的核心协议栈BLIP,现在的版本是BLIP2.0;大家可以去TinyOS的官网搜索BLIP查看介绍;

如何理解BLIP呢?他的存在意义是什么?我们清楚zigbee到6lowpan的升级,zigbee芯片厂商并没有在硬件部分做6lowpan的压缩解压,这些的完成是纯软件实现的,也就需要一个zigbee(IEEE802.15.4)到6lowpan的转换桥梁,BLIP最重要的功能就是如此;

例程目录tinyos-main-release_tinyos_2_1_2\apps\cc2538_Test\blip\TestLinkLocal

例程为TinyOS的官方固件的代码,以后大家使用会发现我的这些例程基本不修改官方的例程,方便大家的兼容学习;

Makefile文件:

  1. COMPONENT=TestLinkLocalAppC  
  2. CFLAGS += -DUSE_TIMER_HANDLER  
  3. #CFLAGS += -DUSE_UART_HANDLER  
  4. CFLAGS += -DUSE_RF_HANDLER  
  5. CFLAGS += -DNOT_USE_PRINTFC_BUT_USE_PRINT  
  6. PFLAGS += -DIN6_PREFIX=\"fec0::\"  
  7.   
  8. include $(MAKERULES)  
  9. CFLAGS += -DIN6_NO_GLOBAL -DLIB6LOWPAN_HC_VERSION=-1  
  10. CFLAGS += -DPRINTFUART_ENABLED  

BLIP分为两种模式:短地址(16bit)和IEEE地址(8bytes/64bit)模式,默认采用短地址模式;注意如果后期的实验如边界路由,RPL,CoAP实验;通信都需要选择同一种模式;默认是短地址;大家在完成基本的通讯后可以修改Makefile,尝试IEEE地址模式;具体参考TinyOS官网BLIP文档;


TestLinkLocalAppC.nc文件:

  1. /** Test the link-local communication in the blip stack  
  2.  */  
  3. configuration TestLinkLocalAppC {  
  4.   
  5. } implementation {  
  6.   components MainC, LedsC;  
  7.   components TestLinkLocalC;  
  8.   components IPStackC;  
  9.   components new TimerMilliC();  
  10.   components new UdpSocketC();  
  11.   
  12.   TestLinkLocalC.Boot -> MainC;  
  13.   TestLinkLocalC.SplitControl -> IPStackC;  
  14.   TestLinkLocalC.Sock -> UdpSocketC;  
  15.   TestLinkLocalC.Timer -> TimerMilliC;  
  16.   TestLinkLocalC.Leds -> LedsC;  
  17.   
  18.   components StaticIPAddressTosIdC; // Use TOS_NODE_ID in address  
  19.   //components StaticIPAddressC; // Use LocalIeee154 in address  
  20. }  

TestLinkLocalC.nc文件:

  1.  /*******************************************************************  
  2.  *实验5----zigbee blip实验  
  3.  *节点需求数 >= 2  
  4.  *编译命令make cc2538cb blip id.xx (xx为1~65533)  
  5.  ********************************************************************/  
  6. #include "blip_printf.h"  
  7. #include <lib6lowpan/ip.h>  
  8.   
  9. module TestLinkLocalC {  
  10.   uses {  
  11.     interface Boot;  
  12.     interface SplitControl;  
  13.     interface UDP as Sock;  
  14.     interface Timer<TMilli>;  
  15.     interface Leds;  
  16.   }  
  17. } implementation {  
  18.   nx_struct echo_state {  
  19.     nx_int8_t cmd;  
  20.     nx_uint32_t seqno;  
  21.   } m_data;  
  22.   
  23.   enum {  
  24.     SVC_PORT = 10210,  
  25.     CMD_ECHO = 1,  
  26.     CMD_REPLY = 2,  
  27.   };  
  28.      
  29.   /***************************************************  
  30.   *启动事件  
  31.   ****************************************************/  
  32.   event void Boot.booted() {  
  33.     call SplitControl.start();  
  34.     m_data.seqno = 0;  
  35.   }  
  36.   
  37.   event void SplitControl.startDone(error_t e) {  
  38.     /**开启约2秒的周期性定时器(单位毫秒)  Timer**/    
  39.     call Timer.startPeriodic(2048);  
  40.     /**端口绑定************************************/  
  41.     call Sock.bind(SVC_PORT);  
  42.   }  
  43.   
  44.   event void SplitControl.stopDone(error_t e) {}  
  45.   
  46.   /***************************************************  
  47.   *Timer定时时间到事件  
  48.   ****************************************************/  
  49.   event void Timer.fired() {  
  50.     struct sockaddr_in6 dest;  
  51.   
  52.     inet_pton6("ff02::1", &dest.sin6_addr);  
  53.     dest.sin6_port = htons(SVC_PORT);  
  54.       
  55.     m_data.cmd = CMD_ECHO;  
  56.     m_data.seqno ++;  
  57.     /***启动zigbee发送,可以自己修改发送内容和长度*****/  
  58.     call Sock.sendto(&dest, &m_data, sizeof(m_data));  
  59.     call Leds.led0Toggle();  
  60.   }  
  61.   /***************************************************  
  62.   *接收事件  
  63.   ****************************************************/  
  64.   event void Sock.recvfrom(struct sockaddr_in6 *src, void *payload,                                                                 
  65.                            uint16_t len, struct ip6_metadata *meta) {  
  66.     nx_struct echo_state *cmd = payload;  
  67.     printf("TestLinkLocalC: recv from: ");  
  68.     printf_in6addr(&src->sin6_addr);  
  69.     printf("\n");  
  70.   
  71.     if (cmd->cmd == CMD_ECHO) {  
  72.       cmd->cmd = CMD_REPLY;  
  73.       call Sock.sendto(src, payload, len);  
  74.       call Leds.led1Toggle();  
  75.     } else {  
  76.       printf("TestLinkLocalC: reply seqno: %li\n", cmd->seqno);  
  77.       call Leds.led2Toggle();  
  78.     }  
  79.   }  
  80. }  

如果大家对nesC语法还是不熟悉,可以先去看看前6部实验帖子;

nx_struct---等价于struct{}__attribute__ ((packed)) ;是为了兼容平台从8位单片机到32位arm的结构体对齐问题;常常使用的关键字;大家可以使用printf例程

测试一下一个struct里面有unsigned char/long成员后的sizeof打印和nx_struct的sizeof的区别;回忆2530的TinyOS代码,nesC编译成app.c后调用perl脚本对app.c进行转换,其中就必须注释掉了nx_struct生成的__attribute__ ((packed)) ;


call SplitControl.start();这句代码大家可以使用yeti2插件图形化组件去查看代码(见视频),手动的分析代码;或者生成的app.c去查看,完成了什么,BLIP的地址初始化;

这个例程有视频,没记错应该是第十四部视频;

SplitControl.startDone事件开启一个2.048秒的周期性定时器;绑定端口,看到这里大家肯定很熟悉了,Socket的写法

inet_pton6(...)函数,说明一下对于TinyOS我们清楚函数修饰是command,但是由于它支持C的所有特性,所以对于C函数的调用和C语言写法一样,不需要使用call关键字;


call Sock.sendto(&dest, &m_data, sizeof(m_data)); 核心发包部分,也是咱们可以去DIY的,可以DIY内容,接收方解析;比如LED控制,大家可以自己去写;或者和之前的例程结合一下咱们可以发送采集的片内温度,又或者将串口接收的数据发送,做一个聊天QQ;


例程本质在烧写两个节点完成通信,定义

CMD_ECHO = 1,
CMD_REPLY = 2,

发送方发送CMD_ECHO ,接收方解析后发送回CMD_REPLY ;例程简单,不做截图了;


需要注意编译命令从这一部开始因为是多节点的通信,我们需要make的时候添加options了,前六部的编译命令是make cc2538cb

这个例程编译命令为make cc2538cb blip id.xx

如两个节点 我们可以make cc2538cb blip id.1烧写

make cc2538cb blip id.2烧写完成实验;

blip的make选项是通知nesC编译器使用blip栈;

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章