forked from xuos/xiuos
add CIP Protocol
This commit is contained in:
parent
242c7d66d2
commit
51299c6b79
|
@ -1,3 +1,3 @@
|
|||
SRC_DIR := advantech beckhoff br delta mitsubishi omron schneider siemens ge xinje inovance keyence
|
||||
SRC_DIR := advantech beckhoff br delta mitsubishi omron schneider siemens ge xinje inovance keyence ab
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
SRC_FILES := ab_l30.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* 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 ab_l30.c
|
||||
* @brief PLC ABB L30 app
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.9.27
|
||||
*/
|
||||
|
||||
#include <control.h>
|
||||
|
||||
void Controlabl30Test(void)
|
||||
{
|
||||
int i = 0;
|
||||
uint16_t read_data_length = 0;
|
||||
uint8_t read_data[1024] = {0};
|
||||
ControlProtocolType CIP_protocol = ControlProtocolFind();
|
||||
if (NULL == CIP_protocol) {
|
||||
printf("%s get CIP protocol %p failed\n", __func__, CIP_protocol);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("%s get CIP protocol %p successfull\n", __func__, CIP_protocol);
|
||||
if (CONTROL_REGISTERED == CIP_protocol->protocol_status) {
|
||||
ControlProtocolOpen(CIP_protocol);
|
||||
|
||||
for (;;) {
|
||||
read_data_length = ControlProtocolRead(CIP_protocol, read_data, sizeof(read_data));
|
||||
printf("%s read [%d] CIP data %d using receipe file\n", __func__, i, read_data_length);
|
||||
i++;
|
||||
PrivTaskDelay(10000);
|
||||
}
|
||||
|
||||
//ControlProtocolClose(CIP_protocol);
|
||||
}
|
||||
}
|
||||
PRIV_SHELL_CMD_FUNCTION(Controlabl30Test, Ab Plc CIP Demo, PRIV_SHELL_CMD_MAIN_ATTR);
|
|
@ -27,3 +27,11 @@ config CONTROL_PROTOCOL_S7
|
|||
if CONTROL_PROTOCOL_S7
|
||||
source "$APP_DIR/Framework/control/plc_protocol/s7/Kconfig"
|
||||
endif
|
||||
|
||||
config CONTROL_PROTOCOL_CIP
|
||||
bool "Using cip control protocol"
|
||||
default n
|
||||
select CONTROL_USING_SOCKET
|
||||
if CONTROL_PROTOCOL_CIP
|
||||
source "$APP_DIR/Framework/control/plc_protocol/cip/Kconfig"
|
||||
endif
|
||||
|
|
|
@ -14,4 +14,8 @@ ifeq ($(CONFIG_CONTROL_PROTOCOL_S7), y)
|
|||
SRC_DIR := s7
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_CONTROL_PROTOCOL_CIP), y)
|
||||
SRC_DIR := cip
|
||||
endif
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
SRC_FILES := $(wildcard ./*.c)
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
|
@ -0,0 +1,394 @@
|
|||
#include "ab_cip_helper.h"
|
||||
#include "ab_cip.h"
|
||||
#include "ab_cip_private.h"
|
||||
|
||||
// #include "socket.h"
|
||||
#include "cip_socket.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <windows.h>
|
||||
#pragma comment(lib, "ws2_32.lib") /* Linking with winsock library */
|
||||
#pragma warning(disable : 4996)
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
// #include <sys/socket.h>
|
||||
// #include <arpa/inet.h>
|
||||
#include <sockets.h>
|
||||
#include "lwip/inet.h"
|
||||
#endif
|
||||
|
||||
int port = 102;
|
||||
char ip_address[64] = {0};
|
||||
bool ab_cip_connect(char *ip_addr, int port, int slot, int *fd)
|
||||
{
|
||||
bool ret = false;
|
||||
int temp_fd = -1;
|
||||
g_plc_slot = slot;
|
||||
|
||||
temp_fd = socket_open_tcp_client_socket(ip_addr, port);
|
||||
*fd = temp_fd;
|
||||
|
||||
printf("%d %s %d\n",temp_fd,__func__,__LINE__);
|
||||
|
||||
if (temp_fd >= 0)
|
||||
ret = initialization_on_connect(temp_fd);
|
||||
|
||||
printf("%d %s %d\n",ret,__func__,__LINE__);
|
||||
|
||||
if (!ret && temp_fd > 0)
|
||||
{
|
||||
socket_close_tcp_socket(temp_fd);
|
||||
*fd = -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool ab_cip_disconnect(int fd)
|
||||
{
|
||||
socket_close_tcp_socket(fd);
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
cip_error_code_e ab_cip_read_bool(int fd, const char *address, bool *val)
|
||||
{
|
||||
cip_error_code_e ret = CIP_ERROR_CODE_FAILED;
|
||||
byte_array_info read_data;
|
||||
memset(&read_data, 0, sizeof(read_data));
|
||||
ret = read_value(fd, address, 1, &read_data);
|
||||
if (ret == CIP_ERROR_CODE_OK && read_data.length > 0)
|
||||
{
|
||||
*val = (bool)read_data.data[0];
|
||||
RELEASE_DATA(read_data.data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
cip_error_code_e ab_cip_read_short(int fd, const char *address, short *val)
|
||||
{
|
||||
cip_error_code_e ret = CIP_ERROR_CODE_FAILED;
|
||||
byte_array_info read_data;
|
||||
memset(&read_data, 0, sizeof(read_data));
|
||||
ret = read_value(fd, address, 1, &read_data);
|
||||
if (ret == CIP_ERROR_CODE_OK && read_data.length >= 2)
|
||||
{
|
||||
*val = bytes2short(read_data.data);
|
||||
}
|
||||
RELEASE_DATA(read_data.data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
cip_error_code_e ab_cip_read_ushort(int fd, const char *address, ushort *val)
|
||||
{
|
||||
cip_error_code_e ret = CIP_ERROR_CODE_FAILED;
|
||||
byte_array_info read_data;
|
||||
memset(&read_data, 0, sizeof(read_data));
|
||||
ret = read_value(fd, address, 1, &read_data);
|
||||
if (ret == CIP_ERROR_CODE_OK && read_data.length >= 2)
|
||||
{
|
||||
*val = bytes2ushort(read_data.data);
|
||||
RELEASE_DATA(read_data.data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
cip_error_code_e ab_cip_read_int32(int fd, const char *address, int32 *val)
|
||||
{
|
||||
cip_error_code_e ret = CIP_ERROR_CODE_FAILED;
|
||||
byte_array_info read_data;
|
||||
memset(&read_data, 0, sizeof(read_data));
|
||||
ret = read_value(fd, address, 4, &read_data);
|
||||
if (ret == CIP_ERROR_CODE_OK && read_data.length >= 4)
|
||||
{
|
||||
*val = bytes2int32(read_data.data);
|
||||
RELEASE_DATA(read_data.data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
cip_error_code_e ab_cip_read_uint32(int fd, const char *address, uint32 *val)
|
||||
{
|
||||
cip_error_code_e ret = CIP_ERROR_CODE_FAILED;
|
||||
byte_array_info read_data;
|
||||
memset(&read_data, 0, sizeof(read_data));
|
||||
ret = read_value(fd, address, 4, &read_data);
|
||||
if (ret == CIP_ERROR_CODE_OK && read_data.length >= 2)
|
||||
{
|
||||
*val = bytes2uint32(read_data.data);
|
||||
RELEASE_DATA(read_data.data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
cip_error_code_e ab_cip_read_int64(int fd, const char *address, int64 *val)
|
||||
{
|
||||
cip_error_code_e ret = CIP_ERROR_CODE_FAILED;
|
||||
byte_array_info read_data;
|
||||
memset(&read_data, 0, sizeof(read_data));
|
||||
ret = read_value(fd, address, 8, &read_data);
|
||||
if (ret == CIP_ERROR_CODE_OK && read_data.length >= 8)
|
||||
{
|
||||
*val = bytes2bigInt(read_data.data);
|
||||
RELEASE_DATA(read_data.data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
cip_error_code_e ab_cip_read_uint64(int fd, const char *address, uint64 *val)
|
||||
{
|
||||
cip_error_code_e ret = CIP_ERROR_CODE_FAILED;
|
||||
byte_array_info read_data;
|
||||
memset(&read_data, 0, sizeof(read_data));
|
||||
ret = read_value(fd, address, 8, &read_data);
|
||||
if (ret == CIP_ERROR_CODE_OK && read_data.length >= 8)
|
||||
{
|
||||
*val = bytes2ubigInt(read_data.data);
|
||||
RELEASE_DATA(read_data.data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
cip_error_code_e ab_cip_read_float(int fd, const char *address, float *val)
|
||||
{
|
||||
cip_error_code_e ret = CIP_ERROR_CODE_FAILED;
|
||||
byte_array_info read_data;
|
||||
memset(&read_data, 0, sizeof(read_data));
|
||||
ret = read_value(fd, address, 1, &read_data);
|
||||
if (ret == CIP_ERROR_CODE_OK && read_data.length >= 4)
|
||||
{
|
||||
*val = bytes2float(read_data.data);
|
||||
}
|
||||
RELEASE_DATA(read_data.data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
cip_error_code_e ab_cip_read_double(int fd, const char *address, double *val)
|
||||
{
|
||||
cip_error_code_e ret = CIP_ERROR_CODE_FAILED;
|
||||
byte_array_info read_data;
|
||||
memset(&read_data, 0, sizeof(read_data));
|
||||
ret = read_value(fd, address, 8, &read_data);
|
||||
if (ret == CIP_ERROR_CODE_OK && read_data.length >= 8)
|
||||
{
|
||||
*val = bytes2double(read_data.data);
|
||||
RELEASE_DATA(read_data.data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
cip_error_code_e ab_cip_read_string(int fd, const char *address, int *length, char **val)
|
||||
{
|
||||
cip_error_code_e ret = CIP_ERROR_CODE_FAILED;
|
||||
if (length != NULL && *length > 0)
|
||||
{
|
||||
byte_array_info read_data;
|
||||
memset(&read_data, 0, sizeof(read_data));
|
||||
ret = read_value(fd, address, *length, &read_data);
|
||||
if (ret == CIP_ERROR_CODE_OK && read_data.length > 6)
|
||||
{
|
||||
*length = 0;
|
||||
uint32 str_length = bytes2uint32(read_data.data + 2);
|
||||
if (str_length > 0)
|
||||
{
|
||||
*length = str_length;
|
||||
char *ret_str = (char *)malloc(str_length + 1);
|
||||
memset(ret_str, 0, str_length + 1);
|
||||
memcpy(ret_str, read_data.data + 6, str_length);
|
||||
*val = ret_str;
|
||||
}
|
||||
RELEASE_DATA(read_data.data);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
cip_error_code_e ab_cip_write_bool(int fd, const char *address, bool val)
|
||||
{
|
||||
cip_error_code_e ret = CIP_ERROR_CODE_FAILED;
|
||||
if (fd > 0 && address != NULL)
|
||||
{
|
||||
int write_len = 2;
|
||||
byte_array_info write_data;
|
||||
memset(&write_data, 0, sizeof(write_data));
|
||||
write_data.data = (byte *)malloc(write_len);
|
||||
write_data.length = write_len;
|
||||
|
||||
if (val)
|
||||
{
|
||||
write_data.data[0] = 0xFF;
|
||||
write_data.data[1] = 0xFF;
|
||||
}
|
||||
ret = write_value(fd, address, 1, 0xC1, write_data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
cip_error_code_e ab_cip_write_short(int fd, const char *address, short val)
|
||||
{
|
||||
cip_error_code_e ret = CIP_ERROR_CODE_FAILED;
|
||||
if (fd > 0 && address != NULL)
|
||||
{
|
||||
int write_len = 2;
|
||||
byte_array_info write_data;
|
||||
memset(&write_data, 0, sizeof(write_data));
|
||||
write_data.data = (byte *)malloc(write_len);
|
||||
write_data.length = write_len;
|
||||
|
||||
short2bytes(val, write_data.data);
|
||||
ret = write_value(fd, address, 1, 0xC3, write_data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
cip_error_code_e ab_cip_write_ushort(int fd, const char *address, ushort val)
|
||||
{
|
||||
cip_error_code_e ret = CIP_ERROR_CODE_FAILED;
|
||||
if (fd > 0 && address != NULL)
|
||||
{
|
||||
int write_len = 2;
|
||||
byte_array_info write_data;
|
||||
memset(&write_data, 0, sizeof(write_data));
|
||||
write_data.data = (byte *)malloc(write_len);
|
||||
write_data.length = write_len;
|
||||
|
||||
ushort2bytes(val, write_data.data);
|
||||
ret = write_value(fd, address, 1, 0xC3, write_data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
cip_error_code_e ab_cip_write_int32(int fd, const char *address, int32 val)
|
||||
{
|
||||
cip_error_code_e ret = CIP_ERROR_CODE_FAILED;
|
||||
if (fd > 0 && address != NULL)
|
||||
{
|
||||
int write_len = 4;
|
||||
byte_array_info write_data;
|
||||
memset(&write_data, 0, sizeof(write_data));
|
||||
write_data.data = (byte *)malloc(write_len);
|
||||
write_data.length = write_len;
|
||||
|
||||
int2bytes(val, write_data.data);
|
||||
ret = write_value(fd, address, 1, 0xC4, write_data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
cip_error_code_e ab_cip_write_uint32(int fd, const char *address, uint32 val)
|
||||
{
|
||||
cip_error_code_e ret = CIP_ERROR_CODE_FAILED;
|
||||
if (fd > 0 && address != NULL)
|
||||
{
|
||||
int write_len = 4;
|
||||
byte_array_info write_data;
|
||||
memset(&write_data, 0, sizeof(write_data));
|
||||
write_data.data = (byte *)malloc(write_len);
|
||||
write_data.length = write_len;
|
||||
|
||||
uint2bytes(val, write_data.data);
|
||||
ret = write_value(fd, address, 1, 0xC4, write_data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
cip_error_code_e ab_cip_write_int64(int fd, const char *address, int64 val)
|
||||
{
|
||||
cip_error_code_e ret = CIP_ERROR_CODE_FAILED;
|
||||
if (fd > 0 && address != NULL)
|
||||
{
|
||||
int write_len = 8;
|
||||
byte_array_info write_data;
|
||||
memset(&write_data, 0, sizeof(write_data));
|
||||
write_data.data = (byte *)malloc(write_len);
|
||||
write_data.length = write_len;
|
||||
|
||||
bigInt2bytes(val, write_data.data);
|
||||
ret = write_value(fd, address, 1, 0xC5, write_data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
cip_error_code_e ab_cip_write_uint64(int fd, const char *address, uint64 val)
|
||||
{
|
||||
cip_error_code_e ret = CIP_ERROR_CODE_FAILED;
|
||||
if (fd > 0 && address != NULL)
|
||||
{
|
||||
int write_len = 8;
|
||||
byte_array_info write_data;
|
||||
memset(&write_data, 0, sizeof(write_data));
|
||||
write_data.data = (byte *)malloc(write_len);
|
||||
write_data.length = write_len;
|
||||
|
||||
ubigInt2bytes(val, write_data.data);
|
||||
ret = write_value(fd, address, 1, 0xC5, write_data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
cip_error_code_e ab_cip_write_float(int fd, const char *address, float val)
|
||||
{
|
||||
cip_error_code_e ret = CIP_ERROR_CODE_FAILED;
|
||||
if (fd > 0 && address != NULL)
|
||||
{
|
||||
int write_len = 4;
|
||||
byte_array_info write_data;
|
||||
memset(&write_data, 0, sizeof(write_data));
|
||||
write_data.data = (byte *)malloc(write_len);
|
||||
write_data.length = write_len;
|
||||
|
||||
float2bytes(val, write_data.data);
|
||||
ret = write_value(fd, address, 1, 0xCA, write_data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
cip_error_code_e ab_cip_write_double(int fd, const char *address, double val)
|
||||
{
|
||||
cip_error_code_e ret = CIP_ERROR_CODE_FAILED;
|
||||
if (fd > 0 && address != NULL)
|
||||
{
|
||||
int write_len = 8;
|
||||
byte_array_info write_data;
|
||||
memset(&write_data, 0, sizeof(write_data));
|
||||
write_data.data = (byte *)malloc(write_len);
|
||||
write_data.length = write_len;
|
||||
|
||||
double2bytes(val, write_data.data);
|
||||
ret = write_value(fd, address, 1, 0xCB, write_data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
cip_error_code_e ab_cip_write_string(int fd, const char *address, int length, const char *val)
|
||||
{
|
||||
cip_error_code_e ret = CIP_ERROR_CODE_FAILED;
|
||||
if (fd > 0 && address != NULL && val != NULL)
|
||||
{
|
||||
byte write_len = length + 1;
|
||||
byte_array_info write_data = {0};
|
||||
write_data.data = (byte *)malloc(write_len);
|
||||
memset(write_data.data, 0, write_len);
|
||||
memcpy(write_data.data, &write_len, 1);
|
||||
memcpy(write_data.data + 1, val, length);
|
||||
write_data.length = write_len;
|
||||
|
||||
char temp_addr[100] = {0};
|
||||
sprintf(temp_addr, "%s", address);
|
||||
ret = write_value(fd, temp_addr, 1, 0xD0, write_data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
byte get_plc_slot()
|
||||
{
|
||||
return g_plc_slot;
|
||||
}
|
||||
|
||||
void set_plc_slot(byte slot)
|
||||
{
|
||||
g_plc_slot = slot;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef __H_AB_CIP_H__
|
||||
#define __H_AB_CIP_H__
|
||||
|
||||
#include "typedef.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
byte get_plc_slot();
|
||||
void set_plc_slot(byte slot);
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
bool ab_cip_connect(char *ip_addr, int port, int slot, int *fd);
|
||||
bool ab_cip_disconnect(int fd);
|
||||
|
||||
// read
|
||||
cip_error_code_e ab_cip_read_bool(int fd, const char *address, bool *val);
|
||||
cip_error_code_e ab_cip_read_short(int fd, const char *address, short *val);
|
||||
cip_error_code_e ab_cip_read_ushort(int fd, const char *address, ushort *val);
|
||||
cip_error_code_e ab_cip_read_int32(int fd, const char *address, int32 *val);
|
||||
cip_error_code_e ab_cip_read_uint32(int fd, const char *address, uint32 *val);
|
||||
cip_error_code_e ab_cip_read_int64(int fd, const char *address, int64 *val);
|
||||
cip_error_code_e ab_cip_read_uint64(int fd, const char *address, uint64 *val);
|
||||
cip_error_code_e ab_cip_read_float(int fd, const char *address, float *val);
|
||||
cip_error_code_e ab_cip_read_double(int fd, const char *address, double *val);
|
||||
cip_error_code_e ab_cip_read_string(int fd, const char *address, int *length, char **val); // need free val
|
||||
|
||||
// write
|
||||
cip_error_code_e ab_cip_write_bool(int fd, const char *address, bool val);
|
||||
cip_error_code_e ab_cip_write_short(int fd, const char *address, short val);
|
||||
cip_error_code_e ab_cip_write_ushort(int fd, const char *address, ushort val);
|
||||
cip_error_code_e ab_cip_write_int32(int fd, const char *address, int32 val);
|
||||
cip_error_code_e ab_cip_write_uint32(int fd, const char *address, uint32 val);
|
||||
cip_error_code_e ab_cip_write_int64(int fd, const char *address, int64 val);
|
||||
cip_error_code_e ab_cip_write_uint64(int fd, const char *address, uint64 val);
|
||||
cip_error_code_e ab_cip_write_float(int fd, const char *address, float val);
|
||||
cip_error_code_e ab_cip_write_double(int fd, const char *address, double val);
|
||||
cip_error_code_e ab_cip_write_string(int fd, const char *address, int length, const char *val);
|
||||
|
||||
#endif //__H_AB_CIP_H__
|
|
@ -0,0 +1,332 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "ab_cip_helper.h"
|
||||
#include "cip_socket.h"
|
||||
|
||||
extern uint32 g_session;
|
||||
extern byte g_plc_slot;
|
||||
extern byte g_registered_command[28];
|
||||
|
||||
// 从地址构造核心报文
|
||||
byte_array_info build_read_core_command(const char *address, int length)
|
||||
{
|
||||
size_t addr_length = strlen(address);
|
||||
size_t addr_adjust_length = addr_length;
|
||||
if (addr_adjust_length % 2 == 1)
|
||||
addr_adjust_length += 1;
|
||||
|
||||
char *temp_address = (char *)malloc(addr_adjust_length);
|
||||
memset(temp_address, 0, addr_adjust_length);
|
||||
memcpy(temp_address, address, strlen(address));
|
||||
|
||||
const ushort command_len = 9 + 26 + (ushort)addr_adjust_length + 1 + 24;
|
||||
byte *command = (byte *)malloc(command_len);
|
||||
memset(command, 0, command_len);
|
||||
|
||||
command[0] = 0x6F; // 命令
|
||||
command[2] = (byte)((command_len - 24) % 256);
|
||||
command[3] = (byte)((command_len - 24) / 256); // 长度
|
||||
|
||||
char temp_session[4] = {0};
|
||||
uint2bytes(g_session, temp_session);
|
||||
command[4] = temp_session[0];
|
||||
command[5] = temp_session[1];
|
||||
command[6] = temp_session[2];
|
||||
command[7] = temp_session[3]; // 会话句柄
|
||||
|
||||
command[0 + 24] = 0x00;
|
||||
command[1 + 24] = 0x00;
|
||||
command[2 + 24] = 0x00;
|
||||
command[3 + 24] = 0x00; // 接口句柄,默认为0x00000000(CIP)
|
||||
command[4 + 24] = 0x01;
|
||||
command[5 + 24] = 0x0A; // 超时(0x000A)
|
||||
command[6 + 24] = 0x02;
|
||||
command[7 + 24] = 0x00; // 项数(0x0002)
|
||||
command[8 + 24] = 0x00;
|
||||
command[9 + 24] = 0x00; // 空地址项(0x0000)
|
||||
command[10 + 24] = 0x00;
|
||||
command[11 + 24] = 0x00; // 长度(0x0000)
|
||||
command[12 + 24] = 0xB2;
|
||||
command[13 + 24] = 0x00; // 未连接数据项(0x00b2)
|
||||
command[14 + 24] = (byte)((command_len - 16 - 24) % 256); // 后面数据包的长度,等全部生成后在赋值
|
||||
command[15 + 24] = (byte)((command_len - 16 - 24) / 256);
|
||||
command[16 + 24] = 0x52; // 服务类型(0x03请求服务列表,0x52请求标签数据)
|
||||
command[17 + 24] = 0x02; // 请求路径大小
|
||||
command[18 + 24] = 0x20;
|
||||
command[19 + 24] = 0x06; // 请求路径(0x0620)
|
||||
command[20 + 24] = 0x24;
|
||||
command[21 + 24] = 0x01; // 请求路径(0x0124)
|
||||
command[22 + 24] = 0x0A;
|
||||
command[23 + 24] = 0xF0;
|
||||
command[24 + 24] = (byte)((6 + addr_adjust_length) % 256); // CIP指令长度
|
||||
command[25 + 24] = (byte)((6 + addr_adjust_length) / 256);
|
||||
|
||||
command[0 + 24 + 26] = 0x4C; // 读取数据
|
||||
command[1 + 24 + 26] = (byte)((addr_adjust_length + 2) / 2);
|
||||
command[2 + 24 + 26] = 0x91;
|
||||
command[3 + 24 + 26] = (byte)addr_length;
|
||||
memcpy(command + 4 + 24 + 26, temp_address, addr_adjust_length);
|
||||
command[4 + 24 + 26 + addr_adjust_length] = (byte)((length) % 256);
|
||||
command[5 + 24 + 26 + addr_adjust_length] = (byte)((length) / 256);
|
||||
|
||||
command[6 + 24 + 26 + addr_adjust_length] = 0x01;
|
||||
command[7 + 24 + 26 + addr_adjust_length] = 0x00;
|
||||
command[8 + 24 + 26 + addr_adjust_length] = 0x01;
|
||||
command[9 + 24 + 26 + addr_adjust_length] = g_plc_slot;
|
||||
|
||||
byte_array_info ret = {0};
|
||||
ret.data = command;
|
||||
ret.length = command_len;
|
||||
free(temp_address);
|
||||
return ret;
|
||||
}
|
||||
|
||||
byte_array_info build_write_core_command(const char *address, ushort typeCode, int length, byte_array_info value)
|
||||
{
|
||||
int val_len = 0;
|
||||
if (value.data != NULL)
|
||||
val_len = value.length;
|
||||
|
||||
size_t addr_length = strlen(address);
|
||||
size_t addr_adjust_length = addr_length;
|
||||
if (addr_adjust_length % 2 == 1)
|
||||
addr_adjust_length += 1;
|
||||
|
||||
char *temp_address = (char *)malloc(addr_adjust_length);
|
||||
memset(temp_address, 0, addr_adjust_length);
|
||||
memcpy(temp_address, address, strlen(address));
|
||||
|
||||
const ushort command_len = 8 + 26 + (ushort)addr_adjust_length + val_len + 4 + 24;
|
||||
byte *command = (byte *)malloc(command_len);
|
||||
memset(command, 0, command_len);
|
||||
|
||||
command[0] = 0x6F; // 命令
|
||||
command[2] = (byte)((command_len - 24) % 256);
|
||||
command[3] = (byte)((command_len - 24) / 256); // 长度
|
||||
|
||||
char temp_session[4] = {0};
|
||||
uint2bytes(g_session, temp_session);
|
||||
command[4] = temp_session[0];
|
||||
command[5] = temp_session[1];
|
||||
command[6] = temp_session[2];
|
||||
command[7] = temp_session[3]; // 会话句柄
|
||||
|
||||
command[0 + 24] = 0x00;
|
||||
command[1 + 24] = 0x00;
|
||||
command[2 + 24] = 0x00;
|
||||
command[3 + 24] = 0x00; // 接口句柄,默认为0x00000000(CIP)
|
||||
command[4 + 24] = 0x01;
|
||||
command[5 + 24] = 0x0A; // 超时(0x0001)
|
||||
command[6 + 24] = 0x02;
|
||||
command[7 + 24] = 0x00; // 项数(0x0002)
|
||||
command[8 + 24] = 0x00;
|
||||
command[9 + 24] = 0x00;
|
||||
command[10 + 24] = 0x00;
|
||||
command[11 + 24] = 0x00; // 空地址项(0x0000)
|
||||
command[12 + 24] = 0xB2;
|
||||
command[13 + 24] = 0x00; // 未连接数据项(0x00b2)
|
||||
command[14 + 24] = (byte)((command_len - 16 - 24) % 256);
|
||||
; // 后面数据包的长度,等全部生成后在赋值
|
||||
command[15 + 24] = (byte)((command_len - 16 - 24) / 256);
|
||||
;
|
||||
command[16 + 24] = 0x52; // 服务类型(0x03请求服务列表,0x52请求标签数据)
|
||||
command[17 + 24] = 0x02; // 请求路径大小
|
||||
command[18 + 24] = 0x20;
|
||||
command[19 + 24] = 0x06; // 请求路径(0x0620)
|
||||
command[20 + 24] = 0x24;
|
||||
command[21 + 24] = 0x01; // 请求路径(0x0124)
|
||||
command[22 + 24] = 0x0A;
|
||||
command[23 + 24] = 0xF0;
|
||||
command[24 + 24] = (byte)((8 + val_len + addr_adjust_length) % 256); // CIP指令长度
|
||||
command[25 + 24] = (byte)((8 + val_len + addr_adjust_length) / 256);
|
||||
|
||||
command[0 + 26 + 24] = 0x4D; // 写数据
|
||||
command[1 + 26 + 24] = (byte)((addr_adjust_length + 2) / 2);
|
||||
command[2 + 26 + 24] = 0x91;
|
||||
command[3 + 26 + 24] = (byte)addr_length;
|
||||
memcpy(command + 4 + 26 + 24, temp_address, addr_adjust_length);
|
||||
command[4 + 26 + 24 + addr_adjust_length] = (byte)(typeCode % 256);
|
||||
command[5 + 26 + 24 + addr_adjust_length] = (byte)(typeCode) / 256;
|
||||
command[6 + 26 + 24 + addr_adjust_length] = (byte)(length % 256); // TODO length ??
|
||||
command[7 + 26 + 24 + addr_adjust_length] = (byte)(length / 256);
|
||||
memcpy(command + 8 + 26 + 24 + addr_adjust_length, value.data, value.length);
|
||||
|
||||
command[8 + 26 + 24 + addr_adjust_length + val_len] = 0x01;
|
||||
command[9 + 26 + 24 + addr_adjust_length + val_len] = 0x00;
|
||||
command[10 + 26 + 24 + addr_adjust_length + val_len] = 0x01;
|
||||
command[11 + 26 + 24 + addr_adjust_length + val_len] = g_plc_slot;
|
||||
|
||||
if (value.data != NULL)
|
||||
free(value.data);
|
||||
|
||||
byte_array_info ret = {0};
|
||||
ret.data = command;
|
||||
ret.length = command_len;
|
||||
return ret;
|
||||
}
|
||||
|
||||
cip_error_code_e cip_analysis_read_byte(byte_array_info response, byte_array_info *ret)
|
||||
{
|
||||
cip_error_code_e ret_code = CIP_ERROR_CODE_OK;
|
||||
if (response.length == 0)
|
||||
return CIP_ERROR_CODE_FAILED;
|
||||
|
||||
int temp_length = 0;
|
||||
int data_length = 0;
|
||||
if (response.length >= 40) // index 38 is count[ushort]
|
||||
{
|
||||
data_length = bytes2ushort(response.data + 38);
|
||||
if (data_length > 6)
|
||||
{
|
||||
temp_length = data_length - 6;
|
||||
ret->data = (byte *)malloc(temp_length);
|
||||
memset(ret->data, 0, temp_length);
|
||||
memcpy(ret->data, response.data + 46, temp_length);
|
||||
ret->length = temp_length;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_code = CIP_ERROR_CODE_UNKOWN;
|
||||
}
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
cip_error_code_e cip_analysis_write_byte(byte_array_info response)
|
||||
{
|
||||
cip_error_code_e ret_code = CIP_ERROR_CODE_OK;
|
||||
if (response.length == 0)
|
||||
return CIP_ERROR_CODE_FAILED;
|
||||
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
cip_error_code_e read_value(int fd, const char *address, int length, byte_array_info *out_bytes)
|
||||
{
|
||||
cip_error_code_e ret = CIP_ERROR_CODE_UNKOWN;
|
||||
byte_array_info core_cmd = build_read_core_command(address, length);
|
||||
if (core_cmd.data != NULL)
|
||||
{
|
||||
int need_send = core_cmd.length;
|
||||
int real_sends = socket_send_data(fd, core_cmd.data, need_send);
|
||||
if (real_sends == need_send)
|
||||
{
|
||||
byte temp[BUFFER_SIZE] = {0};
|
||||
memset(temp, 0, BUFFER_SIZE);
|
||||
byte_array_info response = {0};
|
||||
response.data = temp;
|
||||
response.length = BUFFER_SIZE;
|
||||
if (cip_read_response(fd, &response))
|
||||
ret = cip_analysis_read_byte(response, out_bytes);
|
||||
// printf("%s %hu\n",__func__,response.data);
|
||||
}
|
||||
free(core_cmd.data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
cip_error_code_e write_value(int fd, const char *address, int length, ushort type_code, byte_array_info in_bytes)
|
||||
{
|
||||
cip_error_code_e ret = CIP_ERROR_CODE_UNKOWN;
|
||||
byte_array_info core_cmd = build_write_core_command(address, type_code, length, in_bytes);
|
||||
if (core_cmd.data != NULL)
|
||||
{
|
||||
int need_send = core_cmd.length;
|
||||
int real_sends = socket_send_data(fd, core_cmd.data, need_send);
|
||||
if (real_sends == need_send)
|
||||
{
|
||||
byte temp[BUFFER_SIZE] = {0};
|
||||
memset(temp, 0, BUFFER_SIZE);
|
||||
byte_array_info response = {0};
|
||||
response.data = temp;
|
||||
response.length = BUFFER_SIZE;
|
||||
|
||||
if (cip_read_response(fd, &response))
|
||||
ret = cip_analysis_write_byte(response);
|
||||
}
|
||||
free(core_cmd.data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool initialization_on_connect(int fd)
|
||||
{
|
||||
bool is_ok = false;
|
||||
g_session = 0;
|
||||
|
||||
// First handshake -> send regiseter command
|
||||
byte_array_info temp = {0};
|
||||
int command_len = sizeof(g_registered_command);
|
||||
temp.data = (byte *)malloc(command_len);
|
||||
memcpy(temp.data, g_registered_command, command_len);
|
||||
temp.length = command_len;
|
||||
is_ok = read_data_from_server(fd, temp, &g_session);
|
||||
|
||||
// 返回成功的信号 -> Return a successful signal
|
||||
return is_ok;
|
||||
}
|
||||
|
||||
bool cip_read_response(int fd, byte_array_info *response)
|
||||
{
|
||||
bool is_ok = false;
|
||||
int nread = 0;
|
||||
int content_size = 0;
|
||||
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
byte *content = NULL;
|
||||
byte head[HEAD_SIZE];
|
||||
memset(head, 0, HEAD_SIZE);
|
||||
int recv_size = socket_recv_data_one_loop(fd, head, HEAD_SIZE);
|
||||
if (recv_size >= HEAD_SIZE) // header size
|
||||
{
|
||||
content_size = bytes2ushort(head + 2);
|
||||
if (content_size > 0)
|
||||
{
|
||||
content = (byte *)malloc(content_size);
|
||||
memset(content, 0, content_size);
|
||||
}
|
||||
recv_size = socket_recv_data(fd, content, content_size);
|
||||
if (recv_size == content_size)
|
||||
{
|
||||
response->length = HEAD_SIZE + content_size;
|
||||
response->data = (byte *)malloc(response->length);
|
||||
memset(response->data, 0, response->length);
|
||||
memcpy(response->data, head, HEAD_SIZE);
|
||||
memcpy(response->data + HEAD_SIZE, content, content_size);
|
||||
|
||||
is_ok = true;
|
||||
}
|
||||
|
||||
free(content);
|
||||
}
|
||||
return is_ok;
|
||||
}
|
||||
|
||||
bool read_data_from_server(int fd, byte_array_info send, int *session)
|
||||
{
|
||||
bool is_ok = false;
|
||||
int need_send = send.length;
|
||||
int real_sends = socket_send_data(fd, send.data, need_send);
|
||||
if (real_sends == need_send)
|
||||
{
|
||||
byte_array_info response = {0};
|
||||
is_ok = cip_read_response(fd, &response);
|
||||
if (is_ok)
|
||||
{
|
||||
is_ok = false;
|
||||
if (response.length > 8)
|
||||
{
|
||||
*session = bytes2uint32(response.data + 4);
|
||||
is_ok = true;
|
||||
}
|
||||
|
||||
if (response.data != NULL)
|
||||
free(response.data);
|
||||
}
|
||||
}
|
||||
return is_ok;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef __H_AB_CIP_HELPER_H__
|
||||
#define __H_AB_CIP_HELPER_H__
|
||||
#include "utill.h"
|
||||
|
||||
#define RELEASE_DATA(addr) \
|
||||
{ \
|
||||
if (addr != NULL) \
|
||||
{ \
|
||||
free(addr); \
|
||||
} \
|
||||
}
|
||||
#define BUFFER_SIZE 1024
|
||||
#define HEAD_SIZE 24
|
||||
|
||||
byte_array_info build_read_core_command(const char *address, int length);
|
||||
byte_array_info build_write_core_command(const char *address, ushort typeCode, int length, byte_array_info value);
|
||||
|
||||
cip_error_code_e cip_analysis_read_byte(byte_array_info response, byte_array_info *ret);
|
||||
cip_error_code_e cip_analysis_write_byte(byte_array_info response);
|
||||
|
||||
bool read_data_from_server(int fd, byte_array_info send, int *session);
|
||||
bool cip_read_response(int fd, byte_array_info *response);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
cip_error_code_e read_value(int fd, const char *address, int length, byte_array_info *out_bytes);
|
||||
cip_error_code_e write_value(int fd, const char *address, int length, ushort type_code, byte_array_info in_bytes);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool initialization_on_connect(int fd);
|
||||
|
||||
#endif //__H_AB_CIP_HELPER_H__
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef __H_AB_CIP_PRIVATE_H__
|
||||
#define __H_AB_CIP_PRIVATE_H__
|
||||
#include "typedef.h"
|
||||
|
||||
/// <summary>
|
||||
/// 注册命令
|
||||
/// </summary>
|
||||
const byte g_registered_command[] =
|
||||
{
|
||||
0x65, 0x00, // 注册请求
|
||||
0x04, 0x00, // 命令数据长度(单位字节)
|
||||
0x00, 0x00, 0x00, 0x00, // 会话句柄,初始值为0x00000000
|
||||
0x00, 0x00, 0x00, 0x00, // 状态,初始值为0x00000000(状态好)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 请求通信一方的说明
|
||||
0x00, 0x00, 0x00, 0x00, // 选项,默认为0x00000000
|
||||
0x01, 0x00, // 协议版本(0x0001)
|
||||
0x00, 0x00 // 选项标记(0x0000
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// 会话句柄(由AB PLC生成)
|
||||
uint32 g_session;
|
||||
|
||||
byte g_plc_slot;
|
||||
|
||||
#endif //__H_AB_CIP_PRIVATE_H__
|
|
@ -0,0 +1,31 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.33027.164
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ab_plc_cip_net", "ab_plc_cip_net.vcxproj", "{181055E5-C375-4C97-84A2-90CD807A17FD}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{181055E5-C375-4C97-84A2-90CD807A17FD}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{181055E5-C375-4C97-84A2-90CD807A17FD}.Debug|x64.Build.0 = Debug|x64
|
||||
{181055E5-C375-4C97-84A2-90CD807A17FD}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{181055E5-C375-4C97-84A2-90CD807A17FD}.Debug|x86.Build.0 = Debug|Win32
|
||||
{181055E5-C375-4C97-84A2-90CD807A17FD}.Release|x64.ActiveCfg = Release|x64
|
||||
{181055E5-C375-4C97-84A2-90CD807A17FD}.Release|x64.Build.0 = Release|x64
|
||||
{181055E5-C375-4C97-84A2-90CD807A17FD}.Release|x86.ActiveCfg = Release|Win32
|
||||
{181055E5-C375-4C97-84A2-90CD807A17FD}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {0313BC2F-57C8-4606-B430-4861FF084853}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,177 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{181055E5-C375-4C97-84A2-90CD807A17FD}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>melsec_mc_net</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;_WINSOCK_SECURE_NO_WARNINGS</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<DisableSpecificWarnings>4966</DisableSpecificWarnings>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;_WINSOCK_SECURE_NO_WARNINGS</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<DisableSpecificWarnings>4966</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;_WINSOCK_SECURE_NO_WARNINGS</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<DisableSpecificWarnings>4966</DisableSpecificWarnings>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;_WINSOCK_SECURE_NO_WARNINGS</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<DisableSpecificWarnings>4966</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ab_cip.c" />
|
||||
<ClCompile Include="ab_cip_helper.c" />
|
||||
<ClCompile Include="main.c" />
|
||||
<ClCompile Include="socket.c" />
|
||||
<ClCompile Include="utill.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ab_cip.h" />
|
||||
<ClInclude Include="ab_cip_helper.h" />
|
||||
<ClInclude Include="ab_cip_private.h" />
|
||||
<ClInclude Include="socket.h" />
|
||||
<ClInclude Include="typedef.h" />
|
||||
<ClInclude Include="utill.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,312 @@
|
|||
/*
|
||||
* 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 CIP.c
|
||||
* @brief plc protocol CIP Ethernet/IP
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2023-4-14
|
||||
*/
|
||||
#pragma warning(disable : 4996)
|
||||
#include <cip.h>
|
||||
#include "ab_cip.h"
|
||||
|
||||
|
||||
CIPReadItem CIP_read_item[1024] = {0};
|
||||
|
||||
/**
|
||||
* @description: S7 Receive Plc Data Task
|
||||
* @param parameter - parameter pointer
|
||||
* @return
|
||||
*/
|
||||
void *ReceivePlcDataTask(void *parameter)
|
||||
{
|
||||
struct ControlProtocol *control_protocol = (struct ControlProtocol *)parameter;
|
||||
ReadPlcDataByRecipe(control_protocol->recipe);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: S7 Protocol Open
|
||||
* @param control_protocol - control protocol pointer
|
||||
* @return success : 0 error
|
||||
*/
|
||||
int CIPOpen(struct ControlProtocol *control_protocol)
|
||||
{
|
||||
ControlProtocolOpenDef(control_protocol);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: S7 Protocol Close
|
||||
* @param control_protocol - control protocol pointer
|
||||
* @return success : 0 error
|
||||
*/
|
||||
int CIPClose(struct ControlProtocol *control_protocol)
|
||||
{
|
||||
ControlProtocolCloseDef();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: S7 Protocol Read Data
|
||||
* @param control_protocol - control protocol pointer
|
||||
* @param buf - read data buffer pointer
|
||||
* @param len - read data length
|
||||
* @return success : data length error : 0
|
||||
*/
|
||||
int CIPRead(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 CIP_protocol_done =
|
||||
{
|
||||
._open = CIPOpen,
|
||||
._close = CIPClose,
|
||||
._read = CIPRead,
|
||||
._write = NULL,
|
||||
._ioctl = NULL,
|
||||
};
|
||||
|
||||
/**
|
||||
* @description: Push Data Onto a Stack One By One
|
||||
* @param datastack - data stack pointer
|
||||
* @param args - data pointer
|
||||
* @param length - data length
|
||||
* @return
|
||||
*/
|
||||
void PushDataIntoStack(uint8_t *datastack,uint8_t* args,uint16_t length)
|
||||
{
|
||||
static int index = 8;
|
||||
for(int i =0; i < length; i ++) {
|
||||
datastack[index] = args[i];
|
||||
index++;
|
||||
if(index >= control_protocol->recipe->protocol_data.data_length){
|
||||
index = 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define GET_RESULT(ret) \
|
||||
{ \
|
||||
if (ret != 0) \
|
||||
faild_count++; \
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Read PLC Data By Recipe
|
||||
* @param p_recipe - recipe pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int8_t ReadPlcDataByRecipe(struct ControlRecipe *p_recipe)
|
||||
{
|
||||
static BasicSocketPlc plc_socket = {0};
|
||||
uint16_t data_length = control_protocol->recipe->protocol_data.data_length;
|
||||
uint8_t *CIP_data = control_protocol->recipe->protocol_data.data;
|
||||
struct CircularAreaApp *circular_area = (struct CircularAreaApp *)control_protocol->args;
|
||||
memset(&plc_socket, 0, sizeof(BasicSocketPlc));
|
||||
char plc_ip_string[15] = {0};
|
||||
sprintf(plc_ip_string, "%u.%u.%u.%u",
|
||||
p_recipe->socket_config.plc_ip[0],
|
||||
p_recipe->socket_config.plc_ip[1],
|
||||
p_recipe->socket_config.plc_ip[2],
|
||||
p_recipe->socket_config.plc_ip[3]);
|
||||
char *plc_ip = plc_ip_string;
|
||||
plc_socket.port = control_protocol->recipe->socket_config.port;
|
||||
int fd = -1;
|
||||
int slot = 0;
|
||||
bool ret_con = ab_cip_connect(plc_ip, plc_socket.port, 0, &fd);
|
||||
cip_error_code_e ret = CIP_ERROR_CODE_FAILED;
|
||||
int faild_count = 0;
|
||||
char address[50] = {0};
|
||||
int i = 0;
|
||||
uint8_t val[8] = {0} ;
|
||||
bool all_success = false;
|
||||
bool b_val = true;
|
||||
short s_val = 0;
|
||||
ushort us_val = 0;
|
||||
int i_val = 0;
|
||||
uint32 ui_val = 0;
|
||||
float f_val = 0;
|
||||
double d_val = 0;
|
||||
while (1){
|
||||
if (ret_con || fd > 0)
|
||||
{
|
||||
faild_count = 0;
|
||||
for (i = 0; i < p_recipe->read_item_count; i++)
|
||||
{
|
||||
printf("==============Test count: %d==============\n", i + 1);
|
||||
strcpy(address, CIP_read_item[i].value_name);
|
||||
switch (CIP_read_item[i].value_type)
|
||||
{
|
||||
case 1:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// strcpy(address, CIP_read_item[i].value_name);//
|
||||
// ret = ab_cip_write_bool(fd, address, val);
|
||||
// printf("Write\t %s \tbool:\t %d, \tret: %d\n", address, val, ret);
|
||||
// GET_RESULT(ret);
|
||||
|
||||
b_val = false;
|
||||
ret = ab_cip_read_bool(fd, address, &b_val);
|
||||
// printf("Read\t %s \tbool:\t %d\n", address, b_val);
|
||||
GET_RESULT(ret);
|
||||
memcpy(val,&b_val,sizeof(b_val));
|
||||
PushDataIntoStack(CIP_data,val,1);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// short w_s_val = 23;
|
||||
// strcpy(address, CIP_read_item[i].value_name);
|
||||
// ret = ab_cip_write_short(fd, address, w_s_val);
|
||||
// printf("Write\t %s \tshort:\t %d, \tret: %d\n", address, w_s_val, ret);
|
||||
// GET_RESULT(ret);
|
||||
|
||||
ret = ab_cip_read_short(fd, address, &s_val);
|
||||
// printf("Read\t %s \tshort:\t %d\n", address, s_val);
|
||||
GET_RESULT(ret);
|
||||
memcpy(val,&s_val,sizeof(s_val));
|
||||
PushDataIntoStack(CIP_data,val,2);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// int32 w_i_val = 12345;
|
||||
strcpy(address, CIP_read_item[i].value_name);
|
||||
// ret = ab_cip_write_int32(fd, address, w_i_val);
|
||||
// printf("Write\t %s \tint32:\t %d, \tret: %d\n", address, w_i_val, ret);
|
||||
// GET_RESULT(ret);
|
||||
|
||||
|
||||
ret = ab_cip_read_int32(fd, address, &i_val);
|
||||
// printf("Read\t %s \tint32:\t %d\n", address, i_val);
|
||||
GET_RESULT(ret);
|
||||
memcpy(val,&i_val,sizeof(s_val));
|
||||
PushDataIntoStack(CIP_data,val,2);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// ushort w_us_val = 22;
|
||||
strcpy(address, CIP_read_item[i].value_name);
|
||||
// ret = ab_cip_write_ushort(fd, address, w_us_val);
|
||||
// printf("Write\t %s \tushort:\t %d, \tret: %d\n", address, w_us_val, ret);
|
||||
// GET_RESULT(ret);
|
||||
|
||||
ret = ab_cip_read_ushort(fd, address, &us_val);
|
||||
// printf("Read\t %s \tushort:\t %d\n", address, us_val);
|
||||
GET_RESULT(ret);
|
||||
memcpy(val,&us_val,sizeof(us_val));
|
||||
PushDataIntoStack(CIP_data,val,1);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
// //////////////////////////////////////////////////////////////////////////
|
||||
// uint32 w_ui_val = 22345;
|
||||
strcpy(address, CIP_read_item[i].value_name);
|
||||
// ret = ab_cip_write_uint32(fd, address, w_ui_val);
|
||||
// printf("Write\t %s \tuint32:\t %d, \tret: %d\n", address, w_ui_val, ret);
|
||||
// GET_RESULT(ret);
|
||||
|
||||
ret = ab_cip_read_uint32(fd, address, &ui_val);
|
||||
// printf("Read\t %s \tuint32:\t %d\n", address, ui_val);
|
||||
GET_RESULT(ret);
|
||||
memcpy(val,&ui_val,sizeof(us_val));
|
||||
PushDataIntoStack(CIP_data,val,1);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// double w_d_val = 12345.6789;
|
||||
strcpy(address, CIP_read_item[i].value_name);
|
||||
// ret = ab_cip_write_double(fd, address, w_d_val);
|
||||
// printf("Write\t %s \tdouble:\t %lf, \tret: %d\n", address, w_d_val, ret);
|
||||
// GET_RESULT(ret);
|
||||
|
||||
ret = ab_cip_read_double(fd, address, &d_val);
|
||||
// printf("Read\t %s \tdouble:\t %lf\n", address, d_val);
|
||||
GET_RESULT(ret);
|
||||
memcpy(val,&d_val,sizeof(us_val));
|
||||
PushDataIntoStack(CIP_data,val,1);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// float w_f_val = 32.454f;
|
||||
// strcpy(address, CIP_read_item[i].value_name);
|
||||
// ret = ab_cip_write_float(fd, address, w_f_val);
|
||||
// printf("Write\t %s \tfloat:\t %f, \tret: %d\n", address, w_f_val, ret);
|
||||
// GET_RESULT(ret);
|
||||
|
||||
ret = ab_cip_read_float(fd, address, &f_val);
|
||||
// printf("Read\t %s \tfloat:\t %f\n", address, f_val);
|
||||
GET_RESULT(ret);
|
||||
memcpy(val,&f_val,sizeof(us_val));
|
||||
PushDataIntoStack(CIP_data,val,1);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("value type no found!\n");
|
||||
break;
|
||||
}
|
||||
ControlPrintfList("CIP RECV", CIP_data, data_length);
|
||||
}
|
||||
printf("All Failed count: %d\n", faild_count);
|
||||
if(faild_count != 0)
|
||||
{
|
||||
ab_cip_disconnect(fd);
|
||||
system("pause");
|
||||
}
|
||||
/*read all variable item data, put them into circular_area*/
|
||||
printf("%s get %d item %d length\n", __func__, i, data_length);
|
||||
CircularAreaAppWrite(circular_area, CIP_data, data_length, 0);
|
||||
PrivTaskDelay(100);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: CIP Protocol Cmd Generate
|
||||
* @param p_recipe - recipe pointer
|
||||
* @param protocol_format_info - protocol format info pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int CIPProtocolFormatCmd(struct ControlRecipe *p_recipe, ProtocolFormatInfo *protocol_format_info)
|
||||
{
|
||||
int ret = 0;
|
||||
int i = protocol_format_info->read_item_index;
|
||||
// CIPReadItem *CIP_read_item = (CIPReadItem *)p_recipe->read_item;
|
||||
CIP_read_item[i].value_type = cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "value_type")->valueint;
|
||||
strncpy(CIP_read_item[i].value_name, cJSON_GetObjectItem(protocol_format_info->read_single_item_json, "value_name")->valuestring, 20);
|
||||
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @description: CIP Protocol Init
|
||||
* @param p_recipe - recipe pointer
|
||||
* @return success : 0 error : -1
|
||||
*/
|
||||
int CipProtocolInit(struct ControlRecipe *p_recipe)
|
||||
{
|
||||
p_recipe->read_item = PrivMalloc(sizeof(CIPReadItem) * 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(CIPReadItem));
|
||||
p_recipe->ControlProtocolFormatCmd = CIPProtocolFormatCmd;
|
||||
p_recipe->done = &CIP_protocol_done;
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,174 @@
|
|||
#include "cip_socket.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <windows.h>
|
||||
#pragma comment(lib, "ws2_32.lib") /* Linking with winsock library */
|
||||
#else
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
// #include <sys/socket.h>
|
||||
#include <sockets.h>
|
||||
// #include <arpa/inet.h>
|
||||
#include "lwip/inet.h"
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
int socket_send_data(int fd, void *buf, int nbytes)
|
||||
{
|
||||
int nleft, nwritten;
|
||||
char *ptr = (char *)buf;
|
||||
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
nleft = nbytes;
|
||||
while (nleft > 0)
|
||||
{
|
||||
nwritten = send(fd, ptr, nleft, 0);
|
||||
if (nwritten <= 0)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
nleft -= nwritten;
|
||||
ptr += nwritten;
|
||||
}
|
||||
}
|
||||
|
||||
return (nbytes - nleft);
|
||||
}
|
||||
|
||||
int socket_recv_data(int fd, void *buf, int nbytes)
|
||||
{
|
||||
int nleft, nread;
|
||||
char *ptr = (char *)buf;
|
||||
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
nleft = nbytes;
|
||||
while (nleft > 0)
|
||||
{
|
||||
nread = recv(fd, ptr, nleft, 0);
|
||||
if (nread == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (nread < 0)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
nleft -= nread;
|
||||
ptr += nread;
|
||||
}
|
||||
}
|
||||
|
||||
return (nbytes - nleft);
|
||||
}
|
||||
|
||||
int socket_recv_data_one_loop(int fd, void *buf, int nbytes)
|
||||
{
|
||||
int nleft, nread;
|
||||
char *ptr = (char *)buf;
|
||||
|
||||
if (fd < 0)
|
||||
return -1;
|
||||
|
||||
nleft = nbytes;
|
||||
while (nleft > 0)
|
||||
{
|
||||
nread = recv(fd, ptr, nleft, 0);
|
||||
if (nread == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if (nread < 0)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
nleft -= nread;
|
||||
ptr += nread;
|
||||
|
||||
// 目前只接收一次
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (nbytes - nleft);
|
||||
}
|
||||
|
||||
int socket_open_tcp_client_socket(char *destIp, short destPort)
|
||||
{
|
||||
int sockFd = 0;
|
||||
struct sockaddr_in serverAddr;
|
||||
int ret;
|
||||
|
||||
sockFd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); //IPPROTO_TCP
|
||||
|
||||
printf("%d %s %d\n",sockFd ,__func__,__LINE__);
|
||||
|
||||
if (sockFd < 0)
|
||||
{
|
||||
return -1;
|
||||
#pragma warning(disable : 4996)
|
||||
}
|
||||
|
||||
memset((char *)&serverAddr, 0, sizeof(serverAddr));
|
||||
serverAddr.sin_family = AF_INET;
|
||||
serverAddr.sin_addr.s_addr = inet_addr(destIp);
|
||||
serverAddr.sin_port = (uint16_t)htons((uint16_t)destPort);
|
||||
|
||||
ret = connect(sockFd, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
|
||||
if (ret != 0)
|
||||
{
|
||||
socket_close_tcp_socket(sockFd);
|
||||
sockFd = -1;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
int timeout = 5000; // 5s
|
||||
ret = setsockopt(sockFd, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout));
|
||||
ret = setsockopt(sockFd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout));
|
||||
#else
|
||||
struct timeval timeout = {5, 0}; // 3s
|
||||
ret = setsockopt(sockFd, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout));
|
||||
ret = setsockopt(sockFd, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout));
|
||||
#endif
|
||||
|
||||
return sockFd;
|
||||
}
|
||||
|
||||
void socket_close_tcp_socket(int sockFd)
|
||||
{
|
||||
if (sockFd > 0)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
closesocket(sockFd);
|
||||
#else
|
||||
close(sockFd);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void tinet_ntoa(char *ipstr, unsigned int ip)
|
||||
{
|
||||
sprintf(ipstr, "%d.%d.%d.%d", ip & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, ip >> 24);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
#ifndef __SOCKET_H_
|
||||
#define __SOCKET_H_
|
||||
|
||||
#include "utill.h"
|
||||
|
||||
int socket_send_data(int fd, void *ptr, int nbytes);
|
||||
int socket_recv_data(int fd, void *ptr, int nbytes);
|
||||
int socket_recv_data_one_loop(int fd, void *ptr, int nbytes);
|
||||
int socket_open_tcp_client_socket(char *ip, short port);
|
||||
void socket_close_tcp_socket(int sockFd);
|
||||
|
||||
#endif //__SOCKET_H_
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef __H_TYPEDEF_H__
|
||||
#define __H_TYPEDEF_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short ushort;
|
||||
typedef signed int int32;
|
||||
typedef unsigned int uint32;
|
||||
typedef long long int64;
|
||||
typedef unsigned long long uint64;
|
||||
|
||||
typedef enum _tag_cip_error_code
|
||||
{
|
||||
CIP_ERROR_CODE_OK = 0, // 成功
|
||||
CIP_ERROR_CODE_FAILED = 1, // 错误
|
||||
CIP_ERROR_CODE_UNKOWN = 99, // 未知错误
|
||||
} cip_error_code_e;
|
||||
|
||||
#endif // !__H_TYPEDEF_H__
|
|
@ -0,0 +1,383 @@
|
|||
#include "utill.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#define _WS2_32_WINSOCK_SWAP_LONG(l) \
|
||||
((((l) >> 24) & 0x000000FFL) | \
|
||||
(((l) >> 8) & 0x0000FF00L) | \
|
||||
(((l) << 8) & 0x00FF0000L) | \
|
||||
(((l) << 24) & 0xFF000000L))
|
||||
|
||||
#define _WS2_32_WINSOCK_SWAP_LONGLONG(l) \
|
||||
((((l) >> 56) & 0x00000000000000FFLL) | \
|
||||
(((l) >> 40) & 0x000000000000FF00LL) | \
|
||||
(((l) >> 24) & 0x0000000000FF0000LL) | \
|
||||
(((l) >> 8) & 0x00000000FF000000LL) | \
|
||||
(((l) << 8) & 0x000000FF00000000LL) | \
|
||||
(((l) << 24) & 0x0000FF0000000000LL) | \
|
||||
(((l) << 40) & 0x00FF000000000000LL) | \
|
||||
(((l) << 56) & 0xFF00000000000000LL))
|
||||
|
||||
void short2bytes(short i, byte *bytes)
|
||||
{
|
||||
int size = 2;
|
||||
memset(bytes, 0, sizeof(byte) * size);
|
||||
bytes[0] = (byte)(0xff & i);
|
||||
bytes[1] = (byte)((0xff00 & i) >> 8);
|
||||
}
|
||||
|
||||
short bytes2short(byte *bytes)
|
||||
{
|
||||
short iRetVal = bytes[0] & 0xFF;
|
||||
iRetVal |= (((short)bytes[1] << 8) & 0xFF00);
|
||||
return iRetVal;
|
||||
}
|
||||
|
||||
void ushort2bytes(ushort i, byte *bytes)
|
||||
{
|
||||
int size = 2;
|
||||
memset(bytes, 0, sizeof(byte) * size);
|
||||
bytes[0] = (byte)(0xff & i);
|
||||
bytes[1] = (byte)((0xff00 & i) >> 8);
|
||||
}
|
||||
|
||||
ushort bytes2ushort(byte *bytes)
|
||||
{
|
||||
ushort iRetVal = bytes[0] & 0xFF;
|
||||
iRetVal |= (((ushort)bytes[1] << 8) & 0xFF00);
|
||||
return iRetVal;
|
||||
}
|
||||
|
||||
void int2bytes(int32 i, byte *bytes)
|
||||
{
|
||||
int size = 4;
|
||||
memset(bytes, 0, sizeof(byte) * size);
|
||||
bytes[0] = (byte)(0xff & i);
|
||||
bytes[1] = (byte)((0xff00 & i) >> 8);
|
||||
bytes[2] = (byte)((0xff0000 & i) >> 16);
|
||||
bytes[3] = (byte)((0xff000000 & i) >> 24);
|
||||
}
|
||||
|
||||
int32 bytes2int32(byte *bytes)
|
||||
{
|
||||
int32 iRetVal = bytes[0] & 0xFF;
|
||||
iRetVal |= (((int32)bytes[1] << 8) & 0xFF00);
|
||||
iRetVal |= (((int32)bytes[2] << 16) & 0xFF0000);
|
||||
iRetVal |= (((int32)bytes[3] << 24) & 0xFF000000);
|
||||
return iRetVal;
|
||||
}
|
||||
|
||||
void uint2bytes(uint32 i, byte *bytes)
|
||||
{
|
||||
int size = 4;
|
||||
memset(bytes, 0, sizeof(byte) * size);
|
||||
bytes[0] = (byte)(0xff & i);
|
||||
bytes[1] = (byte)((0xff00 & i) >> 8);
|
||||
bytes[2] = (byte)((0xff0000 & i) >> 16);
|
||||
bytes[3] = (byte)((0xff000000 & i) >> 24);
|
||||
}
|
||||
|
||||
uint32 bytes2uint32(byte *bytes)
|
||||
{
|
||||
uint32 iRetVal = bytes[0] & 0xFF;
|
||||
iRetVal |= (((uint32)bytes[1] << 8) & 0xFF00);
|
||||
iRetVal |= (((uint32)bytes[2] << 16) & 0xFF0000);
|
||||
iRetVal |= (((uint32)bytes[3] << 24) & 0xFF000000);
|
||||
return iRetVal;
|
||||
}
|
||||
|
||||
void bigInt2bytes(int64 i, byte *bytes)
|
||||
{
|
||||
int size = 8;
|
||||
memset(bytes, 0, sizeof(byte) * size);
|
||||
bytes[0] = (byte)(0xff & i);
|
||||
bytes[1] = (byte)(0xff & (i >> 8));
|
||||
bytes[2] = (byte)(0xff & (i >> 16));
|
||||
bytes[3] = (byte)(0xff & (i >> 24));
|
||||
bytes[4] = (byte)(0xff & (i >> 32));
|
||||
bytes[5] = (byte)(0xff & (i >> 40));
|
||||
bytes[6] = (byte)(0xff & (i >> 48));
|
||||
bytes[7] = (byte)(0xff & (i >> 56));
|
||||
}
|
||||
|
||||
int64 bytes2bigInt(byte *bytes)
|
||||
{
|
||||
int64 iRetVal = bytes[0] & 0xFF;
|
||||
iRetVal |= (((int64)bytes[1] << 8) & 0xFF00);
|
||||
iRetVal |= (((int64)bytes[2] << 16) & 0xFF0000);
|
||||
iRetVal |= (((int64)bytes[3] << 24) & 0xFF000000);
|
||||
iRetVal |= (((int64)bytes[4] << 32) & 0xFF00000000);
|
||||
iRetVal |= (((int64)bytes[5] << 40) & 0xFF0000000000);
|
||||
iRetVal |= (((int64)bytes[6] << 48) & 0xFF000000000000);
|
||||
iRetVal |= (((int64)bytes[7] << 56) & 0xFF00000000000000);
|
||||
return iRetVal;
|
||||
}
|
||||
|
||||
void ubigInt2bytes(uint64 i, byte *bytes)
|
||||
{
|
||||
int size = 8;
|
||||
memset(bytes, 0, sizeof(byte) * size);
|
||||
bytes[0] = (byte)(0xff & i);
|
||||
bytes[1] = (byte)(0xff & (i >> 8));
|
||||
bytes[2] = (byte)(0xff & (i >> 16));
|
||||
bytes[3] = (byte)(0xff & (i >> 24));
|
||||
bytes[4] = (byte)(0xff & (i >> 32));
|
||||
bytes[5] = (byte)(0xff & (i >> 40));
|
||||
bytes[6] = (byte)(0xff & (i >> 48));
|
||||
bytes[7] = (byte)(0xff & (i >> 56));
|
||||
}
|
||||
|
||||
uint64 bytes2ubigInt(byte *bytes)
|
||||
{
|
||||
uint64 iRetVal = bytes[0] & 0xFF;
|
||||
iRetVal |= (((uint64)bytes[1] << 8) & 0xFF00);
|
||||
iRetVal |= (((uint64)bytes[2] << 16) & 0xFF0000);
|
||||
iRetVal |= (((uint64)bytes[3] << 24) & 0xFF000000);
|
||||
iRetVal |= (((uint64)bytes[4] << 32) & 0xFF00000000);
|
||||
iRetVal |= (((uint64)bytes[5] << 40) & 0xFF0000000000);
|
||||
iRetVal |= (((uint64)bytes[6] << 48) & 0xFF000000000000);
|
||||
iRetVal |= (((uint64)bytes[7] << 56) & 0xFF00000000000000);
|
||||
return iRetVal;
|
||||
}
|
||||
|
||||
void float2bytes(float i, byte *bytes)
|
||||
{
|
||||
int size = 4;
|
||||
int temp = *(int *)&i;
|
||||
int2bytes(temp, bytes);
|
||||
}
|
||||
|
||||
float bytes2float(byte *bytes)
|
||||
{
|
||||
int temp = bytes2int32(bytes);
|
||||
return *(float *)&temp;
|
||||
}
|
||||
|
||||
void double2bytes(double i, byte *bytes)
|
||||
{
|
||||
int64 temp = *(int64 *)&i;
|
||||
bigInt2bytes(temp, bytes);
|
||||
}
|
||||
|
||||
double bytes2double(byte *bytes)
|
||||
{
|
||||
int64 temp = bytes2bigInt(bytes);
|
||||
return *(double *)&temp;
|
||||
}
|
||||
|
||||
int str_to_int(const char *address)
|
||||
{
|
||||
int ret = 0;
|
||||
ret = (int)strtol(address, NULL, 10);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// void str_toupper(char *input)
|
||||
// {
|
||||
// if (input == NULL)
|
||||
// return;
|
||||
|
||||
// int32 len = strlen(input), i = 0;
|
||||
// for (; i < len; i++)
|
||||
// input[i] = toupper(input[i]);
|
||||
// }
|
||||
|
||||
// void str_tolower(char *input)
|
||||
// {
|
||||
// if (input == NULL)
|
||||
// return;
|
||||
|
||||
// int32 len = strlen(input), i = 0;
|
||||
// for (; i < len; i++)
|
||||
// input[i] = tolower(input[i]);
|
||||
// }
|
||||
|
||||
/**
|
||||
* ×Ö·û´®originÒÔ×Ö·û´®prefix¿ªÍ·£¬·µ»Ø0£»·ñÔò·µ»Ø1£»Òì³£·µ»Ø-1
|
||||
*/
|
||||
int str_start_with(const char *origin, char *prefix)
|
||||
{
|
||||
if (origin == NULL ||
|
||||
prefix == NULL ||
|
||||
strlen(prefix) > strlen(origin))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int n = strlen(prefix), i;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
if (origin[i] != prefix[i])
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ×Ö·û´®originÒÔ×Ö·û´®end½á⣬·µ»Ø0£»·ñÔò·µ»Ø1£»Òì³£·µ»Ø-1
|
||||
*/
|
||||
int str_end_with(const char *origin, char *end)
|
||||
{
|
||||
if (origin == NULL ||
|
||||
end == NULL ||
|
||||
strlen(end) > strlen(origin))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int n = strlen(end);
|
||||
int m = strlen(origin);
|
||||
int i;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
if (origin[m - i - 1] != end[n - i - 1])
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 htonf_(float value)
|
||||
{
|
||||
uint32 Tempval;
|
||||
uint32 Retval;
|
||||
Tempval = *(uint32 *)(&value);
|
||||
Retval = _WS2_32_WINSOCK_SWAP_LONG(Tempval);
|
||||
return Retval;
|
||||
}
|
||||
|
||||
float ntohf_(uint32 value)
|
||||
{
|
||||
const uint32 Tempval = _WS2_32_WINSOCK_SWAP_LONG(value);
|
||||
float Retval;
|
||||
*((uint32 *)&Retval) = Tempval;
|
||||
return Retval;
|
||||
}
|
||||
|
||||
uint64 htond_(double value)
|
||||
{
|
||||
uint64 Tempval;
|
||||
uint64 Retval;
|
||||
Tempval = *(uint64 *)(&value);
|
||||
Retval = _WS2_32_WINSOCK_SWAP_LONGLONG(Tempval);
|
||||
return Retval;
|
||||
}
|
||||
|
||||
double ntohd_(uint64 value)
|
||||
{
|
||||
const uint64 Tempval = _WS2_32_WINSOCK_SWAP_LONGLONG(value);
|
||||
double Retval;
|
||||
*((uint64 *)&Retval) = Tempval;
|
||||
return Retval;
|
||||
}
|
||||
|
||||
uint64 htonll_(uint64 Value)
|
||||
{
|
||||
const uint64 Retval = _WS2_32_WINSOCK_SWAP_LONGLONG(Value);
|
||||
return Retval;
|
||||
}
|
||||
|
||||
uint64 ntohll_(uint64 Value)
|
||||
{
|
||||
const uint64 Retval = _WS2_32_WINSOCK_SWAP_LONGLONG(Value);
|
||||
return Retval;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
/*
|
||||
=============
|
||||
itoa
|
||||
|
||||
Convert integer to string
|
||||
|
||||
PARAMS:
|
||||
- value A 64-bit number to convert
|
||||
- str Destination buffer; should be 66 characters long for radix2, 24 - radix8, 22 - radix10, 18 - radix16.
|
||||
- radix Radix must be in range -36 .. 36. Negative values used for signed numbers.
|
||||
=============
|
||||
*/
|
||||
|
||||
char *cip_itoa(unsigned long long value, char str[], int radix)
|
||||
{
|
||||
char buf[66];
|
||||
char *dest = buf + sizeof(buf);
|
||||
bool sign = false;
|
||||
|
||||
if (value == 0)
|
||||
{
|
||||
memcpy(str, "0", 2);
|
||||
return str;
|
||||
}
|
||||
|
||||
if (radix < 0)
|
||||
{
|
||||
radix = -radix;
|
||||
if ((long long)value < 0)
|
||||
{
|
||||
value = -value;
|
||||
sign = true;
|
||||
}
|
||||
}
|
||||
|
||||
*--dest = '\0';
|
||||
|
||||
switch (radix)
|
||||
{
|
||||
case 16:
|
||||
while (value)
|
||||
{
|
||||
*--dest = '0' + (value & 0xF);
|
||||
if (*dest > '9')
|
||||
*dest += 'A' - '9' - 1;
|
||||
value >>= 4;
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
while (value)
|
||||
{
|
||||
*--dest = '0' + (value % 10);
|
||||
value /= 10;
|
||||
}
|
||||
break;
|
||||
|
||||
case 8:
|
||||
while (value)
|
||||
{
|
||||
*--dest = '0' + (value & 7);
|
||||
value >>= 3;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
while (value)
|
||||
{
|
||||
*--dest = '0' + (value & 1);
|
||||
value >>= 1;
|
||||
}
|
||||
break;
|
||||
|
||||
default: // The slow version, but universal
|
||||
while (value)
|
||||
{
|
||||
*--dest = '0' + (value % radix);
|
||||
if (*dest > '9')
|
||||
*dest += 'A' - '9' - 1;
|
||||
value /= radix;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (sign)
|
||||
*--dest = '-';
|
||||
|
||||
memcpy(str, dest, buf + sizeof(buf) - dest);
|
||||
return str;
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,58 @@
|
|||
#ifndef __UTILL_H__
|
||||
#define __UTILL_H__
|
||||
|
||||
#include "typedef.h"
|
||||
|
||||
typedef struct _tag_byte_array_info
|
||||
{
|
||||
byte *data; // 内容
|
||||
int length; // 长度
|
||||
} byte_array_info;
|
||||
|
||||
typedef struct _tag_bool_array_info
|
||||
{
|
||||
bool *data; // 内容
|
||||
int length; // 长度
|
||||
} bool_array_info;
|
||||
|
||||
void short2bytes(short i, byte *bytes);
|
||||
short bytes2short(byte *bytes);
|
||||
|
||||
void ushort2bytes(ushort i, byte *bytes);
|
||||
ushort bytes2ushort(byte *bytes);
|
||||
|
||||
void int2bytes(int32 i, byte *bytes);
|
||||
int32 bytes2int32(byte *bytes);
|
||||
|
||||
void uint2bytes(uint32 i, byte *bytes);
|
||||
uint32 bytes2uint32(byte *bytes);
|
||||
|
||||
void bigInt2bytes(int64 i, byte *bytes);
|
||||
int64 bytes2bigInt(byte *bytes);
|
||||
|
||||
void ubigInt2bytes(uint64 i, byte *bytes);
|
||||
uint64 bytes2ubigInt(byte *bytes);
|
||||
|
||||
void float2bytes(float i, byte *bytes);
|
||||
float bytes2float(byte *bytes);
|
||||
|
||||
void double2bytes(double i, byte *bytes);
|
||||
double bytes2double(byte *bytes);
|
||||
|
||||
int str_to_int(const char *address);
|
||||
void str_toupper(char *input);
|
||||
void str_tolower(char *input);
|
||||
int str_start_with(const char *origin, char *prefix);
|
||||
|
||||
uint32 htonf_(float value);
|
||||
float ntohf_(uint32 value);
|
||||
uint64 htond_(double value);
|
||||
double ntohd_(uint64 value);
|
||||
uint64 htonll_(uint64 Value);
|
||||
uint64 ntohll_(uint64 Value);
|
||||
|
||||
#ifndef _WIN32
|
||||
char *cip_itoa(unsigned long long value, char str[], int radix);
|
||||
#endif // !_WIN32
|
||||
|
||||
#endif
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* 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 cip.h
|
||||
* @brief plc protocol cip
|
||||
* @version 3.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-10-08
|
||||
*/
|
||||
|
||||
#ifndef Cip_H
|
||||
#define Cip_H
|
||||
|
||||
#include <control_def.h>
|
||||
|
||||
#define BASE_PLC_RECV_BUFF_SIZE 1024
|
||||
|
||||
ControlProtocolType control_protocol;
|
||||
|
||||
int8_t ReadPlcDataByRecipe(struct ControlRecipe *p_recipe);
|
||||
void voidpush(uint8_t *datastack,uint8_t* args,uint16_t length);
|
||||
static uint8_t GetUniformValueTypeMemorySize(UniformValueType uniform_value_type);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UniformValueType value_type;
|
||||
char value_name[20];
|
||||
}CIPReadItem;
|
||||
|
||||
#endif
|
|
@ -56,6 +56,7 @@ typedef enum
|
|||
PROTOCOL_MELSEC_1C,
|
||||
PROTOCOL_MELSEC_3C,
|
||||
PROTOCOL_FREEMODBUS_TCP_SERVER,
|
||||
PROTOCOL_CIP,
|
||||
PROTOCOL_END
|
||||
}ProtocolType;
|
||||
|
||||
|
|
|
@ -53,6 +53,10 @@ extern int S7ProtocolInit(struct ControlRecipe *p_recipe);
|
|||
extern int FreeModbusTcpServerInit(struct ControlRecipe *p_recipe);
|
||||
#endif
|
||||
|
||||
#ifdef CONTROL_PROTOCOL_CIP
|
||||
extern int CipProtocolInit(struct ControlRecipe *p_recipe);
|
||||
#endif
|
||||
|
||||
/*
|
||||
CONTROL FRAMEWORK READ DATA FORMAT:
|
||||
| HEAD |device_id|read data length|read item count| data |
|
||||
|
@ -96,6 +100,9 @@ static struct ControlProtocolInitParam protocol_init[] =
|
|||
{ PROTOCOL_FREEMODBUS_TCP_SERVER, FreeModbusTcpServerInit },
|
||||
#endif
|
||||
|
||||
#ifdef CONTROL_PROTOCOL_CIP
|
||||
{ PROTOCOL_CIP, CipProtocolInit },
|
||||
#endif
|
||||
{ PROTOCOL_END, NULL },
|
||||
};
|
||||
|
||||
|
@ -329,7 +336,7 @@ int ControlProtocolOpenDef(struct ControlProtocol *control_protocol)
|
|||
|
||||
pthread_attr_t attr;
|
||||
attr.schedparam.sched_priority = 19;
|
||||
attr.stacksize = 2048;
|
||||
attr.stacksize = 4096;
|
||||
|
||||
char task_name[] = "control_recv_data";
|
||||
pthread_args_t args;
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
export CROSS_COMPILE ?=/usr/bin/arm-none-eabi-
|
||||
|
||||
<<<<<<< HEAD
|
||||
export CFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -Dgcc -O0 -fgnu89-inline -Wa,-mimplicit-it=thumb -Werror
|
||||
=======
|
||||
export CFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -Dgcc -O0 -fgnu89-inline -Wa,-mimplicit-it=thumb -Werror -Wuninitialized
|
||||
>>>>>>> upstream/prepare_for_master
|
||||
export CFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -Dgcc -O0 -fgnu89-inline -Wa,-mimplicit-it=thumb -Werror -Wuninitialized
|
||||
# export CFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g -fgnu89-inline -Wa,-mimplicit-it=thumb -Werror
|
||||
export AFLAGS := -c -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -x assembler-with-cpp -Wa,-mimplicit-it=thumb -gdwarf-2
|
||||
export LFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi-edu-arm32.map,-cref,-u,Reset_Handler -T $(BSP_ROOT)/link.lds
|
||||
|
|
|
@ -536,6 +536,7 @@ KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/plc_protoc
|
|||
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/plc_protocol/opcua #
|
||||
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/plc_protocol/s7 #
|
||||
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/ipc_protocol/freemodbustcpserver #
|
||||
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/plc_protocol/cip #
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_LIB_USING_CJSON), y)
|
||||
|
|
Loading…
Reference in New Issue