基于WaEdge平台开发Snap7插件
WaEdge平台介绍:WaEdge平台
本项目是基于WaEdge工业边缘平台SDK开发的S7 PLC插件。插件提供对西门子S7系列CPU进行通信和完成读写操作,插件基于WaEdge平台对外提供基于CoAP的RESTFUL接口。本项目代码已经在WaEdge开源组织下开源,访问链接为https://gitee.com/wasome/plugin_s7_plc_snap7。更多的WaEdge社区文章可以参考WaEdge技术博客园.
如果读者想了解如何开发一个插件,可以参考WaEdge工业IoT边缘插件开发帮助
插件开发基本规则:
既然是基于平台的开发,大多数情况需要遵守一定的规则。
WaEdge插件需要具有(实现)以下接口:
typedef struct MODULE_TAG MODULE;
typedef void* MODULE_HANDLE;
typedef struct MODULE_API_TAG MODULE_API;
struct MODULE_TAG
{
const MODULE_API* module_apis;
MODULE_HANDLE module_handle;
};
typedef void*(*pfModule_ParseConfigurationFromJson)(const char* configuration);
typedef void(*pfModule_FreeConfiguration)(void* configuration);
typedef MODULE_HANDLE(*pfModule_Create)(BROKER_HANDLE broker, const void* configuration);
typedef void(*pfModule_Destroy)(MODULE_HANDLE moduleHandle);
typedef void(*pfModule_Receive)(MODULE_HANDLE moduleHandle, MESSAGE_HANDLE messageHandle);
typedef void(*pfModule_Start)(MODULE_HANDLE moduleHandle);
typedef enum MODULE_API_VERSION_TAG
{
MODULE_API_VERSION_1
} MODULE_API_VERSION;
static const MODULE_API_VERSION Module_ApiGatewayVersion = MODULE_API_VERSION_1;
struct MODULE_API_TAG
{
MODULE_API_VERSION version;
};
typedef struct MODULE_API_1_TAG
{
MODULE_API base;
pfModule_ParseConfigurationFromJson Module_ParseConfigurationFromJson;
pfModule_FreeConfiguration Module_FreeConfiguration;
pfModule_Create Module_Create;
pfModule_Destroy Module_Destroy;
pfModule_Receive Module_Receive;
pfModule_Start Module_Start;
} MODULE_API_1;
typedef const MODULE_API* (*pfModule_GetApi)(MODULE_API_VERSION gateway_api_version);
MODULE_EXPORT const MODULE_API* Module_GetApi(MODULE_API_VERSION gateway_api_version);
插件开发基本要求:
一般一种插件对应一种协议,一种协议可以和某些工业设备进行通讯(读写),WaEdge插件需要满足在WaEdge框架内与设备通讯的要求
插件开发:
开发Snap7插件主要工作在于实现 Module_Start
- 创建对象&设置上下文
SNAP7_HANDLE_DATA* handleData = (SNAP7_HANDLE_DATA*)module;
RESTFUL_CONTEXT rest_context = WA_InitRestful(handleData->broker, module);
handleData->restful_context = rest_context;
- 注册资源
Get提供读操作,Put满足写操作
WA_RegisterResource(rest_context, "/snap7", snap7_Get, T_Get);
WA_RegisterResource(rest_context, "/snap7", snap7_Put, T_Put);
- 获取名称&加载设备
const char* plugin_name = WA_GetModuleName(handleData->broker, module);
load_device_config(plugin_name);
- 开启线程&处理加载过来的设备
wa_task_t task1 = bh_new_task((char*)"connect_task",
NULL,
true,
1 * 1000, // repeating task in 1000 ms
task_s7plc_connect);
bh_schedule_task(handleData->task_scheduler, task1, 0);
以上是Start函数的总体框架,下面介绍一些重点函数
1. 处理与设备的连接
处理逻辑放在task_s7plc_connect函数的open_s7_device函数
Snap7协议连接S7设备需要ConnectTo函数,它的参数一次是:IP地址、机架号、卡槽号,返回值为0表示成功。
2. 实现Get函数
S7设备将存储器划分为不同的区域,读取/写入数据需要填写区域号(注:DB区内部也划分了不同区块)
Snap7协议读取函数为ReadArea,参数一次为:区域号、DB区块编号(只有DB/V区有)、起始地址、读取的单位数量、读取的单位、存放读到的数据的地址
起到决定作用的参数只有 区域号、DB区块编号、起始地址,在传入的URI中需要携带这些信息,有了这些,再加上要读取的数据类型,就可以拿到准确数据
2.1 获取数据的具体方法
S7设备的数据存储方式和PC是相反的,因此工业场景下一般需要转换字节序,可以通过Bitset类拿到准确的二进制数据,之后用reinterpret_cast按指定的数据类型的位模式进行重新解析,这样我们就可以拿到准确数据了
3. 实现Put函数
Snap7协议写入函数为WriteArea,参数与ReadArea一致,最后的参数是要写入的数据所在的地址
通过WaEdge框架写入数据时可以传入单个数据,也可以传入数组,框架已经给出了解析数组的函数
拿到数据时,如果是单个需要将字符串转换为数字,如果是数组,框架已经解析好了,之后通过传入的数据类型判断拿item中的哪个值(浮点数和整数的存放方式有本质区别),最后通过C++17的lambda表达式的auto参数接收数据,再转换为具体类型,之后写入就可以了。

浙公网安备 33010602011771号