feat add melsec tcp protocol for control framework, compile OK

This commit is contained in:
Liu_Weichao 2022-12-29 16:35:23 +08:00
parent b933e0decb
commit 6010fe5654
8 changed files with 325 additions and 7 deletions

View File

@ -258,7 +258,7 @@ static uint16_t Melsec3eqlGenerateCommand(uint8_t *p_command, uint32_t command_c
p_command[index++] = (uint8_t)QEQUEST_DESTINSTION_MODULE_IO_NUMBER;
p_command[index++] = (uint8_t)(QEQUEST_DESTINSTION_MODULE_IO_NUMBER >> 8);
p_command[index++] = QEQUEST_DESTINSTION_MODULE_STATION_NUMBER;
p_command[index++] = 0x0c;
p_command[index++] = 0x0C;
p_command[index++] = 0x00;
p_command[index++] = p_read_item->monitoring_timer;
p_command[index++] = p_read_item->monitoring_timer >> 8;
@ -502,7 +502,77 @@ int MelsecInitialDataInfo(MelsecReadItem *p_read_item, uint8_t *p_data)
*/
static int MelsecTransformRecvBuffToData(MelsecReadItem *p_read_item, uint8_t *recv_buff)
{
MelsecDataInfo *p_melsec_data_info = &(p_read_item->data_info);
MelsecFrameType frame_type = p_melsec_data_info->frame_type;
MelsecCommandType command_type = p_melsec_data_info->command_type;
uint8_t *p_data = p_melsec_data_info->base_data_info.p_data;
uint16_t device_points_count = p_read_item->device_points_count;
uint8_t is_ascii = ((MELSEC_1E_FRAME == frame_type) || (MELSEC_3E_Q_L_FRAME == frame_type) || (MELSEC_3E_IQ_R_FRAME == frame_type)) ? 0 : 1;
uint16_t abnormal_code = 0;
switch (frame_type) {
case MELSEC_3E_IQ_R_FRAME:
case MELSEC_3E_Q_L_FRAME:
if (recv_buff[9] != 0 || recv_buff[10] != 0)
abnormal_code = recv_buff[10] * 256 + recv_buff[9];
else
recv_buff += 11;
break;
case MELSEC_1E_FRAME:
if (recv_buff[1] != 0)
abnormal_code = recv_buff[2];
else
recv_buff += 2;
break;
case MELSEC_1C_FRAME:
if (MELSEC_NAK == recv_buff[0])
abnormal_code = recv_buff[5] * 256 + recv_buff[6];
else
recv_buff += 5;
break;
case MELSEC_3C_FRAME:
if (MELSEC_NAK == recv_buff[0])
abnormal_code = ((uint16_t)TransformAsciiToHex(recv_buff[11])) << 12 + ((uint16_t)TransformAsciiToHex(recv_buff[12])) << 8 +
((uint16_t)TransformAsciiToHex(recv_buff[13])) << 4 + ((uint16_t)TransformAsciiToHex(recv_buff[14]));
else
recv_buff += 11;
break;
default:
return -1;
}
if (abnormal_code != 0) {
printf("Data abnormal, abnormal code is %0x!", abnormal_code);
return -1;
}
ControlPrintfList("DATA", recv_buff, (uint16_t)(device_points_count * (READ_IN_BITS == command_type ? 0.5 : 2) * (frame_type >= MELSEC_1C_FRAME ? 2 : 1) + 0.6));
printf("Receive data is ");
for (uint16_t i = 0; i < device_points_count; i++) {
if (READ_IN_BITS == command_type) {
if (!is_ascii) {
p_data[i] = (recv_buff[i / 2] & (i % 2 == 0 ? 0x10 : 0x01)) || 0;
} else {
p_data[i] = TransformAsciiToHex(recv_buff[i]);
}
printf("0x%x", p_data[i]);
} else if (READ_IN_WORD == command_type) {
if (!is_ascii) {
uint16_t recv_buff_index = 2 * (device_points_count - 1 - i);
p_data[2 * i] = recv_buff[recv_buff_index + 1];
p_data[2 * i + 1] = recv_buff[recv_buff_index];
} else {
uint16_t recv_buff_index = 4 * (device_points_count - 1 - i);
p_data[2 * i] = TransformAsciiToHex(recv_buff[recv_buff_index]) * 16 + TransformAsciiToHex(recv_buff[recv_buff_index + 1]);
p_data[2 * i + 1] = TransformAsciiToHex(recv_buff[recv_buff_index + 2]) * 16 + TransformAsciiToHex(recv_buff[recv_buff_index + 3]);
}
printf("0x%x 0x%x", p_data[2 * i], p_data[2 * i + 1]);
}
}
printf("\n");
return 0;
}
/**
@ -513,7 +583,41 @@ static int MelsecTransformRecvBuffToData(MelsecReadItem *p_read_item, uint8_t *r
*/
static int MelsecGetDataBySocket(int32_t socket, MelsecReadItem *p_read_item)
{
uint8_t try_count = 0;
int32_t write_error = 0;
MelsecDataInfo *p_melsec_data_info = &(p_read_item->data_info);
BasicPlcDataInfo *p_base_data_info = &(p_melsec_data_info->base_data_info);
memset(recv_buff, 0, sizeof(recv_buff));
while (try_count < 10) {
ControlPrintfList("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 {
ControlPrintfList("RECV", recv_buff, recv_length);
return MelsecTransformRecvBuffToData(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;
}
/**
@ -523,7 +627,20 @@ static int MelsecGetDataBySocket(int32_t socket, MelsecReadItem *p_read_item)
*/
static int MelsecGetDataBySerial(MelsecReadItem *p_read_item)
{
uint32_t read_length = 0;
memset(recv_buff, 0, sizeof(recv_buff));
MelsecDataInfo *p_melsec_data_info = &(p_read_item->data_info);
BasicPlcDataInfo *p_base_data_info = &(p_melsec_data_info->base_data_info);
ControlPrintfList("SEND", p_base_data_info->p_command, p_base_data_info->command_length);
SerialWrite(p_base_data_info->p_command, p_base_data_info->command_length);
read_length = SerialRead(recv_buff, sizeof(recv_buff));
if (read_length) {
ControlPrintfList("RECV", recv_buff, read_length);
return MelsecTransformRecvBuffToData(p_read_item, recv_buff);
}
}
/**
@ -552,12 +669,17 @@ void *ReceivePlcDataTask(void *parameter)
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);
}
MelsecGetDataBySocket(plc_socket.socket, (MelsecReadItem *)melsec_read_item + i);
if ((PROTOCOL_MELSEC_1C == control_protocol->protocol_type) || (PROTOCOL_MELSEC_3C == control_protocol->protocol_type)) {
MelsecGetDataBySerial((MelsecReadItem *)melsec_read_item + i);
} else {
/*only connect socket when close socket or init*/
while (ControlConnectSocket(&plc_socket) < 0) {
PrivTaskDelay(1000);
}
MelsecGetDataBySocket(plc_socket.socket, (MelsecReadItem *)melsec_read_item + i);
}
}
/*read all variable item data, put them into circular_area*/
@ -638,7 +760,7 @@ int MelsecProtocolFormatCmd(struct ControlRecipe *p_recipe, ProtocolFormatInfo *
melsec_read_item->data_info.command_type = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "command_type")->valueint;
melsec_read_item->data_info.frame_type = p_recipe->protocol_type - PROTOCOL_MELSEC_1E;
melsec_read_item->monitoring_timer = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "monitoring_timer")->valueint;
melsec_read_item->device_code = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "device_code")->valuestring;
melsec_read_item->device_code = MelsecGetDeviceCode(melsec_read_item->data_info.frame_type, cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "device_code")->valuestring);
strncpy(melsec_read_item->head_device_number_string, cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "head_device_number_string")->valuestring, 6);
melsec_read_item->device_points_count = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "device_points_count")->valueint;

View File

@ -0,0 +1,33 @@
{
"device_id": 769,
"device_name": "S01",
"communication_type": 1,
"serial_config": {
"baud_rate": 19200,
"data_bits": 7,
"stop_bits": 1,
"check_mode": 3
},
"protocol_type": 9,
"read_period": 100,
"read_item_list": [
{
"value_name": "启动",
"value_type": 1,
"device_code": "M",
"head_device_number_string": "0",
"device_points_count": 1,
"command_type": 0,
"monitoring_timer": 100
},
{
"value_name": "停止",
"value_type": 1,
"device_code": "M",
"head_device_number_string": "1",
"device_points_count": 1,
"command_type": 0,
"monitoring_timer": 100
}
]
}

View File

@ -0,0 +1,34 @@
{
"device_id": 771,
"device_name": "S03",
"communication_type": 0,
"socket_config": {
"plc_ip": "192.168.250.20",
"local_ip": "192.168.250.233",
"gateway": "192.168.250.1",
"netmask": "255.255.254.0",
"port": 2000
},
"protocol_type": 6,
"read_period": 100,
"read_item_list": [
{
"value_name": "启动",
"value_type": 1,
"device_code": "M",
"head_device_number_string": "0",
"device_points_count": 1,
"command_type": 0,
"monitoring_timer": 100
},
{
"value_name": "停止",
"value_type": 1,
"device_code": "M",
"head_device_number_string": "1",
"device_points_count": 1,
"command_type": 0,
"monitoring_timer": 100
}
]
}

View File

@ -0,0 +1,33 @@
{
"device_id": 770,
"device_name": "S02",
"communication_type": 1,
"serial_config": {
"baud_rate": 19200,
"data_bits": 7,
"stop_bits": 1,
"check_mode": 3
},
"protocol_type": 10,
"read_period": 100,
"read_item_list": [
{
"value_name": "启动",
"value_type": 1,
"device_code": "M",
"head_device_number_string": "0",
"device_points_count": 1,
"command_type": 0,
"monitoring_timer": 100
},
{
"value_name": "停止",
"value_type": 1,
"device_code": "M",
"head_device_number_string": "1",
"device_points_count": 1,
"command_type": 0,
"monitoring_timer": 100
}
]
}

View File

@ -0,0 +1,34 @@
{
"device_id": 773,
"device_name": "S05",
"communication_type": 0,
"socket_config": {
"plc_ip": "192.168.250.20",
"local_ip": "192.168.250.233",
"gateway": "192.168.250.1",
"netmask": "255.255.254.0",
"port": 2000
},
"protocol_type": 8,
"read_period": 100,
"read_item_list": [
{
"value_name": "启动",
"value_type": 1,
"device_code": "M",
"head_device_number_string": "0",
"device_points_count": 1,
"command_type": 0,
"monitoring_timer": 100
},
{
"value_name": "停止",
"value_type": 1,
"device_code": "M",
"head_device_number_string": "1",
"device_points_count": 1,
"command_type": 0,
"monitoring_timer": 100
}
]
}

View File

@ -0,0 +1,34 @@
{
"device_id": 772,
"device_name": "S04",
"communication_type": 0,
"socket_config": {
"plc_ip": "192.168.250.20",
"local_ip": "192.168.250.233",
"gateway": "192.168.250.1",
"netmask": "255.255.254.0",
"port": 2000
},
"protocol_type": 7,
"read_period": 100,
"read_item_list": [
{
"value_name": "启动",
"value_type": 1,
"device_code": "M",
"head_device_number_string": "0",
"device_points_count": 1,
"command_type": 0,
"monitoring_timer": 100
},
{
"value_name": "停止",
"value_type": 1,
"device_code": "M",
"head_device_number_string": "1",
"device_points_count": 1,
"command_type": 0,
"monitoring_timer": 100
}
]
}

View File

@ -50,3 +50,25 @@ void SerialInit(uint32_t baud_rate, uint8_t data_bits, uint8_t stop_bits, uint8_
{
// Uart485Init(baud_rate, data_bits, stop_bits, check_mode);
}
/**
* @description: Control Framework Serial Write
* @param write_data - write data
* @param length - length
* @return
*/
void SerialWrite(uint8_t *write_data, int length)
{
//to do
}
/**
* @description: Control Framework Serial Read
* @param read_data - read data
* @param length - length
* @return
*/
int SerialRead(uint8_t *read_data, int length)
{
//to do
}

View File

@ -44,6 +44,12 @@ void SocketInit(char *ip, char *mask, char *gw);
/*Control Framework Serial Init*/
void SerialInit(uint32_t baud_rate, uint8_t data_bits, uint8_t stop_bits, uint8_t check_mode);
/*Control Framework Serial Write*/
void SerialWrite(uint8_t *write_data, int length);
/*Control Framework Serial Read*/
int SerialRead(uint8_t *read_data, int length);
#ifdef __cplusplus
}
#endif