diff --git a/APP_Framework/Applications/connection_app/4g_app/4g_app.c b/APP_Framework/Applications/connection_app/4g_app/4g_app.c new file mode 100644 index 000000000..fc7eb0213 --- /dev/null +++ b/APP_Framework/Applications/connection_app/4g_app/4g_app.c @@ -0,0 +1,133 @@ +/* + * 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 4g_app.c + * @brief support get data from and send data to 4g server + * @version 3.0 + * @author AIIT XUOS Lab + * @date 2022.12.12 + */ + +#include +#include +#include +#include + +static uint8_t adapter_4g_status = 0; +static pthread_t recv_4g_heart_task; +struct Adapter *adapter_4g; + +static const uint8_t server_addr[] = "xxx.xxx.xxx.xxx"; +static const uint8_t server_port[] = "xxx"; + +#define ADAPTER_4G_HEART "HEART" + +int Adapter4GConnectFunction(struct Adapter *adapter, uint8_t reconnect) +{ + int ret = 0; + int baud_rate = BAUD_RATE_115200; + + if (1 != reconnect) { + ret = AdapterDeviceOpen(adapter); + if (ret < 0) { + goto out; + } + + ret = AdapterDeviceControl(adapter, OPE_INT, &baud_rate); + if (ret < 0) { + goto out; + } + } + + ret = AdapterDeviceConnect(adapter, CLIENT, server_addr, server_port, IPV4); + if (ret < 0) { + goto out; + } + +out: + if (ret < 0) { + AdapterDeviceClose(adapter); + } + return ret; +} + +void Adapter4gSend(uint8_t *send_data, size_t length) +{ + if (adapter_4g_status) { + AdapterDeviceSend(adapter_4g, send_data, length); + } +} + +static void *Receive4gHeartTask(void* parameter) +{ + char recv_msg[16] = {0}; + ssize_t recv_length = 0; + uint8_t net_status_cnt = 0; + + while (1) { + + SetTaskStatus(0x01); + + if (net_status_cnt > 5) { + adapter_4g_status = 0; + + while (Adapter4GConnectFunction(adapter_4g, 1) < 0) { + PrivTaskDelay(10000); + } + + net_status_cnt = 0; + } + + adapter_4g_status = 1; + + recv_length = AdapterDeviceRecv(adapter_4g, recv_msg, 6); + if (recv_length > 0) { + //if (0 == strcmp(recv_msg, ADAPTER_4G_HEART)) { + net_status_cnt = 0; + //} + } else { + printf("4G recv heart error re-recv cnt %d\n", net_status_cnt); + net_status_cnt++; + } + memset(recv_msg, 0, sizeof(recv_msg)); + } +} + +int Adapter4GActive(void) +{ + int ret = 0; + adapter_4g = AdapterDeviceFindByName(ADAPTER_4G_NAME); + +#ifdef ADAPTER_EC200T + adapter_4g->socket.socket_id = 0; + + ret = Adapter4GConnectFunction(adapter_4g, 0); + if (ret < 0) { + printf("Adapter4GConnect failed %d\n", ret); + } + + adapter_4g_status = 1; + + pthread_attr_t attr; + attr.schedparam.sched_priority = 22; + attr.stacksize = 2048; + + PrivTaskCreate(&recv_4g_heart_task, &attr, &Receive4gHeartTask, NULL); + PrivTaskStartup(&recv_4g_heart_task); + +#endif + + return ret; +} + + diff --git a/APP_Framework/Applications/connection_app/4g_app/Makefile b/APP_Framework/Applications/connection_app/4g_app/Makefile new file mode 100644 index 000000000..68d972542 --- /dev/null +++ b/APP_Framework/Applications/connection_app/4g_app/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := 4g_app.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/APP_Framework/Applications/connection_app/Makefile b/APP_Framework/Applications/connection_app/Makefile index f50c4dbda..df4ae9b97 100755 --- a/APP_Framework/Applications/connection_app/Makefile +++ b/APP_Framework/Applications/connection_app/Makefile @@ -1,6 +1,3 @@ - -ifeq ($(CONFIG_SOCKET_DEMO),y) - include $(KERNEL_ROOT)/.config ifeq ($(CONFIG_ADD_NUTTX_FETURES),y) @@ -10,6 +7,10 @@ endif ifeq ($(CONFIG_ADD_XIZI_FETURES),y) + ifeq ($(CONFIG_CONNECTION_ADAPTER_4G),y) + SRC_DIR += 4g_app + endif + ifeq ($(CONFIG_RESOURCES_LWIP),y) SRC_DIR += socket_demo endif @@ -17,4 +18,3 @@ ifeq ($(CONFIG_ADD_XIZI_FETURES),y) include $(KERNEL_ROOT)/compiler.mk endif -endif diff --git a/APP_Framework/Applications/connection_app/socket_demo/lwip_tcp_socket_demo.c b/APP_Framework/Applications/connection_app/socket_demo/lwip_tcp_socket_demo.c index b6e4f9428..48f147fe9 100755 --- a/APP_Framework/Applications/connection_app/socket_demo/lwip_tcp_socket_demo.c +++ b/APP_Framework/Applications/connection_app/socket_demo/lwip_tcp_socket_demo.c @@ -21,7 +21,7 @@ #include #ifdef ADD_XIZI_FETURES -#include "sys_arch.h" +#include #include #include "lwip/sys.h" #endif @@ -33,9 +33,17 @@ #include "stdio.h" #endif -#define TCP_DEMO_BUF_SIZE 65535 +#define TCP_DEMO_BUF_SIZE 65535 +#define TCP_DEMO_SEND_TIMES 20 +#define LWIP_TCP_DEMO_TASK_STACK_SIZE 4096 +#define LWIP_TCP_DEMO_TASK_PRIO 20 -char tcp_socket_ip[] = {192, 168, 250, 252}; +static pthread_t tcp_client_task; +static pthread_t tcp_server_task; + +static char tcp_demo_ipaddr[] = {192, 168, 131, 77}; +static char tcp_demo_netmask[] = {255, 255, 254, 0}; +static char tcp_demo_gwaddr[] = {192, 168, 131, 1}; #ifdef ADD_NUTTX_FETURES #define lw_print printf @@ -46,8 +54,8 @@ char tcp_socket_ip[] = {192, 168, 250, 252}; #define LWIP_TARGET_PORT 4840 #endif -uint16_t tcp_socket_port = LWIP_TARGET_PORT; -char tcp_ip_str[128] = {0}; +static uint16_t tcp_socket_port = 8888; +static char tcp_ip_str[128] = {0}; /******************************************************************************/ void TcpSocketConfigParam(char *ip_str) @@ -55,35 +63,23 @@ void TcpSocketConfigParam(char *ip_str) int ip1, ip2, ip3, ip4, port = 0; if(ip_str == NULL) - { return; - } - if(sscanf(ip_str, "%d.%d.%d.%d:%d", &ip1, &ip2, &ip3, &ip4, &port)) - { + if(sscanf(ip_str, "%d.%d.%d.%d:%d", &ip1, &ip2, &ip3, &ip4, &port)) { printf("config ip %s port %d\n", ip_str, port); strcpy(tcp_ip_str, ip_str); - tcp_socket_ip[0] = ip1; - tcp_socket_ip[1] = ip2; - tcp_socket_ip[2] = ip3; - tcp_socket_ip[3] = ip4; if(port) tcp_socket_port = port; return; } - if(sscanf(ip_str, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4)) - { + if(sscanf(ip_str, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4)) { printf("config ip %s\n", ip_str); - tcp_socket_ip[0] = ip1; - tcp_socket_ip[1] = ip2; - tcp_socket_ip[2] = ip3; - tcp_socket_ip[3] = ip4; strcpy(tcp_ip_str, ip_str); } } -static void TcpSocketRecvTask(void *arg) +static void *TcpSocketRecvTask(void *arg) { int fd = -1, clientfd; int recv_len; @@ -91,18 +87,15 @@ static void TcpSocketRecvTask(void *arg) struct sockaddr_in tcp_addr; socklen_t addr_len; - while(1) - { + while(1) { recv_buf = (char *)malloc(TCP_DEMO_BUF_SIZE); - if (recv_buf == NULL) - { + if (recv_buf == NULL) { lw_error("No memory\n"); continue; } fd = socket(AF_INET, SOCK_STREAM, 0); - if (fd < 0) - { + if (fd < 0) { lw_error("Socket error\n"); free(recv_buf); continue; @@ -113,8 +106,7 @@ static void TcpSocketRecvTask(void *arg) tcp_addr.sin_port = htons(tcp_socket_port); memset(&(tcp_addr.sin_zero), 0, sizeof(tcp_addr.sin_zero)); - if (bind(fd, (struct sockaddr *)&tcp_addr, sizeof(struct sockaddr)) == -1) - { + if (bind(fd, (struct sockaddr *)&tcp_addr, sizeof(struct sockaddr)) == -1) { lw_error("Unable to bind\n"); close(fd); free(recv_buf); @@ -125,8 +117,7 @@ static void TcpSocketRecvTask(void *arg) lw_notice("\nLocal Port:%d\n", tcp_socket_port); // setup socket fd as listening mode - if (listen(fd, 5) != 0 ) - { + if (listen(fd, 5) != 0 ) { lw_error("Unable to listen\n"); close(fd); free(recv_buf); @@ -137,13 +128,11 @@ static void TcpSocketRecvTask(void *arg) clientfd = accept(fd, (struct sockaddr *)&tcp_addr, (socklen_t*)&addr_len); lw_notice("client %s connected\n", inet_ntoa(tcp_addr.sin_addr)); - while(1) - { + while(1) { memset(recv_buf, 0, TCP_DEMO_BUF_SIZE); recv_len = recvfrom(clientfd, recv_buf, TCP_DEMO_BUF_SIZE, 0, (struct sockaddr *)&tcp_addr, &addr_len); - if(recv_len > 0) - { + if(recv_len > 0) { lw_notice("Receive from : %s\n", inet_ntoa(tcp_addr.sin_addr)); lw_notice("Receive data : %d - %s\n\n", recv_len, recv_buf); } @@ -157,26 +146,33 @@ static void TcpSocketRecvTask(void *arg) void TcpSocketRecvTest(int argc, char *argv[]) { - if(argc >= 2) - { + if(argc >= 2) { lw_print("lw: [%s] target ip %s\n", __func__, argv[1]); TcpSocketConfigParam(argv[1]); } #ifdef ADD_XIZI_FETURES - lwip_config_tcp(0, lwip_ipaddr, lwip_netmask, tcp_socket_ip); - sys_thread_new("TcpSocketRecvTask", TcpSocketRecvTask, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO); + lwip_config_tcp(0, tcp_demo_ipaddr, tcp_demo_netmask, tcp_demo_gwaddr); + + pthread_attr_t attr; + attr.schedparam.sched_priority = LWIP_TCP_DEMO_TASK_PRIO; + attr.stacksize = LWIP_TCP_DEMO_TASK_STACK_SIZE; #endif #ifdef ADD_NUTTX_FETURES - TcpSocketRecvTask(NULL); + pthread_attr_t attr = PTHREAD_ATTR_INITIALIZER; + attr.priority = LWIP_TCP_DEMO_TASK_PRIO; + attr.stacksize = LWIP_TCP_DEMO_TASK_STACK_SIZE; #endif + + PrivTaskCreate(&tcp_server_task, &attr, &TcpSocketRecvTask, NULL); + PrivTaskStartup(&tcp_server_task); } PRIV_SHELL_CMD_FUNCTION(TcpSocketRecvTest, a tcp receive sample, PRIV_SHELL_CMD_MAIN_ATTR); -static void TcpSocketSendTask(void *arg) +static void *TcpSocketSendTask(void *arg) { - int cnt = LWIP_DEMO_TIMES; + int cnt = TCP_DEMO_SEND_TIMES; int fd = -1; int ret; char send_msg[128]; @@ -186,10 +182,9 @@ static void TcpSocketSendTask(void *arg) memset(send_msg, 0, sizeof(send_msg)); fd = socket(AF_INET, SOCK_STREAM, 0); - if (fd < 0) - { + if (fd < 0) { lw_print("Socket error\n"); - return; + return NULL; } struct sockaddr_in tcp_sock; @@ -200,17 +195,15 @@ static void TcpSocketSendTask(void *arg) memset(&(tcp_sock.sin_zero), 0, sizeof(tcp_sock.sin_zero)); ret = connect(fd, (struct sockaddr *)&tcp_sock, sizeof(struct sockaddr)); - if (ret) - { - lw_print("Unable to connect %s = %d\n", tcp_ip_str, ret); + if (ret < 0) { + lw_print("Unable to connect %s:%d = %d\n", tcp_ip_str, tcp_socket_port, ret); close(fd); - return; + return NULL; } lw_print("TCP connect %s:%d success, start to send.\n", tcp_ip_str, tcp_socket_port); - while (cnt --) - { + while (cnt --) { lw_print("Lwip client is running.\n"); snprintf(send_msg, sizeof(send_msg), "TCP test package times %d\r\n", cnt); send(fd, send_msg, strlen(send_msg), 0); @@ -219,24 +212,31 @@ static void TcpSocketSendTask(void *arg) } close(fd); - return; + return NULL; } void TcpSocketSendTest(int argc, char *argv[]) { - if(argc >= 2) - { + if(argc >= 2) { lw_print("lw: [%s] target ip %s\n", __func__, argv[1]); TcpSocketConfigParam(argv[1]); } #ifdef ADD_XIZI_FETURES - lwip_config_tcp(0, lwip_ipaddr, lwip_netmask, tcp_socket_ip); - sys_thread_new("Tcp Socket Send", TcpSocketSendTask, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO); + lwip_config_tcp(0, tcp_demo_ipaddr, tcp_demo_netmask, tcp_demo_gwaddr); + + pthread_attr_t attr; + attr.schedparam.sched_priority = LWIP_TCP_DEMO_TASK_PRIO; + attr.stacksize = LWIP_TCP_DEMO_TASK_STACK_SIZE; #endif #ifdef ADD_NUTTX_FETURES - TcpSocketSendTask(NULL); + pthread_attr_t attr = PTHREAD_ATTR_INITIALIZER; + attr.priority = LWIP_TCP_DEMO_TASK_PRIO; + attr.stacksize = LWIP_TCP_DEMO_TASK_STACK_SIZE; #endif + + PrivTaskCreate(&tcp_client_task, &attr, &TcpSocketSendTask, NULL); + PrivTaskStartup(&tcp_client_task); } PRIV_SHELL_CMD_FUNCTION(TcpSocketSendTest, a tcp send sample, PRIV_SHELL_CMD_MAIN_ATTR); diff --git a/APP_Framework/Applications/connection_app/socket_demo/lwip_udp_socket_demo.c b/APP_Framework/Applications/connection_app/socket_demo/lwip_udp_socket_demo.c index 51c94a6c3..30a8a6a59 100755 --- a/APP_Framework/Applications/connection_app/socket_demo/lwip_udp_socket_demo.c +++ b/APP_Framework/Applications/connection_app/socket_demo/lwip_udp_socket_demo.c @@ -20,7 +20,7 @@ #include #ifdef ADD_XIZI_FETURES -#include "sys_arch.h" +#include #include "lwip/sockets.h" #endif @@ -38,11 +38,20 @@ #define lw_print printf #endif -#define UDP_BUF_SIZE 65536 +#define UDP_DEMO_BUF_SIZE 65535 +#define UDP_DEMO_SEND_TIMES 20 +#define LWIP_UDP_DEMO_TASK_STACK_SIZE 4096 +#define LWIP_UDP_DEMO_TASK_PRIO 20 -char udp_socket_ip[] = {192, 168, 250, 252}; -char udp_ip_str[128] = {0}; -uint16_t udp_socket_port = LWIP_LOCAL_PORT; +static pthread_t udp_client_task; +static pthread_t udp_server_task; + +static char udp_demo_ipaddr[] = {192, 168, 131, 77}; +static char udp_demo_netmask[] = {255, 255, 254, 0}; +static char udp_demo_gwaddr[] = {192, 168, 131, 1}; + +static char udp_ip_str[128] = {0}; +static uint16_t udp_socket_port = 8888; /*****************************************************************************/ void UdpSocketConfigParam(char *ip_str) @@ -50,53 +59,38 @@ void UdpSocketConfigParam(char *ip_str) int ip1, ip2, ip3, ip4, port = 0; if(ip_str == NULL) - { return; - } - if(sscanf(ip_str, "%d.%d.%d.%d:%d", &ip1, &ip2, &ip3, &ip4, &port)) - { + if(sscanf(ip_str, "%d.%d.%d.%d:%d", &ip1, &ip2, &ip3, &ip4, &port)) { printf("config ip %s port %d\n", ip_str, port); strcpy(udp_ip_str, ip_str); - udp_socket_ip[0] = ip1; - udp_socket_ip[1] = ip2; - udp_socket_ip[2] = ip3; - udp_socket_ip[3] = ip4; if(port) udp_socket_port = port; return; } - if(sscanf(ip_str, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4)) - { + if(sscanf(ip_str, "%d.%d.%d.%d", &ip1, &ip2, &ip3, &ip4)) { printf("config ip %s\n", ip_str); - udp_socket_ip[0] = ip1; - udp_socket_ip[1] = ip2; - udp_socket_ip[2] = ip3; - udp_socket_ip[3] = ip4; strcpy(udp_ip_str, ip_str); } } -static void UdpSocketRecvTask(void *arg) +static void *UdpSocketRecvTask(void *arg) { int fd = -1; char *recv_buf; struct sockaddr_in udp_addr, server_addr; int recv_len; - while(1) - { - recv_buf = (char *)malloc(UDP_BUF_SIZE); - if(recv_buf == NULL) - { + while(1) { + recv_buf = (char *)PrivMalloc(UDP_DEMO_BUF_SIZE); + if(recv_buf == NULL) { lw_error("No memory\n"); continue; } fd = socket(AF_INET, SOCK_DGRAM, 0); - if(fd < 0) - { + if(fd < 0) { lw_error("Socket error\n"); free(recv_buf); continue; @@ -107,8 +101,7 @@ static void UdpSocketRecvTask(void *arg) udp_addr.sin_port = htons(udp_socket_port); memset(&(udp_addr.sin_zero), 0, sizeof(udp_addr.sin_zero)); - if(bind(fd, (struct sockaddr *)&udp_addr, sizeof(struct sockaddr)) == -1) - { + if(bind(fd, (struct sockaddr *)&udp_addr, sizeof(struct sockaddr)) == -1) { lw_error("Unable to bind\n"); close(fd); free(recv_buf); @@ -118,12 +111,10 @@ static void UdpSocketRecvTask(void *arg) lw_notice("UDP bind success, start to receive.\n"); lw_notice("\n\nLocal Port:%d\n\n", udp_socket_port); - while(1) - { - memset(recv_buf, 0, UDP_BUF_SIZE); - recv_len = recv(fd, recv_buf, UDP_BUF_SIZE, 0); - if(recv_len > 0) - { + while(1) { + memset(recv_buf, 0, UDP_DEMO_BUF_SIZE); + recv_len = recv(fd, recv_buf, UDP_DEMO_BUF_SIZE, 0); + if(recv_len > 0) { lw_notice("Receive from : %s\n", inet_ntoa(server_addr.sin_addr)); lw_notice("Receive data : %s\n\n", recv_buf); } @@ -137,36 +128,41 @@ static void UdpSocketRecvTask(void *arg) void UdpSocketRecvTest(int argc, char *argv[]) { - if(argc >= 2) - { + if(argc >= 2) { lw_notice("lw: [%s] target ip %s\n", __func__, argv[1]); UdpSocketConfigParam(argv[1]); } #ifdef ADD_XIZI_FETURES - lwip_config_tcp(0, lwip_ipaddr, lwip_netmask, udp_socket_ip); - sys_thread_new("UdpSocketRecvTask", UdpSocketRecvTask, NULL, - LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO); + lwip_config_tcp(0, udp_demo_ipaddr, udp_demo_netmask, udp_demo_gwaddr); + + pthread_attr_t attr; + attr.schedparam.sched_priority = LWIP_UDP_DEMO_TASK_PRIO; + attr.stacksize = LWIP_UDP_DEMO_TASK_STACK_SIZE; #endif #ifdef ADD_NUTTX_FETURES - UdpSocketRecvTask(NULL); + pthread_attr_t attr = PTHREAD_ATTR_INITIALIZER; + attr.priority = LWIP_TCP_DEMO_TASK_PRIO; + attr.stacksize = LWIP_TCP_DEMO_TASK_STACK_SIZE; #endif + + PrivTaskCreate(&udp_server_task, &attr, &UdpSocketRecvTask, NULL); + PrivTaskStartup(&udp_server_task); } PRIV_SHELL_CMD_FUNCTION(UdpSocketRecvTest, a udp receive sample, PRIV_SHELL_CMD_MAIN_ATTR); -static void UdpSocketSendTask(void *arg) +static void *UdpSocketSendTask(void *arg) { - int cnt = LWIP_DEMO_TIMES; + int cnt = UDP_DEMO_SEND_TIMES; char send_str[128]; int fd = -1; memset(send_str, 0, sizeof(send_str)); fd = socket(AF_INET, SOCK_DGRAM, 0); - if(fd < 0) - { + if(fd < 0) { lw_error("Socket error\n"); - return; + return NULL; } struct sockaddr_in udp_sock; @@ -175,19 +171,17 @@ static void UdpSocketSendTask(void *arg) udp_sock.sin_addr.s_addr = inet_addr(udp_ip_str); memset(&(udp_sock.sin_zero), 0, sizeof(udp_sock.sin_zero)); - if(connect(fd, (struct sockaddr *)&udp_sock, sizeof(struct sockaddr))) - { - lw_error("Unable to connect\n"); + if(connect(fd, (struct sockaddr *)&udp_sock, sizeof(struct sockaddr)) < 0) { + lw_error("Unable to connect %s:%d\n", udp_ip_str, udp_socket_port); close(fd); - return; + return NULL; } lw_print("UDP connect %s:%d success, start to send.\n", udp_ip_str, udp_socket_port); - while(cnt --) - { + while(cnt --) { snprintf(send_str, sizeof(send_str), "UDP test package times %d\r\n", cnt); send(fd, send_str, strlen(send_str), 0); lw_notice("Send UDP msg: %s ", send_str); @@ -195,25 +189,31 @@ static void UdpSocketSendTask(void *arg) } close(fd); - return; + return NULL; } void UdpSocketSendTest(int argc, char *argv[]) { - if(argc >= 2) - { + if(argc >= 2) { lw_notice("lw: [%s] target ip %s\n", __func__, argv[1]); UdpSocketConfigParam(argv[1]); } #ifdef ADD_XIZI_FETURES - lwip_config_tcp(0, lwip_ipaddr, lwip_netmask, udp_socket_ip); - sys_thread_new("UdpSocketSendTask", UdpSocketSendTask, NULL, LWIP_TASK_STACK_SIZE, - LWIP_DEMO_TASK_PRIO); + lwip_config_tcp(0, udp_demo_ipaddr, udp_demo_netmask, udp_demo_gwaddr); + + pthread_attr_t attr; + attr.schedparam.sched_priority = LWIP_UDP_DEMO_TASK_PRIO; + attr.stacksize = LWIP_UDP_DEMO_TASK_STACK_SIZE; #endif #ifdef ADD_NUTTX_FETURES - UdpSocketSendTask(NULL); + pthread_attr_t attr = PTHREAD_ATTR_INITIALIZER; + attr.priority = LWIP_TCP_DEMO_TASK_PRIO; + attr.stacksize = LWIP_TCP_DEMO_TASK_STACK_SIZE; #endif + + PrivTaskCreate(&udp_client_task, &attr, &UdpSocketSendTask, NULL); + PrivTaskStartup(&udp_client_task); } PRIV_SHELL_CMD_FUNCTION(UdpSocketSendTest, a udp send sample, PRIV_SHELL_CMD_MAIN_ATTR); diff --git a/APP_Framework/Applications/control_app/plc_demo/mitsubishi/mitsubishi_fx3u.c b/APP_Framework/Applications/control_app/plc_demo/mitsubishi/mitsubishi_fx3u.c index 9567871c3..985a5fc61 100644 --- a/APP_Framework/Applications/control_app/plc_demo/mitsubishi/mitsubishi_fx3u.c +++ b/APP_Framework/Applications/control_app/plc_demo/mitsubishi/mitsubishi_fx3u.c @@ -18,6 +18,47 @@ * @date 2022.9.27 */ - +#include + +extern int Adapter4GActive(void); + +void ControlFx3uTest(void) +{ + int i, j = 0; + int read_data_length = 0; + uint8_t read_data[128] = {0}; + +#ifdef CONNECTION_ADAPTER_4G + Adapter4GActive(); +#endif + + ControlProtocolType modbus_tcp_protocol = ControlProtocolFind(); + if (NULL == modbus_tcp_protocol) { + printf("%s get modbus tcp protocol %p failed\n", __func__, modbus_tcp_protocol); + return; + } + + printf("%s get modbus tcp protocol %p successfull\n", __func__, modbus_tcp_protocol); + + if (CONTROL_REGISTERED == modbus_tcp_protocol->protocol_status) { + ControlProtocolOpen(modbus_tcp_protocol); + + for (;;) { + read_data_length = ControlProtocolRead(modbus_tcp_protocol, read_data, sizeof(read_data)); + printf("%s read [%d] modbus tcp data %d using receipe file\n", __func__, i, read_data_length); + if (read_data_length) { + for (j = 0; j < read_data_length; j ++) { + printf("j %d data 0x%x\n", j, read_data[j]); + } + } + i++; + memset(read_data, 0, sizeof(read_data)); + PrivTaskDelay(10000); + } + + //ControlProtocolClose(modbus_tcp_protocol); + } +} +PRIV_SHELL_CMD_FUNCTION(ControlFx3uTest, Mitsubishi fx3u Demo, PRIV_SHELL_CMD_MAIN_ATTR); diff --git a/APP_Framework/Applications/general_functions/circular_area/circular_area_app.c b/APP_Framework/Applications/general_functions/circular_area/circular_area_app.c index 25e81c39c..9ac93bc65 100644 --- a/APP_Framework/Applications/general_functions/circular_area/circular_area_app.c +++ b/APP_Framework/Applications/general_functions/circular_area/circular_area_app.c @@ -48,7 +48,7 @@ int CircularAreaAppIsEmpty(CircularAreaAppType circular_area) CA_PARAM_CHECK(circular_area); if((circular_area->readidx == circular_area->writeidx) && (!circular_area->b_status)) { - printf("the circular area is empty\n"); + //printf("the circular area is empty\n"); return 1; } else { return 0; @@ -164,7 +164,7 @@ int CircularAreaAppRead(CircularAreaAppType circular_area, uint8_t *output_buffe return -1; } - uint32_t read_length = (data_length > CircularAreaAppGetDataLength(circular_area)) ? CircularAreaAppGetDataLength(circular_area) : data_length; + int read_length = (data_length > CircularAreaAppGetDataLength(circular_area)) ? CircularAreaAppGetDataLength(circular_area) : data_length; // if (data_length > CircularAreaAppGetDataLength(circular_area)) { // return -1; // } diff --git a/APP_Framework/Framework/control/Kconfig b/APP_Framework/Framework/control/Kconfig index e9e0a1753..7d757e4ab 100755 --- a/APP_Framework/Framework/control/Kconfig +++ b/APP_Framework/Framework/control/Kconfig @@ -2,12 +2,33 @@ 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 CONTROL_USING_SERIAL_485 + bool + default n + + config CONTROL_USING_SOCKET + bool + default n + if CONTROL_USING_SOCKET + choice + prompt "select socket lib" + default CONTROL_SOCKET_LWIP + + config CONTROL_SOCKET_LWIP + bool "support socket, using LwIP" + select BSP_USING_LWIP + + config CONTROL_SOCKET_W5500 + bool "support socket, using W5500" + select BSP_USING_W5500 + endchoice + endif + 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 bc72c4672..55c7718f1 100755 --- a/APP_Framework/Framework/control/ipc_protocol/Kconfig +++ b/APP_Framework/Framework/control/ipc_protocol/Kconfig @@ -1,8 +1,15 @@ config CONTROL_PROTOCOL_MODBUS_TCP bool "Using modbus_tcp control protocol" default n + select CONTROL_USING_SOCKET +if CONTROL_PROTOCOL_MODBUS_TCP + source "$APP_DIR/Framework/control/ipc_protocol/modbus_tcp/Kconfig" +endif config CONTROL_PROTOCOL_MODBUS_UART bool "Using modbus_uart control protocol" default n - + select CONTROL_USING_SERIAL_485 +if CONTROL_PROTOCOL_MODBUS_UART + source "$APP_DIR/Framework/control/ipc_protocol/modbus_uart/Kconfig" +endif diff --git a/APP_Framework/Framework/control/ipc_protocol/include/modbus_tcp.h b/APP_Framework/Framework/control/ipc_protocol/include/modbus_tcp.h new file mode 100755 index 000000000..3d1532ace --- /dev/null +++ b/APP_Framework/Framework/control/ipc_protocol/include/modbus_tcp.h @@ -0,0 +1,69 @@ +/* + * 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_tcp.h + * @brief support modbus_tcp function + * @version 3.0 + * @author AIIT XUOS Lab + * @date 2022.09.27 + */ + +#ifndef MODBUS_TCP_H +#define MODBUS_TCP_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define MODBUS_TCP_UNIT_ID 0x01 +#define MODBUS_TCP_READ_CMD_LENGTH 0x0C +#define MODBUS_TCP_WRITE_SINGLE_CMD_LENGTH 0x0C + +#define MODBUS_TCP_WRITE_MULTI_HEAD 0x07 + +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 +}ModbusTcpFunctionCode; + +typedef struct +{ + BasicPlcDataInfo base_data_info; + ModbusTcpFunctionCode function_code; +}ModbusTcpDataInfo; + +typedef struct +{ + ModbusTcpDataInfo data_info; + + UniformValueType value_type; + char value_name[20]; + + uint16_t start_address; + uint16_t quantity; +}ModbusTcpReadItem; + +#ifdef __cplusplus +} +#endif + +#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/modbus_tcp.c b/APP_Framework/Framework/control/ipc_protocol/modbus_tcp/modbus_tcp.c index 9fc2d4c6a..dfd0f3577 100755 --- a/APP_Framework/Framework/control/ipc_protocol/modbus_tcp/modbus_tcp.c +++ b/APP_Framework/Framework/control/ipc_protocol/modbus_tcp/modbus_tcp.c @@ -15,6 +15,465 @@ * @brief support modbus_tcp function * @version 3.0 * @author AIIT XUOS Lab - * @date 2022.09.27 + * @date 2022.12.09 */ +#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: Modbus Tcp 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 void ModbusTcpTransformRecvBuffToData(ModbusTcpReadItem *p_read_item, uint8_t *recv_buff) +{ + uint8_t head_length = 9; + uint8_t *data_buffer; + ModbusTcpDataInfo *p_modbus_tcp_data_info = &(p_read_item->data_info); + uint16_t quantity = p_read_item->quantity; + + ModbusTcpFunctionCode function_code = p_modbus_tcp_data_info->function_code; + uint8_t *p_data = p_modbus_tcp_data_info->base_data_info.p_data; + + uint8_t bytes_count = recv_buff[8]; + + if ((WRITE_SINGLE_COIL == function_code) || (WRITE_SINGLE_REGISTER == function_code) || + (WRITE_MULTIPLE_COIL == function_code) || (WRITE_MULTIPLE_REGISTER == function_code)) { + head_length = 10; + if (p_modbus_tcp_data_info->base_data_info.command_ready) { + p_modbus_tcp_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"); +} + +#ifdef CONTROL_USING_SOCKET +/** + * @description: Modbus Tcp Get Data From Socket + * @param socket - socket + * @param p_read_item - read item pointer + * @return success : 0 error : -1 -2 + */ +static int ModbusTcpGetData(int32_t socket, ModbusTcpReadItem *p_read_item) +{ + uint8_t try_count = 0; + int32_t write_error = 0; + + ModbusTcpDataInfo *p_modbus_tcp_data_info = &(p_read_item->data_info); + BasicPlcDataInfo *p_base_data_info = &(p_modbus_tcp_data_info->base_data_info); + + if (!p_base_data_info->command_ready) { + //command not ready, just return + return 1; + } + + 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!\n", 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! read again\n", errno); + memset(recv_buff, 0, sizeof(recv_buff)); + recv_length = socket_read(socket, recv_buff, sizeof(recv_buff)); + if (recv_length > 0) { + ControlPrintfList("RECV", recv_buff, recv_length); + ModbusTcpTransformRecvBuffToData(p_read_item, recv_buff); + return 0; + } + } else { + ControlPrintfList("RECV", recv_buff, recv_length); + ModbusTcpTransformRecvBuffToData(p_read_item, recv_buff); + + return 0; + } + } + + if ((errno == EINTR) || (errno == EAGAIN) || (errno == EWOULDBLOCK)) { + printf("Send command failed, errno is %d!\n", errno); + continue; + } else { + return -1; + } + } + return -2; +} +#endif + +/** + * @description: Modbus Tcp Data Info Init + * @param p_read_item - read item pointer + * @param index - read item index + * @param p_data - control-data pointer + * @return success : 0 error : -1 + */ +static int ModbusTcpInitialDataInfo(ModbusTcpReadItem *p_read_item, uint16_t index, uint8_t *p_data) +{ + uint16_t command_index = 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_TCP_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_TCP_WRITE_SINGLE_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: + if (p_data == NULL) { + return -1; + } else { + //"quantity" define how many coil need to be written,"n_byte" define the bytes of write-data(counted by bit) + uint16_t n_byte = (quantity - 1) / 8 + 1; + p_base_data_info->command_length = n_byte + MODBUS_TCP_WRITE_MULTI_HEAD + 6; + p_base_data_info->p_command = PrivMalloc(p_base_data_info->command_length); + + //13th command define the bytes of write-data + p_base_data_info->p_command[12] = ((quantity - 1) / 8 + 1); + p_base_data_info->p_data = p_data; + p_base_data_info->data_size = n_byte; + p_base_data_info->command_ready = 0; + } + break; + case WRITE_MULTIPLE_REGISTER: + if (p_data == NULL) { + return -1; + } else { + //"quantity" define how many register need to be written + p_base_data_info->command_length = quantity * 2 + MODBUS_TCP_WRITE_MULTI_HEAD + 6; + p_base_data_info->p_command = PrivMalloc(p_base_data_info->command_length); + + //13th command define the bytes of write-data + p_base_data_info->p_command[12] = 2 * quantity; + p_base_data_info->p_data = p_data; + p_base_data_info->data_size = quantity * 2; + p_base_data_info->command_ready = 0; + } + break; + default: + return -2; + break; + } + + memset(p_base_data_info->p_command, 0, p_base_data_info->command_length); + + p_base_data_info->p_command[0] = index >> 8; + p_base_data_info->p_command[1] = index; + p_base_data_info->p_command[2] = 0x00; + p_base_data_info->p_command[3] = 0x00; + p_base_data_info->p_command[4] = 0x00; + + if (function_code < WRITE_MULTIPLE_COIL) { + p_base_data_info->p_command[5] = 0x06; + } else { + p_base_data_info->p_command[5] = 0x09; + } + + p_base_data_info->p_command[6] = MODBUS_TCP_UNIT_ID; + p_base_data_info->p_command[7] = function_code; + p_base_data_info->p_command[8] = start_address >> 8; + p_base_data_info->p_command[9] = start_address; + + if ((function_code != WRITE_SINGLE_COIL) && (function_code != WRITE_SINGLE_REGISTER)) { + p_base_data_info->p_command[10] = quantity >> 8; + p_base_data_info->p_command[11] = quantity; + } + return 0; +} + +/** + * @description: Modbus Tcp Format write data from "g_write_data" + * @param p_read_item - read item pointer + * @return success : 0 error : -1 + */ +static int ModbusTcpForamatWriteData(ModbusTcpReadItem *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 = 10; + break; + case WRITE_MULTIPLE_COIL: + case WRITE_MULTIPLE_REGISTER: + command_index = 13; + break; + default: + return -2; + break; + } + + 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 Tcp 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_tcp_data; + uint16_t read_item_size = sizeof(ModbusTcpReadItem); + + struct ControlProtocol *control_protocol = (struct ControlProtocol *)parameter; + struct CircularAreaApp *circular_area = (struct CircularAreaApp *)control_protocol->args; + ModbusTcpReadItem *modbus_tcp_read_item = (ModbusTcpReadItem *)control_protocol->recipe->read_item; + modbus_tcp_data = control_protocol->recipe->protocol_data.data; + data_length = control_protocol->recipe->protocol_data.data_length; + + 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 ++) { +#ifdef CONTROL_USING_SOCKET + /*only connect socket when close socket or init*/ + while (ControlConnectSocket(&plc_socket) < 0) { + PrivTaskDelay(1000); + } + + ModbusTcpForamatWriteData((ModbusTcpReadItem *)modbus_tcp_read_item + i); + + ModbusTcpGetData(plc_socket.socket, (ModbusTcpReadItem *)modbus_tcp_read_item + i); +#endif + } + + /*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_tcp_data %p\n", __func__, i, data_length, modbus_tcp_data); + CircularAreaAppWrite(circular_area, modbus_tcp_data, data_length, 0); + } + + /*read data every single 'read_period' ms*/ + PrivTaskDelay(control_protocol->recipe->read_period); + } +} + +/** + * @description: Modbus Tcp Protocol Open + * @param control_protocol - control protocol pointer + * @return success : 0 error + */ +int ModbusTcpOpen(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 Tcp Protocol Close + * @param control_protocol - control protocol pointer + * @return success : 0 error + */ +int ModbusTcpClose(struct ControlProtocol *control_protocol) +{ + CircularAreaAppRelease(g_write_data); + +#ifdef CONTROL_USING_SOCKET + ControlDisconnectSocket(&plc_socket); +#endif + + ControlProtocolCloseDef(); + + return 0; +} + +/** + * @description: Modbus Tcp 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 ModbusTcpRead(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 Tcp 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 ModbusTcpWrite(struct ControlProtocol *control_protocol, const void *buf, size_t len) +{ + CircularAreaAppWrite(g_write_data, (uint8_t *)buf, len, 0); + + return 0; +} + +/** + * @description: Modbus Tcp Protocol Ioctl + * @param control_protocol - control protocol pointer + * @param cmd - ioctl cmd + * @param args - ioctl args + * @return success : data length error : 0 + */ +int ModbusTcpIoctl(struct ControlProtocol *control_protocol, int cmd, void *args) +{ + //to do + return 0; +} + +static struct ControlDone modbustcp_protocol_done = +{ + ._open = ModbusTcpOpen, + ._close = ModbusTcpClose, + ._read = ModbusTcpRead, + ._write = ModbusTcpWrite, + ._ioctl = ModbusTcpIoctl, +}; + +/** + * @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 ModbusTcpProtocolFormatCmd(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; + + ModbusTcpReadItem *modbustcp_read_item = (ModbusTcpReadItem *)(p_recipe->read_item) + protocol_format_info->read_item_index; + + modbustcp_read_item->value_type = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "value_type")->valueint; + strncpy(modbustcp_read_item->value_name, cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "value_name")->valuestring, 20); + modbustcp_read_item->data_info.function_code = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "function_code")->valueint; + modbustcp_read_item->start_address = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "start_address")->valueint; + modbustcp_read_item->quantity = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "quantity")->valueint; + + ret = ModbusTcpInitialDataInfo(modbustcp_read_item, + protocol_format_info->read_item_index, + p_read_item_data); + + ControlPrintfList("CMD", modbustcp_read_item->data_info.base_data_info.p_command, modbustcp_read_item->data_info.base_data_info.command_length); + protocol_format_info->last_item_size = GetValueTypeMemorySize(modbustcp_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 ModbusTcpProtocolInit(struct ControlRecipe *p_recipe) +{ + p_recipe->read_item = PrivMalloc(sizeof(ModbusTcpReadItem) * 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(ModbusTcpReadItem)); + + p_recipe->ControlProtocolFormatCmd = ModbusTcpProtocolFormatCmd; + + p_recipe->done = &modbustcp_protocol_done; + + return 0; +} + diff --git a/APP_Framework/Framework/control/ipc_protocol/modbus_tcp/modbus_tcp.h b/APP_Framework/Framework/control/ipc_protocol/modbus_tcp/modbus_tcp.h deleted file mode 100755 index a2063e96f..000000000 --- a/APP_Framework/Framework/control/ipc_protocol/modbus_tcp/modbus_tcp.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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_tcp.h - * @brief support modbus_tcp function - * @version 3.0 - * @author AIIT XUOS Lab - * @date 2022.09.27 - */ - -#ifndef MODBUS_TCP_H -#define MODBUS_TCP_H - - - -#endif diff --git a/APP_Framework/Framework/control/ipc_protocol/modbus_tcp/test_recipe_modbus_tcp.json b/APP_Framework/Framework/control/ipc_protocol/modbus_tcp/test_recipe_modbus_tcp.json new file mode 100644 index 000000000..b08980aaf --- /dev/null +++ b/APP_Framework/Framework/control/ipc_protocol/modbus_tcp/test_recipe_modbus_tcp.json @@ -0,0 +1,142 @@ +{ + "device_id": 4, + "device_name": "GJ2", + "communication_type": 0, + "socket_config": { + "plc_ip": "192.168.250.9", + "local_ip": "192.168.250.233", + "gateway": "192.168.250.1", + "netmask": "255.255.254.0", + "port": 502 + }, + "protocol_type": 2, + "read_period": 100, + "read_item_list": [ + { + "value_name": "M0", + "value_type": 1, + "function_code": 1, + "start_address": 8192, + "quantity": 1 + }, + { + "value_name": "M1", + "value_type": 1, + "function_code": 1, + "start_address":8193, + "quantity": 1 + }, + { + "value_name": "M102", + "value_type": 1, + "function_code": 1, + "start_address": 8294, + "quantity": 1 + }, + { + "value_name": "M200", + "value_type": 1, + "function_code": 1, + "start_address": 8392, + "quantity": 1 + }, + { + "value_name": "M201", + "value_type": 1, + "function_code": 1, + "start_address":8393, + "quantity": 1 + }, + { + "value_name": "M202", + "value_type": 1, + "function_code": 1, + "start_address": 8394, + "quantity": 1 + }, + { + "value_name": "M203", + "value_type": 1, + "function_code": 1, + "start_address": 8395, + "quantity": 1 + }, + { + "value_name": "M204", + "value_type": 1, + "function_code": 1, + "start_address": 8396, + "quantity": 1 + }, + { + "value_name": "M205", + "value_type": 1, + "function_code": 1, + "start_address": 8397, + "quantity": 1 + }, + { + "value_name": "M206", + "value_type": 1, + "function_code": 1, + "start_address": 8398, + "quantity": 1 + }, + { + "value_name": "D20", + "value_type": 3, + "function_code": 3, + "start_address": 20, + "quantity": 1 + }, + { + "value_name": "D21", + "value_type": 3, + "function_code": 3, + "start_address": 21, + "quantity": 1 + }, + { + "value_name": "D22", + "value_type": 3, + "function_code": 3, + "start_address": 22, + "quantity": 1 + }, + { + "value_name": "D23", + "value_type": 3, + "function_code": 3, + "start_address": 23, + "quantity": 1 + }, + { + "value_name": "D202", + "value_type": 9, + "function_code": 3, + "start_address": 202, + "quantity": 2 + }, + { + "value_name": "D204", + "value_type": 9, + "function_code": 3, + "start_address": 204, + "quantity": 2 + }, + { + "value_name": "D206", + "value_type": 9, + "function_code": 3, + "start_address": 206, + "quantity": 2 + }, + { + "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/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..bd86ecf0c --- /dev/null +++ b/APP_Framework/Framework/control/ipc_protocol/modbus_uart/modbus_uart.c @@ -0,0 +1,424 @@ +/* + * 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 cmd_length, 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); + ModbusUartFunctionCode function_code = p_modbus_uart_data_info->function_code; + + 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); + + if (READ_COIL_STATUS == function_code || READ_INPUT_STATUS == function_code) { + cmd_length = 6; + } else if (READ_HOLDING_REGISTER == function_code || READ_INPUT_REGISTER == function_code) { + cmd_length = 7; + } else if (WRITE_SINGLE_COIL == function_code || WRITE_SINGLE_REGISTER == function_code) { + cmd_length = 8; + } else { + //MULTIPLE_COIL and MULTIPLE_REGISTER to do + cmd_length = 0; + } + + read_length = SerialRead(recv_buff, cmd_length); + 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..1f5cf41de --- /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": 1 + } + ] +} \ 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 9839fe26e..91e27b474 100755 --- a/APP_Framework/Framework/control/plc_protocol/Kconfig +++ b/APP_Framework/Framework/control/plc_protocol/Kconfig @@ -1,15 +1,28 @@ config CONTROL_PROTOCOL_FINS bool "Using fins control protocol" default n + select CONTROL_USING_SOCKET +if CONTROL_PROTOCOL_FINS + source "$APP_DIR/Framework/control/plc_protocol/fins/Kconfig" +endif config CONTROL_PROTOCOL_MELSEC bool "Using melsec control protocol" default n +if CONTROL_PROTOCOL_MELSEC + source "$APP_DIR/Framework/control/plc_protocol/melsec/Kconfig" +endif config CONTROL_PROTOCOL_OPCUA bool "Using opcua control protocol" default n +if CONTROL_PROTOCOL_OPCUA + source "$APP_DIR/Framework/control/plc_protocol/opcua/Kconfig" +endif config CONTROL_PROTOCOL_S7 bool "Using s7 control protocol" default n +if CONTROL_PROTOCOL_S7 + source "$APP_DIR/Framework/control/plc_protocol/s7/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/fins/fins.c b/APP_Framework/Framework/control/plc_protocol/fins/fins.c index 1c20eba77..0a8c20125 100644 --- a/APP_Framework/Framework/control/plc_protocol/fins/fins.c +++ b/APP_Framework/Framework/control/plc_protocol/fins/fins.c @@ -154,6 +154,7 @@ static int FinsTransformRecvBuffToData(FinsReadItem *p_read_item, uint8_t *recv_ return 0; } +#ifdef CONTROL_USING_SOCKET /** * @description: Fins Protocol Handshake * @param socket - socket @@ -242,6 +243,7 @@ static int FinsGetData(int32_t socket, FinsReadItem *p_read_item) } return -2; } +#endif /** * @description: Fins Data Info Init @@ -303,6 +305,7 @@ void *ReceivePlcDataTask(void *parameter) while (1) { for (i = 0; i < control_protocol->recipe->read_item_count; i ++) { +#ifdef CONTROL_USING_SOCKET /*only connect socket when close socket or init*/ while (ControlConnectSocket(&plc_socket) < 0) { PrivTaskDelay(1000); @@ -320,6 +323,7 @@ void *ReceivePlcDataTask(void *parameter) plc_socket.secondary_connect_flag = 1; FinsGetData(plc_socket.socket, (FinsReadItem *)fins_read_item + i); +#endif } /*read all variable item data, put them into circular_area*/ @@ -328,7 +332,7 @@ void *ReceivePlcDataTask(void *parameter) CircularAreaAppWrite(circular_area, fins_data, data_length, 0); } - /*read data every single 200ms*/ + /*read data every single 'read_period' ms*/ PrivTaskDelay(control_protocol->recipe->read_period); } } @@ -352,7 +356,9 @@ int FinsOpen(struct ControlProtocol *control_protocol) */ int FinsClose(struct ControlProtocol *control_protocol) { +#ifdef CONTROL_USING_SOCKET ControlDisconnectSocket(&plc_socket); +#endif ControlProtocolCloseDef(); @@ -390,6 +396,8 @@ static struct ControlDone fins_protocol_done = int FinsProtocolFormatCmd(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; FinsReadItem *fins_read_item = (FinsReadItem *)(p_recipe->read_item) + protocol_format_info->read_item_index; @@ -405,11 +413,13 @@ int FinsProtocolFormatCmd(struct ControlRecipe *p_recipe, ProtocolFormatInfo *pr ret = FinsInitialDataInfo(fins_read_item, p_recipe->socket_config.plc_ip[3], p_recipe->socket_config.local_ip[3], - protocol_format_info->p_read_item_data + protocol_format_info->last_item_size); + p_read_item_data); ControlPrintfList("CMD", fins_read_item->data_info.base_data_info.p_command, fins_read_item->data_info.base_data_info.command_length); protocol_format_info->last_item_size = GetValueTypeMemorySize(fins_read_item->value_type); + last_item_size += protocol_format_info->last_item_size; + return ret; } @@ -426,6 +436,8 @@ int FinsProtocolInit(struct ControlRecipe *p_recipe) return -1; } + memset(p_recipe->read_item, 0, sizeof(FinsReadItem)); + p_recipe->ControlProtocolFormatCmd = FinsProtocolFormatCmd; p_recipe->done = &fins_protocol_done; diff --git a/APP_Framework/Framework/control/plc_protocol/include/melsec.h b/APP_Framework/Framework/control/plc_protocol/include/melsec.h index 2586fdd4e..bdefbc33f 100644 --- a/APP_Framework/Framework/control/plc_protocol/include/melsec.h +++ b/APP_Framework/Framework/control/plc_protocol/include/melsec.h @@ -15,5 +15,98 @@ * @brief plc protocol melsec * @version 3.0 * @author AIIT XUOS Lab - * @date 2022-10-08 - */ \ No newline at end of file + * @date 2022-11-29 + */ + +#ifndef MELSEC_H +#define MELSEC_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SUB_HEADER 0x5000 +#define NETWORK_NUMBER 0x00 +#define PC_NUMBER 0xFF +#define QEQUEST_DESTINSTION_MODULE_IO_NUMBER 0x03FF +#define QEQUEST_DESTINSTION_MODULE_STATION_NUMBER 0x00 +#define STATION_NUMBER 0x00 +#define FRAME_NUMBER 0x4639 +#define SELF_STATION_NUMBER 0x00 + +#define MELSEC_NAK 0x15 +#define MELSEC_STX 0x02 +#define MELSEC_ETX 0x03 +#define MELSEC_ENQ 0x05 + +#define MELSEC_1E_FRAME_RB 0x00 +#define MELSEC_1E_FRAME_RW 0x01 +#define MELSEC_1E_FRAME_WB 0x02 +#define MELSEC_1E_FRAME_WW 0x03 + +#define MELSEC_1C_FRAME_RB 0x4252 +#define MELSEC_1C_FRAME_RW 0x5752 +#define MELSEC_1C_FRAME_WB 0x4257 +#define MELSEC_1C_FRAME_WW 0x5757 + +//same as MELSEC_3E_Q_L_FRAME +#define MELSEC_3C_FRAME_RB 0x04010001 +#define MELSEC_3C_FRAME_RW 0x04010000 +#define MELSEC_3C_FRAME_WB 0x14010001 +#define MELSEC_3C_FRAME_WW 0x14010000 + +//same as MELSEC_3C_FRAME +#define MELSEC_3E_Q_L_FRAME_RB 0x04010001 +#define MELSEC_3E_Q_L_FRAME_RW 0x04010000 +#define MELSEC_3E_Q_L_FRAME_WB 0x14010001 +#define MELSEC_3E_Q_L_FRAME_WW 0x14010000 + +#define MELSEC_3E_IQ_R_FRAME_RB 0x04010003 +#define MELSEC_3E_IQ_R_FRAME_RW 0x04010002 +#define MELSEC_3E_IQ_R_FRAME_WB 0x14010003 +#define MELSEC_3E_IQ_R_FRAME_WW 0x14010002 + +typedef enum { + READ_IN_BITS, + READ_IN_WORD, + WRITE_IN_BITS, + WRITE_IN_WORD, + TEST_IN_BIT, + TEST_IN_WORD +}MelsecCommandType; + +typedef enum { + MELSEC_1E_FRAME, + MELSEC_3E_Q_L_FRAME, + MELSEC_3E_IQ_R_FRAME, + MELSEC_1C_FRAME, + MELSEC_3C_FRAME +}MelsecFrameType; + +typedef struct +{ + BasicPlcDataInfo base_data_info; + MelsecCommandType command_type; + MelsecFrameType frame_type; +}MelsecDataInfo; + +typedef struct +{ + MelsecDataInfo data_info; + + UniformValueType value_type; + uint8_t value_name[20]; + + uint16_t monitoring_timer; + uint16_t device_code; + uint8_t head_device_number_string[6]; + uint16_t device_points_count; +}MelsecReadItem; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/APP_Framework/Framework/control/plc_protocol/melsec/Kconfig b/APP_Framework/Framework/control/plc_protocol/melsec/Kconfig index 139597f9c..c441642b9 100755 --- a/APP_Framework/Framework/control/plc_protocol/melsec/Kconfig +++ b/APP_Framework/Framework/control/plc_protocol/melsec/Kconfig @@ -1,2 +1,64 @@ +choice + prompt "select melsec protocol" + default CONTROL_PROTOCOL_MELSEC_1E + config CONTROL_PROTOCOL_MELSEC_1E + bool "support melsec_1e protocol, using SOCKET" + select CONTROL_USING_SOCKET + + config CONTROL_PROTOCOL_MELSEC_3E_Q_L + bool "support melsec_3e_q_l protocol, using SOCKET" + select CONTROL_USING_SOCKET + config CONTROL_PROTOCOL_MELSEC_3E_IQ_R + bool "support melsec_3e_iq_r protocol, using SOCKET" + select CONTROL_USING_SOCKET + + config CONTROL_PROTOCOL_MELSEC_1C + bool "support melsec_1c protocol, using SERIAL" + select CONTROL_USING_SERIAL_485 + + config CONTROL_PROTOCOL_MELSEC_3C + bool "support melsec_3c protocol, using SERIAL" + select CONTROL_USING_SERIAL_485 +endchoice + +if CONTROL_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/Makefile b/APP_Framework/Framework/control/plc_protocol/melsec/Makefile index 608656f03..9f60e0cf7 100755 --- a/APP_Framework/Framework/control/plc_protocol/melsec/Makefile +++ b/APP_Framework/Framework/control/plc_protocol/melsec/Makefile @@ -1,4 +1,4 @@ -SRC_FILES := +SRC_FILES := melsec.c include $(KERNEL_ROOT)/compiler.mk diff --git a/APP_Framework/Framework/control/plc_protocol/melsec/melsec.c b/APP_Framework/Framework/control/plc_protocol/melsec/melsec.c new file mode 100644 index 000000000..27b97a831 --- /dev/null +++ b/APP_Framework/Framework/control/plc_protocol/melsec/melsec.c @@ -0,0 +1,805 @@ +/* +* 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.c + * @brief plc protocol melsec, support 1E、3E_Q_L、3E_IQ_R、1C、3C + * @version 3.0 + * @author AIIT XUOS Lab + * @date 2022-11-29 + */ + +#include + +static BasicSocketPlc plc_socket = {0}; +static uint8_t recv_buff[1024] = {0}; + +/** + * @description: Melsec Get Check Sum + * @param p_command - p_command pointer + * @param command_length - command length + * @return checksum + */ +static uint8_t GetCheckSum(uint8_t *p_command, uint16_t command_length) +{ + uint8_t checksum = 0; + for (uint16_t i = 0; i < command_length; i++) { + checksum += p_command[i]; + } + return checksum; +} + +/** + * @description: Melsec Transform from Hex to Ascii + * @param hex - hex + * @return ascii + */ +static uint8_t TransformHexToAscii(uint8_t hex) +{ + hex %= 0x10; + return hex < 0xA ? hex + '0' : hex - 10 + 'A'; +} + +/** + * @description: Melsec Transform from Ascii to Hex + * @param ascii - ascii + * @return hex + */ +static uint8_t TransformAsciiToHex(uint8_t ascii) +{ + if (ascii > 'F' || ascii < '0' || (ascii > '9' && ascii < 'A')) + return 0; + else + return ascii < 'A' ? ascii - '0' : ascii - 'A' + 10; +} + +/** + * @description: Melsec Get Device Code + * @param frame_type - melsec frame type + * @param device_string - device string + * @return device code + */ +static int MelsecGetDeviceCode(MelsecFrameType frame_type, char device_string[2]) +{ + switch (frame_type) { + case MELSEC_1C_FRAME: + if (strcmp(device_string, "M") == 0) + return 0x4D; + if (strcmp(device_string, "D") == 0) + return 0x44; + if (strcmp(device_string, "B") == 0) + return 0x22; + if (strcmp(device_string, "W") == 0) + return 0x57; + if (strcmp(device_string, "X") == 0) + return 0x58; + if (strcmp(device_string, "Y") == 0) + return 0x59; + case MELSEC_1E_FRAME: + if (strcmp(device_string, "M") == 0) + return 0x4D20; + if (strcmp(device_string, "D") == 0) + return 0x4420; + if (strcmp(device_string, "B") == 0) + return 0x2220; + if (strcmp(device_string, "W") == 0) + return 0x5720; + if (strcmp(device_string, "X") == 0) + return 0x5820; + if (strcmp(device_string, "Y") == 0) + return 0x5920; + case MELSEC_3C_FRAME: + if (strcmp(device_string, "M") == 0) + return 0x4D2A; + if (strcmp(device_string, "D") == 0) + return 0x442A; + if (strcmp(device_string, "B") == 0) + return 0x222A; + if (strcmp(device_string, "W") == 0) + return 0x572A; + case MELSEC_3E_IQ_R_FRAME: + if (strcmp(device_string, "M") == 0) + return 0x0090; + if (strcmp(device_string, "D") == 0) + return 0x00A8; + if (strcmp(device_string, "B") == 0) + return 0x00A0; + if (strcmp(device_string, "W") == 0) + return 0x00B4; + if (strcmp(device_string, "X") == 0) + return 0x009C; + if (strcmp(device_string, "Y") == 0) + return 0x009D; + case MELSEC_3E_Q_L_FRAME: + if (strcmp(device_string, "M") == 0) + return 0x90; + if (strcmp(device_string, "D") == 0) + return 0xA8; + if (strcmp(device_string, "B") == 0) + return 0xA0; + if (strcmp(device_string, "W") == 0) + return 0xB4; + if (strcmp(device_string, "X") == 0) + return 0x9C; + if (strcmp(device_string, "Y") == 0) + return 0x9D; + } +} + +/** + * @description: Melsec Get Command Base Length + * @param frame_type - melsec frame type + * @return command length + */ +static int MelsecGetCommandBaseLength(MelsecFrameType frame_type) +{ + switch (frame_type) { + case MELSEC_1C_FRAME: + return 17; + case MELSEC_1E_FRAME: + return 12; + case MELSEC_3C_FRAME: + return 33; + case MELSEC_3E_IQ_R_FRAME: + case MELSEC_3E_Q_L_FRAME: + return 21; + default: + return -1; + } +} + +/** + * @description: Melsec Get Command Code + * @param frame_type - melsec frame type + * @param command_type - melsec command type + * @return command code + */ +static uint32_t MelsecGetCommandCode(MelsecFrameType frame_type, MelsecCommandType command_type) +{ + switch (frame_type) { + case MELSEC_1C_FRAME: + switch (command_type) { + case READ_IN_BITS: + return MELSEC_1C_FRAME_RB; + case READ_IN_WORD: + return MELSEC_1C_FRAME_RW; + case WRITE_IN_BITS: + return MELSEC_1C_FRAME_WB; + case WRITE_IN_WORD: + return MELSEC_1C_FRAME_WW; + } + case MELSEC_1E_FRAME: + return command_type; + case MELSEC_3C_FRAME: + case MELSEC_3E_Q_L_FRAME: + switch (command_type) { + case READ_IN_BITS: + return MELSEC_3E_Q_L_FRAME_RB; + case READ_IN_WORD: + return MELSEC_3E_Q_L_FRAME_RW; + case WRITE_IN_BITS: + return MELSEC_3E_Q_L_FRAME_WB; + case WRITE_IN_WORD: + return MELSEC_3E_Q_L_FRAME_WW; + } + case MELSEC_3E_IQ_R_FRAME: + switch (command_type) { + case READ_IN_BITS: + return MELSEC_3E_IQ_R_FRAME_RB; + case READ_IN_WORD: + return MELSEC_3E_IQ_R_FRAME_RW; + case WRITE_IN_BITS: + return MELSEC_3E_IQ_R_FRAME_WB; + case WRITE_IN_WORD: + return MELSEC_3E_IQ_R_FRAME_WW; + } + } +} + +/** + * @description: Melsec_1E Cmd Genetare + * @param p_command - command pointer + * @param command_code - command code + * @param p_read_item - p_read_item pointer + * @return success : index error : 0 + */ +static uint16_t Melsec1eGenerateCommand(uint8_t *p_command, uint32_t command_code, MelsecReadItem *p_read_item) +{ + uint16_t index = 0; + + p_command[index++] = command_code; + p_command[index++] = PC_NUMBER; + p_command[index++] = p_read_item->monitoring_timer / 250; + p_command[index++] = (p_read_item->monitoring_timer / 250) >> 8; + + uint16_t head_device_number = 0; + for (uint8_t i = 0; i < 6; i++) { + if (0 != p_read_item->head_device_number_string[i]) + head_device_number = TransformAsciiToHex(p_read_item->head_device_number_string[i]) + head_device_number * (((0x5820 == p_read_item->device_code) || (0x5920 == p_read_item->device_code)) ? 8 : 10); + else + break; + } + p_command[index++] = head_device_number; + p_command[index++] = head_device_number >> (8 * 1); + p_command[index++] = head_device_number >> (8 * 2); + p_command[index++] = head_device_number >> (8 * 3); + p_command[index++] = p_read_item->device_code; + p_command[index++] = p_read_item->device_code >> 8; + p_command[index++] = p_read_item->device_points_count; + p_command[index++] = 0x00; + return index; +} + +/** + * @description: Melsec_3E_Q_L Cmd Genetare + * @param p_command - command pointer + * @param command_code - command code + * @param p_read_item - p_read_item pointer + * @return success : index error : 0 + */ +static uint16_t Melsec3eqlGenerateCommand(uint8_t *p_command, uint32_t command_code, MelsecReadItem *p_read_item) +{ + p_read_item->monitoring_timer /= 250; + uint16_t index = 0; + + p_command[index++] = SUB_HEADER >> 8; + p_command[index++] = (uint8_t)SUB_HEADER; + p_command[index++] = NETWORK_NUMBER; + p_command[index++] = PC_NUMBER; + 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++] = 0x00; + p_command[index++] = p_read_item->monitoring_timer; + p_command[index++] = p_read_item->monitoring_timer >> 8; + p_command[index++] = command_code >> (8 * 2); + p_command[index++] = command_code >> (8 * 3); + p_command[index++] = command_code; + p_command[index++] = command_code >> (8 * 1); + + uint16_t head_device_number = 0; + for (uint8_t i = 0; i < 6; i++) { + if (0 != p_read_item->head_device_number_string[i]) + head_device_number = TransformAsciiToHex(p_read_item->head_device_number_string[i]) + head_device_number * (((0x9c == (uint8_t)p_read_item->device_code) || (0x9d == (uint8_t)p_read_item->device_code)) ? 16 : 10); + else + break; + } + p_command[index++] = head_device_number; + p_command[index++] = head_device_number >> (8 * 1); + p_command[index++] = head_device_number >> (8 * 2); + p_command[index++] = p_read_item->device_code; + p_command[index++] = p_read_item->device_points_count; + p_command[index++] = p_read_item->device_points_count >> 8; + return index; +} + +/** + * @description: Melsec_3E_IQ_R Cmd Genetare + * @param p_command - command pointer + * @param command_code - command code + * @param p_read_item - p_read_item pointer + * @return success : index error : 0 + */ +static uint16_t Melsec3eiqrGenerateCommand(uint8_t *p_command, uint32_t command_code, MelsecReadItem *p_read_item) +{ + uint16_t index = Melsec3eqlGenerateCommand(p_command, command_code, p_read_item) - 6; + + uint16_t head_device_number = 0; + for (uint8_t i = 0; i < 6; i++) { + if (0 != p_read_item->head_device_number_string[i]) + head_device_number = TransformAsciiToHex(p_read_item->head_device_number_string[i]) + head_device_number * (((0x9c == (uint8_t)p_read_item->device_code) || (0x9d == (uint8_t)p_read_item->device_code)) ? 16 : 10); + else + break; + } + p_command[index++] = head_device_number; + p_command[index++] = head_device_number >> (8 * 1); + p_command[index++] = head_device_number >> (8 * 2); + p_command[index++] = head_device_number >> (8 * 3); + p_command[index++] = p_read_item->device_code; + p_command[index++] = p_read_item->device_code >> 8; + p_command[index++] = p_read_item->device_points_count; + p_command[index++] = p_read_item->device_points_count >> 8; + return index; +} + +/** + * @description: Melsec_1C Cmd Genetare + * @param p_command - command pointer + * @param command_code - command code + * @param p_read_item - p_read_item pointer + * @return success : index error : 0 + */ +static uint16_t Melsec1cGenerateCommand(uint8_t *p_command, uint32_t command_code, MelsecReadItem *p_read_item) +{ + p_read_item->monitoring_timer /= 10; + uint16_t index = 0; + uint8_t checksum = 0; + + p_command[index++] = MELSEC_ENQ; + p_command[index++] = TransformHexToAscii(STATION_NUMBER >> 4); + p_command[index++] = TransformHexToAscii(STATION_NUMBER); + p_command[index++] = TransformHexToAscii(PC_NUMBER >> 4); + p_command[index++] = TransformHexToAscii(PC_NUMBER); + p_command[index++] = command_code >> 8; + p_command[index++] = command_code; + p_command[index++] = TransformHexToAscii(p_read_item->monitoring_timer); + p_command[index++] = p_read_item->device_code; + uint8_t head_device_number_string_length = 0; + for (uint8_t i = 0; i < 6; i++) { + if (0 == p_read_item->head_device_number_string[i]) + break; + else + head_device_number_string_length++; + } + p_command[index++] = (head_device_number_string_length - 4 < 0) ? 0x30 : p_read_item->head_device_number_string[head_device_number_string_length - 4]; + p_command[index++] = (head_device_number_string_length - 3 < 0) ? 0x30 : p_read_item->head_device_number_string[head_device_number_string_length - 3]; + p_command[index++] = (head_device_number_string_length - 2 < 0) ? 0x30 : p_read_item->head_device_number_string[head_device_number_string_length - 2]; + p_command[index++] = (head_device_number_string_length - 1 < 0) ? 0x30 : p_read_item->head_device_number_string[head_device_number_string_length - 1]; + p_command[index++] = TransformHexToAscii(p_read_item->device_points_count >> 4); + p_command[index++] = TransformHexToAscii(p_read_item->device_points_count); + checksum = GetCheckSum(p_command + 1, index - 1); + p_command[index++] = TransformHexToAscii(checksum >> 4); + p_command[index++] = TransformHexToAscii(checksum); + return index; +} + +/** + * @description: Melsec_3C Cmd Genetare + * @param p_command - command pointer + * @param command_code - command code + * @param p_read_item - p_read_item pointer + * @return success : index error : 0 + */ +static uint16_t Melsec3cGenerateCommand(uint8_t* p_command, uint32_t command_code, MelsecReadItem *p_read_item) +{ + uint16_t index = 0; + uint8_t checksum = 0; + + p_command[index++] = MELSEC_ENQ; + p_command[index++] = FRAME_NUMBER >> 8; + p_command[index++] = (uint8_t)FRAME_NUMBER; + p_command[index++] = TransformHexToAscii(STATION_NUMBER >> 4); + p_command[index++] = TransformHexToAscii(STATION_NUMBER); + p_command[index++] = TransformHexToAscii(NETWORK_NUMBER >> 4); + p_command[index++] = TransformHexToAscii(NETWORK_NUMBER); + p_command[index++] = TransformHexToAscii(PC_NUMBER >> 4); + p_command[index++] = TransformHexToAscii(PC_NUMBER); + p_command[index++] = TransformHexToAscii(SELF_STATION_NUMBER >> 4); + p_command[index++] = TransformHexToAscii(SELF_STATION_NUMBER); + p_command[index++] = TransformHexToAscii(command_code >> (7 * 4)); + p_command[index++] = TransformHexToAscii(command_code >> (6 * 4)); + p_command[index++] = TransformHexToAscii(command_code >> (5 * 4)); + p_command[index++] = TransformHexToAscii(command_code >> (4 * 4)); + p_command[index++] = TransformHexToAscii(command_code >> (3 * 4)); + p_command[index++] = TransformHexToAscii(command_code >> (2 * 4)); + p_command[index++] = TransformHexToAscii(command_code >> (1 * 4)); + p_command[index++] = TransformHexToAscii(command_code); + p_command[index++] = p_read_item->device_code >> 8; + p_command[index++] = p_read_item->device_code; + uint8_t head_device_number_string_length = 0; + for (uint8_t i = 0; i < 6; i++) { + if (0 == p_read_item->head_device_number_string[i]) + break; + else + head_device_number_string_length++; + } + p_command[index++] = (head_device_number_string_length - 6 < 0) ? 0x30 : p_read_item->head_device_number_string[head_device_number_string_length - 6]; + p_command[index++] = (head_device_number_string_length - 5 < 0) ? 0x30 : p_read_item->head_device_number_string[head_device_number_string_length - 5]; + p_command[index++] = (head_device_number_string_length - 4 < 0) ? 0x30 : p_read_item->head_device_number_string[head_device_number_string_length - 4]; + p_command[index++] = (head_device_number_string_length - 3 < 0) ? 0x30 : p_read_item->head_device_number_string[head_device_number_string_length - 3]; + p_command[index++] = (head_device_number_string_length - 2 < 0) ? 0x30 : p_read_item->head_device_number_string[head_device_number_string_length - 2]; + p_command[index++] = (head_device_number_string_length - 1 < 0) ? 0x30 : p_read_item->head_device_number_string[head_device_number_string_length - 1]; + p_command[index++] = TransformHexToAscii(p_read_item->device_points_count >> (3 * 8)); + p_command[index++] = TransformHexToAscii(p_read_item->device_points_count >> (2 * 8)); + p_command[index++] = TransformHexToAscii(p_read_item->device_points_count >> (1 * 8)); + p_command[index++] = TransformHexToAscii(p_read_item->device_points_count); + checksum = GetCheckSum(p_command + 1, index - 1); + p_command[index++] = TransformHexToAscii(checksum >> 4); + p_command[index++] = TransformHexToAscii(checksum); + return index; +} + +/** + * @description: Melsec Cmd Genetare + * @param p_command - command pointer + * @param command_code - command code + * @param p_read_item - p_read_item pointer + * @return success : index error : 0 + */ +static uint16_t MelsecGenerateCommand(uint8_t *p_command, uint32_t command_code, MelsecReadItem *p_read_item) +{ + uint16_t (*GenerateMelsecCommandFunction)(uint8_t *p_command, uint32_t command_code, MelsecReadItem *p_read_item); + + switch (p_read_item->data_info.frame_type) { + case MELSEC_1E_FRAME: + GenerateMelsecCommandFunction = Melsec1eGenerateCommand; + break; + case MELSEC_3E_IQ_R_FRAME: + GenerateMelsecCommandFunction = Melsec3eiqrGenerateCommand; + break; + case MELSEC_3E_Q_L_FRAME: + GenerateMelsecCommandFunction = Melsec3eqlGenerateCommand; + break; + case MELSEC_1C_FRAME: + GenerateMelsecCommandFunction = Melsec1cGenerateCommand; + break; + case MELSEC_3C_FRAME: + GenerateMelsecCommandFunction = Melsec3cGenerateCommand; + break; + default: + return 0; + } + return GenerateMelsecCommandFunction(p_command, command_code, p_read_item); +} + +/** + * @description: Melsec Data Info Init + * @param p_read_item - read item pointer + * @param p_data - control-data pointer + * @return success : 0 error : -1 + */ +int MelsecInitialDataInfo(MelsecReadItem *p_read_item, uint8_t *p_data) +{ + uint8_t check_sum = 0; + BasicPlcDataInfo *p_base_data_info = &(p_read_item->data_info.base_data_info); + + int command_base_length = MelsecGetCommandBaseLength(p_read_item->data_info.frame_type); + if (command_base_length < 0) { + printf("%s Not supported device code!\n", __func__); + return -1; + } + + switch (p_read_item->data_info.command_type) { + case READ_IN_BITS: + p_base_data_info->command_length = command_base_length; + p_base_data_info->p_command = PrivMalloc(command_base_length); + p_base_data_info->data_size = p_read_item->device_points_count; + p_base_data_info->p_data = p_data; + break; + case READ_IN_WORD: + p_base_data_info->command_length = command_base_length; + p_base_data_info->p_command = PrivMalloc(command_base_length); + p_base_data_info->data_size = p_read_item->device_points_count * 2; + p_base_data_info->p_data = p_data; + break; + case WRITE_IN_BITS: + p_base_data_info->command_length = command_base_length + p_read_item->device_points_count; + p_base_data_info->p_command = PrivMalloc(command_base_length + p_read_item->device_points_count); + command_base_length -= (p_read_item->data_info.frame_type >= MELSEC_1C_FRAME) ? 2 : 0; + memcpy(p_base_data_info->p_command + command_base_length, p_data, p_read_item->device_points_count); + break; + case WRITE_IN_WORD: + p_base_data_info->command_length = command_base_length + p_read_item->device_points_count * 2; + p_base_data_info->p_command = PrivMalloc(command_base_length + p_read_item->device_points_count * 2); + command_base_length -= (p_read_item->data_info.frame_type >= MELSEC_1C_FRAME) ? 2 : 0; + memcpy(p_base_data_info->p_command + command_base_length, p_data, p_read_item->device_points_count * 2); + break; + default: + return -1; + } + + uint32_t command_code = MelsecGetCommandCode(p_read_item->data_info.frame_type, p_read_item->data_info.command_type); + MelsecGenerateCommand(p_base_data_info->p_command, command_code, p_read_item); + + return 0; +} + +/** + * @description: Melsec 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 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; +} + +#ifdef CONTROL_USING_SOCKET +/** + * @description: Melsec Get Data From Socket + * @param socket - socket + * @param p_read_item - read item pointer + * @return success : 0 error : -1 -2 + */ +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; +} +#endif + +/** + * @description: Melsec Get Data From Serial + * @param p_read_item - read item pointer + * @return success : 0 error : -1 -2 + */ +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); + } +} + +/** + * @description: Melsec 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 *melsec_data; + uint16_t read_item_size = sizeof(MelsecReadItem); + + struct ControlProtocol *control_protocol = (struct ControlProtocol *)parameter; + struct CircularAreaApp *circular_area = (struct CircularAreaApp *)control_protocol->args; + MelsecReadItem *melsec_read_item = (MelsecReadItem *)control_protocol->recipe->read_item; + melsec_data = control_protocol->recipe->protocol_data.data; + data_length = control_protocol->recipe->protocol_data.data_length; + + 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; + + while (1) { + for (i = 0; i < control_protocol->recipe->read_item_count; i ++) { + + if ((PROTOCOL_MELSEC_1C == control_protocol->protocol_type) || (PROTOCOL_MELSEC_3C == control_protocol->protocol_type)) { + MelsecGetDataBySerial((MelsecReadItem *)melsec_read_item + i); + } else { +#ifdef CONTROL_USING_SOCKET + /*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 + } + } + + /*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\n", __func__, i, data_length); + CircularAreaAppWrite(circular_area, melsec_data, data_length, 0); + } + + /*read data every single 'read_period' ms*/ + PrivTaskDelay(control_protocol->recipe->read_period); + } +} + +/** + * @description: Melsec Protocol Open + * @param control_protocol - control protocol pointer + * @return success : 0 error + */ +int MelsecOpen(struct ControlProtocol *control_protocol) +{ + ControlProtocolOpenDef(control_protocol); + + return 0; +} + +/** + * @description: Melsec Protocol Close + * @param control_protocol - control protocol pointer + * @return success : 0 error + */ +int MelsecClose(struct ControlProtocol *control_protocol) +{ + if ((PROTOCOL_MELSEC_1C != control_protocol->protocol_type) && (PROTOCOL_MELSEC_3C != control_protocol->protocol_type)) { +#ifdef CONTROL_USING_SOCKET + ControlDisconnectSocket(&plc_socket); +#endif + } + + ControlProtocolCloseDef(); + + return 0; +} + +/** + * @description: Melsec 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 MelsecRead(struct ControlProtocol *control_protocol, void *buf, size_t len) +{ + struct CircularAreaApp *circular_area = (struct CircularAreaApp *)control_protocol->args; + return CircularAreaAppRead(circular_area, buf, len); +} + +static struct ControlDone melsec_protocol_done = +{ + ._open = MelsecOpen, + ._close = MelsecClose, + ._read = MelsecRead, + ._write = NULL, + ._ioctl = NULL, +}; + +/** + * @description: Melsec Protocol Cmd Generate + * @param p_recipe - recipe pointer + * @param protocol_format_info - protocol format info pointer + * @return success : 0 error : -1 + */ +int MelsecProtocolFormatCmd(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; + + MelsecReadItem *melsec_read_item = (MelsecReadItem *)(p_recipe->read_item) + protocol_format_info->read_item_index; + + melsec_read_item->value_type = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "value_type")->valueint; + strncpy(melsec_read_item->value_name, cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "value_name")->valuestring, 20); + 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 = 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; + + ret = MelsecInitialDataInfo(melsec_read_item, p_read_item_data); + + ControlPrintfList("CMD", melsec_read_item->data_info.base_data_info.p_command, melsec_read_item->data_info.base_data_info.command_length); + protocol_format_info->last_item_size = GetValueTypeMemorySize(melsec_read_item->value_type); + + last_item_size += protocol_format_info->last_item_size; + + return ret; +} + +/** + * @description: Melsec Protocol Init + * @param p_recipe - recipe pointer + * @return success : 0 error : -1 + */ +int MelsecProtocolInit(struct ControlRecipe *p_recipe) +{ + p_recipe->read_item = PrivMalloc(sizeof(MelsecReadItem) * 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(MelsecReadItem)); + + p_recipe->ControlProtocolFormatCmd = MelsecProtocolFormatCmd; + + p_recipe->done = &melsec_protocol_done; + + 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 new file mode 100644 index 000000000..7c67c0263 --- /dev/null +++ b/APP_Framework/Framework/control/plc_protocol/melsec/test_recipe_melsec_1c.json @@ -0,0 +1,34 @@ +{ + "device_id": 769, + "device_name": "S01", + "communication_type": 1, + "serial_config": { + "station": 1, + "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 + } + ] +} \ No newline at end of file diff --git a/APP_Framework/Framework/control/plc_protocol/melsec/test_recipe_melsec_1e.json b/APP_Framework/Framework/control/plc_protocol/melsec/test_recipe_melsec_1e.json new file mode 100644 index 000000000..964495ef0 --- /dev/null +++ b/APP_Framework/Framework/control/plc_protocol/melsec/test_recipe_melsec_1e.json @@ -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 + } + ] +} 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 new file mode 100644 index 000000000..5fb0e0dc2 --- /dev/null +++ b/APP_Framework/Framework/control/plc_protocol/melsec/test_recipe_melsec_3c.json @@ -0,0 +1,34 @@ +{ + "device_id": 770, + "device_name": "S02", + "communication_type": 1, + "serial_config": { + "station": 1, + "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 + } + ] +} \ No newline at end of file diff --git a/APP_Framework/Framework/control/plc_protocol/melsec/test_recipe_melsec_3e_iq_r.json b/APP_Framework/Framework/control/plc_protocol/melsec/test_recipe_melsec_3e_iq_r.json new file mode 100644 index 000000000..aa62a5299 --- /dev/null +++ b/APP_Framework/Framework/control/plc_protocol/melsec/test_recipe_melsec_3e_iq_r.json @@ -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 + } + ] +} diff --git a/APP_Framework/Framework/control/plc_protocol/melsec/test_recipe_melsec_3e_q_l.json b/APP_Framework/Framework/control/plc_protocol/melsec/test_recipe_melsec_3e_q_l.json new file mode 100644 index 000000000..59c143e0d --- /dev/null +++ b/APP_Framework/Framework/control/plc_protocol/melsec/test_recipe_melsec_3e_q_l.json @@ -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 + } + ] +} diff --git a/APP_Framework/Framework/control/shared/control_def.c b/APP_Framework/Framework/control/shared/control_def.c index 27ab2d761..c19ae9757 100644 --- a/APP_Framework/Framework/control/shared/control_def.c +++ b/APP_Framework/Framework/control/shared/control_def.c @@ -33,6 +33,18 @@ extern void *ReceivePlcDataTask(void *parameter); extern int FinsProtocolInit(struct ControlRecipe *p_recipe); #endif +#ifdef CONTROL_PROTOCOL_MELSEC +extern int MelsecProtocolInit(struct ControlRecipe *p_recipe); +#endif + +#ifdef CONTROL_PROTOCOL_MODBUS_TCP +extern int ModbusTcpProtocolInit(struct ControlRecipe *p_recipe); +#endif + +#ifdef CONTROL_PROTOCOL_MODBUS_UART +extern int ModbusUartProtocolInit(struct ControlRecipe *p_recipe); +#endif + /* CONTROL FRAMEWORK READ DATA FORMAT: | HEAD |device_id|read data length|read item count| data | @@ -55,6 +67,19 @@ static struct ControlProtocolInitParam protocol_init[] = #ifdef CONTROL_PROTOCOL_FINS { PROTOCOL_FINS, FinsProtocolInit }, #endif +#ifdef CONTROL_PROTOCOL_MELSEC + { PROTOCOL_MELSEC_1E, MelsecProtocolInit }, + { PROTOCOL_MELSEC_3E_Q_L, MelsecProtocolInit }, + { PROTOCOL_MELSEC_3E_IQ_R, MelsecProtocolInit }, + { PROTOCOL_MELSEC_1C, MelsecProtocolInit }, + { PROTOCOL_MELSEC_3C, MelsecProtocolInit }, +#endif +#ifdef CONTROL_PROTOCOL_MODBUS_TCP + { PROTOCOL_MODBUS_TCP, ModbusTcpProtocolInit }, +#endif +#ifdef CONTROL_PROTOCOL_MODBUS_UART + { PROTOCOL_MODBUS_UART, ModbusUartProtocolInit }, +#endif { PROTOCOL_END, NULL }, }; @@ -125,12 +150,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); } /** @@ -184,13 +210,14 @@ static void ControlBasicSocketConfig(struct ControlRecipe *p_recipe, cJSON *p_re */ void ControlPrintfList(char name[5], uint8_t *number_list, uint16_t length) { - printf("\n******************%5s****************\n", name); + printf("\n******************%s****************\n", name); for (int32_t i = 0;i < length;i ++) { printf("0x%x ", number_list[i]); } printf("\n**************************************\n"); } +#ifdef CONTROL_USING_SOCKET /** * @description: Control Framework Connect Socket * @param p_plc - basic socket plc pointer @@ -267,6 +294,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 9126c6c1d..96957ad20 100644 --- a/APP_Framework/Framework/control/shared/control_def.h +++ b/APP_Framework/Framework/control/shared/control_def.h @@ -69,6 +69,7 @@ typedef struct { uint16_t command_length; uint16_t data_size; + uint8_t command_ready; uint8_t *p_command; uint8_t *p_data; }BasicPlcDataInfo; @@ -89,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 eb7172883..fbb01b7ec 100644 --- a/APP_Framework/Framework/control/shared/control_io.c +++ b/APP_Framework/Framework/control/shared/control_io.c @@ -20,6 +20,96 @@ #include +#ifdef CONTROL_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 baud_rate %d data_bits %d stop_bits %d check_mode %d\n", + uart_fd, baud_rate, data_bits, stop_bits, check_mode); + + 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; + + ioctl_cfg.ioctl_driver_type = SERIAL_TYPE; + ioctl_cfg.args = &cfg; + ret = PrivIoctl(uart_fd, OPE_INT, &ioctl_cfg); + if (0 != ret) { + printf("ioctl fd error %d\n", ret); + return; + } + + printf("%s done!\n", __func__); +} +#endif + /** * @description: Control Framework Socket Init * @param ip - local ip pointer @@ -33,9 +123,14 @@ void SocketInit(char *ip, char *mask, char *gw) ip[0], ip[1], ip[2], ip[3], mask[0], mask[1], mask[2], mask[3], gw[0], gw[1], gw[2], gw[3]); +#ifdef CONTROL_USING_SOCKET #ifdef BSP_USING_LWIP lwip_config_tcp(0, ip, mask, gw); #endif +#ifdef BSP_USING_W5500 + //to do +#endif +#endif } /** @@ -48,5 +143,50 @@ 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 CONTROL_USING_SERIAL_485 + Uart485Init(baud_rate, data_bits, stop_bits, check_mode); +#endif +} + +/** + * @description: Control Framework Serial Write + * @param write_data - write data + * @param length - length + * @return + */ +void SerialWrite(uint8_t *write_data, int length) +{ +#ifdef CONTROL_USING_SERIAL_485 + Set485Output(); + PrivTaskDelay(20); + + PrivWrite(uart_fd, write_data, length); + + PrivTaskDelay(15); + Set485Input(); +#endif +} + +/** + * @description: Control Framework Serial Read + * @param read_data - read data + * @param length - length + * @return read data size + */ +int SerialRead(uint8_t *read_data, int length) +{ +#ifdef CONTROL_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); + data_size += data_recv_size; + } + + //need to wait 30ms , make sure write cmd again and receive data successfully + PrivTaskDelay(30); + + return data_size; +#endif } diff --git a/APP_Framework/Framework/control/shared/control_io.h b/APP_Framework/Framework/control/shared/control_io.h index 52c501486..9446916a6 100644 --- a/APP_Framework/Framework/control/shared/control_io.h +++ b/APP_Framework/Framework/control/shared/control_io.h @@ -24,26 +24,42 @@ #include #include +#ifdef CONTROL_USING_SOCKET #ifdef BSP_USING_LWIP #include "lwip/sys.h" #include "lwip/sockets.h" #endif +#endif #ifdef __cplusplus extern "C" { #endif +#ifdef CONTROL_USING_SOCKET #ifdef BSP_USING_LWIP #define socket_write lwip_write #define socket_read lwip_read #endif +#ifdef BSP_USING_W5500 +//to do +#define socket_write +#define socket_read +#endif +#endif + /*Control Framework Socket Init*/ 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 diff --git a/APP_Framework/Framework/transform_layer/xizi/transform.c b/APP_Framework/Framework/transform_layer/xizi/transform.c index 3aa5ac1e0..8995c7906 100644 --- a/APP_Framework/Framework/transform_layer/xizi/transform.c +++ b/APP_Framework/Framework/transform_layer/xizi/transform.c @@ -104,7 +104,7 @@ int PrivTaskDelay(int32_t ms) #ifndef SEPARATE_COMPILE uint32_t PrivGetTickTime() { - return CalculteTimeMsFromTick(CurrentTicksGain()); + return CalculateTimeMsFromTick(CurrentTicksGain()); } #endif /*********************fs**************************/ diff --git a/Ubiquitous/XiZi_IIoT/arch/arm/cortex-m7/interrupt_vector.S b/Ubiquitous/XiZi_IIoT/arch/arm/cortex-m7/interrupt_vector.S index 6397b2f71..a93de8a75 100644 --- a/Ubiquitous/XiZi_IIoT/arch/arm/cortex-m7/interrupt_vector.S +++ b/Ubiquitous/XiZi_IIoT/arch/arm/cortex-m7/interrupt_vector.S @@ -58,7 +58,7 @@ __isr_vector: .long IsrEntry /* Debug Monitor Handler*/ .long 0 /* Reserved*/ .long PendSV_Handler /* PendSV Handler*/ - .long IsrEntry /* SysTick Handler*/ + .long SysTick_Handler /* SysTick Handler*/ /* External Interrupts*/ .long IsrEntry /* DMA channel 0/16 transfer complete*/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/ethernetif.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/ethernetif.c index c50831630..f792d669f 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/ethernetif.c +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/ethernetif.c @@ -39,7 +39,8 @@ Modification: 3、add ETH_RST_PORT and ETH_RST_PIN; 4、add ETH_LINK_LED_PORT and ETH_LINK_LED_PIN; 5、add ethernetif_config_enet_set; -6、add ETHERNET_LOOPBACK_TEST with testnetif and txPbuf. +6、add ETHERNET_LOOPBACK_TEST with testnetif and txPbuf; +7、modify ethernetif_init() and ethernetif_input() to support LwIP. *************************************************/ /******************************************************************************* @@ -282,6 +283,10 @@ static int32_t low_level_init(struct netif *netif) netif->hwaddr[5] = (EthHandle.stcCommInit).au8MacAddr[5]; /* maximum transfer unit */ netif->mtu = 1500U; + + /* device capabilities */ + netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; + /* Enable MAC and DMA transmission and reception */ (void)ETH_Start(); @@ -322,9 +327,9 @@ static int32_t low_level_init(struct netif *netif) * - LL_OK: The packet could be sent * - LL_ERR: The packet couldn't be sent */ -int32_t low_level_output(struct netif *netif, struct pbuf *p) +err_t low_level_output(struct netif *netif, struct pbuf *p) { - int32_t i32Ret; + err_t i32Ret; struct pbuf *q; uint8_t *txBuffer; __IO stc_eth_dma_desc_t *DmaTxDesc; @@ -474,8 +479,22 @@ static struct pbuf *low_level_input(struct netif *netif) */ err_t ethernetif_init(struct netif *netif) { +#if LWIP_NETIF_HOSTNAME + /* Initialize interface hostname */ + netif->hostname = "lwip"; +#endif /* LWIP_NETIF_HOSTNAME */ netif->name[0] = IFNAME0; netif->name[1] = IFNAME1; + +#ifndef ETHERNET_LOOPBACK_TEST + /* We directly use etharp_output() here to save a function call. + * You can instead declare your own function an call etharp_output() + * from it if you have to do some checks before sending (e.g. if link + * is available...) */ + netif->output = ðarp_output; + netif->linkoutput = &low_level_output; +#endif + /* initialize the hardware */ return low_level_init(netif); } @@ -487,15 +506,32 @@ err_t ethernetif_init(struct netif *netif) */ void ethernetif_input(struct netif *netif) { + err_t err; struct pbuf *p; /* Move received packet into a new pbuf */ p = low_level_input(netif); + +#ifndef ETHERNET_LOOPBACK_TEST + /* No packet could be read, silently ignore this */ + if (NULL == p) { + return; + } + + /* Entry point to the LwIP stack */ + err = netif->input(p, netif); + if (err != (err_t)ERR_OK) { + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); + (void)pbuf_free(p); + } +#endif +#ifdef ETHERNET_LOOPBACK_TEST /* No packet could be read, silently ignore this */ if (p != NULL) { EthernetIF_InputCallback(netif, p); free(p); } +#endif } /** diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/hardware_ethernetif.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/hardware_ethernetif.h index 0fb839584..e07b5495e 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/hardware_ethernetif.h +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/hardware_ethernetif.h @@ -135,7 +135,7 @@ extern "C" */ err_t ethernetif_init(struct netif *netif); void ethernetif_input(struct netif *netif); -int32_t low_level_output(struct netif *netif, struct pbuf *p); +err_t low_level_output(struct netif *netif, struct pbuf *p); void EthernetIF_CheckLink(struct netif *netif); void EthernetIF_UpdateLink(struct netif *netif); diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/connect_spi.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/connect_spi.c index f74767f13..8cfae2660 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/connect_spi.c +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/spi/connect_spi.c @@ -61,21 +61,21 @@ Modification: #define SPI6_UNIT (CM_SPI6) #define SPI6_CLK (FCG1_PERIPH_SPI6) -/* SS = PI01 */ -#define SPI6_SS_PORT (GPIO_PORT_I) -#define SPI6_SS_PIN (GPIO_PIN_01) -/* SCK = PH14 */ -#define SPI6_SCK_PORT (GPIO_PORT_H) -#define SPI6_SCK_PIN (GPIO_PIN_14) -#define SPI6_SCK_FUNC (GPIO_FUNC_40) -/* MOSI = PI00 */ -#define SPI6_MOSI_PORT (GPIO_PORT_I) -#define SPI6_MOSI_PIN (GPIO_PIN_00) -#define SPI6_MOSI_FUNC (GPIO_FUNC_41) -/* MISO = PH15 */ -#define SPI6_MISO_PORT (GPIO_PORT_H) -#define SPI6_MISO_PIN (GPIO_PIN_15) -#define SPI6_MISO_FUNC (GPIO_FUNC_42) +/* SS = PE02 */ +#define SPI6_SS_PORT (GPIO_PORT_E) +#define SPI6_SS_PIN (GPIO_PIN_02) +/* SCK = PE03 */ +#define SPI6_SCK_PORT (GPIO_PORT_E) +#define SPI6_SCK_PIN (GPIO_PIN_03) +#define SPI6_SCK_FUNC (GPIO_FUNC_46) +/* MOSI = PE04 */ +#define SPI6_MOSI_PORT (GPIO_PORT_E) +#define SPI6_MOSI_PIN (GPIO_PIN_04) +#define SPI6_MOSI_FUNC (GPIO_FUNC_47) +/* MISO = PE05 */ +#define SPI6_MISO_PORT (GPIO_PORT_E) +#define SPI6_MISO_PIN (GPIO_PIN_05) +#define SPI6_MISO_FUNC (GPIO_FUNC_48) #define SPI6_DEVICE_SLAVE_ID_0 0 diff --git a/Ubiquitous/XiZi_IIoT/board/ok1052-c/.defconfig b/Ubiquitous/XiZi_IIoT/board/ok1052-c/.defconfig new file mode 100644 index 000000000..555b84bcf --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/ok1052-c/.defconfig @@ -0,0 +1,294 @@ +# +# Automatically generated file; DO NOT EDIT. +# XiZi_IIoT Project Configuration +# +CONFIG_BOARD_CORTEX_M7_EVB=y +CONFIG_ARCH_ARM=y + +# +# ok1052-c feature +# +CONFIG_BSP_USING_LPUART=y +CONFIG_BSP_USING_LPUART1=y +CONFIG_SERIAL_BUS_NAME_1="uart1" +CONFIG_SERIAL_DRV_NAME_1="uart1_drv" +CONFIG_SERIAL_1_DEVICE_NAME_0="uart1_dev1" +CONFIG_BSP_USING_LPUART2=y +CONFIG_SERIAL_BUS_NAME_2="uart2" +CONFIG_SERIAL_DRV_NAME_2="uart2_drv" +CONFIG_SERIAL_2_DEVICE_NAME_0="uart2_dev2" +CONFIG_BSP_USING_LPUART3=y +CONFIG_SERIAL_BUS_NAME_3="uart3" +CONFIG_SERIAL_DRV_NAME_3="uart3_drv" +CONFIG_SERIAL_3_DEVICE_NAME_0="uart3_dev3" +# CONFIG_BSP_USING_LPUART4 is not set +# CONFIG_BSP_USING_LPUART8 is not set +# CONFIG_BSP_USING_CH438 is not set +CONFIG_BSP_USING_GPIO=y +CONFIG_PIN_BUS_NAME="pin" +CONFIG_PIN_DRIVER_NAME="pin_drv" +CONFIG_PIN_DEVICE_NAME="pin_dev" +# CONFIG_BSP_USING_I2C is not set +# CONFIG_BSP_USING_LWIP is not set +# CONFIG_BSP_USING_SEMC is not set +# CONFIG_BSP_USING_SDIO is not set +# CONFIG_BSP_USING_LCD is not set +# CONFIG_BSP_USING_TOUCH is not set +# CONFIG_BSP_USING_USB is not set +# CONFIG_BSP_USING_WDT is not set + +# +# config default board resources +# + +# +# config board app name +# +CONFIG_BOARD_APP_NAME="/XiUOS_xidatong_app.bin" + +# +# config board service table +# +CONFIG_SERVICE_TABLE_ADDRESS=0x2007F0000 +CONFIG___STACKSIZE__=4096 + +# +# config board peripheral +# +# CONFIG_MOUNT_SDCARD is not set +# CONFIG_MOUNT_USB is not set + +# +# Hardware feature +# +CONFIG_RESOURCES_SERIAL=y +CONFIG_SERIAL_USING_DMA=y +CONFIG_SERIAL_RB_BUFSZ=128 +CONFIG_RESOURCES_PIN=y + +# +# Kernel feature +# + +# +# separate compile(choose none for compile once) +# +# CONFIG_SEPARATE_COMPILE is not set +# CONFIG_COMPILER_APP is not set +# CONFIG_APP_STARTUP_FROM_SDCARD is not set +CONFIG_APP_STARTUP_FROM_FLASH=y +# CONFIG_COMPILER_KERNEL is not set + +# +# Memory Management +# +# CONFIG_KERNEL_MEMBLOCK is not set +CONFIG_MEM_ALIGN_SIZE=8 +# CONFIG_MEM_EXTERN_SRAM is not set +CONFIG_MM_PAGE_SIZE=4096 + +# +# Using small memory allocator +# +CONFIG_KERNEL_SMALL_MEM_ALLOC=y +CONFIG_SMALL_NUMBER_32B=64 +CONFIG_SMALL_NUMBER_64B=32 + +# +# Task feature +# +CONFIG_USER_APPLICATION=y +# CONFIG_TASK_ISOLATION is not set + +# +# Inter-Task communication +# +CONFIG_KERNEL_SEMAPHORE=y +CONFIG_KERNEL_MUTEX=y +CONFIG_KERNEL_EVENT=y +CONFIG_KERNEL_MESSAGEQUEUE=y +CONFIG_KERNEL_SOFTTIMER=y +CONFIG_SCHED_POLICY_RR_REMAINSLICE=y +# CONFIG_SCHED_POLICY_RR is not set +# CONFIG_SCHED_POLICY_FIFO is not set +# CONFIG_KTASK_PRIORITY_8 is not set +CONFIG_KTASK_PRIORITY_32=y +# CONFIG_KTASK_PRIORITY_256 is not set +CONFIG_KTASK_PRIORITY_MAX=32 +CONFIG_TICK_PER_SECOND=1000 +CONFIG_KERNEL_STACK_OVERFLOW_CHECK=y +CONFIG_IDLE_KTASK_STACKSIZE=1024 +CONFIG_ZOMBIE_KTASK_STACKSIZE=2048 + +# +# Kernel Console +# +CONFIG_KERNEL_CONSOLE=y +CONFIG_KERNEL_BANNER=y +CONFIG_KERNEL_CONSOLEBUF_SIZE=128 + +# +# Kernel Hook +# +# CONFIG_KERNEL_HOOK is not set + +# +# Command shell +# +CONFIG_TOOL_SHELL=y +CONFIG_SHELL_ENTER_CR=y +CONFIG_SHELL_ENTER_LF=y +CONFIG_SHELL_ENTER_CR_AND_LF=y +# CONFIG_SHELL_ENTER_CRLF is not set + +# +# Set shell user control +# +CONFIG_SHELL_DEFAULT_USER="letter" +CONFIG_SHELL_DEFAULT_USER_PASSWORD="" +CONFIG_SHELL_LOCK_TIMEOUT=10000 + +# +# Set shell config param +# +CONFIG_SHELL_TASK_STACK_SIZE=4096 +CONFIG_SHELL_TASK_PRIORITY=20 +CONFIG_SHELL_MAX_NUMBER=5 +CONFIG_SHELL_PARAMETER_MAX_NUMBER=8 +CONFIG_SHELL_HISTORY_MAX_NUMBER=5 +CONFIG_SHELL_PRINT_BUFFER=128 +CONFIG_SHELL_HELP_SHOW_PERMISSION=y +# CONFIG_SHELL_HELP_LIST_USER is not set +CONFIG_SHELL_HELP_LIST_VAR=y +# CONFIG_SHELL_HELP_LIST_KEY is not set + +# +# Kernel data structure Manage +# +CONFIG_KERNEL_QUEUEMANAGE=y +CONFIG_KERNEL_WORKQUEUE=y +CONFIG_WORKQUEUE_KTASK_STACKSIZE=2048 +CONFIG_WORKQUEUE_KTASK_PRIORITY=23 +CONFIG_QUEUE_MAX=16 +CONFIG_KERNEL_WAITQUEUE=y +CONFIG_KERNEL_DATAQUEUE=y +# CONFIG_KERNEL_CIRCULAR_AREA is not set +# CONFIG_KERNEL_AVL_TREE is not set + +# +# Kernel components init +# +CONFIG_KERNEL_COMPONENTS_INIT=y +CONFIG_ENV_INIT_KTASK_STACK_SIZE=8192 +CONFIG_KERNEL_USER_MAIN=y +CONFIG_NAME_NUM_MAX=32 +# CONFIG_KERNEL_DEBUG is not set +# CONFIG_ARCH_SMP is not set + +# +# hash table config +# +CONFIG_ID_HTABLE_SIZE=16 +CONFIG_ID_NUM_MAX=128 +# CONFIG_KERNEL_TEST is not set + +# +# Lib +# +CONFIG_LIB=y +CONFIG_LIB_POSIX=y +CONFIG_LIB_NEWLIB=y +# CONFIG_LIB_MUSLLIB is not set + +# +# C++ features +# +# CONFIG_LIB_CPLUSPLUS is not set + +# +# File system +# +CONFIG_FS_VFS=y +CONFIG_VFS_USING_WORKDIR=y +CONFIG_FS_VFS_DEVFS=y +CONFIG_FS_VFS_FATFS=y +# CONFIG_FS_CH376 is not set +# CONFIG_FS_LWEXT4 is not set + +# +# APP_Framework +# + +# +# Framework +# +CONFIG_TRANSFORM_LAYER_ATTRIUBUTE=y +CONFIG_ADD_XIZI_FETURES=y +# CONFIG_ADD_NUTTX_FETURES is not set +# CONFIG_ADD_RTTHREAD_FETURES is not set +# CONFIG_SUPPORT_SENSOR_FRAMEWORK is not set +# CONFIG_SUPPORT_CONNECTION_FRAMEWORK is not set +# CONFIG_SUPPORT_KNOWING_FRAMEWORK is not set +# CONFIG_SUPPORT_CONTROL_FRAMEWORK is not set + +# +# Security +# +# CONFIG_CRYPTO is not set +# CONFIG_MBEDTLS is not set + +# +# Applications +# + +# +# config stack size and priority of main task +# +CONFIG_MAIN_KTASK_STACK_SIZE=4096 +CONFIG_MAIN_KTASK_PRIORITY=16 + +# +# ota app +# +# CONFIG_APPLICATION_OTA is not set + +# +# test app +# +# CONFIG_USER_TEST is not set + +# +# connection app +# +# CONFIG_APPLICATION_CONNECTION is not set + +# +# control app +# + +# +# knowing app +# +# CONFIG_APPLICATION_KNOWING is not set + +# +# sensor app +# +# CONFIG_APPLICATION_SENSOR is not set +# CONFIG_USING_EMBEDDED_DATABASE_APP is not set +# CONFIG_APP_USING_WEBNET is not set + +# +# lib +# +CONFIG_APP_SELECT_NEWLIB=y +# CONFIG_APP_SELECT_OTHER_LIB is not set +# CONFIG_LIB_USING_CJSON is not set +# CONFIG_LIB_USING_QUEUE is not set +# CONFIG_LIB_LV is not set + +# +# LVGL configuration +# +# CONFIG_LV_CONF_MINIMAL is not set +# CONFIG_USING_EMBEDDED_DATABASE is not set diff --git a/Ubiquitous/XiZi_IIoT/board/ok1052-c/board.c b/Ubiquitous/XiZi_IIoT/board/ok1052-c/board.c index d891bfd50..842fa63d0 100644 --- a/Ubiquitous/XiZi_IIoT/board/ok1052-c/board.c +++ b/Ubiquitous/XiZi_IIoT/board/ok1052-c/board.c @@ -364,6 +364,32 @@ status_t BOARD_Camera_I2C_ReceiveSCCB( #endif /* SDK_I2C_BASED_COMPONENT_USED */ #endif +void ImxrtMsDelay(uint32 ms) +{ + uint64 ticks = 0; + uint32 told, tnow, tcnt = 0; + uint32 reload = SysTick->LOAD; + + ticks = ((uint64)ms * ((uint64)reload + 1) * TICK_PER_SECOND) / 1000; + told = SysTick->VAL; + + //KPrintf("%s reload %u ms %u ticks %u told %u\n", __func__, reload, ms, ticks, told); + + while (1) { + tnow = SysTick->VAL; + if (tnow != told) { + if (tnow < told) { + tcnt += told - tnow; + } else { + tcnt += reload - tnow + told; + } + told = tnow; + if (tcnt >= ticks) { + break; + } + } + } +} void BOARD_SD_Pin_Config(uint32_t speed, uint32_t strength) { @@ -574,7 +600,6 @@ void SysTick_Handler(int irqn, void *arg) { TickAndTaskTimesliceUpdate(); } -DECLARE_HW_IRQ(SYSTICK_IRQN, SysTick_Handler, NONE); #ifdef BSP_USING_LPUART void imxrt_uart_pins_init(void) diff --git a/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/ethernet/enet_ethernetif.c b/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/ethernet/enet_ethernetif.c index 4560f454a..764637188 100755 --- a/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/ethernet/enet_ethernetif.c +++ b/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/ethernet/enet_ethernetif.c @@ -81,14 +81,11 @@ /******************************************************************************* * Code ******************************************************************************/ +extern void ImxrtMsDelay(uint32 ms); -void enet_delay(void) +void enet_delay(uint32 ms) { - volatile uint32_t i = 0; - for (i = 0; i < 1000000; ++i) - { - __asm("NOP"); /* delay */ - } + ImxrtMsDelay(ms); } void Time_Update_LwIP(void) @@ -124,7 +121,7 @@ void ethernetif_gpio_init(void) GPIO_PinInit(GPIO1, 3, &gpio_config); /* pull up the ENET_INT before RESET. */ GPIO_WritePinOutput(GPIO1, 3, 0); - enet_delay(); + enet_delay(30); GPIO_WritePinOutput(GPIO1, 3, 1); } diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/.defconfig b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/.defconfig new file mode 100644 index 000000000..ad4f5b2b4 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/.defconfig @@ -0,0 +1,294 @@ +# +# Automatically generated file; DO NOT EDIT. +# XiZi_IIoT Project Configuration +# +CONFIG_BOARD_CORTEX_M7_EVB=y +CONFIG_ARCH_ARM=y + +# +# xidatong-arm32 feature +# +CONFIG_BSP_USING_LPUART=y +CONFIG_BSP_USING_LPUART1=y +CONFIG_SERIAL_BUS_NAME_1="uart1" +CONFIG_SERIAL_DRV_NAME_1="uart1_drv" +CONFIG_SERIAL_1_DEVICE_NAME_0="uart1_dev1" +CONFIG_BSP_USING_LPUART2=y +CONFIG_SERIAL_BUS_NAME_2="uart2" +CONFIG_SERIAL_DRV_NAME_2="uart2_drv" +CONFIG_SERIAL_2_DEVICE_NAME_0="uart2_dev2" +CONFIG_BSP_USING_LPUART3=y +CONFIG_SERIAL_BUS_NAME_3="uart3" +CONFIG_SERIAL_DRV_NAME_3="uart3_drv" +CONFIG_SERIAL_3_DEVICE_NAME_0="uart3_dev3" +# CONFIG_BSP_USING_LPUART4 is not set +# CONFIG_BSP_USING_LPUART8 is not set +# CONFIG_BSP_USING_CH438 is not set +CONFIG_BSP_USING_GPIO=y +CONFIG_PIN_BUS_NAME="pin" +CONFIG_PIN_DRIVER_NAME="pin_drv" +CONFIG_PIN_DEVICE_NAME="pin_dev" +# CONFIG_BSP_USING_I2C is not set +# CONFIG_BSP_USING_LWIP is not set +# CONFIG_BSP_USING_SEMC is not set +# CONFIG_BSP_USING_SDIO is not set +# CONFIG_BSP_USING_LCD is not set +# CONFIG_BSP_USING_TOUCH is not set +# CONFIG_BSP_USING_USB is not set +# CONFIG_BSP_USING_WDT is not set + +# +# config default board resources +# + +# +# config board app name +# +CONFIG_BOARD_APP_NAME="/XiUOS_xidatong_app.bin" + +# +# config board service table +# +CONFIG_SERVICE_TABLE_ADDRESS=0x2007F0000 +CONFIG___STACKSIZE__=4096 + +# +# config board peripheral +# +# CONFIG_MOUNT_SDCARD is not set +# CONFIG_MOUNT_USB is not set + +# +# Hardware feature +# +CONFIG_RESOURCES_SERIAL=y +CONFIG_SERIAL_USING_DMA=y +CONFIG_SERIAL_RB_BUFSZ=128 +CONFIG_RESOURCES_PIN=y + +# +# Kernel feature +# + +# +# separate compile(choose none for compile once) +# +# CONFIG_SEPARATE_COMPILE is not set +# CONFIG_COMPILER_APP is not set +# CONFIG_APP_STARTUP_FROM_SDCARD is not set +CONFIG_APP_STARTUP_FROM_FLASH=y +# CONFIG_COMPILER_KERNEL is not set + +# +# Memory Management +# +# CONFIG_KERNEL_MEMBLOCK is not set +CONFIG_MEM_ALIGN_SIZE=8 +# CONFIG_MEM_EXTERN_SRAM is not set +CONFIG_MM_PAGE_SIZE=4096 + +# +# Using small memory allocator +# +CONFIG_KERNEL_SMALL_MEM_ALLOC=y +CONFIG_SMALL_NUMBER_32B=64 +CONFIG_SMALL_NUMBER_64B=32 + +# +# Task feature +# +CONFIG_USER_APPLICATION=y +# CONFIG_TASK_ISOLATION is not set + +# +# Inter-Task communication +# +CONFIG_KERNEL_SEMAPHORE=y +CONFIG_KERNEL_MUTEX=y +CONFIG_KERNEL_EVENT=y +CONFIG_KERNEL_MESSAGEQUEUE=y +CONFIG_KERNEL_SOFTTIMER=y +CONFIG_SCHED_POLICY_RR_REMAINSLICE=y +# CONFIG_SCHED_POLICY_RR is not set +# CONFIG_SCHED_POLICY_FIFO is not set +# CONFIG_KTASK_PRIORITY_8 is not set +CONFIG_KTASK_PRIORITY_32=y +# CONFIG_KTASK_PRIORITY_256 is not set +CONFIG_KTASK_PRIORITY_MAX=32 +CONFIG_TICK_PER_SECOND=1000 +CONFIG_KERNEL_STACK_OVERFLOW_CHECK=y +CONFIG_IDLE_KTASK_STACKSIZE=1024 +CONFIG_ZOMBIE_KTASK_STACKSIZE=2048 + +# +# Kernel Console +# +CONFIG_KERNEL_CONSOLE=y +CONFIG_KERNEL_BANNER=y +CONFIG_KERNEL_CONSOLEBUF_SIZE=128 + +# +# Kernel Hook +# +# CONFIG_KERNEL_HOOK is not set + +# +# Command shell +# +CONFIG_TOOL_SHELL=y +CONFIG_SHELL_ENTER_CR=y +CONFIG_SHELL_ENTER_LF=y +CONFIG_SHELL_ENTER_CR_AND_LF=y +# CONFIG_SHELL_ENTER_CRLF is not set + +# +# Set shell user control +# +CONFIG_SHELL_DEFAULT_USER="letter" +CONFIG_SHELL_DEFAULT_USER_PASSWORD="" +CONFIG_SHELL_LOCK_TIMEOUT=10000 + +# +# Set shell config param +# +CONFIG_SHELL_TASK_STACK_SIZE=4096 +CONFIG_SHELL_TASK_PRIORITY=20 +CONFIG_SHELL_MAX_NUMBER=5 +CONFIG_SHELL_PARAMETER_MAX_NUMBER=8 +CONFIG_SHELL_HISTORY_MAX_NUMBER=5 +CONFIG_SHELL_PRINT_BUFFER=128 +CONFIG_SHELL_HELP_SHOW_PERMISSION=y +# CONFIG_SHELL_HELP_LIST_USER is not set +CONFIG_SHELL_HELP_LIST_VAR=y +# CONFIG_SHELL_HELP_LIST_KEY is not set + +# +# Kernel data structure Manage +# +CONFIG_KERNEL_QUEUEMANAGE=y +CONFIG_KERNEL_WORKQUEUE=y +CONFIG_WORKQUEUE_KTASK_STACKSIZE=2048 +CONFIG_WORKQUEUE_KTASK_PRIORITY=23 +CONFIG_QUEUE_MAX=16 +CONFIG_KERNEL_WAITQUEUE=y +CONFIG_KERNEL_DATAQUEUE=y +# CONFIG_KERNEL_CIRCULAR_AREA is not set +# CONFIG_KERNEL_AVL_TREE is not set + +# +# Kernel components init +# +CONFIG_KERNEL_COMPONENTS_INIT=y +CONFIG_ENV_INIT_KTASK_STACK_SIZE=8192 +CONFIG_KERNEL_USER_MAIN=y +CONFIG_NAME_NUM_MAX=32 +# CONFIG_KERNEL_DEBUG is not set +# CONFIG_ARCH_SMP is not set + +# +# hash table config +# +CONFIG_ID_HTABLE_SIZE=16 +CONFIG_ID_NUM_MAX=128 +# CONFIG_KERNEL_TEST is not set + +# +# Lib +# +CONFIG_LIB=y +CONFIG_LIB_POSIX=y +CONFIG_LIB_NEWLIB=y +# CONFIG_LIB_MUSLLIB is not set + +# +# C++ features +# +# CONFIG_LIB_CPLUSPLUS is not set + +# +# File system +# +CONFIG_FS_VFS=y +CONFIG_VFS_USING_WORKDIR=y +CONFIG_FS_VFS_DEVFS=y +CONFIG_FS_VFS_FATFS=y +# CONFIG_FS_CH376 is not set +# CONFIG_FS_LWEXT4 is not set + +# +# APP_Framework +# + +# +# Framework +# +CONFIG_TRANSFORM_LAYER_ATTRIUBUTE=y +CONFIG_ADD_XIZI_FETURES=y +# CONFIG_ADD_NUTTX_FETURES is not set +# CONFIG_ADD_RTTHREAD_FETURES is not set +# CONFIG_SUPPORT_SENSOR_FRAMEWORK is not set +# CONFIG_SUPPORT_CONNECTION_FRAMEWORK is not set +# CONFIG_SUPPORT_KNOWING_FRAMEWORK is not set +# CONFIG_SUPPORT_CONTROL_FRAMEWORK is not set + +# +# Security +# +# CONFIG_CRYPTO is not set +# CONFIG_MBEDTLS is not set + +# +# Applications +# + +# +# config stack size and priority of main task +# +CONFIG_MAIN_KTASK_STACK_SIZE=4096 +CONFIG_MAIN_KTASK_PRIORITY=16 + +# +# ota app +# +# CONFIG_APPLICATION_OTA is not set + +# +# test app +# +# CONFIG_USER_TEST is not set + +# +# connection app +# +# CONFIG_APPLICATION_CONNECTION is not set + +# +# control app +# + +# +# knowing app +# +# CONFIG_APPLICATION_KNOWING is not set + +# +# sensor app +# +# CONFIG_APPLICATION_SENSOR is not set +# CONFIG_USING_EMBEDDED_DATABASE_APP is not set +# CONFIG_APP_USING_WEBNET is not set + +# +# lib +# +CONFIG_APP_SELECT_NEWLIB=y +# CONFIG_APP_SELECT_OTHER_LIB is not set +# CONFIG_LIB_USING_CJSON is not set +# CONFIG_LIB_USING_QUEUE is not set +# CONFIG_LIB_LV is not set + +# +# LVGL configuration +# +# CONFIG_LV_CONF_MINIMAL is not set +# CONFIG_USING_EMBEDDED_DATABASE is not set diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/board.c b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/board.c index 1a64fc4f2..af87f9229 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/board.c +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/board.c @@ -83,6 +83,33 @@ extern int Imxrt1052HwLcdInit(void); extern int HwTouchInit(); #endif +void ImxrtMsDelay(uint32 ms) +{ + uint64 ticks = 0; + uint32 told, tnow, tcnt = 0; + uint32 reload = SysTick->LOAD; + + ticks = ((uint64)ms * ((uint64)reload + 1) * TICK_PER_SECOND) / 1000; + told = SysTick->VAL; + + //KPrintf("%s reload %u ms %u ticks %u told %u\n", __func__, reload, ms, ticks, told); + + while (1) { + tnow = SysTick->VAL; + if (tnow != told) { + if (tnow < told) { + tcnt += told - tnow; + } else { + tcnt += reload - tnow + told; + } + told = tnow; + if (tcnt >= ticks) { + break; + } + } + } +} + void BOARD_SD_Pin_Config(uint32_t speed, uint32_t strength) { IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B0_00_USDHC1_CMD, @@ -291,7 +318,6 @@ void SysTick_Handler(int irqn, void *arg) { TickAndTaskTimesliceUpdate(); } -DECLARE_HW_IRQ(SYSTICK_IRQN, SysTick_Handler, NONE); struct InitSequenceDesc _board_init[] = { @@ -300,7 +326,7 @@ struct InitSequenceDesc _board_init[] = #endif #ifdef BSP_USING_CH438 - {"ch438", Imxrt1052HwCh438Init()}, + {"ch438", Imxrt1052HwCh438Init }, #endif #ifdef BSP_USING_SDIO diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/ethernet/enet_ethernetif.c b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/ethernet/enet_ethernetif.c index 3df2f6e40..1b32163dd 100755 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/ethernet/enet_ethernetif.c +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/third_party_driver/ethernet/enet_ethernetif.c @@ -81,14 +81,11 @@ /******************************************************************************* * Code ******************************************************************************/ +extern void ImxrtMsDelay(uint32 ms); -void enet_delay(void) +void enet_delay(uint32 ms) { - volatile uint32_t i = 0; - for (i = 0; i < 10000000; ++i) - { - __asm("NOP"); /* delay */ - } + ImxrtMsDelay(ms); } void Time_Update_LwIP(void) @@ -126,7 +123,7 @@ void ethernetif_gpio_init(void) /* pull up the ENET_INT before RESET. */ GPIO_WritePinOutput(GPIO1, 10, 1); GPIO_WritePinOutput(GPIO1, 3, 0); - enet_delay(); + enet_delay(30); GPIO_WritePinOutput(GPIO1, 3, 1); } diff --git a/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/.defconfig b/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/.defconfig new file mode 100644 index 000000000..3c7407613 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/.defconfig @@ -0,0 +1,294 @@ +# +# Automatically generated file; DO NOT EDIT. +# XiZi_IIoT Project Configuration +# +CONFIG_BOARD_CORTEX_M7_EVB=y +CONFIG_ARCH_ARM=y + +# +# xiwangtong-arm32 feature +# +CONFIG_BSP_USING_LPUART=y +CONFIG_BSP_USING_LPUART1=y +CONFIG_SERIAL_BUS_NAME_1="uart1" +CONFIG_SERIAL_DRV_NAME_1="uart1_drv" +CONFIG_SERIAL_1_DEVICE_NAME_0="uart1_dev1" +CONFIG_BSP_USING_LPUART2=y +CONFIG_SERIAL_BUS_NAME_2="uart2" +CONFIG_SERIAL_DRV_NAME_2="uart2_drv" +CONFIG_SERIAL_2_DEVICE_NAME_0="uart2_dev2" +CONFIG_BSP_USING_LPUART3=y +CONFIG_SERIAL_BUS_NAME_3="uart3" +CONFIG_SERIAL_DRV_NAME_3="uart3_drv" +CONFIG_SERIAL_3_DEVICE_NAME_0="uart3_dev3" +# CONFIG_BSP_USING_LPUART4 is not set +# CONFIG_BSP_USING_LPUART8 is not set +# CONFIG_BSP_USING_CH438 is not set +CONFIG_BSP_USING_GPIO=y +CONFIG_PIN_BUS_NAME="pin" +CONFIG_PIN_DRIVER_NAME="pin_drv" +CONFIG_PIN_DEVICE_NAME="pin_dev" +# CONFIG_BSP_USING_I2C is not set +# CONFIG_BSP_USING_LWIP is not set +# CONFIG_BSP_USING_SEMC is not set +# CONFIG_BSP_USING_SDIO is not set +# CONFIG_BSP_USING_LCD is not set +# CONFIG_BSP_USING_TOUCH is not set +# CONFIG_BSP_USING_USB is not set +# CONFIG_BSP_USING_WDT is not set + +# +# config default board resources +# + +# +# config board app name +# +CONFIG_BOARD_APP_NAME="/XiUOS_xidatong_app.bin" + +# +# config board service table +# +CONFIG_SERVICE_TABLE_ADDRESS=0x2007F0000 +CONFIG___STACKSIZE__=4096 + +# +# config board peripheral +# +# CONFIG_MOUNT_SDCARD is not set +# CONFIG_MOUNT_USB is not set + +# +# Hardware feature +# +CONFIG_RESOURCES_SERIAL=y +CONFIG_SERIAL_USING_DMA=y +CONFIG_SERIAL_RB_BUFSZ=128 +CONFIG_RESOURCES_PIN=y + +# +# Kernel feature +# + +# +# separate compile(choose none for compile once) +# +# CONFIG_SEPARATE_COMPILE is not set +# CONFIG_COMPILER_APP is not set +# CONFIG_APP_STARTUP_FROM_SDCARD is not set +CONFIG_APP_STARTUP_FROM_FLASH=y +# CONFIG_COMPILER_KERNEL is not set + +# +# Memory Management +# +# CONFIG_KERNEL_MEMBLOCK is not set +CONFIG_MEM_ALIGN_SIZE=8 +# CONFIG_MEM_EXTERN_SRAM is not set +CONFIG_MM_PAGE_SIZE=4096 + +# +# Using small memory allocator +# +CONFIG_KERNEL_SMALL_MEM_ALLOC=y +CONFIG_SMALL_NUMBER_32B=64 +CONFIG_SMALL_NUMBER_64B=32 + +# +# Task feature +# +CONFIG_USER_APPLICATION=y +# CONFIG_TASK_ISOLATION is not set + +# +# Inter-Task communication +# +CONFIG_KERNEL_SEMAPHORE=y +CONFIG_KERNEL_MUTEX=y +CONFIG_KERNEL_EVENT=y +CONFIG_KERNEL_MESSAGEQUEUE=y +CONFIG_KERNEL_SOFTTIMER=y +CONFIG_SCHED_POLICY_RR_REMAINSLICE=y +# CONFIG_SCHED_POLICY_RR is not set +# CONFIG_SCHED_POLICY_FIFO is not set +# CONFIG_KTASK_PRIORITY_8 is not set +CONFIG_KTASK_PRIORITY_32=y +# CONFIG_KTASK_PRIORITY_256 is not set +CONFIG_KTASK_PRIORITY_MAX=32 +CONFIG_TICK_PER_SECOND=1000 +CONFIG_KERNEL_STACK_OVERFLOW_CHECK=y +CONFIG_IDLE_KTASK_STACKSIZE=1024 +CONFIG_ZOMBIE_KTASK_STACKSIZE=2048 + +# +# Kernel Console +# +CONFIG_KERNEL_CONSOLE=y +CONFIG_KERNEL_BANNER=y +CONFIG_KERNEL_CONSOLEBUF_SIZE=128 + +# +# Kernel Hook +# +# CONFIG_KERNEL_HOOK is not set + +# +# Command shell +# +CONFIG_TOOL_SHELL=y +CONFIG_SHELL_ENTER_CR=y +CONFIG_SHELL_ENTER_LF=y +CONFIG_SHELL_ENTER_CR_AND_LF=y +# CONFIG_SHELL_ENTER_CRLF is not set + +# +# Set shell user control +# +CONFIG_SHELL_DEFAULT_USER="letter" +CONFIG_SHELL_DEFAULT_USER_PASSWORD="" +CONFIG_SHELL_LOCK_TIMEOUT=10000 + +# +# Set shell config param +# +CONFIG_SHELL_TASK_STACK_SIZE=4096 +CONFIG_SHELL_TASK_PRIORITY=20 +CONFIG_SHELL_MAX_NUMBER=5 +CONFIG_SHELL_PARAMETER_MAX_NUMBER=8 +CONFIG_SHELL_HISTORY_MAX_NUMBER=5 +CONFIG_SHELL_PRINT_BUFFER=128 +CONFIG_SHELL_HELP_SHOW_PERMISSION=y +# CONFIG_SHELL_HELP_LIST_USER is not set +CONFIG_SHELL_HELP_LIST_VAR=y +# CONFIG_SHELL_HELP_LIST_KEY is not set + +# +# Kernel data structure Manage +# +CONFIG_KERNEL_QUEUEMANAGE=y +CONFIG_KERNEL_WORKQUEUE=y +CONFIG_WORKQUEUE_KTASK_STACKSIZE=2048 +CONFIG_WORKQUEUE_KTASK_PRIORITY=23 +CONFIG_QUEUE_MAX=16 +CONFIG_KERNEL_WAITQUEUE=y +CONFIG_KERNEL_DATAQUEUE=y +# CONFIG_KERNEL_CIRCULAR_AREA is not set +# CONFIG_KERNEL_AVL_TREE is not set + +# +# Kernel components init +# +CONFIG_KERNEL_COMPONENTS_INIT=y +CONFIG_ENV_INIT_KTASK_STACK_SIZE=8192 +CONFIG_KERNEL_USER_MAIN=y +CONFIG_NAME_NUM_MAX=32 +# CONFIG_KERNEL_DEBUG is not set +# CONFIG_ARCH_SMP is not set + +# +# hash table config +# +CONFIG_ID_HTABLE_SIZE=16 +CONFIG_ID_NUM_MAX=128 +# CONFIG_KERNEL_TEST is not set + +# +# Lib +# +CONFIG_LIB=y +CONFIG_LIB_POSIX=y +CONFIG_LIB_NEWLIB=y +# CONFIG_LIB_MUSLLIB is not set + +# +# C++ features +# +# CONFIG_LIB_CPLUSPLUS is not set + +# +# File system +# +CONFIG_FS_VFS=y +CONFIG_VFS_USING_WORKDIR=y +CONFIG_FS_VFS_DEVFS=y +CONFIG_FS_VFS_FATFS=y +# CONFIG_FS_CH376 is not set +# CONFIG_FS_LWEXT4 is not set + +# +# APP_Framework +# + +# +# Framework +# +CONFIG_TRANSFORM_LAYER_ATTRIUBUTE=y +CONFIG_ADD_XIZI_FETURES=y +# CONFIG_ADD_NUTTX_FETURES is not set +# CONFIG_ADD_RTTHREAD_FETURES is not set +# CONFIG_SUPPORT_SENSOR_FRAMEWORK is not set +# CONFIG_SUPPORT_CONNECTION_FRAMEWORK is not set +# CONFIG_SUPPORT_KNOWING_FRAMEWORK is not set +# CONFIG_SUPPORT_CONTROL_FRAMEWORK is not set + +# +# Security +# +# CONFIG_CRYPTO is not set +# CONFIG_MBEDTLS is not set + +# +# Applications +# + +# +# config stack size and priority of main task +# +CONFIG_MAIN_KTASK_STACK_SIZE=4096 +CONFIG_MAIN_KTASK_PRIORITY=16 + +# +# ota app +# +# CONFIG_APPLICATION_OTA is not set + +# +# test app +# +# CONFIG_USER_TEST is not set + +# +# connection app +# +# CONFIG_APPLICATION_CONNECTION is not set + +# +# control app +# + +# +# knowing app +# +# CONFIG_APPLICATION_KNOWING is not set + +# +# sensor app +# +# CONFIG_APPLICATION_SENSOR is not set +# CONFIG_USING_EMBEDDED_DATABASE_APP is not set +# CONFIG_APP_USING_WEBNET is not set + +# +# lib +# +CONFIG_APP_SELECT_NEWLIB=y +# CONFIG_APP_SELECT_OTHER_LIB is not set +# CONFIG_LIB_USING_CJSON is not set +# CONFIG_LIB_USING_QUEUE is not set +# CONFIG_LIB_LV is not set + +# +# LVGL configuration +# +# CONFIG_LV_CONF_MINIMAL is not set +# CONFIG_USING_EMBEDDED_DATABASE is not set diff --git a/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/board.c b/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/board.c index 165a7025c..4127bd0fd 100644 --- a/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/board.c +++ b/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/board.c @@ -83,6 +83,33 @@ extern int Imxrt1052HwLcdInit(void); extern int HwTouchInit(); #endif +void ImxrtMsDelay(uint32 ms) +{ + uint64 ticks = 0; + uint32 told, tnow, tcnt = 0; + uint32 reload = SysTick->LOAD; + + ticks = ((uint64)ms * ((uint64)reload + 1) * TICK_PER_SECOND) / 1000; + told = SysTick->VAL; + + //KPrintf("%s reload %u ms %u ticks %u told %u\n", __func__, reload, ms, ticks, told); + + while (1) { + tnow = SysTick->VAL; + if (tnow != told) { + if (tnow < told) { + tcnt += told - tnow; + } else { + tcnt += reload - tnow + told; + } + told = tnow; + if (tcnt >= ticks) { + break; + } + } + } +} + void BOARD_SD_Pin_Config(uint32_t speed, uint32_t strength) { IOMUXC_SetPinConfig(IOMUXC_GPIO_SD_B0_00_USDHC1_CMD, @@ -291,7 +318,6 @@ void SysTick_Handler(int irqn, void *arg) { TickAndTaskTimesliceUpdate(); } -DECLARE_HW_IRQ(SYSTICK_IRQN, SysTick_Handler, NONE); struct InitSequenceDesc _board_init[] = { diff --git a/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/third_party_driver/ethernet/enet_ethernetif.c b/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/third_party_driver/ethernet/enet_ethernetif.c index 6360d9911..31d211a37 100755 --- a/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/third_party_driver/ethernet/enet_ethernetif.c +++ b/Ubiquitous/XiZi_IIoT/board/xiwangtong-arm32/third_party_driver/ethernet/enet_ethernetif.c @@ -81,14 +81,11 @@ /******************************************************************************* * Code ******************************************************************************/ +extern void ImxrtMsDelay(uint32 ms); -void enet_delay(void) +void enet_delay(uint32 ms) { - volatile uint32_t i = 0; - for (i = 0; i < 1000000; ++i) - { - __asm("NOP"); /* delay */ - } + ImxrtMsDelay(ms); } void Time_Update_LwIP(void) @@ -112,7 +109,7 @@ void ethernetif_gpio_init(void) /* pull up the ENET_INT before RESET. */ GPIO_WritePinOutput(GPIO1, 10, 1); GPIO_WritePinOutput(GPIO1, 3, 0); - enet_delay(); + enet_delay(30); GPIO_WritePinOutput(GPIO1, 3, 1); } diff --git a/Ubiquitous/XiZi_IIoT/fs/shared/src/poll.c b/Ubiquitous/XiZi_IIoT/fs/shared/src/poll.c index efd25bb27..178a3e1b5 100644 --- a/Ubiquitous/XiZi_IIoT/fs/shared/src/poll.c +++ b/Ubiquitous/XiZi_IIoT/fs/shared/src/poll.c @@ -86,7 +86,7 @@ static int PollWaitTimeout(struct poll_table *pt, int msec) thread = pt->polling_thread; - timeout = CalculteTickFromTimeMs(msec); + timeout = CalculateTickFromTimeMs(msec); level = CriticalAreaLock(); diff --git a/Ubiquitous/XiZi_IIoT/kernel/include/xs_ktick.h b/Ubiquitous/XiZi_IIoT/kernel/include/xs_ktick.h index faaf195d9..c56751c1f 100644 --- a/Ubiquitous/XiZi_IIoT/kernel/include/xs_ktick.h +++ b/Ubiquitous/XiZi_IIoT/kernel/include/xs_ktick.h @@ -26,7 +26,7 @@ x_ticks_t CurrentTicksGain(void); void TickAndTaskTimesliceUpdate(void); -x_ticks_t CalculteTickFromTimeMs(uint32 ms); -uint32 CalculteTimeMsFromTick(x_ticks_t ticks); +x_ticks_t CalculateTickFromTimeMs(uint32 ms); +uint32 CalculateTimeMsFromTick(x_ticks_t ticks); #endif diff --git a/Ubiquitous/XiZi_IIoT/kernel/memory/gatherblock.c b/Ubiquitous/XiZi_IIoT/kernel/memory/gatherblock.c index a4a0d482c..6ac255725 100644 --- a/Ubiquitous/XiZi_IIoT/kernel/memory/gatherblock.c +++ b/Ubiquitous/XiZi_IIoT/kernel/memory/gatherblock.c @@ -304,7 +304,7 @@ void *AllocBlockMemGather(GatherMemType gm_handler, int32 msec) /* get descriptor of task */ task = GetKTaskDescriptor(); - wait_time = CalculteTickFromTimeMs(msec); + wait_time = CalculateTickFromTimeMs(msec); critical_value = CriticalAreaLock(); /* no free gatherblock*/ diff --git a/Ubiquitous/XiZi_IIoT/kernel/thread/event.c b/Ubiquitous/XiZi_IIoT/kernel/thread/event.c index 871486f7f..4217b9676 100644 --- a/Ubiquitous/XiZi_IIoT/kernel/thread/event.c +++ b/Ubiquitous/XiZi_IIoT/kernel/thread/event.c @@ -153,7 +153,7 @@ static int32 _EventProcess(struct Event *event, uint32 events, uint32 options, i task = GetKTaskDescriptor(); task->exstatus = EOK; - timeout = CalculteTickFromTimeMs(msec); + timeout = CalculateTickFromTimeMs(msec); lock = CriticalAreaLock(); diff --git a/Ubiquitous/XiZi_IIoT/kernel/thread/ktask.c b/Ubiquitous/XiZi_IIoT/kernel/thread/ktask.c index a06236b91..e72ea0d16 100644 --- a/Ubiquitous/XiZi_IIoT/kernel/thread/ktask.c +++ b/Ubiquitous/XiZi_IIoT/kernel/thread/ktask.c @@ -220,7 +220,7 @@ x_err_t _MdelayKTask(KTaskDescriptorType task, uint32 ms) return -EINVALED; } - ticks = CalculteTickFromTimeMs(ms); + ticks = CalculateTickFromTimeMs(ms); return _DelayKTask(task, ticks); } diff --git a/Ubiquitous/XiZi_IIoT/kernel/thread/msgqueue.c b/Ubiquitous/XiZi_IIoT/kernel/thread/msgqueue.c index 8d2be3c79..ee58bc0d7 100644 --- a/Ubiquitous/XiZi_IIoT/kernel/thread/msgqueue.c +++ b/Ubiquitous/XiZi_IIoT/kernel/thread/msgqueue.c @@ -99,7 +99,7 @@ static x_err_t _MsgQueueSend(struct MsgQueue *mq, if(WAITING_FOREVER == msec) timeout = WAITING_FOREVER; else - timeout = CalculteTickFromTimeMs(msec); + timeout = CalculateTickFromTimeMs(msec); lock = CriticalAreaLock(); if (mq->num_msgs >= mq->max_msgs && timeout == 0) { @@ -207,7 +207,7 @@ static x_err_t _MsgQueueRecv(struct MsgQueue *mq, tick_delta = 0; task = GetKTaskDescriptor(); - timeout = CalculteTickFromTimeMs(msec); + timeout = CalculateTickFromTimeMs(msec); lock = CriticalAreaLock(); if (mq->index == 0 && timeout == 0) { diff --git a/Ubiquitous/XiZi_IIoT/kernel/thread/mutex.c b/Ubiquitous/XiZi_IIoT/kernel/thread/mutex.c index 88c1177a9..ff4aaded2 100644 --- a/Ubiquitous/XiZi_IIoT/kernel/thread/mutex.c +++ b/Ubiquitous/XiZi_IIoT/kernel/thread/mutex.c @@ -83,7 +83,7 @@ static int32 _MutexObtain(struct Mutex *mutex, int32 msec) NULL_PARAM_CHECK(mutex); task = GetKTaskDescriptor(); - wait_time = CalculteTickFromTimeMs(msec); + wait_time = CalculateTickFromTimeMs(msec); lock = CriticalAreaLock(); SYS_KDEBUG_LOG(KDBG_IPC, diff --git a/Ubiquitous/XiZi_IIoT/kernel/thread/semaphore.c b/Ubiquitous/XiZi_IIoT/kernel/thread/semaphore.c index ac6f6eeb3..54ff78629 100644 --- a/Ubiquitous/XiZi_IIoT/kernel/thread/semaphore.c +++ b/Ubiquitous/XiZi_IIoT/kernel/thread/semaphore.c @@ -97,7 +97,7 @@ static int32 _SemaphoreObtain(struct Semaphore *sem, int32 msec) if(WAITING_FOREVER == msec) wait_time = WAITING_FOREVER; else - wait_time = CalculteTickFromTimeMs(msec); + wait_time = CalculateTickFromTimeMs(msec); lock = CriticalAreaLock(); SYS_KDEBUG_LOG(KDBG_IPC, ("obtain semaphore: id %d, value %d, by task %s\n", diff --git a/Ubiquitous/XiZi_IIoT/kernel/thread/tick.c b/Ubiquitous/XiZi_IIoT/kernel/thread/tick.c index 49f75f38c..30156d39e 100644 --- a/Ubiquitous/XiZi_IIoT/kernel/thread/tick.c +++ b/Ubiquitous/XiZi_IIoT/kernel/thread/tick.c @@ -96,7 +96,7 @@ void TickAndTaskTimesliceUpdate(void) */ #define MIN_TICKS 1 -x_ticks_t CalculteTickFromTimeMs(uint32 ms) +x_ticks_t CalculateTickFromTimeMs(uint32 ms) { uint32 tmp = 0; x_ticks_t ticks = 0; @@ -121,7 +121,7 @@ x_ticks_t CalculteTickFromTimeMs(uint32 ms) * @param ticks ticks need to be converted * @return ms */ -uint32 CalculteTimeMsFromTick(x_ticks_t ticks) +uint32 CalculateTimeMsFromTick(x_ticks_t ticks) { uint32 ms = 0; diff --git a/Ubiquitous/XiZi_IIoT/resources/include/bus_serial.h b/Ubiquitous/XiZi_IIoT/resources/include/bus_serial.h index 917acfc1e..96af36dc6 100644 --- a/Ubiquitous/XiZi_IIoT/resources/include/bus_serial.h +++ b/Ubiquitous/XiZi_IIoT/resources/include/bus_serial.h @@ -46,6 +46,7 @@ struct SerialDataCfg uint16 serial_buffer_size; int32 serial_timeout; + uint8 is_ext_uart; uint8 ext_uart_no; enum ExtSerialPortConfigure port_configure; }; diff --git a/Ubiquitous/XiZi_IIoT/resources/serial/dev_serial.c b/Ubiquitous/XiZi_IIoT/resources/serial/dev_serial.c index 43c94addd..428e1c935 100644 --- a/Ubiquitous/XiZi_IIoT/resources/serial/dev_serial.c +++ b/Ubiquitous/XiZi_IIoT/resources/serial/dev_serial.c @@ -154,6 +154,8 @@ static inline int SerialDevIntRead(struct SerialHardwareDevice *serial_dev, stru CriticalAreaUnLock(lock); + MdelayKTask(20); + *read_data = get_char; read_data++; read_length--; diff --git a/Ubiquitous/XiZi_IIoT/tool/shell/letter-shell/shell.h b/Ubiquitous/XiZi_IIoT/tool/shell/letter-shell/shell.h index 75084d63c..6e55fd27e 100644 --- a/Ubiquitous/XiZi_IIoT/tool/shell/letter-shell/shell.h +++ b/Ubiquitous/XiZi_IIoT/tool/shell/letter-shell/shell.h @@ -25,7 +25,7 @@ * you cannot use double-clicking the tab to complete the command help, * and you cannot use the shell timeout lock */ -#define SHELL_GET_TICK() CalculteTimeMsFromTick(CurrentTicksGain()) +#define SHELL_GET_TICK() CalculateTimeMsFromTick(CurrentTicksGain()) /**