forked from xuos/xiuos
feat add control_framework, support fins protocol, compile OK
This commit is contained in:
@@ -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
|
||||
*/
|
||||
Reference in New Issue
Block a user