diff --git a/APP_Framework/Framework/control/Kconfig b/APP_Framework/Framework/control/Kconfig index e9e0a1753..5618d752f 100755 --- a/APP_Framework/Framework/control/Kconfig +++ b/APP_Framework/Framework/control/Kconfig @@ -2,12 +2,15 @@ menuconfig SUPPORT_CONTROL_FRAMEWORK bool "support control framework" default n select TRANSFORM_LAYER_ATTRIUBUTE - select BSP_USING_LWIP select BSP_USING_SDIO select MOUNT_SDCARD_FS select LIB_USING_CJSON if SUPPORT_CONTROL_FRAMEWORK + config BSP_USING_SERIAL_485 + bool + default n + config CONTROL_RECIPE_FILE string "control framework recipe file name" default "test_recipe.json" diff --git a/APP_Framework/Framework/control/ipc_protocol/Kconfig b/APP_Framework/Framework/control/ipc_protocol/Kconfig index 3c586a36b..cd48d8cc5 100755 --- a/APP_Framework/Framework/control/ipc_protocol/Kconfig +++ b/APP_Framework/Framework/control/ipc_protocol/Kconfig @@ -1,6 +1,7 @@ config CONTROL_PROTOCOL_MODBUS_TCP bool "Using modbus_tcp control protocol" default n + select BSP_USING_LWIP if CONTROL_PROTOCOL_MODBUS_TCP source "$APP_DIR/Framework/control/ipc_protocol/modbus_tcp/Kconfig" endif diff --git a/APP_Framework/Framework/control/ipc_protocol/include/modbus_uart.h b/APP_Framework/Framework/control/ipc_protocol/include/modbus_uart.h new file mode 100644 index 000000000..f07c1604e --- /dev/null +++ b/APP_Framework/Framework/control/ipc_protocol/include/modbus_uart.h @@ -0,0 +1,67 @@ +/* + * 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 modbus_uart.h + * @brief support modbus_uart function + * @version 3.0 + * @author AIIT XUOS Lab + * @date 2022.12.29 + */ + +#ifndef MODBUS_UART_H +#define MODBUS_UART_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define MODBUS_UART_READ_CMD_LENGTH 0x08 +#define MODBUS_UART_WRITE_CMD_LENGTH 0x08 + +typedef enum +{ + READ_COIL_STATUS = 0x01, //read coil cmd + READ_INPUT_STATUS = 0x02, //read input colr cmd + READ_HOLDING_REGISTER = 0x03, //read register info cmd + READ_INPUT_REGISTER = 0x04, //read input register cmd + WRITE_SINGLE_COIL = 0x05, //write coil cmd + WRITE_SINGLE_REGISTER = 0x06, //write single register cmd + WRITE_MULTIPLE_COIL = 0x0F, //write multi coil cmd + WRITE_MULTIPLE_REGISTER = 0x10 //write multi register cmd +}ModbusUartFunctionCode; + +typedef struct +{ + BasicPlcDataInfo base_data_info; + ModbusUartFunctionCode function_code; +}ModbusUartDataInfo; + +typedef struct +{ + ModbusUartDataInfo data_info; + + UniformValueType value_type; + char value_name[20]; + + uint8_t station; + uint16_t start_address; + uint16_t quantity; +}ModbusUartReadItem; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/APP_Framework/Framework/control/ipc_protocol/modbus_tcp/test_recipe_modbus.json b/APP_Framework/Framework/control/ipc_protocol/modbus_tcp/test_recipe_modbus_tcp.json similarity index 100% rename from APP_Framework/Framework/control/ipc_protocol/modbus_tcp/test_recipe_modbus.json rename to APP_Framework/Framework/control/ipc_protocol/modbus_tcp/test_recipe_modbus_tcp.json diff --git a/APP_Framework/Framework/control/ipc_protocol/modbus_uart/Kconfig b/APP_Framework/Framework/control/ipc_protocol/modbus_uart/Kconfig index 139597f9c..bc6a0cae9 100755 --- a/APP_Framework/Framework/control/ipc_protocol/modbus_uart/Kconfig +++ b/APP_Framework/Framework/control/ipc_protocol/modbus_uart/Kconfig @@ -1,2 +1,37 @@ +if ADD_XIZI_FETURES + config CONTROL_FRAMEWORK_UART_485_DIR + int "control framework 485 direction pin number" + default "2" + config CONTROL_FRAMEWORK_PIN_DEV + string "control framework device pin dev path" + default "/dev/pin_dev" + + config CONTROL_FRAMEWORK_DRIVER_EXTUART + bool "Using extra uart to control framework" + default n + + config CONTROL_FRAMEWORK_UART_DEV + string "control framework device uart dev path" + default "/dev/uart3_dev3" + depends on !CONTROL_FRAMEWORK_DRIVER_EXTUART + + if CONTROL_FRAMEWORK_DRIVER_EXTUART + config CONTROL_FRAMEWORK_UART_DEV + string "control framework device extra uart dev path" + default "/dev/extuart_dev0" + + config CONTROL_FRAMEWORK_DEV_EXT_PORT + int "if control framework device using extuart, choose port" + default "0" + endif +endif + +if ADD_NUTTX_FETURES + +endif + +if ADD_RTTHREAD_FETURES + +endif diff --git a/APP_Framework/Framework/control/ipc_protocol/modbus_uart/Makefile b/APP_Framework/Framework/control/ipc_protocol/modbus_uart/Makefile index 608656f03..f22b4fb9a 100755 --- a/APP_Framework/Framework/control/ipc_protocol/modbus_uart/Makefile +++ b/APP_Framework/Framework/control/ipc_protocol/modbus_uart/Makefile @@ -1,4 +1,4 @@ -SRC_FILES := +SRC_FILES := modbus_uart.c include $(KERNEL_ROOT)/compiler.mk diff --git a/APP_Framework/Framework/control/ipc_protocol/modbus_uart/modbus_uart.c b/APP_Framework/Framework/control/ipc_protocol/modbus_uart/modbus_uart.c new file mode 100644 index 000000000..ef5f0351c --- /dev/null +++ b/APP_Framework/Framework/control/ipc_protocol/modbus_uart/modbus_uart.c @@ -0,0 +1,412 @@ +/* + * 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 modbus_uart.c + * @brief support modbus_uart function + * @version 3.0 + * @author AIIT XUOS Lab + * @date 2022.12.29 + */ + +#include + +/*using cirtular area to receive write-data*/ +#define CA_DATA_LENGTH 512 +struct CircularAreaApp *g_write_data; + +static BasicSocketPlc plc_socket = {0}; +static uint8_t recv_buff[1024] = {0}; + +/** + * @description: CRC16 check + * @param data data buffer + * @param length data length + * @return check code + */ +static uint16_t ModbusUartCrc16(uint8_t *data, uint32_t length) +{ + int j; + uint16_t reg_crc = 0xFFFF; + + while (length--) { + reg_crc ^= *data++; + for (j = 0;j < 8;j ++) { + if(reg_crc & 0x01) + reg_crc = reg_crc >> 1 ^ 0xA001; + else + reg_crc = reg_crc >> 1; + } + } + printf(" crc = [0x%x]\n", reg_crc); + return reg_crc; +} + +/** + * @description: Modbus Uart Data Transform from Receive Buffer To Control-Data + * @param p_read_item - read item pointer + * @param recv_buff - receive buff + * @return success : 0 error : -1 + */ +static int ModbusUartTransformRecvBuffToData(ModbusUartReadItem *p_read_item, uint8_t *recv_buff) +{ + uint8_t head_length = 3; + uint8_t *data_buffer; + ModbusUartDataInfo *p_modbus_uart_data_info = &(p_read_item->data_info); + uint16_t quantity = p_read_item->quantity; + + ModbusUartFunctionCode function_code = p_modbus_uart_data_info->function_code; + uint8_t *p_data = p_modbus_uart_data_info->base_data_info.p_data; + + uint8_t bytes_count = recv_buff[2]; + + if ((WRITE_SINGLE_COIL == function_code) || (WRITE_SINGLE_REGISTER == function_code)) { + head_length = 4; + if (p_modbus_uart_data_info->base_data_info.command_ready) { + p_modbus_uart_data_info->base_data_info.command_ready = 0; + } + } + + data_buffer = recv_buff + head_length;//remove head data + + if (READ_COIL_STATUS == function_code || READ_INPUT_STATUS == function_code) { + printf("Receive data is "); + for (int i = 0;i < bytes_count;i ++) { + for (int j = 0;j < 8;j ++) { + if ((i * 8 + j) < p_read_item->quantity) { + *(uint8_t *)(p_data + i * 8 + j) = ((data_buffer[i] >> j) & 0x01) ? 1 : 0; + printf("0x%x", *(uint8_t *)(p_data + i * 8 + j)); + } + } + } + } else if (READ_HOLDING_REGISTER == function_code || READ_INPUT_REGISTER == function_code) { + printf("Receive data is "); + for (uint16_t i = 0; i < quantity; i ++) { + ((int16_t *)p_data)[i] = ((int16_t *)data_buffer)[quantity - i - 1]; + printf("0x%x 0x%x ", p_data[2 * i], p_data[2 * i + 1]); + } + } + printf("\n"); + + return 0; +} + +/** + * @description: Modbus Uart Get Data From Serial + * @param p_read_item - read item pointer + * @return success : 0 error : -1 -2 + */ +static int ModbusUartGetDataBySerial(ModbusUartReadItem *p_read_item) +{ + uint32_t read_length = 0; + memset(recv_buff, 0, sizeof(recv_buff)); + + ModbusUartDataInfo *p_modbus_uart_data_info = &(p_read_item->data_info); + BasicPlcDataInfo *p_base_data_info = &(p_modbus_uart_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 ModbusUartTransformRecvBuffToData(p_read_item, recv_buff); + } +} + +/** + * @description: Modbus Uart Data Info Init + * @param p_read_item - read item pointer + * @param station - uart station number + * @param p_data - control-data pointer + * @return success : 0 error : -1 -2 + */ +static int ModbusUartInitialDataInfo(ModbusUartReadItem *p_read_item, uint8_t station, uint8_t *p_data) +{ + uint16_t command_crc = 0; + uint8_t function_code = p_read_item->data_info.function_code; + uint16_t start_address = p_read_item->start_address; + uint16_t quantity = p_read_item->quantity; + + BasicPlcDataInfo *p_base_data_info = &(p_read_item->data_info.base_data_info); + + switch (function_code) + { + case READ_COIL_STATUS: + case READ_INPUT_STATUS: + case READ_HOLDING_REGISTER: + case READ_INPUT_REGISTER: + p_base_data_info->command_length = MODBUS_UART_READ_CMD_LENGTH; + p_base_data_info->p_command = PrivMalloc(p_base_data_info->command_length); + p_base_data_info->p_data = p_data; + p_base_data_info->command_ready = 1; + break; + case WRITE_SINGLE_COIL: + case WRITE_SINGLE_REGISTER: + if (p_data == NULL) { + return -1; + } else { + p_base_data_info->command_length = MODBUS_UART_WRITE_CMD_LENGTH; + p_base_data_info->p_command = PrivMalloc(p_base_data_info->command_length); + p_base_data_info->p_data = p_data; + p_base_data_info->data_size = 2; + p_base_data_info->command_ready = 0; + } + break; + case WRITE_MULTIPLE_COIL: + case WRITE_MULTIPLE_REGISTER: + //to do + printf("%s unsupported function code %d\n", __func__, function_code); + return -1; + default: + return -2; + } + + memset(p_base_data_info->p_command, 0, p_base_data_info->command_length); + + p_base_data_info->p_command[0] = station; + p_base_data_info->p_command[1] = function_code; + p_base_data_info->p_command[2] = start_address >> 8; + p_base_data_info->p_command[3] = start_address; + if ((function_code != WRITE_SINGLE_COIL) && (function_code != WRITE_SINGLE_REGISTER)) { + p_base_data_info->p_command[4] = quantity >> 8; + p_base_data_info->p_command[5] = quantity; + command_crc = ModbusUartCrc16(p_base_data_info->p_command, 6); + p_base_data_info->p_command[6] = command_crc & 0xFF; + p_base_data_info->p_command[7] = (command_crc >> 8) & 0xFF; + } + + return 0; +} + +/** + * @description: Modbus Uart Format write data from "g_write_data" + * @param p_read_item - read item pointer + * @return success : 0 error : -1 -2 + */ +static int ModbusUartForamatWriteData(ModbusUartReadItem *p_read_item) +{ + int i = 0; + uint16_t command_index = 0; + int write_data_length = 0; + uint8_t write_data_buffer[32] = {0}; + + BasicPlcDataInfo *p_base_data_info = &(p_read_item->data_info.base_data_info); + uint8_t *p_command = p_base_data_info->p_command; + uint8_t function_code = p_read_item->data_info.function_code; + + if (function_code < WRITE_SINGLE_COIL) { + return 0; + } + + write_data_length = CircularAreaAppRead(g_write_data, write_data_buffer, p_base_data_info->data_size); + if (p_base_data_info->data_size != write_data_length) { + //printf("%s get write data %d [should be %d]failed!\n", __func__, write_data_length, p_base_data_info->data_size); + return 0; + } + + switch (function_code) + { + case WRITE_SINGLE_COIL: + case WRITE_SINGLE_REGISTER: + command_index = 4; + break; + case WRITE_MULTIPLE_COIL: + case WRITE_MULTIPLE_REGISTER: + printf("%s unsupported function code %d\n", __func__, function_code); + return -1; + default: + return -2; + } + + for (i = 0; i < write_data_length; i ++) { + p_base_data_info->p_command[command_index + i] = write_data_buffer[i]; + } + + p_base_data_info->command_ready = 1; + + return write_data_length; +} + +/** + * @description: Modbus Uart Receive Plc Data Task + * @param parameter - parameter pointer + * @return + */ +void *ReceivePlcDataTask(void *parameter) +{ + int i = 0; + uint8_t try_count = 0; + uint16_t data_length = 0; + uint8_t *modbus_uart_data; + uint16_t read_item_size = sizeof(ModbusUartReadItem); + + struct ControlProtocol *control_protocol = (struct ControlProtocol *)parameter; + struct CircularAreaApp *circular_area = (struct CircularAreaApp *)control_protocol->args; + ModbusUartReadItem *modbus_uart_read_item = (ModbusUartReadItem *)control_protocol->recipe->read_item; + modbus_uart_data = control_protocol->recipe->protocol_data.data; + data_length = control_protocol->recipe->protocol_data.data_length; + + while (1) { + for (i = 0; i < control_protocol->recipe->read_item_count; i ++) { + + ModbusUartForamatWriteData((ModbusUartReadItem *)modbus_uart_read_item + i); + + ModbusUartGetDataBySerial((ModbusUartReadItem *)modbus_uart_read_item + i); + } + + /*read all variable item data, put them into circular_area*/ + if (i == control_protocol->recipe->read_item_count) { + printf("%s get %d item %d length modbus_uart_data %p\n", __func__, i, data_length, modbus_uart_data); + CircularAreaAppWrite(circular_area, modbus_uart_data, data_length, 0); + } + + /*read data every single 'read_period' ms*/ + PrivTaskDelay(control_protocol->recipe->read_period); + } +} + +/** + * @description: Modbus Uart Protocol Open + * @param control_protocol - control protocol pointer + * @return success : 0 error + */ +int ModbusUartOpen(struct ControlProtocol *control_protocol) +{ + ControlProtocolOpenDef(control_protocol); + + g_write_data = CircularAreaAppInit(CA_DATA_LENGTH); + if (NULL == g_write_data) { + printf("%s CircularAreaInit error\n", __func__); + return -1; + } + + return 0; +} + +/** + * @description: Modbus Uart Protocol Close + * @param control_protocol - control protocol pointer + * @return success : 0 error + */ +int ModbusUartClose(struct ControlProtocol *control_protocol) +{ + CircularAreaAppRelease(g_write_data); + + ControlProtocolCloseDef(); + + return 0; +} + +/** + * @description: Modbus Uart Protocol Read Data + * @param control_protocol - control protocol pointer + * @param buf - read data buffer + * @param len - read data length + * @return success : data length error : 0 + */ +int ModbusUartRead(struct ControlProtocol *control_protocol, void *buf, size_t len) +{ + struct CircularAreaApp *circular_area = (struct CircularAreaApp *)control_protocol->args; + return CircularAreaAppRead(circular_area, buf, len); +} + +/** + * @description: Modbus Uart Protocol Write Data + * @param control_protocol - control protocol pointer + * @param buf - write data buffer + * @param len - write data length + * @return success : data length error : 0 + */ +int ModbusUartWrite(struct ControlProtocol *control_protocol, const void *buf, size_t len) +{ + CircularAreaAppWrite(g_write_data, (uint8_t *)buf, len, 0); + + return 0; +} + +/** + * @description: Modbus Uart Protocol Ioctl + * @param control_protocol - control protocol pointer + * @param cmd - ioctl cmd + * @param args - ioctl args + * @return success : data length error : 0 + */ +int ModbusUartIoctl(struct ControlProtocol *control_protocol, int cmd, void *args) +{ + //to do + return 0; +} + +static struct ControlDone modbusuart_protocol_done = +{ + ._open = ModbusUartOpen, + ._close = ModbusUartClose, + ._read = ModbusUartRead, + ._write = ModbusUartWrite, + ._ioctl = ModbusUartIoctl, +}; + +/** + * @description: Modbus TCP Protocol Cmd Generate + * @param p_recipe - recipe pointer + * @param protocol_format_info - protocol format info pointer + * @return success : 0 error : -1 + */ +int ModbusUartProtocolFormatCmd(struct ControlRecipe *p_recipe, ProtocolFormatInfo *protocol_format_info) +{ + int ret = 0; + static uint8_t last_item_size = 0; + uint8_t *p_read_item_data = protocol_format_info->p_read_item_data + last_item_size; + + ModbusUartReadItem *modbusuart_read_item = (ModbusUartReadItem *)(p_recipe->read_item) + protocol_format_info->read_item_index; + + modbusuart_read_item->value_type = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "value_type")->valueint; + strncpy(modbusuart_read_item->value_name, cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "value_name")->valuestring, 20); + modbusuart_read_item->data_info.function_code = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "function_code")->valueint; + modbusuart_read_item->start_address = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "start_address")->valueint; + modbusuart_read_item->quantity = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "quantity")->valueint; + + ret = ModbusUartInitialDataInfo(modbusuart_read_item, + p_recipe->serial_config.station, + p_read_item_data); + + ControlPrintfList("CMD", modbusuart_read_item->data_info.base_data_info.p_command, modbusuart_read_item->data_info.base_data_info.command_length); + protocol_format_info->last_item_size = GetValueTypeMemorySize(modbusuart_read_item->value_type); + + last_item_size += protocol_format_info->last_item_size; + + return ret; + +} + +/** + * @description: Modbus TCP Protocol Init + * @param p_recipe - recipe pointer + * @return success : 0 error : -1 + */ +int ModbusUartProtocolInit(struct ControlRecipe *p_recipe) +{ + p_recipe->read_item = PrivMalloc(sizeof(ModbusUartReadItem) * p_recipe->read_item_count); + if (NULL == p_recipe->read_item) { + PrivFree(p_recipe->read_item); + return -1; + } + + memset(p_recipe->read_item, 0, sizeof(ModbusUartReadItem)); + + p_recipe->ControlProtocolFormatCmd = ModbusUartProtocolFormatCmd; + + p_recipe->done = &modbusuart_protocol_done; + + return 0; +} diff --git a/APP_Framework/Framework/control/ipc_protocol/modbus_uart/test_recipe_modbus_uart.json b/APP_Framework/Framework/control/ipc_protocol/modbus_uart/test_recipe_modbus_uart.json new file mode 100644 index 000000000..613d010c6 --- /dev/null +++ b/APP_Framework/Framework/control/ipc_protocol/modbus_uart/test_recipe_modbus_uart.json @@ -0,0 +1,30 @@ +{ + "device_id": 1, + "device_name": "GJ2", + "communication_type": 1, + "serial_config": { + "station": 1, + "baud_rate": 9600, + "data_bits": 8, + "stop_bits": 1, + "check_mode": 0 + }, + "protocol_type": 3, + "read_period": 100, + "read_item_list": [ + { + "value_name": "M0", + "value_type": 1, + "function_code": 1, + "start_address": 8192, + "quantity": 1 + }, + { + "value_name": "D208", + "value_type": 9, + "function_code": 3, + "start_address": 208, + "quantity": 2 + } + ] +} \ No newline at end of file diff --git a/APP_Framework/Framework/control/plc_protocol/Kconfig b/APP_Framework/Framework/control/plc_protocol/Kconfig index 11d498f81..46f632974 100755 --- a/APP_Framework/Framework/control/plc_protocol/Kconfig +++ b/APP_Framework/Framework/control/plc_protocol/Kconfig @@ -1,6 +1,7 @@ config CONTROL_PROTOCOL_FINS bool "Using fins control protocol" default n + select BSP_USING_LWIP if CONTROL_PROTOCOL_FINS source "$APP_DIR/Framework/control/plc_protocol/fins/Kconfig" endif diff --git a/APP_Framework/Framework/control/plc_protocol/fins/Kconfig b/APP_Framework/Framework/control/plc_protocol/fins/Kconfig index 139597f9c..8b1378917 100755 --- a/APP_Framework/Framework/control/plc_protocol/fins/Kconfig +++ b/APP_Framework/Framework/control/plc_protocol/fins/Kconfig @@ -1,2 +1 @@ - diff --git a/APP_Framework/Framework/control/plc_protocol/melsec/Kconfig b/APP_Framework/Framework/control/plc_protocol/melsec/Kconfig index 93392b091..8a8d32c5a 100755 --- a/APP_Framework/Framework/control/plc_protocol/melsec/Kconfig +++ b/APP_Framework/Framework/control/plc_protocol/melsec/Kconfig @@ -4,17 +4,61 @@ choice config CONTROL_PROTOCOL_MELSEC_1E bool "support melsec_1e protocol, using TCP" + select BSP_USING_LWIP config CONTROL_PROTOCOL_MELSEC_3E_Q_L bool "support melsec_3e_q_l protocol, using TCP" + select BSP_USING_LWIP config CONTROL_PROTOCOL_MELSEC_3E_IQ_R bool "support melsec_3e_iq_r protocol, using TCP" + select BSP_USING_LWIP config CONTROL_PROTOCOL_MELSEC_1C bool "support melsec_1c protocol, using SERIAL" + select BSP_USING_SERIAL_485 config CONTROL_PROTOCOL_MELSEC_3C bool "support melsec_3c protocol, using SERIAL" + select BSP_USING_SERIAL_485 endchoice +if BSP_USING_SERIAL_485 + if ADD_XIZI_FETURES + config CONTROL_FRAMEWORK_UART_485_DIR + int "control framework 485 direction pin number" + default "2" + + config CONTROL_FRAMEWORK_PIN_DEV + string "control framework device pin dev path" + default "/dev/pin_dev" + + config CONTROL_FRAMEWORK_DRIVER_EXTUART + bool "Using extra uart to control framework" + default n + + config CONTROL_FRAMEWORK_UART_DEV + string "control framework device uart dev path" + default "/dev/uart3_dev3" + depends on !CONTROL_FRAMEWORK_DRIVER_EXTUART + + if CONTROL_FRAMEWORK_DRIVER_EXTUART + config CONTROL_FRAMEWORK_UART_DEV + string "control framework device extra uart dev path" + default "/dev/extuart_dev0" + + config CONTROL_FRAMEWORK_DEV_EXT_PORT + int "if control framework device using extuart, choose port" + default "0" + endif + endif + + if ADD_NUTTX_FETURES + + endif + + if ADD_RTTHREAD_FETURES + + endif + +endif diff --git a/APP_Framework/Framework/control/plc_protocol/melsec/melsec.c b/APP_Framework/Framework/control/plc_protocol/melsec/melsec.c index 465d2b532..584fbdaf5 100644 --- a/APP_Framework/Framework/control/plc_protocol/melsec/melsec.c +++ b/APP_Framework/Framework/control/plc_protocol/melsec/melsec.c @@ -575,6 +575,7 @@ static int MelsecTransformRecvBuffToData(MelsecReadItem *p_read_item, uint8_t *r return 0; } +#ifdef BSP_USING_LWIP /** * @description: Melsec Get Data From Socket * @param socket - socket @@ -619,6 +620,7 @@ static int MelsecGetDataBySocket(int32_t socket, MelsecReadItem *p_read_item) } return -2; } +#endif /** * @description: Melsec Get Data From Serial @@ -673,12 +675,14 @@ void *ReceivePlcDataTask(void *parameter) if ((PROTOCOL_MELSEC_1C == control_protocol->protocol_type) || (PROTOCOL_MELSEC_3C == control_protocol->protocol_type)) { MelsecGetDataBySerial((MelsecReadItem *)melsec_read_item + i); } else { +#ifdef BSP_USING_LWIP /*only connect socket when close socket or init*/ while (ControlConnectSocket(&plc_socket) < 0) { PrivTaskDelay(1000); } MelsecGetDataBySocket(plc_socket.socket, (MelsecReadItem *)melsec_read_item + i); +#endif } } @@ -712,8 +716,12 @@ int MelsecOpen(struct ControlProtocol *control_protocol) */ int MelsecClose(struct ControlProtocol *control_protocol) { - ControlDisconnectSocket(&plc_socket); - + if ((PROTOCOL_MELSEC_1C != control_protocol->protocol_type) && (PROTOCOL_MELSEC_3C != control_protocol->protocol_type)) { +#ifdef BSP_USING_LWIP + ControlDisconnectSocket(&plc_socket); +#endif + } + ControlProtocolCloseDef(); return 0; diff --git a/APP_Framework/Framework/control/plc_protocol/melsec/test_recipe_melsec_1c.json b/APP_Framework/Framework/control/plc_protocol/melsec/test_recipe_melsec_1c.json index ee43fe00c..7c67c0263 100644 --- a/APP_Framework/Framework/control/plc_protocol/melsec/test_recipe_melsec_1c.json +++ b/APP_Framework/Framework/control/plc_protocol/melsec/test_recipe_melsec_1c.json @@ -3,6 +3,7 @@ "device_name": "S01", "communication_type": 1, "serial_config": { + "station": 1, "baud_rate": 19200, "data_bits": 7, "stop_bits": 1, diff --git a/APP_Framework/Framework/control/plc_protocol/melsec/test_recipe_melsec_3c.json b/APP_Framework/Framework/control/plc_protocol/melsec/test_recipe_melsec_3c.json index 097acbdbd..5fb0e0dc2 100644 --- a/APP_Framework/Framework/control/plc_protocol/melsec/test_recipe_melsec_3c.json +++ b/APP_Framework/Framework/control/plc_protocol/melsec/test_recipe_melsec_3c.json @@ -3,6 +3,7 @@ "device_name": "S02", "communication_type": 1, "serial_config": { + "station": 1, "baud_rate": 19200, "data_bits": 7, "stop_bits": 1, diff --git a/APP_Framework/Framework/control/shared/control_def.c b/APP_Framework/Framework/control/shared/control_def.c index 306b1b5f4..3168af845 100644 --- a/APP_Framework/Framework/control/shared/control_def.c +++ b/APP_Framework/Framework/control/shared/control_def.c @@ -143,12 +143,13 @@ static uint16_t GetRecipeTotalDataLength(cJSON* read_item_list_json) static void ControlBasicSerialConfig(struct ControlRecipe *p_recipe, cJSON *p_recipe_file_json) { cJSON *p_serial_config_json = cJSON_GetObjectItem(p_recipe_file_json, "serial_config"); + p_recipe->serial_config.station = cJSON_GetObjectItem(p_serial_config_json, "station")->valueint; p_recipe->serial_config.baud_rate = cJSON_GetObjectItem(p_serial_config_json, "baud_rate")->valueint; p_recipe->serial_config.data_bits = cJSON_GetObjectItem(p_serial_config_json, "data_bits")->valueint; p_recipe->serial_config.stop_bits = cJSON_GetObjectItem(p_serial_config_json, "stop_bits")->valueint; p_recipe->serial_config.check_mode = cJSON_GetObjectItem(p_serial_config_json, "check_mode")->valueint; - printf("Serial_config: baud_rate: %d, data_bits: %d, stop_bits: %d, check_mode is %d\n", - p_recipe->serial_config.baud_rate, p_recipe->serial_config.data_bits, p_recipe->serial_config.stop_bits, p_recipe->serial_config.check_mode); + printf("Serial_config:station: %d baud_rate: %d, data_bits: %d, stop_bits: %d, check_mode is %d\n", + p_recipe->serial_config.station, p_recipe->serial_config.baud_rate, p_recipe->serial_config.data_bits, p_recipe->serial_config.stop_bits, p_recipe->serial_config.check_mode); } /** @@ -209,6 +210,7 @@ void ControlPrintfList(char name[5], uint8_t *number_list, uint16_t length) printf("\n**************************************\n"); } +#ifdef BSP_USING_LWIP /** * @description: Control Framework Connect Socket * @param p_plc - basic socket plc pointer @@ -285,6 +287,7 @@ int ControlDisconnectSocket(BasicSocketPlc *p_plc) return error; } +#endif /** * @description: Control Framework Protocol Open for Sub_Protocol, Init Circular Area and Receive Data Task diff --git a/APP_Framework/Framework/control/shared/control_def.h b/APP_Framework/Framework/control/shared/control_def.h index fced6fd80..96957ad20 100644 --- a/APP_Framework/Framework/control/shared/control_def.h +++ b/APP_Framework/Framework/control/shared/control_def.h @@ -90,6 +90,7 @@ struct ProtocolData struct SerialConfig { + uint8_t station; uint32_t baud_rate; uint8_t data_bits; uint8_t stop_bits; diff --git a/APP_Framework/Framework/control/shared/control_io.c b/APP_Framework/Framework/control/shared/control_io.c index b1a8ae1c8..0bc8b77d7 100644 --- a/APP_Framework/Framework/control/shared/control_io.c +++ b/APP_Framework/Framework/control/shared/control_io.c @@ -20,6 +20,92 @@ #include +#ifdef BSP_USING_SERIAL_485 +static int pin_fd = 0; +static int uart_fd = 0; + +/** + * @description: Set Uart 485 Input + * @return + */ +static void Set485Input(void) +{ + struct PinStat pin_stat; + pin_stat.pin = CONTROL_FRAMEWORK_UART_485_DIR; + pin_stat.val = GPIO_LOW; + PrivWrite(pin_fd, &pin_stat, 1); +} + +/** + * @description: Set Uart 485 Output + * @return + */ +static void Set485Output(void) +{ + struct PinStat pin_stat; + pin_stat.pin = CONTROL_FRAMEWORK_UART_485_DIR; + pin_stat.val = GPIO_HIGH; + PrivWrite(pin_fd, &pin_stat, 1); +} + +/** + * @description: Control Framework Uart 485 Init + * @param baud_rate - baud rate + * @param data_bits - data bits + * @param stop_bits - stop bits + * @param check_mode - check mode, even、odd、none + * @return + */ +void Uart485Init(uint32_t baud_rate, uint8_t data_bits, uint8_t stop_bits, uint8_t check_mode) +{ + int ret = 0; + + pin_fd = PrivOpen(CONTROL_FRAMEWORK_PIN_DEV, O_RDWR); + if (pin_fd < 0) { + printf("open %s error\n", CONTROL_FRAMEWORK_PIN_DEV); + return; + } + + struct PinParam pin_param; + pin_param.cmd = GPIO_CONFIG_MODE; + pin_param.mode = GPIO_CFG_OUTPUT; + pin_param.pin = CONTROL_FRAMEWORK_UART_485_DIR; + + struct PrivIoctlCfg ioctl_cfg; + ioctl_cfg.ioctl_driver_type = PIN_TYPE; + ioctl_cfg.args = &pin_param; + PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg); + + uart_fd = open(CONTROL_FRAMEWORK_UART_DEV, O_RDWR); + if (uart_fd < 0) { + printf("open fd error %d\n", uart_fd); + return; + } + printf("Uart485Init open fd %d\n", uart_fd); + + struct SerialDataCfg cfg; + cfg.serial_baud_rate = baud_rate; + cfg.serial_data_bits = data_bits; + cfg.serial_stop_bits = stop_bits; + cfg.serial_buffer_size = 128; + cfg.serial_parity_mode = check_mode; + cfg.serial_bit_order = 0; + cfg.serial_invert_mode = 0; +#ifdef CONTROL_FRAMEWORK_DRIVER_EXTUART + cfg.ext_uart_no = 0; + cfg.port_configure = PORT_CFG_INIT; +#endif + cfg.serial_timeout = 10000; + + if (ret != PrivIoctl(uart_fd, OPE_INT, &cfg)) { + printf("ioctl fd error %d\n", ret); + return; + } + + printf("%s done!\n", __func__); +} +#endif + /** * @description: Control Framework Socket Init * @param ip - local ip pointer @@ -48,7 +134,9 @@ void SocketInit(char *ip, char *mask, char *gw) */ void SerialInit(uint32_t baud_rate, uint8_t data_bits, uint8_t stop_bits, uint8_t check_mode) { - // Uart485Init(baud_rate, data_bits, stop_bits, check_mode); +#ifdef BSP_USING_SERIAL_485 + Uart485Init(baud_rate, data_bits, stop_bits, check_mode); +#endif } /** @@ -59,16 +147,41 @@ void SerialInit(uint32_t baud_rate, uint8_t data_bits, uint8_t stop_bits, uint8_ */ void SerialWrite(uint8_t *write_data, int length) { - //to do +#ifdef BSP_USING_SERIAL_485 + Set485Output(); + PrivTaskDelay(20); + + PrivWrite(uart_fd, write_data, length); + + PrivTaskDelay(10); + Set485Input(); +#endif } /** * @description: Control Framework Serial Read * @param read_data - read data * @param length - length - * @return + * @return read data size */ int SerialRead(uint8_t *read_data, int length) { - //to do +#ifdef BSP_USING_SERIAL_485 + int data_size = 0; + int data_recv_size = 0; + + while (data_size < length) { + data_recv_size = PrivRead(uart_fd, read_data + data_recv_size, length); + // for (int i = 0; i < data_recv_size; i ++) { + // printf("idx %d data 0x%x\n", i, recv_data[i + data_size]); + // } + + data_size += data_recv_size; + } + + //need to wait 25ms , make sure write cmd again and receive data successfully + PrivTaskDelay(25); + + return data_size; +#endif }