协议驱动开发
介绍协议驱动开发入门
1 简介
1.1 目的
本文档是协议驱动开发的说明文档,阐述了与 PLC 设备的交互过程和具体接口定义,并不限于其中的某个功能的具体实现。
1.2 范围
所有协议驱动 SDK 适用。
2 接口详细设计
2.1 全局接口
2.1.1 全局初始化接口
/*
* @brief 全局初始化
* @param [IN] param 类型:(void*)INIT_PARAM
* @return void
* 日记初始化,资源初始化
*/
SYC_SDK_API void SYC_SDK_TYPE SYC_MODBUS_SDK_Init(void* param);
2.1.2 全局释放接口
/*
* @brief 全局释放
* @return void
* 释放初始化资源
*/
SYC_SDK_API void SYC_SDK_TYPE SYC_MODBUS_SDK_Fini();
2.2 通用接口
2.2.1 事件回调接口
/*
* @brief 事件回调接口
* @param [OUT] handle 为回调的设备句柄
* @param [OUT] events 为事件类型,
* @param [OUT] context 为用户上下文
*/
void(_ SYC_EVENT_CALLBACK)(void_ handle, int events, void* context);
2.2.2 设置事件回调
/*
* @brief 设置事件回调
* @param [IN] handle 创建设备时返回的设备句柄
* @param [IN] callback 事件回调接口,当有事件发生时,sdk 会回调该接口
* @param [IN] context 用户上下文,用于区分不同的使用者
* @return void
*/
SYC_SDK_API void SYC_SDK_TYPE SYC_MODBUS_SDK_SetEventCallback(SYC_HANDLE handle, SYC_EVENT_CALLBACK callback, void* context);
2.2.3 创建设备句柄接口
/*
* @brief 创建设备句柄接口
* @param [IN] ip 设备 ip 地址
* @param [IN] Port 设备端口(502)
* @param [IN] extparam 连接扩展参数 类型:(void*)CONNECT_EXT_PARAM
* @return sdk 句柄(连接不成功时,返回值为 null)
*/
SYC_SDK_API SYC_HANDLE SYC_SDK_TYPE SYC_MODBUS_SDK_CreateHandle(const SYC_CHAR* ip, int port, void* extparam);
2.2.4 释放设备句柄接口
/*
* @brief 释放设备句柄接口
* @param [IN] handle 设备句柄
* @return void
*/
SYC_SDK_API void SYC_SDK_TYPE SYC_MODBUS_SDK_DeleteHandle(SYC_HANDLE handle);
2.2.5 设备连接打开接口
/*
* @brief 打开设备连接接口
* @param [IN] handle 设备句柄
* @return bool 连接不成功时,返回值为 false
* 用于连接设备,连接成功返回设备句柄
*/
SYC_SDK_API bool SYC_SDK_TYPE SYC_MODBUS_SDK_Open(SYC_HANDLE handle);
2.2.6 设备连接关闭接口
/*
* @brief 关闭设备连接接口
* @param [IN] handle 设备句柄
* @return void
*/
SYC_SDK_API void SYC_SDK_TYPE SYC_MODBUS_SDK_Close(SYC_HANDLE handle);
2.2.7 通用采集接口
* @brief 通用读接口
* @param [IN] handle 设备句柄
* @param [IN] addr 起始地址
* @param [IN] offset 读取的偏移量,字寄存器时,单位为字节;位寄存器时,单位为位
* @param [IN] data 存放读取结果的缓存首地址
* @param [IN] size 读取结果的大小
* @param [IN] extparam 扩展参数 类型:(void*)STD_PARAM
* @return bool 读成功时返回 true,失败时返回 false
*/
SYC_SDK_API bool SYC_SDK_TYPE SYC_MODBUS_SDK_Read(void* handle, const char* addr, int offset, void* data, int& size, void* extparam);
2.2.8 通用控制接口
/*
* @brief 通用写接口
* @param [IN] handle 设备句柄
* @param [IN] addr 起始地址
* @param [IN] data 存放待写入数据的缓存首地址
* @param [IN] size 待写入数据的大小
* @param [IN] extparam 扩展参数 类型:(void*)STD_PARAM
* @return bool 读成功时返回 true,失败时返回 false
*/
SYC_SDK_API bool SYC_SDK_TYPE SYC_MODBUS_SDK_Write(void* handle, const char* addr, void* data, int size, void* extparam);
2.3 数据结构定义
//全局初始化参数
typedef struct tagInitParam
{
int logLevel; //日志等级
unsigned int logKeepDays; //日志保存时间
unsigned long logCapacity; //日志保存容量
tagInitParam()
{
logLevel = 0;
logKeepDays = 0;
logCapacity = 0;
}
}INIT_PARAM, * LP_INIT_PARAM;
//连接扩展参数
typedef struct tagConnectExtParam
{
unsigned int connectTimeout; //连接超时,单位 s
unsigned int responseTimeout; //响应超时,单位 ms
tagConnectExtParam()
{
connectTimeout = 3;
responseTimeout = 1000;
}
}CONNECT_EXT_PARAM, * LP_CONNECT_EXT_PARAM;
//驱动原始报文
typedef struct tagDriverDebugMsg
{
SYC_U8 msg[5120];
SYC_S32 len;
SYC_S64 time;
SYC_S32 code;
tagDriverDebugMsg()
{
code = 0;
_memset_(msg, 0, 5120);
time = 0;
len = 0;
}
}DRIVER_DEBUG_MSG, * LP_DRIVER_DEBUG_MSG;
//标准通用
typedef struct tagStdDebugParam
{
_std_::_string_ traceId; //traceId
int64_t timespend; //驱动读写耗时
_std_::_string_ msgId; //报文 ID
bool generateMsg; //是否产生报文
DRIVER_DEBUG_MSG reqMsg; //发送报文
DRIVER_DEBUG_MSG rspMsg; //接收报文
SYC_S32 debugToolSwitch; //调试工具开关
unsigned char devid; //设备 ID
unsigned char headAddress; //起始地址
SYC_VARIABLE_TYPE type; //变量类型
_std_::_string_ rackNumer; //机台号
_std_::_string_ addressNumber; //地址域
_std_::_string_ passWord;//密码
_std_::_string_ operatorCode;//操作者代码
int feCount;//前导字节
tagStdDebugParam()
{
timespend = 0;
generateMsg = true;
debugToolSwitch = 0;
devid = 1;
headAddress = 1;
type = SYC_VARIABLE_TYPE_BIT;
feCount = 0;
}
}STD_PARAM, * LP_STD_PARAM;
//标签信息
typedef struct tagLableInfo
{
char parentName[256]; //父节点标签名
char name[256]; //标签名
char type[256]; //标签类型
uint32_t size; //数据大小
uint32_t iGroup; //组(绝对地址的区号)
uint32_t iOffs; //偏移(绝对地址的偏移)
_std_::_string_ traceId; //traceId
int64_t timespend; //驱动读写耗时
tagLableInfo()
{
_memset_(parentName, 0, sizeof(parentName));
_memset_(name, 0, sizeof(name));
_memset_(type, 0, sizeof(type));
size = 0;
iGroup = 0;
iOffs = 0;
timespend = 0;
}
}LABLE_INFO, * LP_LABLE_INFO;
//节点信息
typedef struct nodeInfo
{
char browseName[200]; //浏览名称
char nodeId[200]; //节点名
unsigned int nodeClass; //节点类枚举(0 不明确, 1 对象, 2 变量)
unsigned int variableType; //变量类型(0 常量, 1 数组, 2 拓展/结构体)
unsigned int dataType; //数据类型
unsigned int dataSize; //数据大小
nodeInfo()
{
_memset_(browseName, 0, sizeof(browseName));
_memset_(nodeId, 0, sizeof(nodeId));
nodeClass = 0;
variableType = 0;
dataType = 0;
dataSize = 0;
}
}NODE_INFO, * LP_NODE_INFO;
2.4 宏定义
#define SYC_SDK_TYPE _cdecl
#define SYC_SDK_API __declspec(dllexport)
typedef unsigned char SYC_U8;
typedef unsigned short SYC_U16;
typedef unsigned int SYC_U32;
typedef signed char SYC_S8;
typedef signed short SYC_S16;
typedef signed int SYC_S32;
typedef float SYC_F32;
typedef double SYC_F64;
typedef unsigned long long SYC_U64;
typedef signed long long SYC_S64;
typedef char SYC_CHAR;
typedef void* SYC_HANDLE;
//变量类型
typedef enum
{
//通用
SYC_VARIABLE_TYPE_BIT = 0, //二进制变量
SYC_VARIABLE_TYPE_S8 = 1, //有符号 8 位整型
SYC_VARIABLE_TYPE_U8 = 2, //无符号 8 位整型
SYC_VARIABLE_TYPE_S16 = 3, //有符号 16 位整型
SYC_VARIABLE_TYPE_U16 = 4, //无符号 16 位整型
SYC_VARIABLE_TYPE_S32 = 5, //有符号 32 位整型
SYC_VARIABLE_TYPE_U32 = 6, //无符号 32 位整型
SYC_VARIABLE_TYPE_S64 = 7, //有符号 64 位整型
SYC_VARIABLE_TYPE_U64 = 8, //无符号 64 位整型
SYC_VARIABLE_TYPE_F32 = 9, //F32 位浮点数 IEEE754
SYC_VARIABLE_TYPE_F64 = 10, //F64 位浮点数 IEEE754
SYC_VARIABLE_TYPE_STR = 11, //字符串
//S7
SYC_VARIABLE_TYPE_WSTR = 12, //宽字符串
SYC_VARIABLE_TYPE_TEXT_8BIT_CHARSET = 13, //文本变量 8 位字符集
SYC_VARIABLE_TYPE_TEXT_16BIT_CHARSET = 14, //文本变量 16 位字符集
SYC_VARIABLE_TYPE_TEXT_TIMER = 15, //定时器
SYC_VARIABLE_TYPE_TEXT_DATE = 16, //日期
SYC_VARIABLE_TYPE_TEXT_TIME = 17, //时间
SYC_VARIABLE_TYPE_TEXT_DATETIME = 18, //日期时间
SYC_VARIABLE_TYPE_UNDEFINE
}SYC_VARIABLE_TYPE;
3 示例
3.1 MODBUS 协议代码示例
//事件回调函数
void sys_modbus_sdk_event_callback(void* handle, int events, void* context)
{
_printf_("sys_modbus_sdk_event_callback ==> events=[%d]\n", events);
}
bool Test::sys_modbus_sdk_test()
{
bool result = false;
INIT_PARAM initParam;
initParam.logCapacity = 50 _ 1024 _ 1024;
initParam.logKeepDays = 7;
initParam.logLevel = LogLevel::LL_DEBUG;
SYC_MODBUS_SDK_Init(&initParam);
void* handle = SYC_MODBUS_SDK_CreateHandle("192.168.1.3", 502, NULL);
if (NULL == handle)
{
result = false;
SYC_MODBUS_SDK_Fini();
return result;
}
SYC_MODBUS_SDK_SetEventCallback(handle, sys_modbus_sdk_event_callback, NULL);
bool isOpen = false;
do
{
if ((false == isOpen) || (2 == modbus_event))
{
result = SYC_MODBUS_SDK_Open(handle);
if (false == result)
{
isOpen = false;
sleep_ms(2000);
continue;
}
isOpen = true;
}
STD_PARAM param;
param.devid = 1;
#ifdef _read_test_
unsigned char dest[1024] = { 0 };
int size = 0;
result = SYC_MODBUS_SDK_Read(handle, "409001", 2, dest, size, ¶m);
/*
float F_data;
double D_data;
memcpy(&D_data, dest, size);
*/
#endif // _read_test_
#ifdef _write_test_
unsigned char msg[] = {0xff, 0x00};
/*
float f_data = 12.2;
double d_data = 14.54;
unsigned char data[8];
memcpy(data, &d_data, sizeof(d_data));
*/
result = SYC_MODBUS_SDK_Write(handle, "001000", msg, sizeof(msg), ¶m);
#endif // _write_test_
sleep_ms(2000);
} while (true);
SYC_MODBUS_SDK_Close(handle);
SYC_MODBUS_SDK_DeleteHandle(handle);
SYC_MODBUS_SDK_Fini();
return true;
}