feat add control_framework, support fins protocol, compile OK

This commit is contained in:
Liu_Weichao
2022-11-21 17:20:44 +08:00
parent 72e09d82e7
commit 5560fc5318
31 changed files with 2152 additions and 445 deletions
@@ -1,2 +1,15 @@
config CONTROL_PROTOCOL_FINS
bool "Using fins control protocol"
default n
config CONTROL_PROTOCOL_MELSEC
bool "Using melsec control protocol"
default n
config CONTROL_PROTOCOL_OPCUA
bool "Using opcua control protocol"
default n
config CONTROL_PROTOCOL_S7
bool "Using s7 control protocol"
default n
@@ -1,4 +1,17 @@
SRC_DIR := fins melsec opcua s7
ifeq ($(CONFIG_CONTROL_PROTOCOL_FINS), y)
SRC_DIR := fins
endif
ifeq ($(CONFIG_CONTROL_PROTOCOL_MELSEC), y)
SRC_DIR := melsec
endif
ifeq ($(CONFIG_CONTROL_PROTOCOL_OPCUA), y)
SRC_DIR := opcua
endif
ifeq ($(CONFIG_CONTROL_PROTOCOL_S7), y)
SRC_DIR := s7
endif
include $(KERNEL_ROOT)/compiler.mk
@@ -1,4 +1,4 @@
SRC_FILES :=
SRC_FILES := fins.c
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,368 @@
/*
* Copyright (c) 2022 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file fins.c
* @brief plc protocol fins
* @version 3.0
* @author AIIT XUOS Lab
* @date 2022-10-08
*/
#include <fins.h>
#define FINS_COMMAND_LENGTH 34
static struct CircularAreaApp *circular_area;
static uint8_t handshake_require_command[] = {0x46, 0x49, 0x4E, 0x53, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
static uint8_t handshake_respond_buff[24] = {0};
static uint8_t recv_buff[1024] = {0};
static uint8_t FinsAreaCode(char area_char, FinsDataType type)
{
uint8_t area_code = 0;
if (area_char == 'C')
area_code = (type == FINS_DATA_TYPE_BIT ? 0x30 : 0xB0);
if (area_char == 'W')
area_code = (type == FINS_DATA_TYPE_BIT ? 0x31 : 0xB1);
if (area_char == 'H')
area_code = (type == FINS_DATA_TYPE_BIT ? 0x32 : 0xB2);
if (area_char == 'D')
area_code = (type == FINS_DATA_TYPE_BIT ? 0x02 : 0x82);
return area_code;
}
static uint16_t FinsCommandGenerate(uint8_t *p_command, uint16_t plc_ip_4, uint16_t pc_ip_4, FinsCommandCode command_code, char area_char,
FinsDataType data_type, uint16_t start_address, uint8_t bit_address, uint16_t data_length)
{
uint8_t index = 0;
p_command[index++] = (uint8_t)(FINS_HEADER_HEAD >> (3 * 8));
p_command[index++] = (uint8_t)(FINS_HEADER_HEAD >> (2 * 8));
p_command[index++] = (uint8_t)(FINS_HEADER_HEAD >> (1 * 8));
p_command[index++] = (uint8_t)FINS_HEADER_HEAD;
p_command[index++] = (uint8_t)FINS_HEADER_READ_COMMAND_LENGTH >> (3 * 8);
p_command[index++] = (uint32_t)FINS_HEADER_READ_COMMAND_LENGTH >> (2 * 8);
p_command[index++] = (uint32_t)FINS_HEADER_READ_COMMAND_LENGTH >> (1 * 8);
p_command[index++] = (uint32_t)FINS_HEADER_READ_COMMAND_LENGTH;
p_command[index++] = (uint32_t)FINS_HEADER_COMMAND >> (3 * 8);
p_command[index++] = (uint32_t)FINS_HEADER_COMMAND >> (2 * 8);
p_command[index++] = (uint32_t)FINS_HEADER_COMMAND >> (1 * 8);
p_command[index++] = (uint32_t)FINS_HEADER_COMMAND;
p_command[index++] = (uint32_t)FINS_HEADER_ERROR_CODE >> (3 * 8);
p_command[index++] = (uint32_t)FINS_HEADER_ERROR_CODE >> (2 * 8);
p_command[index++] = (uint32_t)FINS_HEADER_ERROR_CODE >> (1 * 8);
p_command[index++] = (uint32_t)FINS_HEADER_ERROR_CODE;
p_command[index++] = FINS_ICF;
p_command[index++] = FINS_RSV;
p_command[index++] = FINS_GCT;
p_command[index++] = FINS_DNA;
p_command[index++] = plc_ip_4;
p_command[index++] = FINS_DA2;
p_command[index++] = FINS_SNA;
p_command[index++] = pc_ip_4;
p_command[index++] = FINS_SA2;
p_command[index++] = FINS_SID;
p_command[index++] = command_code >> 8;
p_command[index++] = command_code;
p_command[index++] = FinsAreaCode(area_char, data_type);
p_command[index++] = start_address >> 8;
p_command[index++] = start_address;
p_command[index++] = bit_address;
p_command[index++] = data_length >> 8;
p_command[index++] = data_length;
return index;
}
static int FinsTransformRecvBuffToData(FinsReadItem *p_read_item, uint8_t *recv_buff)
{
FinsDataInfo *p_fins_data_info = &(p_read_item->data_info);
uint8_t error_code = recv_buff[3];
if (error_code) {
printf("Data abnormal, abnormal error code is %08x!", error_code);
return -1;
}
recv_buff += 30;
FinsCommandCode command_code = p_fins_data_info->command_code;
if (FINS_COMMAND_CODE_READ == command_code) {
uint16_t data_length = p_read_item->data_length;
ControlPrintList("DATA", recv_buff, data_length * (FINS_DATA_TYPE_BIT == p_read_item->data_type ? 1 : 2));
printf("Receive data is ");
if (FINS_DATA_TYPE_BIT == p_read_item->data_type) {
memcpy(p_fins_data_info->base_data_info.p_data, recv_buff, data_length);
printf("%02x", p_fins_data_info->base_data_info.p_data[0]);
} else {
uint8_t *p_data = p_fins_data_info->base_data_info.p_data;
for (uint16_t i = 0; i < data_length; i ++) {
p_data[2 * i] = recv_buff[2 * (data_length - i - 1)];
p_data[2 * i + 1] = recv_buff[2 * (data_length - i - 1) + 1];
printf("%03x%03x", p_data[2 * i], p_data[2 * i + 1]);
}
}
printf("\nRead fins plc data success!\n");
} else if (FINS_COMMAND_CODE_WRITE == command_code) {
/*to do*/
printf("Write fins plc cmd success!\n");
}
return 0;
}
static int FinsHandshake(int32_t socket, uint16_t local_ip_4)
{
handshake_require_command[18] = (uint8_t)(local_ip_4 >> 8);
handshake_require_command[19] = (uint8_t)local_ip_4;
uint8_t try_count = 0;
while (try_count < 10) {
ControlPrintList("SEND", (uint8_t *)handshake_require_command, sizeof(handshake_require_command));
int32_t write_error = socket_write(socket, handshake_require_command, sizeof(handshake_require_command));
if (write_error < 0) {
printf("Write socket error, errno is %d!", errno);
} else {
int32_t recv_length = socket_read(socket, (uint8_t *)handshake_respond_buff, sizeof(handshake_respond_buff));
if (recv_length < 0) {
printf("Read socket error, errno is %d!", errno);
} else {
ControlPrintList("RECV", (uint8_t *)handshake_respond_buff, recv_length);
/*check fins handshake respond*/
uint8_t error_code = handshake_respond_buff[15];
if (error_code == 0 || error_code == 0x21) {
return 0;
} else {
printf("Fins handshake failed, errno is %05x!", handshake_respond_buff[15]);
return -1;
}
}
}
if ((errno == EINTR) || (errno == EAGAIN) || (errno == EWOULDBLOCK)) {
printf("Send plc command failed, errno is %d!", errno);
continue;
} else {
break;
}
}
return -2;
}
static int FinsGetData(int32_t socket, FinsReadItem *p_read_item, struct ControlRecipe *p_recipe)
{
uint8_t try_count = 0;
int32_t write_error = 0;
FinsDataInfo *p_fins_data_info = &(p_read_item->data_info);
BasicPlcDataInfo *p_base_data_info = &(p_fins_data_info->base_data_info);
memset(recv_buff, 0, sizeof(recv_buff));
while (try_count < 10) {
ControlPrintList("SEND", p_base_data_info->p_command, p_base_data_info->command_length);
try_count++;
write_error = socket_write(socket, p_base_data_info->p_command, p_base_data_info->command_length);
if (write_error < 0) {
printf("Write socket error, errno is %d!", errno);
} else {
PrivTaskDelay(20);
int32_t recv_length = socket_read(socket, recv_buff, sizeof(recv_buff));
if (recv_length < 0) {
printf("Read socket error, errno is %d!", errno);
} else {
ControlPrintList("RECV", recv_buff, recv_length);
return FinsTransformRecvBuffToData(p_read_item, recv_buff);
}
}
if ((errno == EINTR) || (errno == EAGAIN) || (errno == EWOULDBLOCK)) {
printf("Send plc command failed, errno is %d!", errno);
continue;
} else {
return -1;
}
}
return -2;
}
static int FinsInitialDataInfo(FinsReadItem *p_read_item, uint16_t plc_ip_4, uint16_t local_ip_4, FinsCommandCode command_code,
char area_char, FinsDataType data_type, uint16_t start_address, uint8_t bit_address, uint16_t data_length, uint8_t *p_data)
{
p_read_item->area_char = area_char;
p_read_item->data_type = data_type;
p_read_item->data_info.command_code = command_code;
p_read_item->start_address = start_address;
p_read_item->bit_address = bit_address;
p_read_item->data_length = data_length;
BasicPlcDataInfo *p_base_data_info = &(p_read_item->data_info.base_data_info);
switch (command_code)
{
case FINS_COMMAND_CODE_READ:
data_length *= (data_type == FINS_DATA_TYPE_BIT ? 1 : 2);
p_base_data_info->command_length = FINS_COMMAND_LENGTH;
p_base_data_info->p_command = (p_data == NULL ? PrivMalloc(FINS_COMMAND_LENGTH + data_length) : PrivMalloc(FINS_COMMAND_LENGTH));
p_base_data_info->data_size = data_length;
p_base_data_info->p_data = (p_data == NULL ? p_base_data_info->p_command + FINS_COMMAND_LENGTH : p_data);
break;
case FINS_COMMAND_CODE_WRITE:
//To Do
break;
default:
return -1;
}
uint16_t command_length = FinsCommandGenerate(p_base_data_info->p_command, plc_ip_4, local_ip_4, command_code, area_char,
data_type, start_address, bit_address, data_length);
return 0;
}
void *ReceivePlcDataTask(void *parameter)
{
int i = 0;
uint8_t try_count = 0;
uint16_t data_length = 0;
uint8_t *fins_data;
uint16_t read_item_size = sizeof(FinsReadItem);
struct ControlProtocol *control_protocol = (struct ControlProtocol *)parameter;
circular_area = (struct CircularAreaApp *)control_protocol->args;
FinsReadItem *fins_read_item = (FinsReadItem *)control_protocol->recipe->read_item;
fins_data = control_protocol->recipe->protocol_data->data;
data_length = control_protocol->recipe->protocol_data->data_length;
BasicSocketPlc plc_socket;
memset(&plc_socket, 0, sizeof(BasicSocketPlc));
memcpy(plc_socket.ip, control_protocol->recipe->socket_config.plc_ip, 4);
plc_socket.port = control_protocol->recipe->socket_config.port;
plc_socket.socket = -1;
plc_socket.secondary_connect_flag = 0;
while (1) {
for (i = 0; i < control_protocol->recipe->read_item_count; i ++) {
/*only connect socket when close socket or init*/
while (ControlConnectSocket(&plc_socket) < 0) {
PrivTaskDelay(1000);
}
/*need to handshake after connect socket using FINS protocol*/
if (0 == plc_socket.secondary_connect_flag) {
if (FinsHandshake(plc_socket.socket, control_protocol->recipe->socket_config.local_ip[3]) < 0) {
plc_socket.secondary_connect_flag = 0;
ControlDisconnectSocket(&plc_socket);
continue;
}
}
plc_socket.secondary_connect_flag = 1;
FinsGetData(plc_socket.socket, (FinsReadItem *)fins_read_item + i, control_protocol->recipe);
}
/*read all variable item data, put them into circular_area*/
if (i == control_protocol->recipe->read_item_count) {
CircularAreaAppWrite(circular_area, fins_data, data_length, 0);
}
/*read data every single 200ms*/
PrivTaskDelay(200);
}
}
int FinsOpen(struct ControlProtocol *control_protocol)
{
ControlProtocolOpenDef(control_protocol);
return 0;
}
int FinsClose(struct ControlProtocol *control_protocol)
{
ControlProtocolCloseDef();
}
int FinsRead(struct ControlProtocol *control_protocol, void *buf, size_t len)
{
return CircularAreaAppRead(circular_area, buf, len);
}
static struct ControlDone fins_protocol_done =
{
._open = FinsOpen,
._close = FinsClose,
._read = FinsRead,
._write = NULL,
._ioctl = NULL,
};
int FinsProtocolFormatCmd(struct ControlRecipe *p_recipe, ProtocolFormatInfo *protocol_format_info)
{
int ret = 0;
static uint8_t last_data_length = 0;
p_recipe->read_item = PrivMalloc(sizeof(FinsReadItem) * p_recipe->read_item_count);
FinsReadItem *fins_read_item = (FinsReadItem *)(p_recipe->read_item) + protocol_format_info->read_item_index;
fins_read_item->value_type = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "value_type")->valueint;
strncpy(fins_read_item->value_name, cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "value_name")->valuestring, 20);
ret = FinsInitialDataInfo(fins_read_item,
p_recipe->socket_config.plc_ip[3],
p_recipe->socket_config.local_ip[3],
FINS_COMMAND_CODE_READ,
cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "area_char")->valuestring[0],
cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "data_type")->valueint,
cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "start_address")->valueint,
cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "bit_address")->valueint,
cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "data_length")->valueint,
p_recipe->protocol_data->data + last_data_length);
ControlPrintList("CMD", fins_read_item->data_info.base_data_info.p_command, fins_read_item->data_info.base_data_info.command_length);
last_data_length = GetValueTypeMemorySize(fins_read_item->value_type);
return ret;
}
int FinsProtocolInit(struct ControlRecipe *p_recipe)
{
struct ControlProtocol *p_control_protocol = CONTAINER_OF(p_recipe, struct ControlProtocol, recipe);
if (NULL == p_control_protocol) {
printf("%s get control protocol failed\n", __func__);
return -1;
}
FinsReadItem *fins_read_item = PrivMalloc(sizeof(FinsReadItem) * p_recipe->read_item_count);
if (NULL == fins_read_item) {
PrivFree(fins_read_item);
return -1;
}
p_recipe->read_item = (void *)fins_read_item;
p_recipe->ControlProtocolFormatCmd = FinsProtocolFormatCmd;
p_control_protocol->done = &fins_protocol_done;
return 0;
}
@@ -0,0 +1,331 @@
{
"device_id": 769,
"device_name": "S01",
"communication_type": 0,
"socket_config": {
"plc_ip": "192.168.250.22",
"local_ip": "192.168.250.233",
"gateway": "192.168.250.1",
"netmask": "255.255.254.0",
"port": 9600
},
"protocol_type": 6,
"read_period": 100,
"read_item_list": [
{
"value_name": "启动",
"value_type": 1,
"area_char": "W",
"data_type": 0,
"start_address": 0,
"bit_address": 0,
"data_length": 1
},
{
"value_name": "停止",
"value_type": 1,
"area_char": "W",
"data_type": 0,
"start_address": 0,
"bit_address": 1,
"data_length": 1
},
{
"value_name": "使能",
"value_type": 1,
"area_char": "H",
"data_type": 0,
"start_address": 0,
"bit_address": 2,
"data_length": 1
},
{
"value_name": "回零",
"value_type": 1,
"area_char": "D",
"data_type": 0,
"start_address": 0,
"bit_address": 3,
"data_length": 1
},
{
"value_name": "急停",
"value_type": 1,
"area_char": "W",
"data_type": 0,
"start_address": 0,
"bit_address": 4,
"data_length": 1
},
{
"value_name": "正限位",
"value_type": 1,
"area_char": "W",
"data_type": 0,
"start_address": 10,
"bit_address": 11,
"data_length": 1
},
{
"value_name": "负限位",
"value_type": 1,
"area_char": "W",
"data_type": 0,
"start_address": 10,
"bit_address": 12,
"data_length": 1
},
{
"value_name": "自动运行中",
"value_type": 1,
"area_char": "W",
"data_type": 0,
"start_address": 200,
"bit_address": 5,
"data_length": 1
},
{
"value_name": "故障",
"value_type": 1,
"area_char": "W",
"data_type": 0,
"start_address": 200,
"bit_address": 6,
"data_length": 1
},
{
"value_name": "待机",
"value_type": 1,
"area_char": "W",
"data_type": 0,
"start_address": 200,
"bit_address": 7,
"data_length": 1
},
{
"value_name": "手动模式",
"value_type": 1,
"area_char": "W",
"data_type": 0,
"start_address": 300,
"bit_address": 0,
"data_length": 1
},
{
"value_name": "自动模式",
"value_type": 1,
"area_char": "W",
"data_type": 0,
"start_address": 300,
"bit_address": 1,
"data_length": 1
},
{
"value_name": "运行方向",
"value_type": 1,
"area_char": "W",
"data_type": 0,
"start_address": 300,
"bit_address": 2,
"data_length": 1
},
{
"value_name": "复位",
"value_type": 1,
"area_char": "W",
"data_type": 0,
"start_address": 400,
"bit_address": 3,
"data_length": 1
},
{
"value_name": "备用1",
"value_type": 1,
"area_char": "W",
"data_type": 0,
"start_address": 400,
"bit_address": 4,
"data_length": 1
},
{
"value_name": "产量",
"value_type": 3,
"area_char": "D",
"data_type": 1,
"start_address": 10,
"bit_address": 0,
"data_length": 1
},
{
"value_name": "整型1",
"value_type": 3,
"area_char": "D",
"data_type": 1,
"start_address": 11,
"bit_address": 0,
"data_length": 1
},
{
"value_name": "整型2",
"value_type": 3,
"area_char": "D",
"data_type": 1,
"start_address": 20,
"bit_address": 0,
"data_length": 1
},
{
"value_name": "整型3",
"value_type": 3,
"area_char": "D",
"data_type": 1,
"start_address": 100,
"bit_address": 0,
"data_length": 1
},
{
"value_name": "整型4",
"value_type": 3,
"area_char": "W",
"data_type": 1,
"start_address": 100,
"bit_address": 0,
"data_length": 1
},
{
"value_name": "整型5",
"value_type": 3,
"area_char": "W",
"data_type": 1,
"start_address": 101,
"bit_address": 0,
"data_length": 1
},
{
"value_name": "整型6",
"value_type": 3,
"area_char": "W",
"data_type": 1,
"start_address": 110,
"bit_address": 0,
"data_length": 1
},
{
"value_name": "整型7",
"value_type": 3,
"area_char": "H",
"data_type": 1,
"start_address": 10,
"bit_address": 0,
"data_length": 1
},
{
"value_name": "整型8",
"value_type": 3,
"area_char": "H",
"data_type": 1,
"start_address": 20,
"bit_address": 0,
"data_length": 1
},
{
"value_name": "整型9",
"value_type": 3,
"area_char": "H",
"data_type": 1,
"start_address": 21,
"bit_address": 0,
"data_length": 1
},
{
"value_name": "速度",
"value_type": 9,
"area_char": "D",
"data_type": 1,
"start_address": 2000,
"bit_address": 0,
"data_length": 2
},
{
"value_name": "加速度",
"value_type": 9,
"area_char": "D",
"data_type": 1,
"start_address": 2002,
"bit_address": 0,
"data_length": 2
},
{
"value_name": "减速度",
"value_type": 9,
"area_char": "D",
"data_type": 1,
"start_address": 2004,
"bit_address": 0,
"data_length": 2
},
{
"value_name": "起始位置",
"value_type": 9,
"area_char": "D",
"data_type": 1,
"start_address": 300,
"bit_address": 0,
"data_length": 2
},
{
"value_name": "终点位置",
"value_type": 9,
"area_char": "D",
"data_type": 1,
"start_address": 302,
"bit_address": 0,
"data_length": 2
},
{
"value_name": "张力值",
"value_type": 9,
"area_char": "W",
"data_type": 1,
"start_address": 80,
"bit_address": 0,
"data_length": 2
},
{
"value_name": "浮点型1",
"value_type": 8,
"area_char": "H",
"data_type": 1,
"start_address": 100,
"bit_address": 0,
"data_length": 4
},
{
"value_name": "浮点型2",
"value_type": 8,
"area_char": "H",
"data_type": 1,
"start_address": 104,
"bit_address": 0,
"data_length": 4
},
{
"value_name": "浮点型3",
"value_type": 8,
"area_char": "H",
"data_type": 1,
"start_address": 108,
"bit_address": 0,
"data_length": 4
},
{
"value_name": "浮点型4",
"value_type": 8,
"area_char": "H",
"data_type": 1,
"start_address": 112,
"bit_address": 0,
"data_length": 4
}
]
}
@@ -0,0 +1,86 @@
/*
* Copyright (c) 2022 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file fins.h
* @brief plc protocol fins
* @version 3.0
* @author AIIT XUOS Lab
* @date 2022-10-08
*/
#ifndef FINS_H
#define FINS_H
#include <control_def.h>
#ifdef __cplusplus
extern "C" {
#endif
#define FINS_HEADER_HEAD 0x46494E53
#define FINS_HEADER_READ_COMMAND_LENGTH 0x0000001A
#define FINS_HEADER_COMMAND 0x00000002
#define FINS_HEADER_ERROR_CODE 0x00000000
#define FINS_ICF 0x80
#define FINS_RSV 0x00
#define FINS_REPLY_ICF 0xC0
#define FINS_GCT 0x02
#define FINS_DNA 0x00
#define FINS_DA2 0x00
#define FINS_SNA 0x00
#define FINS_SA2 0x00
#define FINS_SID 0x00
typedef enum
{
FINS_COMMAND_CODE_READ = 0x0101,
FINS_COMMAND_CODE_WRITE = 0x0102
}FinsCommandCode;
typedef enum
{
FINS_DATA_TYPE_BIT,
FINS_DATA_TYPE_WORD
}FinsDataType;
typedef struct
{
BasicPlcDataInfo base_data_info;
FinsCommandCode command_code;
}FinsDataInfo;
typedef struct
{
int32_t socket;
uint16_t plc_ip_4;
}FinsHandshakeParameter;
typedef struct
{
FinsDataInfo data_info;
UniformValueType value_type;
char value_name[20];
char area_char;
FinsDataType data_type;
uint16_t start_address;
uint8_t bit_address;
uint16_t data_length;
}FinsReadItem;
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,19 @@
/*
* Copyright (c) 2022 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file melsec.h
* @brief plc protocol melsec
* @version 3.0
* @author AIIT XUOS Lab
* @date 2022-10-08
*/
@@ -0,0 +1,19 @@
/*
* Copyright (c) 2022 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file opcua.h
* @brief control protocol opcua
* @version 3.0
* @author AIIT XUOS Lab
* @date 2022-10-08
*/
@@ -0,0 +1,19 @@
/*
* Copyright (c) 2022 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file s7.h
* @brief plc protocol s7
* @version 3.0
* @author AIIT XUOS Lab
* @date 2022-10-08
*/