航ರ_ರ · 2022年11月13日 · 江苏

【GD32F427开发板试用】OpenWSN无线协议栈移植与CPS系统搭建

本篇文章主要介绍兆易创新GD32F427开发板上移植OpenWSN无线协议以及搭建CPS系统。

openwsn

物联网实现了巨大的应用,如能源感知住宅或实时资产跟踪。随着这些网络越来越成熟,标准化机构已经开始对这些微型设备网络的通信方式进行标准化。
2546411.png

OpenWSN项目的目标是在各种软件和硬件平台上提供基于物联网标准的完整协议栈的开源实现,这种实现可以帮助学术界和工业界验证这些标准对物联网的适用性,使这些网络真正无处不在。

6TiSCH

OpenWSN首次完整的实现6TiSCH协议标准,为IEEE802.15.4e(6TiSCH)工作组(WG)在IEEE802.15.4 TSCH链路层之上进行控制平面和IP层适配的标准化工作提供了借鉴。与主流的无线通信协议(例如WiFi,zigbee,Bluetooth)不同,6TiSCH的MAC层采用TSCH(Time SlottedChannel Hopping )协议标准,所有的通信活动采用时间触发方式依次执行,在保证实时通信的同时,确保所有的通信操作均可借助时间线进行溯源,同时允许使用者自定义任务执行序列,TSCH协议的可靠性和确定性已经在wirelessHART协议中得到验证,这也预示着该协议标准将能够为时间敏感的工业网络提供新的解决思路。
捕获.JPG
这些协议包括最低配置的网络自组机制、支持安全连接过程的协商机制、分布式网络调度管理方法。在网络层,6LoWPAN框架提供无状态报头压缩协议(RFC4944)、上下文报头压缩(RFC6282、RFC8025和RFC8138)以及通过RFC4944和IETF实现的报文分段机制。由RFC8505提供邻居发现。低功耗网络路由协议(RPL)按照目标函数(RFC6552)以多跳拓扑组织网络。该套件还定义了传输路由信息(RFC6553)和启用向下源路由(RFC6654)的协议扩展。6TiSCH提供了一种机制,通过实现链路层拓扑与路由拓扑相匹配,使节点能够与其最佳连接的父节点保持同步。CoAP和OSCORE提供了支持安全连接过程以及补充堆栈的工具,实现了低开销的安全RESTful交互。

代码移植

OpenWSN首次完整的实现6TiSCH协议标准,为IEEE802.15.4e(6TiSCH)工作组(WG)在IEEE802.15.4 TSCH链路层之上进行控制平面和IP层适配的标准化工作提供了借鉴。与主流的无线通信协议(例如WiFi,zigbee,Bluetooth)不同,6TiSCH的MAC层采用TSCH(Time SlottedChannel Hopping )协议标准,所有的通信活动采用时间触发方式依次执行,在保证实时通信的同时,确保所有的通信操作均可借助时间线进行溯源,同时允许使用者自定义任务执行序列,TSCH协议的可靠性和确定性已经在wirelessHART协议中得到验证,这也预示着该协议标准将能够为时间敏感的工业网络提供新的解决思路。
stack_organization.png
为了方便移植,建议直接在github上下载openwsn-develop, 下图展示了OpenWSN的文件结构,我们主要用到图中标识的文件:
1.jpg
创建工程文件,并将Openwsn源码加入工程中。
1.jpg
bsp中主要包含Board、debugpins.c、leds.c以及加密算法(openaes.c、crytoengine.c);openstack主要包含完整协议实现。
2.jpg
kernel主要包含任务调度器,实现对时间及报文的处理任务的调度。
3.jpg
opendri包含对不同芯片的串口、传感器、计时器的兼容实现
4.jpg
最后添加头文件地址。
5.jpg
将部分库文件(uarrt,time,gpio,aes,spi,i2c(可选,主要看与开发板互联的无线芯片采用的通信协议),)及启动文件添加到bsp/board/GD32F427文件下,并实现硬件接口代码(主要实现radio.c,sctimer.c,leds.c,board.c,board_info.c,debugpins.c,spi.h/i2c.c,eui64.c,cryptoengines.c(可选,加密算法)),这里贴出leds.c文件的示例代码(由于开发板只支持2个LED外设,其余LED将通过引脚进行连接)。

#include "hal_gpio.h"
#include "leds.h"

/* LED0. */
#define LED0_GPIO_PORT GPIOI
#define LED0_GPIO_PIN  GPIO_PIN_0

/* LED1. */
#define LED1_GPIO_PORT GPIOD
#define LED1_GPIO_PIN  GPIO_PIN_2

/* LED2. */
#define LED2_GPIO_PORT GPIOC
#define LED2_GPIO_PIN  GPIO_PIN_6

/* LED3. */
#define LED3_GPIO_PORT GPIOC
#define LED3_GPIO_PIN  GPIO_PIN_9
void Delay(void);
void GPIO_Toggle(GPIO_Type  * GPIOx, uint16_t pin){
        GPIOx->ODR ^= pin;
}

void    leds_init(void){
    GPIO_Init_Type gpio_init;
        /* LED0. */
    gpio_init.Pins  = GPIO_PIN_0;
    gpio_init.PinMode  = GPIO_PinMode_Out_PushPull;
    gpio_init.Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOI, &gpio_init);

    /* LED1. */
    gpio_init.Pins  = GPIO_PIN_2;
    gpio_init.PinMode  = GPIO_PinMode_Out_PushPull;
    gpio_init.Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOD, &gpio_init);
    
    /* LED2. */
    gpio_init.Pins  = GPIO_PIN_6;
    gpio_init.PinMode  = GPIO_PinMode_Out_PushPull;
    gpio_init.Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &gpio_init);

    /* LED3. */
    gpio_init.Pins  = GPIO_PIN_9;
    gpio_init.PinMode  = GPIO_PinMode_Out_PushPull;
    gpio_init.Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &gpio_init);
}
    
    
void    leds_error_on(void){
    GPIO_WriteBit(LED0_GPIO_PORT, LED0_GPIO_PIN, 0u); /* led on. */

}
void    leds_error_off(void){
    GPIO_WriteBit(LED0_GPIO_PORT, LED0_GPIO_PIN, 1u); /* led off. */
}
void    leds_error_toggle(void){
  GPIO_Toggle(LED0_GPIO_PORT, LED0_GPIO_PIN);
}
    
uint8_t leds_error_isOn(void){
    uint8_t bitstatus = 0x00;
    if(GPIO_ReadOutDataBit(LED0_GPIO_PORT, LED0_GPIO_PIN))
        return bitstatus = 0x01;
    else 
    return bitstatus = 0x00;
}
void    leds_error_blink(void){}

void    leds_radio_on(void){
GPIO_WriteBit(LED1_GPIO_PORT, LED1_GPIO_PIN, 0u); /* led on. */
}
void    leds_radio_off(void){
GPIO_WriteBit(LED1_GPIO_PORT, LED1_GPIO_PIN, 1u); /* led off. */
}
void    leds_radio_toggle(void){
 GPIO_Toggle(LED1_GPIO_PORT, LED1_GPIO_PIN);
}
uint8_t leds_radio_isOn(void){
    uint8_t bitstatus = 0x00;
    if(GPIO_ReadOutDataBit(LED1_GPIO_PORT, LED1_GPIO_PIN))
        return bitstatus = 0x01;
    else 
    return bitstatus = 0x00;
}

void    leds_sync_on(void){
GPIO_WriteBit(LED2_GPIO_PORT, LED2_GPIO_PIN, 0u); /* led on. */
}
void    leds_sync_off(void){
GPIO_WriteBit(LED2_GPIO_PORT, LED2_GPIO_PIN, 1u); /* led off. */
}
void    leds_sync_toggle(void){
 GPIO_Toggle(LED2_GPIO_PORT, LED2_GPIO_PIN);
}
uint8_t leds_sync_isOn(void){
uint8_t bitstatus = 0x00;
    if(GPIO_ReadOutDataBit(LED2_GPIO_PORT, LED2_GPIO_PIN))
        return bitstatus = 0x01;
    else 
    return bitstatus = 0x00;
}

void    leds_debug_on(void){
GPIO_WriteBit(LED3_GPIO_PORT, LED3_GPIO_PIN, 0u); /* led on. */
}
void    leds_debug_off(void){
GPIO_WriteBit(LED3_GPIO_PORT, LED3_GPIO_PIN, 1u); /* led off. */

}
void    leds_debug_toggle(void){
GPIO_Toggle(LED3_GPIO_PORT, LED3_GPIO_PIN);
}
uint8_t leds_debug_isOn(void){
    uint8_t bitstatus = 0x00;
    if(GPIO_ReadOutDataBit(LED3_GPIO_PORT, LED3_GPIO_PIN))
        return bitstatus = 0x01;
    else 
    return bitstatus = 0x00;
}

void    leds_all_on(void){
    GPIO_WriteBit(LED0_GPIO_PORT, LED0_GPIO_PIN, 0u); 
    GPIO_WriteBit(LED1_GPIO_PORT, LED1_GPIO_PIN, 0u); 
    GPIO_WriteBit(LED2_GPIO_PORT, LED2_GPIO_PIN, 0u); 
    GPIO_WriteBit(LED3_GPIO_PORT, LED3_GPIO_PIN, 0u); 

}
void    leds_all_off(void){
    GPIO_WriteBit(LED0_GPIO_PORT, LED0_GPIO_PIN, 1u);
    GPIO_WriteBit(LED1_GPIO_PORT, LED1_GPIO_PIN, 1u);
    GPIO_WriteBit(LED2_GPIO_PORT, LED2_GPIO_PIN, 1u);
    GPIO_WriteBit(LED3_GPIO_PORT, LED3_GPIO_PIN, 1u);

}
void    leds_all_toggle(void){
    GPIO_Toggle(LED0_GPIO_PORT, LED0_GPIO_PIN);
    GPIO_Toggle(LED1_GPIO_PORT, LED1_GPIO_PIN);
    GPIO_Toggle(LED2_GPIO_PORT, LED2_GPIO_PIN);
    GPIO_Toggle(LED3_GPIO_PORT, LED3_GPIO_PIN);
}


void    leds_circular_shift(void){
    GPIO_Toggle(LED0_GPIO_PORT, LED0_GPIO_PIN);
    Delay();
    GPIO_Toggle(LED0_GPIO_PORT, LED0_GPIO_PIN);
    Delay();
    GPIO_Toggle(LED1_GPIO_PORT, LED1_GPIO_PIN);
    Delay();
    GPIO_Toggle(LED1_GPIO_PORT, LED1_GPIO_PIN);
    Delay();
    GPIO_Toggle(LED2_GPIO_PORT, LED2_GPIO_PIN);
    Delay();
    GPIO_Toggle(LED2_GPIO_PORT, LED2_GPIO_PIN);
    Delay();
    GPIO_Toggle(LED3_GPIO_PORT, LED3_GPIO_PIN);
    Delay();
    GPIO_Toggle(LED3_GPIO_PORT, LED3_GPIO_PIN);
}
void    leds_increment(void){}

void Delay(void){
    
    unsigned long ik;
    for(ik=0;ik<0x7fff8;ik++) ;
} 

移植结果验证

这里我们借助openwsn源码中提供的单元测试代码验证移植结果:
//main.c

#include <stdint.h>
#include <stdio.h>

#include "board_init.h"
#include "leds.h"
/*
 * Definitions.
 */

/*
 * Variables.
 */

/*
 * Declerations.
 */
void some_delay(void);
/*
 * Functions.
 */
int main(void)
{
        uint8_t i;
    BOARD_Init();
        leds_init();
        
    printf("\r\ngpio_basic example.\r\n");

    while (1)
    {
//        if ( GPIO_ReadInDataBit(BOARD_KEY0_GPIO_PORT, BOARD_KEY0_GPIO_PIN) ) /* key is no pressed. */
//        {
//            GPIO_WriteBit(BOARD_LED0_GPIO_PORT, BOARD_LED0_GPIO_PIN, 1u); /* led off. */
//            GPIO_WriteBit(BOARD_LED1_GPIO_PORT, BOARD_LED1_GPIO_PIN, 0u); /* led on. */
//        }
//        else /* key is pressed. */
//        {
//            GPIO_WriteBit(BOARD_LED0_GPIO_PORT, BOARD_LED0_GPIO_PIN, 0u); /* led on. */
//            GPIO_WriteBit(BOARD_LED1_GPIO_PORT, BOARD_LED1_GPIO_PIN, 1u); /* led off. */
//        }
     leds_error_on();          some_delay();
   leds_error_off();         some_delay();
   leds_error_toggle();      some_delay();
   leds_error_blink();       some_delay();
   
   // radio LED functions
   leds_radio_on();          some_delay();
   leds_radio_off();         some_delay();
   leds_radio_toggle();      some_delay();
   
   // sync LED functions
   leds_sync_on();           some_delay();
   leds_sync_off();          some_delay();
   leds_sync_toggle();       some_delay();
   
   // debug LED functions
   leds_debug_on();          some_delay();
   leds_debug_off();         some_delay();
   leds_debug_toggle();      some_delay();
   
   // all LED functions
   leds_all_off();           some_delay();
   leds_all_on();            some_delay();
   leds_all_off();           some_delay();
   leds_all_toggle();        some_delay();
   
   // LED increment function
   leds_all_off();           some_delay();
   for (i=0;i<9;i++) {
      leds_increment();      some_delay();
   }
   
   // LED circular shift function
   leds_all_off();           some_delay();
   leds_error_on();          some_delay();
   for (i=0;i<9;i++) {
      leds_circular_shift(); some_delay();
   }
   
    }
}

void some_delay(void) {
   volatile uint16_t delay;
   for (delay=0xffff;delay>0;delay--);
}

微信图片_20221113214752.jpg
微信图片_20221113214745.jpg

在之前的文章中介绍了将ucos-ii移植到GD32F310开发板上的操作指导,为了构建将传感、驱动和计算组件紧密集成到分布式反馈回路的网络物理系统(CPS),我们将尝试分别将运行OS的GD32F310和OpenWSN的GD427V借助于BLOT协议实现互联,组件完整的CPS系统。
微信截图_20221113215059.png

推荐阅读
关注数
10708
内容数
187
中国高性能通用微控制器领域的领跑者兆易创新GD系列芯片技术专栏。
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息