forked from xuos/xiuos
1、feat add modbus tcp protocol for control framework; 2、fix spi6 io define error on hc32f4a0 board from Liu_Weichao
it is OK
This commit is contained in:
commit
d1da6ae35b
|
@ -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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <transform.h>
|
||||
#include <adapter.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := 4g_app.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -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
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include <transform.h>
|
||||
|
||||
#ifdef ADD_XIZI_FETURES
|
||||
#include "sys_arch.h"
|
||||
#include <sys_arch.h>
|
||||
#include <lwip/sockets.h>
|
||||
#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);
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include <transform.h>
|
||||
|
||||
#ifdef ADD_XIZI_FETURES
|
||||
#include "sys_arch.h"
|
||||
#include <sys_arch.h>
|
||||
#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);
|
||||
|
||||
|
|
|
@ -18,6 +18,47 @@
|
|||
* @date 2022.9.27
|
||||
*/
|
||||
|
||||
|
||||
#include <control.h>
|
||||
|
||||
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);
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
// }
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 <control_def.h>
|
||||
|
||||
#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
|
|
@ -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 <control_def.h>
|
||||
|
||||
#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
|
|
@ -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 <modbus_tcp.h>
|
||||
|
||||
/*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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
SRC_FILES :=
|
||||
SRC_FILES := modbus_uart.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
||||
|
|
|
@ -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 <modbus_uart.h>
|
||||
|
||||
/*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;
|
||||
}
|
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -15,5 +15,98 @@
|
|||
* @brief plc protocol melsec
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-10-08
|
||||
*/
|
||||
* @date 2022-11-29
|
||||
*/
|
||||
|
||||
#ifndef MELSEC_H
|
||||
#define MELSEC_H
|
||||
|
||||
#include <control_def.h>
|
||||
|
||||
#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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
SRC_FILES :=
|
||||
SRC_FILES := melsec.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
||||
|
|
|
@ -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 <melsec.h>
|
||||
|
||||
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;
|
||||
}
|
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -20,6 +20,96 @@
|
|||
|
||||
#include <control_io.h>
|
||||
|
||||
#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
|
||||
}
|
||||
|
|
|
@ -24,26 +24,42 @@
|
|||
#include <transform.h>
|
||||
#include <list.h>
|
||||
|
||||
#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
|
||||
|
|
|
@ -104,7 +104,7 @@ int PrivTaskDelay(int32_t ms)
|
|||
#ifndef SEPARATE_COMPILE
|
||||
uint32_t PrivGetTickTime()
|
||||
{
|
||||
return CalculteTimeMsFromTick(CurrentTicksGain());
|
||||
return CalculateTimeMsFromTick(CurrentTicksGain());
|
||||
}
|
||||
#endif
|
||||
/*********************fs**************************/
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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[] =
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -220,7 +220,7 @@ x_err_t _MdelayKTask(KTaskDescriptorType task, uint32 ms)
|
|||
return -EINVALED;
|
||||
}
|
||||
|
||||
ticks = CalculteTickFromTimeMs(ms);
|
||||
ticks = CalculateTickFromTimeMs(ms);
|
||||
|
||||
return _DelayKTask(task, ticks);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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--;
|
||||
|
|
|
@ -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())
|
||||
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue