add CIP Protocol

This commit is contained in:
Wien.b 2023-10-11 02:22:00 -07:00
parent 242c7d66d2
commit 51299c6b79
25 changed files with 2110 additions and 7 deletions

View File

@ -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

View File

@ -0,0 +1,3 @@
SRC_FILES := ab_l30.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,2 @@
SRC_FILES := $(wildcard ./*.c)
include $(KERNEL_ROOT)/compiler.mk

View File

@ -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;
}

View File

@ -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__

View File

@ -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; // 接口句柄默认为0x00000000CIP
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; // 接口句柄默认为0x00000000CIP
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;
}

View File

@ -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__

View File

@ -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__

View File

@ -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

View File

@ -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>

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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_

View File

@ -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__

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -56,6 +56,7 @@ typedef enum
PROTOCOL_MELSEC_1C,
PROTOCOL_MELSEC_3C,
PROTOCOL_FREEMODBUS_TCP_SERVER,
PROTOCOL_CIP,
PROTOCOL_END
}ProtocolType;

View File

@ -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;

View File

@ -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

View File

@ -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)