全功能版本的modbus_rt,实现包括modbus RTU,ASCII,TCP,UDP的modbus,支持主机和从机功能,支持自定义文件传输功能

This commit is contained in:
SenySunny 2024-01-31 12:22:25 +08:00
parent daacac97b7
commit cbfdd778c2
6 changed files with 2831 additions and 0 deletions

View File

@ -0,0 +1,78 @@
from PikaObj import *
class _data_trans:
def _reg2reg(self, val: int) -> int: ...
def _regs2regs(self, val: list) -> list: ...
def _regs2bytes(self, val: list, mode: int) -> bytes: ...
def _regs2str(self, val: list, mode: int) -> str: ...
def _regs2signed(self, val: list, mode: int) -> list: ...
def _regs2int(self, val: list, mode: int) -> list: ...
def _regs2uint(self, val: list, mode: int) -> list: ...
def _regs2long(self, val: list, mode: int) -> list: ...
# def _regs2ulong(self, val: list, mode: int) -> list: ...
def _regs2float(self, val: list, mode: int) -> list: ...
def _regs2double(self, val: list, mode: int) -> list: ...
def _bytes2regs(self, val: any, mode: int) -> list: ...
def _str2regs(self, val: str, mode: int) -> list: ...
def _int2regs(self, val: list, mode: int) -> list: ...
def _uint2regs(self, val: list, mode: int) -> list: ...
def _long2regs(self, val: list, mode: int) -> list: ...
# def _ulong2regs(self, val: list, mode: int) -> list: ...
def _float2regs(self, val: list, mode: int) -> list: ...
def _double2regs(self, val: list, mode: int) -> list: ...
class _rtu:
def __del__(self): ...
def _init(self, mode: int): ...
def _set_serial(self, devname: str, baudrate: int, bytesize: int, parity: str, stopbits: int, xonxoff: int) -> int: ...
def _set_over_type(self, over_type: int) -> int: ...
def _set_net(self, ip: str, port: int, type: int) -> int: ...
def _set_ip(self, ip: str) -> int: ...
def _set_port(self, port: int) -> int: ...
def _set_type(self, type: int) -> int: ...
def _set_p2p(self, p2p_flag: int) -> int: ...
def _open(self) -> int: ...
def _isopen(self) -> int: ...
def _close(self) -> int: ...
def _slave_set_addr(self, addr: int) -> int: ...
def _slave_set_strict(self, strict: int) -> int: ...
def _slave_add_block(self, name: str, type: int, addr: int, nums: int) -> int: ...
def _slave_set_pre_ans_callback(self, cb: any) -> int: ...
def _slave_set_done_callback(self, cb: any) -> int: ...
def _slave_set_dev_binding(self, flag: int) -> int: ...
def _master_set_server(self, saddr: str,sport: int) -> int: ...
def _master_get_saddr(self) -> str: ...
def _slave_read_regs(self, type: int, addr: int, *val) -> list: ...
def _slave_write_regs(self, type: int, addr: int, *val) -> int: ...
def _master_read_list(self, slave: int, fuction: int, addr: int, *val) -> list: ...
def _master_write_int(self, slave: int, fuction: int, addr: int, *val) -> int: ...
def _master_write_list(self, slave: int, fuction: int, addr: int, *val) -> int: ...
def _master_download(self, slave: int, file_dev: str, file_master: str) -> int: ...
def _master_upload(self, slave: int, file_dev: str, file_master: str) -> int: ...
class _tcp:
def __del__(self): ...
def _init(self, mode: int): ...
def _set_net(self, ip: str, port: int, type: int) -> int: ...
def _set_ip(self, ip: str) -> int: ...
def _set_port(self, port: int) -> int: ...
def _set_type(self, type: int) -> int: ...
def _set_p2p(self, p2p_flag: int) -> int: ...
def _open(self) -> int: ...
def _isopen(self) -> int: ...
def _close(self) -> int: ...
def _slave_set_addr(self, addr: int) -> int: ...
def _slave_set_strict(self, strict: int) -> int: ...
def _slave_add_block(self, name: str, type: int, addr: int, nums: int) -> int: ...
def _slave_set_pre_ans_callback(self, cb: any) -> int: ...
def _slave_set_done_callback(self, cb: any) -> int: ...
def _slave_set_dev_binding(self, flag: int) -> int: ...
def _master_set_server(self, saddr: str,sport: int) -> int: ...
def _master_get_saddr(self) -> str: ...
def _slave_read_regs(self, type: int, addr: int, *val) -> list: ...
def _slave_write_regs(self, type: int, addr: int, *val) -> int: ...
def _master_read_list(self, slave: int, fuction: int, addr: int, *val) -> list: ...
def _master_write_int(self, slave: int, fuction: int, addr: int, *val) -> int: ...
def _master_write_list(self, slave: int, fuction: int, addr: int, *val) -> int: ...
def _master_download(self, slave: int, file_dev: str, file_master: str) -> int: ...
def _master_upload(self, slave: int, file_dev: str, file_master: str) -> int: ...

View File

@ -0,0 +1,466 @@
/**
* @file _modbus_rt.c
* @brief modbus_rt的pika层的API实现
* @author SenySunny (senysunny@163.com)
* @date 2023-05-14
*
* @attention
*
* <h2><center>&copy; Copyright (c) 2022 Ma Longwei.
* All rights reserved.</center></h2>
*
*/
#include "PikaStdData_List.h"
#include "_modbus_rt__data_trans.h"
#include "modbus_rt_platform_memory.h"
#include "modbus_data_trans.h"
int _modbus_rt__data_trans__reg2reg(PikaObj *self, int val) {
#if (!MODBUS_DATA_TRANS_ENABLE)
pika_platform_printf("MODBUS_DATA_TRANS_ENABLE is not enabled.\n");
return 0;
#else
return modbus_data_reg2reg((uint16_t)val);
#endif
}
PikaObj* _modbus_rt__data_trans__regs2regs(PikaObj *self, PikaObj* val) {
#if (!MODBUS_DATA_TRANS_ENABLE)
pika_platform_printf("MODBUS_DATA_TRANS_ENABLE is not enabled.\n");
return NULL;
#else
(void)(self);
size_t len_list = pikaList_getSize(val);
PikaList* list = New_PikaList();
for(size_t i = 0; i < len_list; i++ ) {
uint16_t temp = (uint16_t)pikaList_getInt(val, i);
pikaList_append(list, arg_newInt(modbus_data_reg2reg(temp)));
}
return list;
#endif
}
Arg* _modbus_rt__data_trans__regs2bytes(PikaObj *self, PikaObj* val, int mode) {
#if (!MODBUS_DATA_TRANS_ENABLE)
pika_platform_printf("MODBUS_DATA_TRANS_ENABLE is not enabled.\n");
return NULL;
#else
(void)(self);
uint8_t *_Dst = NULL;
uint16_t *_Src = NULL;
size_t len_list = pikaList_getSize(val);
size_t len = len_list << 1;
_Dst = modbus_rt_calloc(1,len);
_Src = modbus_rt_calloc(1,len);
for(size_t i = 0;i < len_list; i++) {
_Src[i] = (uint16_t)pikaList_getInt(val, i);
}
modbus_data_regs2bytes(mode, _Dst, _Src, len_list);
Arg* r = arg_newBytes(_Dst, len);
modbus_rt_free(_Dst);
modbus_rt_free(_Src);
return r;
#endif
}
char* _modbus_rt__data_trans__regs2str(PikaObj *self, PikaObj* val, int mode) {
#if (!MODBUS_DATA_TRANS_ENABLE)
pika_platform_printf("MODBUS_DATA_TRANS_ENABLE is not enabled.\n");
return NULL;
#else
(void)(self);
char *_Dst = NULL;
uint16_t *_Src = NULL;
size_t len_list = pikaList_getSize(val);
_Dst = modbus_rt_calloc(1,(len_list << 1) + 1);
_Src = modbus_rt_calloc(1,len_list << 1);
for(size_t i = 0;i < len_list; i++) {
_Src[i] = (uint16_t)pikaList_getInt(val, i);
}
modbus_data_regs2str(mode, _Dst, _Src, len_list);
char* str = obj_cacheStr(self, _Dst);
modbus_rt_free(_Dst);
modbus_rt_free(_Src);
return str;
#endif
}
PikaObj* _modbus_rt__data_trans__regs2signed(PikaObj *self, PikaObj* val, int mode){
#if (!MODBUS_DATA_TRANS_ENABLE)
pika_platform_printf("MODBUS_DATA_TRANS_ENABLE is not enabled.\n");
return NULL;
#else
(void)(self);
int16_t *_Dst = NULL;
uint16_t *_Src = NULL;
size_t len_list = pikaList_getSize(val);
_Dst = modbus_rt_calloc(1,len_list << 1);
_Src = modbus_rt_calloc(1,len_list << 1);
for(size_t i = 0;i < len_list; i++) {
_Src[i] = (uint16_t)pikaList_getInt(val, i);
}
modbus_data_regs2signed(mode, _Dst, _Src, len_list);
PikaList* list = New_PikaList();
for(size_t i = 0; i < len_list; i++ ) {
pikaList_append(list, arg_newInt(_Dst[i]));
}
modbus_rt_free(_Dst);
modbus_rt_free(_Src);
return list;
#endif
}
PikaObj* _modbus_rt__data_trans__regs2int(PikaObj *self, PikaObj* val, int mode) {
#if (!MODBUS_DATA_TRANS_ENABLE)
pika_platform_printf("MODBUS_DATA_TRANS_ENABLE is not enabled.\n");
return NULL;
#else
(void)(self);
int32_t *_Dst = NULL;
uint16_t *_Src = NULL;
size_t len_list = pikaList_getSize(val);
size_t len_ret = len_list >> 1;
if(len_list & 0x01) {
len_ret += 1;
}
_Dst = modbus_rt_calloc(1,len_ret << 2);
_Src = modbus_rt_calloc(1,len_list << 1);
for(size_t i = 0;i < len_list; i++) {
_Src[i] = (uint16_t)pikaList_getInt(val, i);
}
modbus_data_regs2int(mode, _Dst, _Src, len_list);
PikaList* list = New_PikaList();
for(size_t i = 0; i < len_ret; i++ ) {
pikaList_append(list, arg_newInt(_Dst[i]));
}
modbus_rt_free(_Dst);
modbus_rt_free(_Src);
return list;
#endif
}
PikaObj* _modbus_rt__data_trans__regs2uint(PikaObj *self, PikaObj* val, int mode) {
#if (!MODBUS_DATA_TRANS_ENABLE)
pika_platform_printf("MODBUS_DATA_TRANS_ENABLE is not enabled.\n");
return NULL;
#else
(void)(self);
uint32_t *_Dst = NULL;
uint16_t *_Src = NULL;
size_t len_list = pikaList_getSize(val);
size_t len_ret = len_list >> 1;
if(len_list & 0x01) {
len_ret += 1;
}
_Dst = modbus_rt_calloc(1,len_ret << 2);
_Src = modbus_rt_calloc(1,len_list << 1);
for(size_t i = 0;i < len_list; i++) {
_Src[i] = (uint16_t)pikaList_getInt(val, i);
}
modbus_data_regs2uint(mode, _Dst, _Src, len_list);
PikaList* list = New_PikaList();
for(size_t i = 0; i < len_ret; i++ ) {
pikaList_append(list, arg_newInt(_Dst[i]));
}
modbus_rt_free(_Dst);
modbus_rt_free(_Src);
return list;
#endif
}
PikaObj* _modbus_rt__data_trans__regs2long(PikaObj *self, PikaObj* val, int mode) {
#if (!MODBUS_DATA_TRANS_ENABLE)
pika_platform_printf("MODBUS_DATA_TRANS_ENABLE is not enabled.\n");
return NULL;
#else
(void)(self);
int64_t *_Dst = NULL;
uint16_t *_Src = NULL;
size_t len_list = pikaList_getSize(val);
size_t len_ret = len_list >> 2;
if(len_list & 0x03) {
len_ret += 1;
}
_Dst = modbus_rt_calloc(1,len_ret << 3);
_Src = modbus_rt_calloc(1,len_list << 1);
for(size_t i = 0;i < len_list; i++) {
_Src[i] = (uint16_t)pikaList_getInt(val, i);
}
modbus_data_regs2long(mode, _Dst, _Src, len_list);
PikaList* list = New_PikaList();
for(size_t i = 0; i < len_ret; i++ ) {
pikaList_append(list, arg_newInt(_Dst[i]));
}
modbus_rt_free(_Dst);
modbus_rt_free(_Src);
return list;
#endif
}
PikaObj* _modbus_rt__data_trans__regs2float(PikaObj *self, PikaObj* val, int mode) {
#if (!MODBUS_DATA_TRANS_ENABLE)
pika_platform_printf("MODBUS_DATA_TRANS_ENABLE is not enabled.\n");
return NULL;
#else
(void)(self);
float *_Dst = NULL;
uint16_t *_Src = NULL;
size_t len_list = pikaList_getSize(val);
size_t len_ret = len_list >> 1;
if(len_list & 0x01) {
len_ret += 1;
}
_Dst = modbus_rt_calloc(1,len_ret << 2);
_Src = modbus_rt_calloc(1,len_list << 1);
for(size_t i = 0;i < len_list; i++) {
_Src[i] = (uint16_t)pikaList_getInt(val, i);
}
modbus_data_regs2float(mode, _Dst, _Src, len_list);
PikaList* list = New_PikaList();
for(size_t i = 0; i < len_ret; i++ ) {
pikaList_append(list, arg_newFloat(_Dst[i]));
}
modbus_rt_free(_Dst);
modbus_rt_free(_Src);
return list;
#endif
}
PikaObj* _modbus_rt__data_trans__regs2double(PikaObj *self, PikaObj* val, int mode) {
#if (!MODBUS_DATA_TRANS_ENABLE)
pika_platform_printf("MODBUS_DATA_TRANS_ENABLE is not enabled.\n");
return NULL;
#else
(void)(self);
double *_Dst = NULL;
uint16_t *_Src = NULL;
size_t len_list = pikaList_getSize(val);
size_t len_ret = len_list >> 2;
if(len_list & 0x03) {
len_ret += 1;
}
_Dst = modbus_rt_calloc(1,len_ret << 3);
_Src = modbus_rt_calloc(1,len_list << 1);
for(size_t i = 0;i < len_list; i++) {
_Src[i] = (uint16_t)pikaList_getInt(val, i);
}
modbus_data_regs2double(mode, _Dst, _Src, len_list);
PikaList* list = New_PikaList();
for(size_t i = 0; i < len_ret; i++ ) {
pikaList_append(list, arg_newFloat(_Dst[i]));
}
modbus_rt_free(_Dst);
modbus_rt_free(_Src);
return list;
#endif
}
PikaObj* _modbus_rt__data_trans__bytes2regs(PikaObj *self, Arg* val, int mode) {
#if (!MODBUS_DATA_TRANS_ENABLE)
pika_platform_printf("MODBUS_DATA_TRANS_ENABLE is not enabled.\n");
return NULL;
#else
(void)(self);
ArgType t = arg_getType(val);
if (ARG_TYPE_BYTES != t) {
return NULL;
}
uint16_t *_Dst = NULL;
uint8_t* _Src = arg_getBytes(val);
size_t _Src_len = arg_getBytesSize(val);
size_t len_ret = _Src_len >> 1;
if(_Src_len & 0x01) {
len_ret += 1;
}
_Dst = modbus_rt_calloc(1,len_ret << 1);
modbus_data_bytes2regs(mode, _Dst, _Src, _Src_len);
PikaList* list = New_PikaList();
for(size_t i = 0; i < len_ret; i++ ) {
pikaList_append(list, arg_newInt(_Dst[i]));
}
modbus_rt_free(_Dst);
return list;
#endif
}
PikaObj* _modbus_rt__data_trans__str2regs(PikaObj *self, char* val, int mode) {
#if (!MODBUS_DATA_TRANS_ENABLE)
pika_platform_printf("MODBUS_DATA_TRANS_ENABLE is not enabled.\n");
return NULL;
#else
(void)(self);
uint16_t *_Dst = NULL;
char * _Src = val;
size_t _Src_len = strlen(val) + 1;
size_t len_ret = _Src_len >> 1;
if(_Src_len & 0x01) {
len_ret += 1;
}
_Dst = modbus_rt_calloc(1,len_ret << 1);
modbus_data_str2regs(mode, _Dst, _Src, _Src_len);
PikaList* list = New_PikaList();
for(size_t i = 0; i < len_ret; i++ ) {
pikaList_append(list, arg_newInt(_Dst[i]));
}
modbus_rt_free(_Dst);
return list;
#endif
}
PikaObj* _modbus_rt__data_trans__signed2regs(PikaObj *self, PikaObj* val, int mode) {
#if (!MODBUS_DATA_TRANS_ENABLE)
pika_platform_printf("MODBUS_DATA_TRANS_ENABLE is not enabled.\n");
return NULL;
#else
(void)(self);
uint16_t *_Dst = NULL;
int16_t * _Src = NULL;
size_t len_list = pikaList_getSize(val);
size_t len_ret = len_list;
_Dst = modbus_rt_calloc(1,len_ret << 1);
_Src = modbus_rt_calloc(1,len_list << 1);
for(int i = 0; i < len_list; i++ ) {
_Src[i] = (int16_t)pikaList_getInt(val, i);
}
modbus_data_signed2regs(mode, _Dst, _Src, len_list);
PikaList* list = New_PikaList();
for(int i = 0; i < len_ret; i++ ) {
pikaList_append(list, arg_newInt(_Dst[i]));
}
modbus_rt_free(_Dst);
modbus_rt_free(_Src);
return list;
#endif
}
PikaObj* _modbus_rt__data_trans__int2regs(PikaObj *self, PikaObj* val, int mode) {
#if (!MODBUS_DATA_TRANS_ENABLE)
pika_platform_printf("MODBUS_DATA_TRANS_ENABLE is not enabled.\n");
return NULL;
#else
(void)(self);
uint16_t *_Dst = NULL;
int32_t * _Src = NULL;
size_t len_list = pikaList_getSize(val);
size_t len_ret = len_list << 1;
_Dst = modbus_rt_calloc(1,len_ret << 1);
_Src = modbus_rt_calloc(1,len_list << 2);
for(int i = 0; i < len_list; i++ ) {
_Src[i] = (int32_t)pikaList_getInt(val, i);
}
modbus_data_int2regs(mode, _Dst, _Src, len_list);
PikaList* list = New_PikaList();
for(int i = 0; i < len_ret; i++ ) {
pikaList_append(list, arg_newInt(_Dst[i]));
}
modbus_rt_free(_Dst);
modbus_rt_free(_Src);
return list;
#endif
}
PikaObj* _modbus_rt__data_trans__uint2regs(PikaObj *self, PikaObj* val, int mode) {
#if (!MODBUS_DATA_TRANS_ENABLE)
pika_platform_printf("MODBUS_DATA_TRANS_ENABLE is not enabled.\n");
return NULL;
#else
(void)(self);
uint16_t *_Dst = NULL;
uint32_t * _Src = NULL;
size_t len_list = pikaList_getSize(val);
size_t len_ret = len_list << 1;
_Dst = modbus_rt_calloc(1,len_ret << 1);
_Src = modbus_rt_calloc(1,len_list << 2);
for(int i = 0; i < len_list; i++ ) {
_Src[i] = (uint32_t)pikaList_getInt(val, i);
}
modbus_data_uint2regs(mode, _Dst, _Src, len_list);
PikaList* list = New_PikaList();
for(int i = 0; i < len_ret; i++ ) {
pikaList_append(list, arg_newInt(_Dst[i]));
}
modbus_rt_free(_Dst);
modbus_rt_free(_Src);
return list;
#endif
}
PikaObj* _modbus_rt__data_trans__long2regs(PikaObj *self, PikaObj* val, int mode) {
#if (!MODBUS_DATA_TRANS_ENABLE)
pika_platform_printf("MODBUS_DATA_TRANS_ENABLE is not enabled.\n");
return NULL;
#else
(void)(self);
uint16_t *_Dst = NULL;
int64_t * _Src = NULL;
size_t len_list = pikaList_getSize(val);
size_t len_ret = len_list << 2;
_Dst = modbus_rt_calloc(1,len_ret << 1);
_Src = modbus_rt_calloc(1,len_list << 3);
for(int i = 0; i < len_list; i++ ) {
_Src[i] = (int64_t)pikaList_getInt(val, i);
}
modbus_data_long2regs(mode, _Dst, _Src, len_list);
PikaList* list = New_PikaList();
for(int i = 0; i < len_ret; i++ ) {
pikaList_append(list, arg_newInt(_Dst[i]));
}
modbus_rt_free(_Dst);
modbus_rt_free(_Src);
return list;
#endif
}
PikaObj* _modbus_rt__data_trans__float2regs(PikaObj *self, PikaObj* val, int mode) {
#if (!MODBUS_DATA_TRANS_ENABLE)
pika_platform_printf("MODBUS_DATA_TRANS_ENABLE is not enabled.\n");
return NULL;
#else
(void)(self);
uint16_t *_Dst = NULL;
float * _Src = NULL;
size_t len_list = pikaList_getSize(val);
size_t len_ret = len_list << 1;
_Dst = modbus_rt_calloc(1,len_ret << 1);
_Src = modbus_rt_calloc(1,len_list << 2);
for(int i = 0; i < len_list; i++ ) {
_Src[i] = (float)pikaList_getFloat(val, i);
}
modbus_data_float2regs(mode, _Dst, _Src, len_list);
PikaList* list = New_PikaList();
for(int i = 0; i < len_ret; i++ ) {
pikaList_append(list, arg_newInt(_Dst[i]));
}
modbus_rt_free(_Dst);
modbus_rt_free(_Src);
return list;
#endif
}
PikaObj* _modbus_rt__data_trans__double2regs(PikaObj *self, PikaObj* val, int mode) {
#if (!MODBUS_DATA_TRANS_ENABLE)
pika_platform_printf("MODBUS_DATA_TRANS_ENABLE is not enabled.\n");
return NULL;
#else
(void)(self);
uint16_t *_Dst = NULL;
double * _Src = NULL;
size_t len_list = pikaList_getSize(val);
size_t len_ret = len_list << 2;
_Dst = modbus_rt_calloc(1,len_ret << 1);
_Src = modbus_rt_calloc(1,len_list << 3);
for(int i = 0; i < len_list; i++ ) {
_Src[i] = (double)pikaList_getFloat(val, i);
}
modbus_data_double2regs(mode, _Dst, _Src, len_list);
PikaList* list = New_PikaList();
for(int i = 0; i < len_ret; i++ ) {
pikaList_append(list, arg_newInt(_Dst[i]));
}
modbus_rt_free(_Dst);
modbus_rt_free(_Src);
return list;
#endif
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,974 @@
/**
* @file _modbus_rt.c
* @brief modbus_rt的pika层的API实现
* @author SenySunny (senysunny@163.com)
* @date 2023-05-14
*
* @attention
*
* <h2><center>&copy; Copyright (c) 2022 Ma Longwei.
* All rights reserved.</center></h2>
*
*/
#include "PikaObj.h"
#include "PikaStdData_List.h"
#include "TinyObj.h"
#include "_modbus_rt__tcp.h"
#include "modbus_tcp.h"
#if MODBUS_P2P_ENABLE
#include "modbus_p2p.h"
#endif
void _modbus_rt__tcp___del__(PikaObj *self) {
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
return 0;
#else
int ret = 0;
tcp_modbus_device_t dev = (tcp_modbus_device_t)obj_getPtr(self, "dev");
if(NULL == dev) {
pika_platform_printf("modbus_tcp_del error, dev is NULL.\n");
return ;
}
ret = modbus_tcp_destroy(&dev);
if(MODBUS_RT_EOK != ret){
pika_platform_printf("modbus_tcp_destroy error, code:%d.\n", ret);
return ;
}
obj_setPtr(self, "dev", NULL);
#endif
}
void _modbus_rt__tcp__init(PikaObj *self, int mode) {
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
#else
tcp_modbus_device_t dev = modbus_tcp((modbus_mode_type)mode);
if(NULL == dev) {
pika_platform_printf("modbus_tcp create error.\n");
}
obj_setInt(self, "mode", mode);
obj_setPtr(self, "dev", dev);
#endif
}
int _modbus_rt__tcp__set_net(PikaObj *self, char* ip, int port, int type) {
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
return 0;
#else
int ret = 0;
tcp_modbus_device_t dev = (tcp_modbus_device_t)obj_getPtr(self, "dev");
if(NULL == dev) {
pika_platform_printf("modbus_tcp_set_net error, dev is NULL.\n");
return 0;
}
if(0 != dev->status) {
pika_platform_printf("modbus_tcp_set_net error, dev is opened.\n");
return 0;
}
if(0 == strlen(ip)) {
ip = NULL;
}
ret = modbus_tcp_set_net(dev, ip, port, type);
if(MODBUS_RT_EOK != ret){
pika_platform_printf("modbus_tcp_set_net error, code:%d.\n", ret);
return 0;
}
return 1;
#endif
}
int _modbus_rt__tcp__set_ip(PikaObj *self, char* ip) {
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
return 0;
#else
int ret = 0;
tcp_modbus_device_t dev = (tcp_modbus_device_t)obj_getPtr(self, "dev");
if(NULL == dev) {
pika_platform_printf("modbus_tcp_set_ip error, dev is NULL.\n");
return 0;
}
if(0 != dev->status) {
pika_platform_printf("modbus_tcp_set_ip error, dev is opened.\n");
return 0;
}
if(0 == strlen(ip)) {
ip = NULL;
}
ret = modbus_tcp_set_ip(dev, ip);
if(MODBUS_RT_EOK != ret){
pika_platform_printf("modbus_tcp_set_ip error, code:%d.\n", ret);
return 0;
}
return 1;
#endif
}
int _modbus_rt__tcp__set_port(PikaObj *self, int port) {
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
return 0;
#else
int ret = 0;
tcp_modbus_device_t dev = (tcp_modbus_device_t)obj_getPtr(self, "dev");
if(NULL == dev) {
pika_platform_printf("modbus_tcp_set_port error, dev is NULL.\n");
return 0;
}
if(0 != dev->status) {
pika_platform_printf("modbus_tcp_set_port error, dev is opened.\n");
return 0;
}
ret = modbus_tcp_set_port(dev, port);
if(MODBUS_RT_EOK != ret){
pika_platform_printf("modbus_tcp_set_port error, code:%d.\n", ret);
return 0;
}
return 1;
#endif
}
int _modbus_rt__tcp__set_type(PikaObj *self, int type) {
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
return 0;
#else
int ret = 0;
tcp_modbus_device_t dev = (tcp_modbus_device_t)obj_getPtr(self, "dev");
if(NULL == dev) {
pika_platform_printf("modbus_tcp_set_type error, dev is NULL.\n");
return 0;
}
if(0 != dev->status) {
pika_platform_printf("modbus_tcp_set_type error, dev is opened.\n");
return 0;
}
ret = modbus_tcp_set_type(dev, type);
if(MODBUS_RT_EOK != ret){
pika_platform_printf("modbus_tcp_set_type error, code:%d.\n", ret);
return 0;
}
return 1;
#endif
}
int _modbus_rt__tcp__set_p2p(PikaObj *self, int p2p_flag) {
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
return 0;
#elif (!MODBUS_P2P_ENABLE)
pika_platform_printf("MODBUS_P2P_ENABLE is not enabled.\n");
return 0;
#else
int ret = 0;
tcp_modbus_device_t dev = (tcp_modbus_device_t)obj_getPtr(self, "dev");
if(NULL == dev) {
pika_platform_printf("modbus_tcp_set_p2p error, dev is NULL.\n");
return 0;
}
if(0 != dev->status) {
pika_platform_printf("modbus_tcp_set_p2p error, dev is opened.\n");
return 0;
}
ret = modbus_tcp_set_p2p_flag(dev, p2p_flag);
if(MODBUS_RT_EOK != ret){
pika_platform_printf("modbus_tcp_set_p2p error, code:%d.\n", ret);
return 0;
}
return 1;
#endif
}
int _modbus_rt__tcp__open(PikaObj *self) {
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
return 0;
#else
int ret = 0;
tcp_modbus_device_t dev = (tcp_modbus_device_t)obj_getPtr(self, "dev");
if(NULL == dev) {
pika_platform_printf("modbus_tcp_open error, dev is NULL.\n");
return 0;
}
if(0 != dev->status) {
pika_platform_printf("modbus_tcp_open error, dev is opened.\n");
return 0;
}
ret = modbus_tcp_open(dev);
if(MODBUS_RT_EOK != ret){
pika_platform_printf("modbus_tcp_open error, code: %d.\n", ret);
return 0;
}
return 1;
#endif
}
int _modbus_rt__tcp__isopen(PikaObj *self) {
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
return 0;
#else
tcp_modbus_device_t dev = (tcp_modbus_device_t)obj_getPtr(self, "dev");
if(NULL == dev) {
pika_platform_printf("modbus_tcp_isopen error, dev is NULL.\n");
return 0;
}
return modbus_tcp_isopen(dev);
#endif
}
int _modbus_rt__tcp__close(PikaObj *self) {
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
return 0;
#else
int ret = 0;
tcp_modbus_device_t dev = (tcp_modbus_device_t)obj_getPtr(self, "dev");
if(NULL == dev) {
pika_platform_printf("modbus_tcp_close error, dev is NULL.\n");
return 0;
}
if(0 == dev->status) {
pika_platform_printf("modbus_tcp_close error, dev is closed.\n");
return 0;
}
ret = modbus_tcp_close(dev);
if(MODBUS_RT_EOK != ret){
pika_platform_printf("modbus_tcp_close error, code: %d.\n", ret);
return 0;
}
return 1;
#endif
}
int _modbus_rt__tcp__slave_set_addr(PikaObj *self, int addr) {
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
return 0;
#else
int ret = 0;
tcp_modbus_device_t dev = (tcp_modbus_device_t)obj_getPtr(self, "dev");
if(NULL == dev) {
pika_platform_printf("modbus_tcp_set_addr error, dev is NULL.\n");
return 0;
}
if(MODBUS_SLAVE != dev->mode){
pika_platform_printf("modbus_tcp_set_addr is only for slave.\n");
return 0;
}
if(0 != dev->status) {
pika_platform_printf("modbus_tcp_set_addr error, dev is opened.\n");
return 0;
}
ret = modbus_tcp_set_addr(dev,addr);
if(MODBUS_RT_EOK != ret){
pika_platform_printf("modbus_tcp_set_addr error, code: %d.\n", ret);
return 0;
}
return 1;
#endif
}
int _modbus_rt__tcp__slave_set_strict(PikaObj *self, int strict) {
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
return 0;
#else
int ret = 0;
tcp_modbus_device_t dev = (tcp_modbus_device_t)obj_getPtr(self, "dev");
if(NULL == dev) {
pika_platform_printf("modbus_tcp_set_strict error, dev is NULL.\n");
return 0;
}
if(MODBUS_SLAVE != dev->mode){
pika_platform_printf("modbus_tcp_set_strict is only for slave.\n");
return 0;
}
if(0 != dev->status) {
pika_platform_printf("modbus_tcp_set_strict error, dev is opened.\n");
return 0;
}
ret = modbus_tcp_set_strict(dev,strict);
if(MODBUS_RT_EOK != ret){
pika_platform_printf("modbus_tcp_set_strict error, code: %d.\n", ret);
return 0;
}
return 1;
#endif
}
int _modbus_rt__tcp__slave_add_block(PikaObj *self, char* name, int type, int addr, int nums) {
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
return 0;
#else
int ret = 0;
tcp_modbus_device_t dev = (tcp_modbus_device_t)obj_getPtr(self, "dev");
if(NULL == dev) {
pika_platform_printf("modbus_tcp_add_block error, dev is NULL.\n");
return 0;
}
if(MODBUS_SLAVE != dev->mode){
pika_platform_printf("modbus_tcp_add_block is only for slave.\n");
return 0;
}
if(0 != dev->status) {
pika_platform_printf("modbus_tcp_add_block error, dev is opened.\n");
return 0;
}
if((0 >= strlen(name)) || (0 > type) || (4 < type)){
pika_platform_printf("modbus_tcp_add_block: the para is error.\n");
return 0;
}
int len = 0;
if((CIOLS == type) || (INPUTS == type)) {
len = nums;
} else if((INPUT_REGISTERS == type) || (REGISTERS == type)) {
len = nums * 2;
}
obj_setBytes(self, name, NULL, len);
uint8_t* block = obj_getBytes(self, name);
ret = modbus_tcp_add_block(dev,type, addr, block, nums);
if(MODBUS_RT_EOK != ret){
pika_platform_printf("modbus_tcp_add_block error, code: %d.\n", ret);
return 0;
}
return 1;
#endif
}
#if (MODBUS_TCP_SLAVE_ENABLE) || (MODBUS_TCP_MASTER_ENABLE)
PikaEventListener* g_modbus_rt_tcp_event_listener = NULL;
#endif
int _modbus_rt__tcp__slave_pre_ans_handler(agile_modbus_t *ctx, int slave, int function,int addr, int quantity) {
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
return 0;
#else
char hash_str[32] = {0};
memset(hash_str, 0, sizeof(hash_str));
sprintf(hash_str, "pre_ans%p", ctx);
uint32_t eventId = hash_time33(hash_str);
Arg* evt_obj_arg = arg_newDirectObj(New_TinyObj);
PikaObj* evt_obj = arg_getPtr(evt_obj_arg);
obj_setInt(evt_obj, "slave", slave);
obj_setInt(evt_obj, "function", function);
obj_setInt(evt_obj, "addr", addr);
obj_setInt(evt_obj, "quantity", quantity);
pika_eventListener_send(g_modbus_rt_tcp_event_listener, eventId, evt_obj_arg);
return 1;
#endif
}
int _modbus_rt__tcp__slave_set_pre_ans_callback(PikaObj *self, Arg* cb) {
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
return 0;
#else
int ret = 0;
tcp_modbus_device_t dev = (tcp_modbus_device_t)obj_getPtr(self, "dev");
if(NULL == dev) {
pika_platform_printf("modbus_tcp_set_pre_ans_callback error, dev is NULL.\n");
return 0;
}
if(MODBUS_SLAVE != dev->mode){
pika_platform_printf("modbus_tcp_set_pre_ans_callback is only for slave.\n");
return 0;
}
if(0 != dev->status) {
pika_platform_printf("modbus_tcp_set_pre_ans_callback error, dev is opened.\n");
return 0;
}
if(NULL == cb) {
pika_platform_printf("modbus_tcp_set_pre_ans_callback error, cb is NULL.\n");
return 0;
}
ret = modbus_tcp_set_pre_ans_callback(dev,_modbus_rt__tcp__slave_pre_ans_handler);
if(MODBUS_RT_EOK != ret){
pika_platform_printf("modbus_rtu_set_pre_ans_callback error, code: %d.\n", ret);
return 0;
}
if (NULL == g_modbus_rt_tcp_event_listener) {
pika_eventListener_init(&g_modbus_rt_tcp_event_listener);
}
char hash_str[32] = {0};
memset(hash_str, 0, sizeof(hash_str));
sprintf(hash_str, "pre_ans%p", dev->ctx);
uint32_t eventId = hash_time33(hash_str);
pika_eventListener_registEventCallback(g_modbus_rt_tcp_event_listener, eventId, cb);
return 1;
#endif
}
int _modbus_rt__tcp__slave_done_handler(agile_modbus_t *ctx, int slave, int function,int addr, int quantity) {
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
return 0;
#else
char hash_str[32] = {0};
memset(hash_str, 0, sizeof(hash_str));
sprintf(hash_str, "done%p", ctx);
uint32_t eventId = hash_time33(hash_str);
Arg* evt_obj_arg = arg_newDirectObj(New_TinyObj);
PikaObj* evt_obj = arg_getPtr(evt_obj_arg);
obj_setInt(evt_obj, "slave", slave);
obj_setInt(evt_obj, "function", function);
obj_setInt(evt_obj, "addr", addr);
obj_setInt(evt_obj, "quantity", quantity);
pika_eventListener_send(g_modbus_rt_tcp_event_listener, eventId, evt_obj_arg);
return 1;
#endif
}
int _modbus_rt__tcp__slave_set_done_callback(PikaObj *self, Arg* cb) {
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
return 0;
#else
int ret = 0;
tcp_modbus_device_t dev = (tcp_modbus_device_t)obj_getPtr(self, "dev");
if(NULL == dev) {
pika_platform_printf("modbus_tcp_set_done_callback error, dev is NULL.\n");
return 0;
}
if(MODBUS_SLAVE != dev->mode){
pika_platform_printf("modbus_tcp_set_done_callback is only for slave.\n");
return 0;
}
if(0 != dev->status) {
pika_platform_printf("modbus_tcp_set_done_callback error, dev is opened.\n");
return 0;
}
if(NULL == cb) {
pika_platform_printf("modbus_tcp_set_done_callback error, cb is NULL.\n");
return 0;
}
ret = modbus_tcp_set_done_callback(dev,_modbus_rt__tcp__slave_done_handler);
if(MODBUS_RT_EOK != ret){
pika_platform_printf("modbus_tcp_set_done_callback error, code: %d.\n", ret);
return 0;
}
if (NULL == g_modbus_rt_tcp_event_listener) {
pika_eventListener_init(&g_modbus_rt_tcp_event_listener);
}
char hash_str[32] = {0};
memset(hash_str, 0, sizeof(hash_str));
sprintf(hash_str, "done%p", dev->ctx);
uint32_t eventId = hash_time33(hash_str);
pika_eventListener_registEventCallback(g_modbus_rt_tcp_event_listener, eventId, cb);
return 1;
#endif
}
int _modbus_rt__tcp__slave_set_dev_binding(PikaObj *self, int flag) {
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
return 0;
#elif (!SLAVE_DATA_DEVICE_BINDING)
pika_platform_printf("SLAVE_DATA_DEVICE_BINDING is not activated.\n");
return 0;
#else
int ret = 0;
tcp_modbus_device_t dev = (tcp_modbus_device_t)obj_getPtr(self, "dev");
if(NULL == dev) {
pika_platform_printf("modbus_tcp_set_dev_binding error, dev is NULL.\n");
return 0;
}
if(MODBUS_SLAVE != dev->mode){
pika_platform_printf("modbus_tcp_set_dev_binding is only for slave.\n");
return 0;
}
if(0 != dev->status) {
pika_platform_printf("modbus_tcp_set_dev_binding error, dev is opened.\n");
return 0;
}
ret = modbus_tcp_set_dev_binding(dev,flag);
if(MODBUS_RT_EOK != ret){
pika_platform_printf("modbus_tcp_set_dev_binding error, code: %d.\n", ret);
return 0;
}
return 1;
#endif
}
int _modbus_rt__tcp__master_set_server(PikaObj *self, char* saddr, int sport) {
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
return 0;
#else
int ret = 0;
tcp_modbus_device_t dev = (tcp_modbus_device_t)obj_getPtr(self, "dev");
if(NULL == dev) {
pika_platform_printf("modbus_tcp_set_server error, dev is NULL.\n");
return 0;
}
if(MODBUS_MASTER != dev->mode){
pika_platform_printf("modbus_tcp_set_server is only for master.\n");
return 0;
}
ret = modbus_tcp_set_server(dev, saddr, sport);
if(MODBUS_RT_EOK != ret){
pika_platform_printf("modbus_tcp_set_server error, code: %d.\n", ret);
return 0;
}
return 1;
#endif
}
char* _modbus_rt__tcp__master_get_saddr(PikaObj *self) {
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
return NULL;
#else
int ret = 0;
tcp_modbus_device_t dev = (tcp_modbus_device_t)obj_getPtr(self, "dev");
if(NULL == dev) {
pika_platform_printf("modbus_tcp_get_saddr error, dev is NULL.\n");
return NULL;
}
if((MODBUS_MASTER != dev->mode)){
pika_platform_printf("modbus_tcp_get_saddr is only for master.\n");
return NULL;
}
char saddr[INET_ADDRSTRLEN];
ret = modbus_tcp_get_saddr(dev, saddr);
if(MODBUS_RT_EOK != ret){
pika_platform_printf("modbus_tcp_get_saddr error, code: %d.\n", ret);
return NULL;
}
char* str = obj_cacheStr(self, saddr);
return str;
#endif
}
PikaObj* _modbus_rt__tcp__slave_read_regs(PikaObj *self, int type, int addr, PikaTuple* val){
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
return NULL;
#else
int ret = 0;
tcp_modbus_device_t dev = (tcp_modbus_device_t)obj_getPtr(self, "dev");
if(NULL == dev) {
pika_platform_printf("modbus_tcp_read_regs error, dev is NULL.\n");
return NULL;
}
if(MODBUS_SLAVE != dev->mode){
pika_platform_printf("modbus_tcp_read_regs is only for slave.\n");
return NULL;
}
if(0 == dev->status) {
pika_platform_printf("modbus_tcp_read_regs error, dev is not opened.\n");
return 0;
}
uint8_t *dest = NULL;
/* 确保参数正确,且值无误*/
if(1 != pikaTuple_getSize(val)) {
pika_platform_printf("modbus_tcp_read_regs: the para num of func is error.\n");
return NULL;
}
Arg* arg_0 = pikaTuple_getArg(val, 0);
ArgType t = arg_getType(arg_0);
if (ARG_TYPE_INT != t) {
pika_platform_printf("modbus_tcp_read_regs: the para type of func is error.\n");
return NULL;
}
int quantity = arg_getInt(arg_0);
if(0 >= quantity) {
pika_platform_printf("modbus_tcp_read_regs: quantity can not be zero or negative.\n");
return NULL;
}
if((CIOLS == type) || (INPUTS == type)) {
dest = modbus_rt_calloc(1,quantity);
if(dest == NULL) {
pika_platform_printf("modbus_tcp_read_regs: mem is not enough.\n");
return NULL;
}
} else if((INPUT_REGISTERS == type) || (REGISTERS == type)) {
dest = modbus_rt_calloc(1,quantity * 2);
if(dest == NULL) {
pika_platform_printf("modbus_tcp_read_regs: mem is not enough.\n");
return NULL;
}
}
ret = modbus_tcp_excuse(dev, MODBUS_READ, type, addr, quantity, dest);
if(MODBUS_RT_EOK != ret) {
modbus_rt_free(dest);
pika_platform_printf("modbus_tcp_read_regs: modbus_tcp_excuse error, code: %d.\n", ret);
return NULL;
}
uint16_t *dest_r = (uint16_t *)dest;
PikaList* list = New_PikaList();
for(int i = 0; i < quantity; i++ ) {
if((CIOLS == type) || (INPUTS == type)) {
pikaList_append(list, arg_newInt(dest[i]));
} else if((INPUT_REGISTERS == type) || (REGISTERS == type)) {
pikaList_append(list, arg_newInt(dest_r[i]));
}
}
modbus_rt_free(dest);
return list;
#endif
}
int _modbus_rt__tcp__slave_write_regs(PikaObj *self, int type, int addr, PikaTuple* val) {
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
return 0;
#else
int ret = 0;
tcp_modbus_device_t dev = (tcp_modbus_device_t)obj_getPtr(self, "dev");
if(NULL == dev) {
pika_platform_printf("modbus_tcp_write_regs error, dev is NULL.\n");
return 0;
}
if(MODBUS_SLAVE != dev->mode){
pika_platform_printf("modbus_tcp_write_regs is only for master.\n");
return 0;
}
if(0 == dev->status) {
pika_platform_printf("modbus_tcp_write_regs error, dev is not opened.\n");
return 0;
}
uint8_t *dest = NULL;
/* 确保参数正确,且值无误*/
if(2 != pikaTuple_getSize(val)) {
pika_platform_printf("modbus_tcp_write_regs: the para num of func is error.\n");
return 0;
}
Arg* arg_0 = pikaTuple_getArg(val, 0);
ArgType t = arg_getType(arg_0);
if (ARG_TYPE_INT != t) {
pika_platform_printf("modbus_tcp_write_regs: the para0 type of func is error.\n");
return 0;
}
int quantity = arg_getInt(arg_0);
if((CIOLS == type) || (INPUTS == type)) {
dest = modbus_rt_calloc(1,quantity);
if(dest == NULL) {
pika_platform_printf("modbus_tcp_write_regs: mem is not enough.\n");
return 0;
}
memset(dest,0,quantity);
} else if((INPUT_REGISTERS == type) || (REGISTERS == type)) {
dest = modbus_rt_calloc(1,quantity * 2);
if(dest == NULL) {
pika_platform_printf("modbus_tcp_write_regs: mem is not enough.\n");
return 0;
}
memset(dest,0,quantity * 2);
}
Arg* arg_1 = pikaTuple_getArg(val, 1);
t = arg_getType(arg_1);
if (ARG_TYPE_OBJECT != t) {
pika_platform_printf("modbus_tcp_write_regs: the para1 type of func is error.\n");
return 0;
}
PikaObj* _list = arg_getPtr(arg_1);
int len_list = pikaList_getSize(_list);
if(len_list > quantity) {
len_list = quantity;
}
if((CIOLS == type) || (INPUTS == type)) {
for(int i = 0; i < len_list; i++) {
dest[i] = pikaList_getInt(_list, i);
}
ret = modbus_tcp_excuse(dev, MODBUS_WRITE, type, addr, quantity, dest);
if(MODBUS_RT_EOK != ret) {
modbus_rt_free(dest);
pika_platform_printf("modbus_tcp_write_regs: modbus_tcp_excuse error, code: %d.\n", ret);
return 0;
}
} else if((INPUT_REGISTERS == type) || (REGISTERS == type)) {
uint16_t *dest_r = (uint16_t *)dest;
for(int i = 0; i < len_list; i++){
dest_r[i] = pikaList_getInt(_list, i);
}
ret = modbus_tcp_excuse(dev, MODBUS_WRITE, type, addr, quantity, dest_r);
if(MODBUS_RT_EOK != ret) {
modbus_rt_free(dest);
pika_platform_printf("modbus_tcp_write_regs: modbus_tcp_excuse error, code: %d.\n", ret);
return 0;
}
}
modbus_rt_free(dest);
return 1;
#endif
}
PikaObj* _modbus_rt__tcp__master_read_list(PikaObj *self, int slave, int fuction, int addr, PikaTuple* val) {
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
return NULL;
#else
int ret = 0;
tcp_modbus_device_t dev = (tcp_modbus_device_t)obj_getPtr(self, "dev");
if(NULL == dev) {
pika_platform_printf("modbus_tcp_read_list error, dev is NULL.\n");
return NULL;
}
if(MODBUS_MASTER != dev->mode){
pika_platform_printf("modbus_tcp_read_list is only for master.\n");
return NULL;
}
if(0 == dev->status) {
pika_platform_printf("modbus_tcp_read_list error, dev is not opened.\n");
return 0;
}
uint8_t *dest = NULL;
/* 确保参数正确,且值无误*/
if(1 != pikaTuple_getSize(val)) {
pika_platform_printf("modbus_tcp_read_list: the para num of func is error.\n");
return NULL;
}
Arg* arg_0 = pikaTuple_getArg(val, 0);
ArgType t = arg_getType(arg_0);
if (ARG_TYPE_INT != t) {
pika_platform_printf("modbus_tcp_read_list: the para type of func is error.\n");
return NULL;
}
int quantity = arg_getInt(arg_0);
if(0 >= quantity) {
pika_platform_printf("modbus_tcp_read_list: quantity can not be zero or negative.\n");
return NULL;
}
if((AGILE_MODBUS_FC_READ_COILS == fuction) ||(AGILE_MODBUS_FC_READ_DISCRETE_INPUTS == fuction)) {
dest = modbus_rt_calloc(1,quantity);
if(dest == NULL) {
pika_platform_printf("modbus_tcp_read_list: mem is not enough.\n");
return NULL;
}
} else if((AGILE_MODBUS_FC_READ_HOLDING_REGISTERS == fuction) ||(AGILE_MODBUS_FC_READ_INPUT_REGISTERS == fuction)) {
dest = modbus_rt_calloc(1,quantity * 2);
if(dest == NULL) {
pika_platform_printf("modbus_tcp_read_list: mem is not enough.\n");
return NULL;
}
}
ret = modbus_tcp_excuse(dev, slave, fuction, addr, quantity, dest);
if(MODBUS_RT_EOK != ret) {
modbus_rt_free(dest);
pika_platform_printf("modbus_tcp_read_list: modbus_tcp_excuse error, code: %d.\n", ret);
return NULL;
}
uint16_t *dest_r = (uint16_t *)dest;
PikaList* list = New_PikaList();
for(int i = 0; i < quantity; i++ ) {
if((AGILE_MODBUS_FC_READ_COILS == fuction) ||(AGILE_MODBUS_FC_READ_DISCRETE_INPUTS == fuction)) {
pikaList_append(list, arg_newInt(dest[i]));
} else if((AGILE_MODBUS_FC_READ_HOLDING_REGISTERS == fuction) ||(AGILE_MODBUS_FC_READ_INPUT_REGISTERS == fuction)) {
pikaList_append(list, arg_newInt(dest_r[i]));
}
}
modbus_rt_free(dest);
return list;
#endif
}
int _modbus_rt__tcp__master_write_int(PikaObj *self, int slave, int fuction, int addr, PikaTuple* val) {
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
return 0;
#else
int ret = 0;
tcp_modbus_device_t dev = (tcp_modbus_device_t)obj_getPtr(self, "dev");
if(NULL == dev) {
pika_platform_printf("modbus_tcp_write_int error, dev is NULL.\n");
return 0;
}
if(MODBUS_MASTER != dev->mode){
pika_platform_printf("modbus_tcp_write_int is only for master.\n");
return 0;
}
if(0 == dev->status) {
pika_platform_printf("modbus_tcp_write_int error, dev is not opened.\n");
return 0;
}
/* 确保参数正确,且值无误*/
if(1 != pikaTuple_getSize(val)) {
pika_platform_printf("modbus_tcp_write_int: the para num of func is error.\n");
return 0;
}
Arg* arg_0 = pikaTuple_getArg(val, 0);
ArgType t = arg_getType(arg_0);
if (ARG_TYPE_INT != t) {
pika_platform_printf("modbus_tcp_write_int: the para type of func is error.\n");
return 0;
}
int value = arg_getInt(arg_0);
ret = modbus_tcp_excuse(dev, slave, fuction, addr, 1, &value);
if(MODBUS_RT_EOK != ret) {
pika_platform_printf("modbus_tcp_write_int: modbus_tcp_excuse error, code: %d.\n", ret);
return 0;
}
return 1;
#endif
}
int _modbus_rt__tcp__master_write_list(PikaObj *self, int slave, int fuction, int addr, PikaTuple* val) {
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
return 0;
#else
int ret = 0;
tcp_modbus_device_t dev = (tcp_modbus_device_t)obj_getPtr(self, "dev");
if(NULL == dev) {
pika_platform_printf("modbus_tcp_write_int error, dev is NULL.\n");
return 0;
}
if(MODBUS_MASTER != dev->mode){
pika_platform_printf("modbus_tcp_write_int is only for master.\n");
return 0;
}
if(0 == dev->status) {
pika_platform_printf("modbus_tcp_write_int error, dev is not opened.\n");
return 0;
}
uint8_t *dest = NULL;
/* 确保参数正确,且值无误*/
if(2 != pikaTuple_getSize(val)) {
pika_platform_printf("modbus_tcp_write_int: the para num of func is error.\n");
return 0;
}
Arg* arg_0 = pikaTuple_getArg(val, 0);
ArgType t = arg_getType(arg_0);
if (ARG_TYPE_INT != t) {
pika_platform_printf("modbus_tcp_write_int: the para0 type of func is error.\n");
return 0;
}
int quantity = arg_getInt(arg_0);
if(fuction == AGILE_MODBUS_FC_WRITE_MULTIPLE_COILS) {
dest = modbus_rt_calloc(1,quantity);
if(dest == NULL) {
pika_platform_printf("modbus_tcp_write_int: mem is not enough.\n");
return 0;
}
memset(dest,0,quantity);
} else if(fuction == AGILE_MODBUS_FC_WRITE_MULTIPLE_REGISTERS) {
dest = modbus_rt_calloc(1,quantity * 2);
if(dest == NULL) {
pika_platform_printf("modbus_tcp_write_int: mem is not enough.\n");
return 0;
}
memset(dest,0,quantity * 2);
}
Arg* arg_1 = pikaTuple_getArg(val, 1);
t = arg_getType(arg_1);
if (ARG_TYPE_OBJECT != t) {
pika_platform_printf("modbus_tcp_write_int: the para1 type of func is error.\n");
return 0;
}
PikaObj* _list = arg_getPtr(arg_1);
int len_list = pikaList_getSize(_list);
if(len_list > quantity) {
len_list = quantity;
}
if(fuction == AGILE_MODBUS_FC_WRITE_MULTIPLE_COILS) {
for(int i = 0; i < len_list; i++) {
dest[i] = pikaList_getInt(_list, i);
}
ret = modbus_tcp_excuse(dev, slave, fuction, addr, quantity, dest);
if(MODBUS_RT_EOK != ret) {
modbus_rt_free(dest);
pika_platform_printf("modbus_tcp_write_int: modbus_tcp_excuse error, code: %d.\n", ret);
return 0;
}
} else if(fuction == AGILE_MODBUS_FC_WRITE_MULTIPLE_REGISTERS) {
uint16_t *dest_r = (uint16_t *)dest;
for(int i = 0; i < len_list; i++){
dest_r[i] = pikaList_getInt(_list, i);
}
ret = modbus_tcp_excuse(dev, slave, fuction, addr, quantity, dest_r);
if(MODBUS_RT_EOK != ret) {
modbus_rt_free(dest);
pika_platform_printf("modbus_tcp_write_int: modbus_tcp_excuse error, code: %d.\n", ret);
return 0;
}
}
modbus_rt_free(dest);
return 1;
#endif
}
int _modbus_rt__tcp__master_download(PikaObj *self, int slave, char* file_dev, char* file_master) {
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
return 0;
#elif (!MODBUS_P2P_ENABLE) || (!MODBUS_P2P_MASTER_ENABLE)
pika_platform_printf("MODBUS_P2P_ENABLE and MODBUS_P2P_MASTER_ENABLE is not enabled.\n");
return 0;
#else
int ret = 0;
tcp_modbus_device_t dev = (tcp_modbus_device_t)obj_getPtr(self, "dev");
if(NULL == dev) {
pika_platform_printf("modbus_tcp_download error, dev is NULL.\n");
return 0;
}
if(MODBUS_MASTER != dev->mode){
pika_platform_printf("modbus_tcp_download is only for master.\n");
return 0;
}
if(0 == dev->status) {
pika_platform_printf("modbus_tcp_download error, dev is not opened.\n");
return 0;
}
if(0 == dev->p2p_flag) {
pika_platform_printf("modbus_tcp_download error, p2p_flag is not seted.\n");
return 0;
}
ret = modbus_tcp_excuse_file(dev, slave, MODBUS_WRITE, file_dev, file_master);
if(MODBUS_RT_EOK != ret) {
pika_platform_printf("modbus_tcp_download error, code: %d.\n", ret);
return 0;
}
return 1;
#endif
}
int _modbus_rt__tcp__master_upload(PikaObj *self, int slave, char* file_dev, char* file_master) {
#if (!MODBUS_TCP_SLAVE_ENABLE) && (!MODBUS_TCP_MASTER_ENABLE)
pika_platform_printf("modbus tcp is not activated.\n");
return 0;
#elif (!MODBUS_P2P_ENABLE) || (!MODBUS_P2P_MASTER_ENABLE)
pika_platform_printf("MODBUS_P2P_ENABLE and MODBUS_P2P_MASTER_ENABLE is not enabled.\n");
return 0;
#else
int ret = 0;
tcp_modbus_device_t dev = (tcp_modbus_device_t)obj_getPtr(self, "dev");
if(NULL == dev) {
pika_platform_printf("modbus_tcp_upload error, dev is NULL.\n");
return 0;
}
if(MODBUS_MASTER != dev->mode){
pika_platform_printf("modbus_tcp_upload is only for master.\n");
return 0;
}
if(0 == dev->status) {
pika_platform_printf("modbus_tcp_upload error, dev is not opened.\n");
return 0;
}
if(0 == dev->p2p_flag) {
pika_platform_printf("modbus_tcp_upload error, p2p_flag is not seted.\n");
return 0;
}
ret = modbus_tcp_excuse_file(dev, slave, MODBUS_READ, file_dev, file_master);
if(MODBUS_RT_EOK != ret) {
pika_platform_printf("modbus_tcp_upload error, code: %d.\n", ret);
return 0;
}
return 1;
#endif
}

View File

@ -0,0 +1,196 @@
import _modbus_rt
import modbus_rt_defines as cst
LITTLE_ENDIAL_SWAP = 0
BIG_ENDIAL_SWAP = 1
LITTLE_ENDIAL = 2
BIG_ENDIAL = 3
SLAVE = 0
MASTER = 1
SOCK_STREAM = 1
SOCK_DGRAM = 2
class data_trans(_modbus_rt._data_trans):
def reg2reg(self, val: int):
return self._reg2reg(val)
def regs2regs(self, val: list):
return self._regs2regs(val)
def regs2bytes(self, val: list, mode = LITTLE_ENDIAL_SWAP):
if type(val) != list:
print("para only for type list")
return
return self._regs2bytes(val, mode)
def regs2str(self, val: list, mode = LITTLE_ENDIAL_SWAP):
return self._regs2str(val, mode)
def regs2signed(self, val: list, mode = LITTLE_ENDIAL_SWAP):
return self._regs2signed(val, mode)
def regs2int(self, val: list, mode = LITTLE_ENDIAL_SWAP):
return self._regs2uint(val, mode)
def regs2uint(self, val: list, mode = LITTLE_ENDIAL_SWAP):
return self._regs2int(val, mode)
def regs2long(self, val: list, mode = LITTLE_ENDIAL_SWAP):
return self._regs2long(val, mode)
def regs2float(self, val: list, mode = LITTLE_ENDIAL_SWAP):
return self._regs2float(val, mode)
def regs2double(self, val: list, mode = LITTLE_ENDIAL_SWAP):
return self._regs2double(val, mode)
def bytes2regs(self, val: any, mode = LITTLE_ENDIAL_SWAP):
return self._bytes2regs(val, mode)
def str2regs(self, val: str, mode = LITTLE_ENDIAL_SWAP):
return self._str2regs(val, mode)
def signed2regs(self, val: list, mode = LITTLE_ENDIAL_SWAP):
return self._signed2regs(val, mode)
def int2regs(self, val: list, mode = LITTLE_ENDIAL_SWAP):
return self._int2regs(val, mode)
def uint2regs(self, val: list, mode = LITTLE_ENDIAL_SWAP):
return self._uint2regs(val, mode)
def long2regs(self, val: list, mode = LITTLE_ENDIAL_SWAP):
return self._long2regs(val, mode)
def float2regs(self, val: list, mode = LITTLE_ENDIAL_SWAP):
return self._float2regs(val, mode)
def double2regs(self, val: list, mode = LITTLE_ENDIAL_SWAP):
return self._double2regs(val, mode)
class rtu(_modbus_rt._rtu):
mode = SLAVE
ascii_flag = 0
def __init__(self, mode = SLAVE):
return self._init(mode)
def set_serial(self, devname: str, baudrate = 115200, bytesize = 8, parity = 'N', stopbits = 1, xonxoff = 0):
return self._set_serial(devname, baudrate, bytesize, parity, stopbits, xonxoff)
def set_over_type(self, over_type: int):
return self._set_over_type(over_type)
def set_net(self, ip = '', port = 502, type = SOCK_STREAM):
return self._set_net(ip, port, type)
def set_ip(self, ip: str):
return self._set_ip(ip)
def set_port(self, port: int):
return self._set_port(port)
def set_type(self, type: int):
return self._set_type(type)
def set_p2p(self, p2p_flag: int):
return self._set_p2p(p2p_flag)
def open(self):
return self._open()
def isopen(self):
return self._isopen()
def close(self):
return self._close()
# 该函数仅对从机有效
def set_addr(self, addr: int):
return self._slave_set_addr(addr)
# 该函数仅对从机有效
def set_strict(self, strict: int):
return self._slave_set_strict(strict)
# 该函数仅对从机有效
def add_block(self, name: str, type: int, addr: int, nums: int):
return self._slave_add_block(name, type, addr, nums)
def set_pre_ans_callback(self, cb):
return self._slave_set_pre_ans_callback(cb)
def set_done_callback(self, cb):
return self._slave_set_done_callback(cb)
def set_dev_binding(self, flag: int):
return self._slave_set_dev_binding(flag)
# 该函数仅对主机有效
def set_server(self, saddr: str,sport: int):
return self._master_set_server(saddr,sport)
def get_saddr(self):
return self._master_get_saddr()
def excuse(self, dir_slave: int, type_function: int, addr: int, *val):
if self.mode == SLAVE:
if dir_slave == 0 :
return self._slave_read_regs(type_function, addr, *val)
elif dir_slave == 1 :
return self._slave_write_regs(type_function, addr, *val)
else :
return
elif self.mode == MASTER:
if type_function >= cst.READ_COILS and type_function <= cst.READ_INPUT_REGISTERS:
return self._master_read_list(dir_slave,type_function, addr, *val)
elif type_function >= cst.WRITE_SINGLE_COIL and type_function <= cst.WRITE_SINGLE_REGISTER:
return self._master_write_int(dir_slave,type_function, addr, *val)
elif type_function >= cst.WRITE_MULTIPLE_COILS and type_function <= cst.WRITE_MULTIPLE_REGISTERS:
return self._master_write_list(dir_slave,type_function, addr, *val)
else :
return
else :
return
# 该函数仅对主机有效
def download(self, slave: int, file_dev: str, file_master: str):
return self._master_download(slave, file_dev, file_master)
# 该函数仅对主机有效
def upload(self, slave: int, file_dev: str, file_master: str):
return self._master_upload(slave, file_dev, file_master)
class ascii(rtu):
mode = SLAVE
ascii_flag = 0
class tcp(_modbus_rt._tcp):
mode = SLAVE
def __init__(self, mode = SLAVE):
return self._init(mode)
def set_net(self, ip = '', port = 502, type = SOCK_STREAM):
return self._set_net(ip, port, type)
def set_ip(self, ip: str):
return self._set_ip(ip)
def set_port(self, port: int):
return self._set_port(port)
def set_type(self, type: int):
return self._set_type(type)
def set_p2p(self, p2p_flag: int):
return self._set_p2p(p2p_flag)
def open(self):
return self._open()
def isopen(self):
return self._isopen()
def close(self):
return self._close()
# 该函数仅对从机有效
def set_addr(self, addr: int):
return self._slave_set_addr(addr)
# 该函数仅对从机有效
def set_strict(self, strict: int):
return self._slave_set_strict(strict)
# 该函数仅对从机有效
def add_block(self, name: str, type: int, addr: int, nums: int):
return self._slave_add_block(name, type, addr, nums)
def set_pre_ans_callback(self, cb):
return self._slave_set_pre_ans_callback(cb)
def set_done_callback(self, cb):
return self._slave_set_done_callback(cb)
def set_dev_binding(self, flag: int):
return self._slave_set_dev_binding(flag)
# 该函数仅对主机有效
def set_server(self, saddr: str,sport: int):
return self._master_set_server(saddr,sport)
def get_saddr(self):
return self._master_get_saddr()
def excuse(self, dir_slave: int, type_function: int, addr: int, *val):
if self.mode == SLAVE:
if dir_slave == 0 :
return self._slave_read_regs(type_function, addr, *val)
elif dir_slave == 1 :
return self._slave_write_regs(type_function, addr, *val)
else :
return
elif self.mode == MASTER:
if type_function >= cst.READ_COILS and type_function <= cst.READ_INPUT_REGISTERS:
return self._master_read_list(dir_slave,type_function, addr, *val)
elif type_function >= cst.WRITE_SINGLE_COIL and type_function <= cst.WRITE_SINGLE_REGISTER:
return self._master_write_int(dir_slave,type_function, addr, *val)
elif type_function >= cst.WRITE_MULTIPLE_COILS and type_function <= cst.WRITE_MULTIPLE_REGISTERS:
return self._master_write_list(dir_slave,type_function, addr, *val)
else :
return
else :
return
# 该函数仅对主机有效
def download(self, slave: int, file_dev: str, file_master: str):
return self._master_download(slave, file_dev, file_master)
# 该函数仅对主机有效
def upload(self, slave: int, file_dev: str, file_master: str):
return self._master_upload(slave, file_dev, file_master)

View File

@ -0,0 +1,55 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Modbus TestKit: Implementation of Modbus protocol in python
(C)2009 - Luc Jean - luc.jean@gmail.com
(C)2009 - Apidev - http://www.apidev.fr
This is distributed under GNU LGPL license, see license.txt
"""
#modbus mode
SLAVE = 0
MASTER = 1
#modebus tcp type
SOCK_STREAM = 1
SOCK_DGRAM = 2
#modbus exception codes
ILLEGAL_FUNCTION = 1
ILLEGAL_DATA_ADDRESS = 2
ILLEGAL_DATA_VALUE = 3
SLAVE_DEVICE_FAILURE = 4
COMMAND_ACKNOWLEDGE = 5
SLAVE_DEVICE_BUSY = 6
MEMORY_PARITY_ERROR = 8
#supported modbus functions
READ_COILS = 1
READ_DISCRETE_INPUTS = 2
READ_HOLDING_REGISTERS = 3
READ_INPUT_REGISTERS = 4
WRITE_SINGLE_COIL = 5
WRITE_SINGLE_REGISTER = 6
READ_EXCEPTION_STATUS = 7
DIAGNOSTIC = 8
WRITE_MULTIPLE_COILS = 15
WRITE_MULTIPLE_REGISTERS = 16
REPORT_SLAVE_ID = 17
MASK_WRITE_REGISTER = 22
READ_WRITE_MULTIPLE_REGISTERS = 23
DEVICE_INFO = 43
#supported block types
CIOLS = 0
INPUTS = 1
INPUT_REGISTERS = 3
REGISTERS = 4
#data trans endian mode
LITTLE_ENDIAL_SWAP = 0
BIG_ENDIAL_SWAP = 1
LITTLE_ENDIAL = 2
BIG_ENDIAL = 3