From 5623b7861709e083b864fddd553a995e17efa2c3 Mon Sep 17 00:00:00 2001
From: zhangzheng <1358745329@qq.com>
Date: Tue, 3 Oct 2023 15:51:31 +0800
Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0modbus&=E4=BF=AE=E6=94=B9sysc?=
=?UTF-8?q?all=E5=87=BD=E6=95=B0=E5=90=8D&=E4=BF=AE=E6=94=B9ns=E6=B3=A8?=
=?UTF-8?q?=E5=86=8C=E6=96=B9=E5=BC=8F?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.vscode/settings.json | 4 +-
mkrtos_user/lib/CMakeLists.txt | 1 +
mkrtos_user/lib/modbus/CMakeLists.txt | 49 +
mkrtos_user/lib/modbus/inc/MD_RTU_Config.h | 39 +
.../lib/modbus/inc/modbus_base/MD_RTU_CRC16.h | 29 +
.../lib/modbus/inc/modbus_base/MD_RTU_Error.h | 28 +
.../modbus/inc/modbus_base/MD_RTU_MapTable.h | 55 +
.../lib/modbus/inc/modbus_base/MD_RTU_Queue.h | 51 +
.../lib/modbus/inc/modbus_base/MD_RTU_Tool.h | 52 +
.../lib/modbus/inc/modbus_base/MD_RTU_Type.h | 43 +
.../inc/modbus_rtu_master/MDM_RTU_Fun.h | 246 +++
.../inc/modbus_rtu_master/MDM_RTU_RW_Man.h | 34 +
.../inc/modbus_rtu_master/MDM_RTU_User_Fun.h | 10 +
.../modbus/inc/modbus_rtu_slave/MDS_RTU_Fun.h | 136 ++
.../inc/modbus_rtu_slave/MDS_RTU_User_Fun.h | 41 +
.../lib/modbus/inc/port/MD_RTU_SysInterface.h | 57 +
.../lib/modbus/src/modbus_base/MD_RTU_CRC16.c | 85 +
.../modbus/src/modbus_base/MD_RTU_MapTable.c | 61 +
.../lib/modbus/src/modbus_base/MD_RTU_Queue.c | 224 +++
.../src/modbus_rtu_master/MDM_RTU_Fun.c | 1386 +++++++++++++++++
.../src/modbus_rtu_master/MDM_RTU_RW_Man.c | 158 ++
.../src/modbus_rtu_master/MDM_RTU_User_Fun.c | 103 ++
.../modbus/src/modbus_rtu_slave/MDS_RTU_Fun.c | 695 +++++++++
.../src/modbus_rtu_slave/MDS_RTU_User_Fun.c | 225 +++
.../lib/modbus/src/port/MD_RTU_SysInterface.c | 75 +
mkrtos_user/lib/sys/inc/u_types.h | 20 +
mkrtos_user/lib/sys/src/syscall.S | 8 +-
mkrtos_user/lib/sys/src/u_factory.c | 8 +-
mkrtos_user/lib/sys/src/u_ipc.c | 8 +-
mkrtos_user/lib/sys/src/u_irq_sender.c | 6 +-
mkrtos_user/lib/sys/src/u_log.c | 4 +-
mkrtos_user/lib/sys/src/u_mm.c | 6 +-
mkrtos_user/lib/sys/src/u_sys.c | 2 +-
mkrtos_user/lib/sys/src/u_task.c | 8 +-
mkrtos_user/lib/sys/src/u_thread.c | 10 +-
mkrtos_user/lib/sys_svr/inc/ns_types.h | 8 +-
mkrtos_user/lib/sys_svr/src/fs_cli.c | 49 +-
mkrtos_user/lib/sys_svr/src/ns_cli.c | 23 +-
mkrtos_user/lib/sys_util/inc/u_rpc.h | 4 +-
mkrtos_user/lib/sys_util/src/u_app_loader.c | 8 +-
mkrtos_user/server/app/CMakeLists.txt | 11 +
mkrtos_user/server/app/drv/drv.c | 12 +-
mkrtos_user/server/app/modbus/MDM_RTU_APP.c | 229 +++
mkrtos_user/server/app/modbus/MDM_RTU_APP.h | 8 +
.../server/app/modbus/MDM_RTU_Serial.c | 124 ++
.../server/app/modbus/MDM_RTU_Serial.h | 30 +
mkrtos_user/server/fs/fatfs/main.c | 3 +-
mkrtos_user/server/hello/src/main.c | 6 +-
mkrtos_user/server/init/src/main.c | 2 -
mkrtos_user/server/init/src/namespace.c | 5 +-
50 files changed, 4400 insertions(+), 89 deletions(-)
create mode 100644 mkrtos_user/lib/modbus/CMakeLists.txt
create mode 100644 mkrtos_user/lib/modbus/inc/MD_RTU_Config.h
create mode 100644 mkrtos_user/lib/modbus/inc/modbus_base/MD_RTU_CRC16.h
create mode 100644 mkrtos_user/lib/modbus/inc/modbus_base/MD_RTU_Error.h
create mode 100644 mkrtos_user/lib/modbus/inc/modbus_base/MD_RTU_MapTable.h
create mode 100644 mkrtos_user/lib/modbus/inc/modbus_base/MD_RTU_Queue.h
create mode 100644 mkrtos_user/lib/modbus/inc/modbus_base/MD_RTU_Tool.h
create mode 100644 mkrtos_user/lib/modbus/inc/modbus_base/MD_RTU_Type.h
create mode 100644 mkrtos_user/lib/modbus/inc/modbus_rtu_master/MDM_RTU_Fun.h
create mode 100644 mkrtos_user/lib/modbus/inc/modbus_rtu_master/MDM_RTU_RW_Man.h
create mode 100644 mkrtos_user/lib/modbus/inc/modbus_rtu_master/MDM_RTU_User_Fun.h
create mode 100644 mkrtos_user/lib/modbus/inc/modbus_rtu_slave/MDS_RTU_Fun.h
create mode 100644 mkrtos_user/lib/modbus/inc/modbus_rtu_slave/MDS_RTU_User_Fun.h
create mode 100644 mkrtos_user/lib/modbus/inc/port/MD_RTU_SysInterface.h
create mode 100644 mkrtos_user/lib/modbus/src/modbus_base/MD_RTU_CRC16.c
create mode 100644 mkrtos_user/lib/modbus/src/modbus_base/MD_RTU_MapTable.c
create mode 100644 mkrtos_user/lib/modbus/src/modbus_base/MD_RTU_Queue.c
create mode 100644 mkrtos_user/lib/modbus/src/modbus_rtu_master/MDM_RTU_Fun.c
create mode 100644 mkrtos_user/lib/modbus/src/modbus_rtu_master/MDM_RTU_RW_Man.c
create mode 100644 mkrtos_user/lib/modbus/src/modbus_rtu_master/MDM_RTU_User_Fun.c
create mode 100644 mkrtos_user/lib/modbus/src/modbus_rtu_slave/MDS_RTU_Fun.c
create mode 100644 mkrtos_user/lib/modbus/src/modbus_rtu_slave/MDS_RTU_User_Fun.c
create mode 100644 mkrtos_user/lib/modbus/src/port/MD_RTU_SysInterface.c
create mode 100644 mkrtos_user/server/app/modbus/MDM_RTU_APP.c
create mode 100644 mkrtos_user/server/app/modbus/MDM_RTU_APP.h
create mode 100644 mkrtos_user/server/app/modbus/MDM_RTU_Serial.c
create mode 100644 mkrtos_user/server/app/modbus/MDM_RTU_Serial.h
diff --git a/.vscode/settings.json b/.vscode/settings.json
index a0047cb00..d27cf1970 100755
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -186,7 +186,9 @@
"spi2.h": "c",
"wk2xx.h": "c",
"cwchar": "c",
- "test.h": "c"
+ "test.h": "c",
+ "uart5.h": "c",
+ "wk2xx_hw.h": "c"
},
"cortex-debug.showRTOS": false,
"cortex-debug.variableUseNaturalFormat": true,
diff --git a/mkrtos_user/lib/CMakeLists.txt b/mkrtos_user/lib/CMakeLists.txt
index eb920e4a0..58611ac2b 100644
--- a/mkrtos_user/lib/CMakeLists.txt
+++ b/mkrtos_user/lib/CMakeLists.txt
@@ -9,6 +9,7 @@ set(CMAKE_ASM_FLAGS ${CMAKE_C_FLAGS})
add_subdirectory(sys)
add_subdirectory(sys_util)
add_subdirectory(sys_svr)
+add_subdirectory(modbus)
add_subdirectory(stm32f1_bsp)
add_subdirectory(libc_backend)
add_subdirectory(mlibc)
diff --git a/mkrtos_user/lib/modbus/CMakeLists.txt b/mkrtos_user/lib/modbus/CMakeLists.txt
new file mode 100644
index 000000000..f1fd5f7fe
--- /dev/null
+++ b/mkrtos_user/lib/modbus/CMakeLists.txt
@@ -0,0 +1,49 @@
+cmake_minimum_required(VERSION 3.13)
+
+
+set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} \
+-fPIC -n -pie -fpie -fpic -msingle-pic-base -mno-pic-data-is-text-relative \
+-Wl,--gc-sections -D__dietlibc__ -D__arm__ -D__WORDSIZE=32 -D__ARM_ARCH_7M__ \
+" )
+set(CMAKE_ASM_FLAGS ${CMAKE_C_FLAGS})
+
+
+file(GLOB_RECURSE deps *.c *.S)
+add_library(
+ xtinymodbus
+ STATIC
+ ${deps}
+)
+target_include_directories(
+ xtinymodbus
+ PUBLIC
+ ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/modbus/inc/modbus_base
+ ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/modbus/inc/modbus_rtu_master
+ ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/modbus/inc/modbus_rtu_slave
+ ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/modbus/inc/port
+ ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/modbus/inc/serial
+ ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/modbus/inc
+
+ ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys/inc
+ ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/sys_util/inc
+ ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/cpio
+
+ ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/arch/arm/
+ ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/arch/generic
+ ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/obj/src/internal
+ ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/src/include
+ ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/src/internal
+ ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/obj/include
+ ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/include
+)
+target_link_libraries(
+ xtinymodbus
+ PUBLIC
+ sys
+ sys_util
+ muslc
+)
+add_dependencies(xtinymodbus sys)
+add_dependencies(xtinymodbus muslc)
+
+
diff --git a/mkrtos_user/lib/modbus/inc/MD_RTU_Config.h b/mkrtos_user/lib/modbus/inc/MD_RTU_Config.h
new file mode 100644
index 000000000..c87fa846b
--- /dev/null
+++ b/mkrtos_user/lib/modbus/inc/MD_RTU_Config.h
@@ -0,0 +1,39 @@
+/**
+ *@brief Modbus configuration file.
+ *@file MD_RTU_Config.h
+ *@author zspace
+ */
+#ifndef _MD_RTU_CONFIG_H__
+#define _MD_RTU_CONFIG_H__
+
+#define MD_RTU_USED_OS 0 ///< Whether modbus RTU USES an operating system
+
+#define MD_RTU_CRC16_FAST_MODE 1 ///< CRC check mode configuration
+
+///< Configuration related to the slave
+#define MDS_REG_COIL_ITEM_NUM 20 ///< Maximum number of discrete maps
+#define MDS_RTU_CMD_SIZE 256 ///< Single instruction length
+#define MDS_RTU_SEND_CACHE_SIZE 256 ///< Send buffer length
+#define MDS_USE_SEND_CACHE 1 ///< Whether to enable sending cache
+#define MDS_RTU_QUEUE_SIZE 256 ///< Buffer queue size
+
+///< Host related configuration
+#define MDM_REG_COIL_ITEM_NUM 20 ///< Maximum number of discrete maps
+#define MDM_RTU_SEND_CACHE_SIZE 256 ///< Send buffer length
+#define MDM_USE_SEND_CACHE 1 ///< Whether to enable sending cache
+#define MDM_RTU_QUEUE_SIZE 256 ///< Buffer queue size
+
+#define MDM_MIX_CALL_DELAY 500 ///< The delay time before the mix call
+
+///< Configuration related to blocking read-write controller
+#define MDM_RW_CTRL_LIST_SIZE 20 ///< Maximum number of controllers
+
+#define MDS_USE_IDENTICAL_MAPPING 1 ///< Different slaves use the same mapping source
+
+#ifdef MDS_USE_IDENTICAL_MAPPING
+#define STATIC_T static
+#else
+#define STATIC_T
+#endif
+
+#endif
diff --git a/mkrtos_user/lib/modbus/inc/modbus_base/MD_RTU_CRC16.h b/mkrtos_user/lib/modbus/inc/modbus_base/MD_RTU_CRC16.h
new file mode 100644
index 000000000..bc64d3bc6
--- /dev/null
+++ b/mkrtos_user/lib/modbus/inc/modbus_base/MD_RTU_CRC16.h
@@ -0,0 +1,29 @@
+/**@file MD_RTU_CRC16.h
+* @brief Modbus RTU CRC16 Check module
+* @author zspace
+* @date 2020-4-10
+* @version V1.0
+**********************************************************************************
+* @par Open source address
+* https://github.com/lotoohe-space/XTinyModbus
+* @par modify log:
+*
+* | Date | Version | Author | Description
+* |
|---|
| 2020-4-10 | 1.0 | zspace | First version
+* |
+*
+**********************************************************************************
+*/
+#ifndef _MD_RTU_CRC16_H__
+#define _MD_RTU_CRC16_H__
+
+/*********************************HEAD FILE************************************/
+#include "MD_RTU_Type.h"
+#include "MD_RTU_Config.h"
+/*********************************END******************************************/
+
+/*********************************Function declaration************************/
+//uint16 MD_CRC16Update(uint16 CRC, uint8 byte);
+/*********************************END******************************************/
+
+#endif
diff --git a/mkrtos_user/lib/modbus/inc/modbus_base/MD_RTU_Error.h b/mkrtos_user/lib/modbus/inc/modbus_base/MD_RTU_Error.h
new file mode 100644
index 000000000..762cf4a4d
--- /dev/null
+++ b/mkrtos_user/lib/modbus/inc/modbus_base/MD_RTU_Error.h
@@ -0,0 +1,28 @@
+#ifndef _MDM_RTU_ERROR_H__
+#define _MDM_RTU_ERROR_H__
+
+typedef enum{
+ ERR_VOID=0, /*Null pointer error*/
+ ERR_NONE=1, /*No error*/
+ ERR_CTE_OBJ, /*Object creation error*/
+ ERR_IDLE, /*The block is currently free*/
+ ERR_QUEUE, /*Queue write error*/
+ ERR_OVER_TIME, /*Timeout error*/
+ ERR_SEND_FIN, /*Send complete*/
+ ERR_RW_OV_TIME_ERR, /*Send timeout error*/
+ ERR_DEV_DIS, /*Device disconnection*/
+ ERR_SLAVE_ADDR, /*The slave address does not match*/
+ ERR_DATA_LEN, /*Data length error*/
+ ERR_DATA_SAVE, /*Data saving error*/
+
+ /*The following error is returned from the slave machine.*/
+ ERR_READ_COIL, /*Read coil error*/
+ ERR_READ_INPUT, /*Read input error*/
+ ERR_READ_HOLD_REG, /*Read holding register error*/
+ ERR_READ_INPUT_REG, /*Error reading input register*/
+ ERR_WRITE_COIL, /*Write coil error*/
+ ERR_WRITE_REG, /*Write register error*/
+ ERR_RW_FIN, /*The slave receives and the master receives the correct response*/
+}MDError;
+
+#endif
diff --git a/mkrtos_user/lib/modbus/inc/modbus_base/MD_RTU_MapTable.h b/mkrtos_user/lib/modbus/inc/modbus_base/MD_RTU_MapTable.h
new file mode 100644
index 000000000..fce64eca3
--- /dev/null
+++ b/mkrtos_user/lib/modbus/inc/modbus_base/MD_RTU_MapTable.h
@@ -0,0 +1,55 @@
+/**@file MD_RTU_MapTable.h
+* @brief Modbus RTU Discrete mapping management module
+* @author zspace
+* @date 2020-4-10
+* @version V1.0
+**********************************************************************************
+* @par Open source address
+* https://github.com/lotoohe-space/XTinyModbus
+* @par modify log:
+*
+* | Date | Version | Author | Description
+* |
|---|
| 2020-4-10 | 1.0 | zspace | First version
+* |
+*
+**********************************************************************************
+*/
+
+#ifndef _MD_RTU_REGCOIL_H__
+#define _MD_RTU_REGCOIL_H__
+
+/*********************************HEAD FILE************************************/
+#include "MD_RTU_Type.h"
+/*********************************END******************************************/
+
+/*********************************CUSTOM DATA TYPE************************************/
+
+/**@enum AddrType
+* @brief Modbus RTU types
+*/
+typedef enum{
+ COILS_TYPE=1, ///< coil type
+ INPUT_TYPE=2, ///< input type
+ HOLD_REGS_TYPE=3, ///< hold reg type
+ INPUT_REGS_TYPE=4 ///< input reg type
+}AddrType;
+
+/**@struct MapTableItem
+* @brief Discrete mapping structure \n
+* Map modbus addresses to memory addresses
+*/
+typedef struct{
+ uint16 modbusAddr; ///< Modbus address
+ uint16* modbusData; ///< Stored data
+ uint16 modbusDataSize; ///< Map size
+ AddrType addrType; ///< Address type,Reference @see :: AddrType
+ uint8 devAddr; ///< Indicate which device the mapping item belongs to. For the time being, only the master uses this variable and the slave ignores it
+}*PMapTableItem,MapTableItem;
+/*********************************END******************************************/
+
+/*********************************FUNCTION DECLARATION************************************/
+uint8 MapTableAdd(void* obj,PMapTableItem pMapTableItem,uint16 tabSize);
+uint8 MapTableDel(void* obj,PMapTableItem pMapTableItem,uint16 tabSize);
+/*********************************END******************************************/
+
+#endif
diff --git a/mkrtos_user/lib/modbus/inc/modbus_base/MD_RTU_Queue.h b/mkrtos_user/lib/modbus/inc/modbus_base/MD_RTU_Queue.h
new file mode 100644
index 000000000..0cd98c0ef
--- /dev/null
+++ b/mkrtos_user/lib/modbus/inc/modbus_base/MD_RTU_Queue.h
@@ -0,0 +1,51 @@
+/********************************************************************************
+* @File name: MD_RTU_Queue.c
+* @Author: zspace
+* @Emial: 1358745329@qq.com
+* @Version: 1.0
+* @Date: 2020-4-10
+* @Description: Modbus RTU Queue function module
+********************************************************************************/
+#ifndef _SQQUEUE_H__
+#define _SQQUEUE_H__
+
+/*********************************HEAD FILE************************************/
+#include "MD_RTU_Type.h"
+#include "MD_RTU_Config.h"
+/*********************************END******************************************/
+
+/*********************************TYPE DEFINITION**************************************/
+//typedef uint8 MDQueueDateType;
+typedef void MDQueueDataType;
+typedef struct {
+ //MDQueueDateType data[MD_RTU_QUEUE_SIZE+1];
+ MDQueueDataType *data;
+ uint16 maxVal;
+ int16 front, rear;
+ uint8 valid;
+}*PMDSqQueue, MDSqQueue;
+/*********************************END******************************************/
+
+/*user used data type.*/
+typedef enum{
+ CHAR_TYPE=0,
+ UINT8_TYPE,
+ SHORT_TYPE,
+ INT_TYPE,
+ FLOAT_TYPE
+}*PSqQueueType,SqQueueType;
+
+/*********************************FUNCTION DECLARATION**************************************/
+uint8 MDInitQueue(MDSqQueue *q,MDQueueDataType* data,uint16 maxVal);
+uint16 MDQueueLength(MDSqQueue* q);
+void MDResetQueue(MDSqQueue* q);
+uint8 MDQueueEmpty(MDSqQueue* q);
+uint8 MDenQueueH(MDSqQueue* q, MDQueueDataType *e,SqQueueType type);
+uint8 MDenQueue(MDSqQueue* q, MDQueueDataType *e,SqQueueType type);
+uint8 MDdeQueue(MDSqQueue* q, MDQueueDataType *e,SqQueueType type);
+uint8 MDdeQueueF(MDSqQueue* q, MDQueueDataType *e,SqQueueType type);
+uint8 MDgetTailQueue(MDSqQueue* q, MDQueueDataType* e,SqQueueType type);
+/*********************************END******************************************/
+
+#endif
+
diff --git a/mkrtos_user/lib/modbus/inc/modbus_base/MD_RTU_Tool.h b/mkrtos_user/lib/modbus/inc/modbus_base/MD_RTU_Tool.h
new file mode 100644
index 000000000..df210c805
--- /dev/null
+++ b/mkrtos_user/lib/modbus/inc/modbus_base/MD_RTU_Tool.h
@@ -0,0 +1,52 @@
+#ifndef _MD_RTU_TOOL_H__
+#define _MD_RTU_TOOL_H__
+
+#include "MD_RTU_Type.h"
+
+typedef void (*MDS_RTU_TimeHandlerFunction)(void* obj
+ ,uint32 times
+ );
+typedef void (*MDS_RTU_SendBytesFunction)(uint8 *byte,uint16 num);
+typedef void (*MDS_RTU_RecByteFunction)(void* obj, uint8 byte);
+typedef void (*MDS_RTU_RecSendConv)(uint8 mode);
+
+typedef void (*MD_RTU_SerialInit)(void* obj,uint32 baud,uint8 dataBits,uint8 stopBit,uint8 parity);
+
+typedef struct{
+ /*Data sending and receiving related functions*/
+ MDS_RTU_SendBytesFunction mdRTUSendBytesFunction;
+ MDS_RTU_RecByteFunction mdRTURecByteFunction;
+ MDS_RTU_RecSendConv mdRTURecSendConv;
+ /*Timer callback function*/
+ MDS_RTU_TimeHandlerFunction mdRTUTimeHandlerFunction;
+}*PModbusBase,ModbusBase;
+
+/*Convert to ModbusBase*/
+#define TO_MDBase(a) ((PModbusBase)(a))
+
+/*Get the variables in RegCoilItem*/
+#define MDS_RTU_REG_COIL_LIST(a) ((a)->pRegCoilList)
+#define MDS_RTU_REG_COIL_ITEM_ADDR(a) ((a)->modbusAddr)
+#define MDS_RTU_REG_COIL_ITEM_DATA(a) ((a)->modbusData)
+#define MDS_RTU_REG_COIL_ITEM_Data_Size(a) ((a)->modbusDataSize)
+#define MDS_RTU_REG_COIL_ITEM_ADDR_TYPE(a) ((a)->addrType)
+
+/*The following macros are used to manipulate the bits of variables*/
+#define MD_GET_BIT(a,b) (((a)>>(b))&0x1)
+#define MD_SET_BIT(a,b) (a)|=(1<<(b))
+#define MD_CLR_BIT(a,b) (a)&=(~(1<<(b)))
+
+/*Transceiver mode conversion*/
+#define MD_RTU_SEND_MODE(a) while((a)->lastTimesTick!=0xFFFFFFFF);\
+if((a)->modbusBase.mdRTURecSendConv)(a)->modbusBase.mdRTURecSendConv(TRUE)
+#define MD_RTU_RECV_MODE(a) while((a)->lastTimesTick!=0xFFFFFFFF);\
+if((a)->modbusBase.mdRTURecSendConv)(a)->modbusBase.mdRTURecSendConv(FALSE)
+
+/*Swap the high and low bytes of a halfword*/
+#define MD_SWAP_HL(a) (a)=((((a)&0xff)<<8)|(((a)>>8)&0xff))
+
+/*Take high and low byte*/
+#define MD_H_BYTE(a) (((a)>>8)&0xff)
+#define MD_L_BYTE(a) ((a)&0xff)
+
+#endif
diff --git a/mkrtos_user/lib/modbus/inc/modbus_base/MD_RTU_Type.h b/mkrtos_user/lib/modbus/inc/modbus_base/MD_RTU_Type.h
new file mode 100644
index 000000000..6d49e1d6d
--- /dev/null
+++ b/mkrtos_user/lib/modbus/inc/modbus_base/MD_RTU_Type.h
@@ -0,0 +1,43 @@
+/**
+ * @file MD_RTU_Type.h
+ * @brief None
+ * @details None
+ * @author zspace
+ * @date 2020/3/23
+ * @version A001
+ * @par History: None
+ */
+#ifndef _MD_RTU_TYPE_H__
+#define _MD_RTU_TYPE_H__
+
+#include "MD_RTU_Config.h"
+
+#if MD_RTU_USED_OS
+#include "RTOS_Type.h"
+#else
+typedef unsigned char uchar;
+typedef unsigned char uint8;
+typedef char int8;
+typedef unsigned int uint32;
+typedef int int32;
+typedef unsigned short uint16;
+typedef short int16;
+
+typedef uint8 BOOL;
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define BOOL uint8
+#endif
+
+#endif
diff --git a/mkrtos_user/lib/modbus/inc/modbus_rtu_master/MDM_RTU_Fun.h b/mkrtos_user/lib/modbus/inc/modbus_rtu_master/MDM_RTU_Fun.h
new file mode 100644
index 000000000..b78dfc196
--- /dev/null
+++ b/mkrtos_user/lib/modbus/inc/modbus_rtu_master/MDM_RTU_Fun.h
@@ -0,0 +1,246 @@
+/********************************************************************************
+* @File name: MD_RTU_Fun.h
+* @Author: zspace
+* @Emial: 1358745329@qq.com
+* @Version: 1.0
+* @Date: 2020-4-10
+* @Description: Modbus RTU Host function module
+********************************************************************************/
+
+#ifndef _MEM_RTU_FUN_H__
+#define _MEM_RTU_FUN_H__
+/*********************************HEAD FILE************************************/
+#include "MD_RTU_Queue.h"
+#include "MD_RTU_Type.h"
+#include "MD_RTU_Error.h"
+#include "MD_RTU_Tool.h"
+#include "MD_RTU_MapTable.h"
+#include "MD_RTU_Config.h"
+#include "MD_RTU_SysInterface.h"
+
+/*********************************END******************************************/
+
+/*********************************CUSTOM DATA TYPE************************************/
+/*Function code in Modbus RTU*/
+typedef enum{
+ READ_COIL=1,
+ READ_INPUT=2,
+ READ_HOLD_REG=3,
+ READ_INPUT_REG=4,
+ WRITE_SIN_COIL=5,
+ WRITE_SIN_REG=6,
+ WRITE_COILS=15,
+ WRITE_REGS=16
+}ModbusFunCode;
+
+typedef struct{
+ /*Inherit modbusBase*/
+ ModbusBase modbusBase;
+ /*Discrete mapping list, the data read is stored in it*/
+ PMapTableItem pMapTableList[MDM_REG_COIL_ITEM_NUM];
+ /*Data receiving queue*/
+ MDSqQueue mdSqQueue;
+#if MD_RTU_USED_OS
+ /**/
+ MD_RTU_LOCK_HANDLE mdRTULockHandle;
+ MD_RTU_LOCK_HANDLE mdRTULockObjHandle;
+ MD_RTU_LOCK_HANDLE mdRTULockObj1Handle;
+ MD_RTU_TASK_HANDLE mdRTUTaskHandle;
+ MD_RTU_MSG_HANDLE mdRTUMsgHandle;
+#endif
+#if MDM_USE_SEND_CACHE
+ uint8 serialSendCache[MDM_RTU_SEND_CACHE_SIZE]; /*Send cache*/
+ uint16 serialSendCount; /*Number of bytes sent*/
+#endif
+
+ /*The time of the last reception, 0xFFFFFFF means that the detection frame has not started*/
+ uint32 lastTimesTick;
+ /*Current real-time time unit 100US*/
+ uint32 timesTick;
+
+ /*Frame interval time 3.5T*/
+ uint16 frameIntervalTime;
+
+ /*CRC16 received*/
+ uint16 CRC16Update;
+
+ /*Parent class address, used to distinguish time slice occupation during non-blocking read*/
+ void * parentObj;
+
+ /*1 means one frame of data is received*/
+ uint8 recvFlag;
+
+ /*last mode*/
+ uint8 blockMode;
+}*PModbus_RTU,Modbus_RTU;
+
+#if MD_RTU_USED_OS
+#define MD_RTU_LOCK_HANDLE_ARG(a) (a)->mdRTULockHandle
+#define MD_RTU_LOCK_OBJ_HANDLE_ARG(a) (a)->mdRTULockObjHandle
+#define MD_RTU_LOCK_OBJ1_HANDLE_ARG(a) (a)->mdRTULockObj1Handle
+#define MD_RTU_TASK_HANDLE_ARG(a) (a)->mdRTUTaskHandle
+#define MD_RTU_MSG_HANDLE_ARG(a) (a)->mdRTUMsgHandle
+#else
+#define MD_RTU_LOCK_HANDLE_ARG(a)
+#define MD_RTU_LOCK_OBJ_HANDLE_ARG(a)
+#define MD_RTU_LOCK_OBJ1_HANDLE_ARG(a)
+//#define MD_RTU_SEM_HANDLE_ARG(a)
+#define MD_RTU_MSG_HANDLE_ARG(a)
+#endif
+
+/*Send control block*/
+typedef struct{
+ PModbus_RTU pModbus_RTU;/*modbus rtu*/
+
+ uint32 sendIntervalTime;/*The sending interval, that is, sending once for a long time.*/
+
+ uint32 sendTimeTick;/*Time when sending*/
+ uint8 RTCount;/*Number of retransmissions*/
+
+ uint32 sendOverTime;/*Set sending timeout time*/
+
+ uint8 RTTimes;/*The set number of retransmissions. When it is 255, it means that retransmissions will continue.*/
+ uint8 sendFlag;/*Send flag
+ 0 Unsent
+ 1 Already sent
+ 2 Sent successfully
+ 3 Failed to send
+ */
+ uint8 flag; /*
+ bit0:Device offline polling flag (when flag is 1, the control block will not be polled when the device is offline).
+ bit1:Device offline polling enable
+ */
+}*PModbus_RTU_CB,Modbus_RTU_CB;
+
+/*Get device offline flag*/
+#define MD_CB_GET_DIS_FLAG(a) MD_GET_BIT(a->flag,0)
+#define MD_CB_SET_DIS_FLAG(a) MD_SET_BIT(a->flag,0)
+#define MD_CB_CLR_DIS_FLAG(a) MD_CLR_BIT(a->flag,0)
+
+/*Device enable flag*/
+#define MD_CB_GET_DIS_FLAG_EN(a) MD_GET_BIT(a->flag,1)
+#define MD_CB_SET_DIS_FLAG_EN(a) MD_SET_BIT(a->flag,1)
+#define MD_CB_CLR_DIS_FLAG_EN(a) MD_CLR_BIT(a->flag,1)
+
+
+
+
+/*********************************END******************************************/
+
+/*********************************MACRO DEFINITION************************************/
+#if MDM_USE_SEND_CACHE
+
+#define MEM_RTU_START_EN(a) {uint16 CRCUpdate1=0xFFFF;(a)->serialSendCount=0
+
+#define MEM_RTU_EN_QUEUE(a,b) (a)->serialSendCache[(a)->serialSendCount++]=(b);\
+CRCUpdate1=MD_CRC16Update(CRCUpdate1,(b))
+
+#define MEM_RTU_END_EN(a) a->serialSendCache[a->serialSendCount++]=(uint8)(CRCUpdate1);\
+ a->serialSendCache[a->serialSendCount++]=(uint8)(CRCUpdate1>>8);\
+(TO_MDBase(a))->mdRTUSendBytesFunction(a->serialSendCache,a->serialSendCount);}
+
+#else
+#define MEM_RTU_START_EN() {uint16 CRCUpdate=0xFFFF;
+#define MEM_RTU_EN_QUEUE(a,b) MDM_RTU_SendByte((a),(b));\
+CRCUpdate=MD_CRC16Update(CRCUpdate,(b))
+#define MEM_RTU_END_EN(a) MDM_RTU_SendByte(a,(uint8)CRCUpdate);\
+ MDM_RTU_SendByte(a,(uint8)(CRCUpdate>>8));\
+}
+#endif
+/*********************************END******************************************/
+
+/*********************************FUNCTION DEFINITION************************************/
+
+#if MD_RTU_USED_OS ///< used os
+void MDM_RTU_SysProcessTask(void *arg);
+#endif
+
+/*Modbus RTU block initialization function*/
+MDError MDM_RTU_Init(
+ PModbus_RTU pModbusRTU,
+ MD_RTU_SerialInit mdRTUSerialInitFun,
+ uint32 baud,
+ uint8 dataBits,
+ uint8 stopBits,
+ uint8 parity
+);
+/*Control block initialization function*/
+void MDM_RTU_CB_Init(
+ PModbus_RTU_CB pModbusRTUCB
+ ,PModbus_RTU pModbusRTU
+ ,uint32 sendIntervalTime
+ ,uint32 sendOverTime/*Send timeout*/
+ ,uint8 RTTimes/*The number of retransmissions, when it is 255, it means that retransmissions have been performed.*/
+);
+void MDM_RTU_QueueInit(PModbus_RTU pModbus_RTU,
+ uint8* recvQueueData,
+ uint16 recvQueueSize
+);
+
+/*Called in the timer interrupt function, the time unit is 100us*/
+void MDM_RTU_TimeHandler(void *obj,uint32 timesTick);
+/*Called in the serial port receive interrupt function*/
+void MDM_RTU_RecvByte(void *obj,uint8 byte);
+
+/*Control block timeout reset*/
+void MDM_RTU_CB_OverTimeReset(PModbus_RTU_CB pModbusRTUCB);
+void MDM_RTU_CB_ClrDisFlag(PModbus_RTU_CB pModbusRTUCB);
+void MDM_RTU_CB_SetDisPollEnFlag(PModbus_RTU_CB pModbusRTUCB,BOOL state);
+
+BOOL MDM_RTU_AddMapItem(PModbus_RTU pModbusRTU,PMapTableItem pRegCoilItem);
+
+/*Get data from the queue*/
+MDError MDM_RTU_ReadByte(PModbus_RTU pModbusRTU,uint8 *res,uint8 len);
+MDError MDM_RTU_ReadUint16(PModbus_RTU pModbusRTU,uint16 *res,uint8 len);
+
+///*Non-blocking read and write basis functions*/
+//MDError MDM_RTU_NB_RW(PModbus_RTU_CB pModbus_RTU_CB,ModbusFunCode funCode,uint8 slaveAddr,uint16 startAddr,uint16 numOf,void *wData);
+///*Blocking read and write basis functions*/
+//MDError MDM_RTU_RW(PModbus_RTU_CB pModbus_RTU_CB,ModbusFunCode funCode,uint8 slaveAddr,uint16 startAddr,uint16 numOf,void *wData);
+
+/*The following is non-blocking read and write*/
+MDError MDM_RTU_NB_ReadCoil(PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf);
+MDError MDM_RTU_NB_ReadInput(PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf);
+MDError MDM_RTU_NB_ReadHoldReg(PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf);
+MDError MDM_RTU_NB_ReadInputReg(PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf);
+MDError MDM_RTU_NB_WriteSingleCoil(
+ PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,BOOL boolVal);
+MDError MDM_RTU_NB_WriteSingleReg(
+ PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 val);
+MDError MDM_RTU_NB_WriteCoils(
+ PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf,uint8* val);
+MDError MDM_RTU_NB_WriteRegs(
+ PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf,uint16* val);
+
+/*The following is a blocking read and write*/
+MDError MDM_RTU_ReadCoil(PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf);
+MDError MDM_RTU_ReadInput(PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf);
+MDError MDM_RTU_ReadHoldReg(PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf);
+MDError MDM_RTU_ReadInputReg(PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf);
+MDError MDM_RTU_WriteSingleCoil(
+ PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,BOOL boolVal);
+MDError MDM_RTU_WriteSingleReg(
+ PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 val);
+MDError MDM_RTU_WriteCoils(
+ PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf,uint8* val);
+MDError MDM_RTU_WriteRegs(
+ PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf,uint16* val);
+
+/*The following API is used to be blocking, but can be mixed with non-blocking calls,
+you may need to set the value of the MDM_MIX_CALL_DELAY parameter.*/
+MDError MDM_RTU_MixReadCoil(PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf);
+MDError MDM_RTU_MixReadInput(PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf);
+MDError MDM_RTU_MixReadHoldReg(PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf);
+MDError MDM_RTU_MixReadInputReg(PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf);
+MDError MDM_RTU_MixWriteSingleCoil(
+ PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,BOOL boolVal);
+MDError MDM_RTU_MixWriteSingleReg(
+ PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 val);
+MDError MDM_RTU_MixWriteCoils(
+ PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf,uint8* val);
+MDError MDM_RTU_MixWriteRegs(
+ PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf,uint16* val);
+
+/*********************************END******************************************/
+
+#endif
diff --git a/mkrtos_user/lib/modbus/inc/modbus_rtu_master/MDM_RTU_RW_Man.h b/mkrtos_user/lib/modbus/inc/modbus_rtu_master/MDM_RTU_RW_Man.h
new file mode 100644
index 000000000..b4bea8d86
--- /dev/null
+++ b/mkrtos_user/lib/modbus/inc/modbus_rtu_master/MDM_RTU_RW_Man.h
@@ -0,0 +1,34 @@
+#ifndef _MDM_RTU_RW_MAN_H__
+#define _MDM_RTU_RW_MAN_H__
+
+#include "MD_RTU_Type.h"
+#include "MD_RTU_Config.h"
+
+typedef enum{
+ RW_NONE=0,
+ RW_ERR,
+ RW_OK
+}MDM_RW_CtrlErr;
+
+typedef MDM_RW_CtrlErr (*MDMSendReadCallBack)(void*arg);
+
+/*Host's non-blocking mode sending controller*/
+typedef struct{
+
+ MDMSendReadCallBack MDMSendReadFun; /*Read and write functions called cyclically*/
+ void *arg; /*parameter*/
+ const char *RWCtrlName; /*Send control name*/
+ uint8 flag; /*Flag
+ bit:0 Is it used
+ bit:1 Single send
+ bit:7 The slave is disconnected or a single transmission is completed.
+ */
+}*PMDM_RW_Ctrl,MDM_RW_Ctrl;
+
+PMDM_RW_Ctrl MDM_RW_CtrlAddRW(MDMSendReadCallBack cbFun,void *arg,const char *RWCtrlName);
+void MDM_RW_CtrlSetRWOnceFlag(PMDM_RW_Ctrl pMDM_RW_Ctrl,BOOL flag);
+void MDM_RW_CtrlResetRetranFlag(PMDM_RW_Ctrl pMDM_RW_Ctrl);
+void MDM_RW_CtrlSetRWOnceFlag(PMDM_RW_Ctrl pMDM_RW_Ctrl,BOOL flag);
+void MDM_RW_CtrlLoop(void);
+
+#endif
diff --git a/mkrtos_user/lib/modbus/inc/modbus_rtu_master/MDM_RTU_User_Fun.h b/mkrtos_user/lib/modbus/inc/modbus_rtu_master/MDM_RTU_User_Fun.h
new file mode 100644
index 000000000..d99f0e054
--- /dev/null
+++ b/mkrtos_user/lib/modbus/inc/modbus_rtu_master/MDM_RTU_User_Fun.h
@@ -0,0 +1,10 @@
+#ifndef _MDM_RTU_USER_FUN_H_
+#define _MDM_RTU_USER_FUN_H_
+
+#include "MD_RTU_Type.h"
+#include "MD_RTU_MapTable.h"
+
+BOOL MDM_RTU_ReadBits(void* obj,uint16 modbusAddr,uint16 numOf, uint8 *res, AddrType opAddrType,uint8 devAddr);
+BOOL MDM_RTU_ReadRegs(void* obj,uint16 modbusAddr,uint16 numOf, uint16 *res, AddrType opAddrType,uint8 devAddr);
+
+#endif
diff --git a/mkrtos_user/lib/modbus/inc/modbus_rtu_slave/MDS_RTU_Fun.h b/mkrtos_user/lib/modbus/inc/modbus_rtu_slave/MDS_RTU_Fun.h
new file mode 100644
index 000000000..e69faba13
--- /dev/null
+++ b/mkrtos_user/lib/modbus/inc/modbus_rtu_slave/MDS_RTU_Fun.h
@@ -0,0 +1,136 @@
+/**
+ * @file name: MD_RTU_Fun.h
+ * @author zspace
+ * @version 1.0
+ * @date 2020-4-10
+ * @brief MModbus RTU Slave receiving function module.
+ */
+
+#ifndef _MD_RTU_FUN_H__
+#define _MD_RTU_FUN_H__
+/*********************************HEAD FILE************************************/
+#include "MD_RTU_Queue.h"
+#include "MD_RTU_MapTable.h"
+#include "MD_RTU_Type.h"
+#include "MD_RTU_Tool.h"
+#include "MD_RTU_Config.h"
+/*********************************END******************************************/
+
+/*********************************VARIABLE TYPE DECLARATION***********************************/
+typedef void (*MDSWriteFunciton)(void *obj, uint16 modbusAddr, uint16 wLen, AddrType addrType);
+
+typedef struct
+{
+ ModbusBase modbusBase; /*Inherit modbusBase*/
+ MDSWriteFunciton mdsWriteFun; /*Slave write callback function*/
+ MDSqQueue mdSqQueue; /*Data receiving queue*/
+ MDSqQueue mdMsgSqQueue; /*Message processing queue*/
+ uint8 salveAddr; /*Slave address*/
+
+ uint8 serialReadCache[MDS_RTU_CMD_SIZE]; /*Single instruction read queue*/
+ uint16 serialReadCount; /*Instruction length*/
+#if MDS_USE_SEND_CACHE
+ uint8 serialSendCache[MDS_RTU_SEND_CACHE_SIZE]; /*Send buffer*/
+ uint16 serialSendCount; /*Number of bytes sent*/
+#endif
+ PMapTableItem pMapTableList[MDS_REG_COIL_ITEM_NUM]; /*Register registry*/
+
+ /*The time of the last reception, 0xFFFFFFFF means that the detection frame has not started*/
+ uint32 lastTimesTick;
+ /*Current real-time time unit 100US*/
+ uint32 timesTick;
+
+ /*Last sent time*/
+ uint32 lastSendTimes;
+
+ /*Frame interval time 3.5T*/
+ uint16 frameIntervalTime;
+
+ /*CRC16 received*/
+ uint16 CRC16Update;
+
+} *PModbusS_RTU, ModbusS_RTU;
+
+/*Exception code*/
+typedef enum
+{
+ READ_COIL_ANL = 0x81,
+ READ_INPUT_ANL = 0x82,
+ READ_HOLD_REGS = 0x83,
+ READ_INPUT_REGS = 0X84,
+ WRITE_SIN_COIL = 0X85,
+ WRITE_SIN_REG = 0x86,
+ WRITE_COILS = 0X8F,
+ WRITE_REGS = 0X90
+} ANLCode;
+
+/*error code*/
+typedef enum
+{
+ ILLEGAL_FUN = 0x01, /*Not yet supported*/
+ ILLEGAL_DAT_ADDR = 0x2,
+ ILLEGAL_DAT_VAL = 0x3,
+ SLAVE_DEV_FAILURE = 0x4, /*Not yet supported*/
+ /*There is an error code behind, but it is not used yet*/
+} ErrorCode;
+/*********************************END******************************************/
+
+/*********************************MACRO DEFINITION****************************************/
+#define MDS_RTU_FUN_CODE(a) (((PModbusS_RTU)(a))->serialReadCache[1])
+#define MDS_RTU_CRC16(a) (((((PModbusS_RTU)(a))->serialReadCache[a->serialReadCount - 1]) << 8) | \
+ (((PModbusS_RTU)(a))->serialReadCache[a->serialReadCount]))
+
+#define MDS_RTU_START_REG(a) (((((PModbusS_RTU)(a))->serialReadCache[2]) << 8) | \
+ (((PModbusS_RTU)(a))->serialReadCache[3]))
+#define MDS_RTU_REGS_NUM(a) (((((PModbusS_RTU)(a))->serialReadCache[4]) << 8) | \
+ (((PModbusS_RTU)(a))->serialReadCache[5]))
+#define MDS_RTU_BYTES_NUM(a) ((a)->serialReadCache[6])
+
+#if MDS_USE_SEND_CACHE
+/*Start sending*/
+#define MDS_START_SEND(a) \
+ { \
+ uint16 CRC16 = 0xFFFF; \
+ a->serialSendCount = 0
+/*Send a byte*/
+#define MDS_SEND_BYTE(a, b) \
+ CRC16 = MD_CRC16Update(CRC16, (b)); \
+ a->serialSendCache[a->serialSendCount++] = b
+/*End sending*/
+#define MDS_SEND_END(a) \
+ a->serialSendCache[a->serialSendCount++] = (uint8)(CRC16); \
+ a->serialSendCache[a->serialSendCount++] = (uint8)(CRC16 >> 8); \
+ (TO_MDBase(a))->mdRTUSendBytesFunction(a->serialSendCache, a->serialSendCount); \
+ }
+#else
+/*The following macro is used to send modbus data and calculate the check at the same time*/
+#define MDS_START_SEND(a) \
+ { \
+ uint8 CRC16Temp; \
+ uint16 CRC16 = 0xFFFF;
+#define MDS_SEND_BYTE(a, b) \
+ CRC16 = MD_CRC16Update(CRC16, (b)); \
+ MDS_RTU_SendByte(a, b)
+#define MDS_SEND_END(a) \
+ CRC16Temp = CRC16 & 0xFF; \
+ (TO_MDBase(a))->mdRTUSendBytesFunction((uint8 *)(&(CRC16Temp)), 1); \
+ CRC16Temp = (CRC16 >> 8) & 0xFF; \
+ (TO_MDBase(a))->mdRTUSendBytesFunction((uint8 *)(&(CRC16Temp)), 1); \
+ }
+#endif
+/*********************************END******************************************/
+
+/*********************************FUNCTION DECLARATION************************************/
+void MDS_RTU_Init(PModbusS_RTU pModbusRTU, MD_RTU_SerialInit mdRTUSerialInitFun, uint8 salveAddr,
+ uint32 baud, uint8 dataBits, uint8 stopBits, uint8 parity);
+void MDS_RTU_QueueInit(PModbusS_RTU pModbus_RTU,
+ uint8 *recvQueueData,
+ uint16 recvQueueSize,
+ uint8 *msgProcessQueueData,
+ uint16 msgProcessQueueSize);
+void MDS_RTU_SetWriteListenFun(PModbusS_RTU pModbus_RTU, MDSWriteFunciton wFun);
+BOOL MDS_RTU_AddMapItem(PModbusS_RTU pModbusRTU, PMapTableItem pRegCoilItem);
+void MDS_RTU_Process(PModbusS_RTU pModbus_RTU);
+/*********************************END******************************************/
+
+#endif
diff --git a/mkrtos_user/lib/modbus/inc/modbus_rtu_slave/MDS_RTU_User_Fun.h b/mkrtos_user/lib/modbus/inc/modbus_rtu_slave/MDS_RTU_User_Fun.h
new file mode 100644
index 000000000..78b272148
--- /dev/null
+++ b/mkrtos_user/lib/modbus/inc/modbus_rtu_slave/MDS_RTU_User_Fun.h
@@ -0,0 +1,41 @@
+/********************************************************************************
+ * @File name: MD_RTU_User_Fun.h
+ * @Author: zspace
+ * @Version: 1.0
+ * @Date: 2020-4-10
+ * @Description: Modbus RTU host user calling function
+ ********************************************************************************/
+
+#ifndef _MD_RTU_USER_FUN_H__
+#define _MD_RTU_USER_FUN_H__
+
+/*********************************HEAD FILE************************************/
+#include "MD_RTU_Type.h"
+#include "MD_RTU_MapTable.h"
+/*********************************END******************************************/
+
+/*********************************Function declaration************************************/
+/*General users do not need to call the following functions*/
+BOOL MDS_RTU_ReadBits(void *obj, uint16 modbusAddr, uint16 numOf, uint8 *res, AddrType opAddrType);
+BOOL MDS_RTU_ReadRegs(void *obj, uint16 modbusAddr, uint16 numOf, uint16 *res, AddrType opAddrType);
+BOOL MDS_RTU_WriteBit(void *obj, uint16 modbusAddr, uint8 bit, AddrType opAddrType);
+BOOL MDS_RTU_WriteBits(void *obj, uint16 modbusAddr, uint16 numOf, uint16 *bit, AddrType opAddrType);
+BOOL MDS_RTU_WriteReg(void *obj, uint16 modbusAddr, uint16 reg, AddrType opAddrType);
+BOOL MDS_RTU_WriteRegs(void *obj, uint16 modbusAddr, uint16 numOf, uint16 *reg, uint8 isBigE, AddrType opAddrType);
+
+/*The following function user calls*/
+BOOL MDS_RTU_WriteCoil(void *obj, uint16 modbusAddr, uint8 bit);
+BOOL MDS_RTU_WriteInput(void *obj, uint16 modbusAddr, uint8 bit);
+BOOL MDS_RTU_WriteCoils(void *obj, uint16 modbusAddr, uint16 numOf, uint16 *bit);
+BOOL MDS_RTU_WriteInputs(void *obj, uint16 modbusAddr, uint16 numOf, uint16 *bit);
+BOOL MDS_RTU_WriteHoldReg(void *obj, uint16 modbusAddr, uint16 reg);
+BOOL MDS_RTU_WriteHoldRegs(void *obj, uint16 modbusAddr, uint16 numOf, uint16 *reg);
+BOOL MDS_RTU_WriteInputReg(void *obj, uint16 modbusAddr, uint16 reg);
+BOOL MDS_RTU_WriteInputRegs(void *obj, uint16 modbusAddr, uint16 numOf, uint16 *reg);
+BOOL MDS_RTU_ReadCoils(void *obj, uint16 modbusAddr, uint16 numOf, uint8 *res);
+BOOL MDS_RTU_ReadInput(void *obj, uint16 modbusAddr, uint16 numOf, uint8 *res);
+BOOL MDS_RTU_ReadHoldRegs(void *obj, uint16 modbusAddr, uint16 numOf, uint16 *res);
+BOOL MDS_RTU_ReadInputRegs(void *obj, uint16 modbusAddr, uint16 numOf, uint16 *res);
+/*********************************END******************************************/
+
+#endif
diff --git a/mkrtos_user/lib/modbus/inc/port/MD_RTU_SysInterface.h b/mkrtos_user/lib/modbus/inc/port/MD_RTU_SysInterface.h
new file mode 100644
index 000000000..45aa22f91
--- /dev/null
+++ b/mkrtos_user/lib/modbus/inc/port/MD_RTU_SysInterface.h
@@ -0,0 +1,57 @@
+#ifndef _MD_SYS_INTERFACE_H__
+#define _MD_SYS_INTERFACE_H__
+#include "MD_RTU_Config.h"
+
+#if MD_RTU_USED_OS
+
+#include "MD_RTU_Type.h"
+#include "MD_RTU_Tool.h"
+#include "MD_RTU_Queue.h"
+
+///< RTOS files
+#include "RTOS_msg.h"
+#include "RTOS_mutex.h"
+#include "RTOS_task.h"
+
+#define MD_RTU_LOCK_HANDLE PMUTEX_CB ///< Locked object name
+#define MD_RTU_MSG_HANDLE PMSG_CB ///< Msg oobject name
+#define MD_RTU_TASK_HANDLE PTASK_TCB ///< task oobject name
+
+#define MD_RTU_TASK_LEVEL 6
+#define MD_RTU_TASK_STACK_SIZE 128
+
+#define MD_RTU_WAIT_UNLESS 0xFFFFFFFF ///< always waiting
+#define MD_RTU_MSG_BOX_LENGTH 32
+
+uint8 MD_RTU_CreateThread(PModbusBase pModbusBase, void (*funTask)(void *arg), MD_RTU_TASK_HANDLE *pTaskObj);
+void MD_RTU_Delay(uint32 ms);
+
+uint8 MD_RTU_CreateMsg(PModbusBase pModbusBase, MD_RTU_MSG_HANDLE *pMsgObj,
+ uint32 msgBoxLength);
+uint8 MD_RTU_MsgPut(PModbusBase pModbusBase, MD_RTU_MSG_HANDLE pMsgObj, void *msg, uint32 msgPutDelay);
+uint8 MD_RTU_MsgGet(PModbusBase pModbusBase, MD_RTU_MSG_HANDLE pMsgObj, void **msg, uint32 msgGetDelay);
+
+uint8 MD_RTU_CreateLock(PModbusBase pModbusBase, MD_RTU_LOCK_HANDLE *pLockObj);
+uint8 MD_RTU_Lock(PModbusBase pModbusBase, MD_RTU_LOCK_HANDLE lockObj, uint32 mutexWaitDelay);
+uint8 MD_RTU_Unlock(PModbusBase pModbusBase, MD_RTU_LOCK_HANDLE lockObj);
+
+uint32 MD_RTU_GetSysTick(void);
+#endif
+
+#if MD_RTU_USED_OS
+#define MD_RTU_LOCK(a, b) MD_RTU_Lock(a, b, MD_RTU_WAIT_UNLESS)
+#define MD_RTU_UNLOCK(a, b) MD_RTU_Unlock(a, b)
+#define MD_RTU_MSG_PUT(a, b, c, d) MD_RTU_MsgPut(a, b, c, d)
+#define MD_RTU_MSG_GET(a, b, c, d) MD_RTU_MsgGet(a, b, c, d)
+#else
+#include "u_sys.h"
+#include "u_sleep.h"
+#define MD_RTU_LOCK(a, b)
+#define MD_RTU_UNLOCK(a, b)
+#define MD_RTU_MSG_PUT(a, b, c, d)
+#define MD_RTU_MSG_GET(a, b, c, d)
+#define MD_RTU_GetSysTick() (sys_read_tick())
+#define MD_RTU_Delay(a) u_sleep_ms(a)
+#endif
+
+#endif
diff --git a/mkrtos_user/lib/modbus/src/modbus_base/MD_RTU_CRC16.c b/mkrtos_user/lib/modbus/src/modbus_base/MD_RTU_CRC16.c
new file mode 100644
index 000000000..97a4d3aa0
--- /dev/null
+++ b/mkrtos_user/lib/modbus/src/modbus_base/MD_RTU_CRC16.c
@@ -0,0 +1,85 @@
+/**@file MD_RTU_CRC16.c
+* @brief Modbus RTU CRC16 Check module
+* @author zspace
+* @date 2020-4-10
+* @version V1.0
+**********************************************************************************
+* @par Open source address
+* https://github.com/lotoohe-space/XTinyModbus
+* @par modify log:
+*
+* | Date | Version | Author | Description
+* |
|---|
| 2020-4-10 | 1.0 | zspace | First version
+* |
+*
+**********************************************************************************
+*/
+/*********************************HEAD FILE************************************/
+#include "MD_RTU_CRC16.h"
+/*********************************END******************************************/
+
+/*********************************VARIABLE DECLARATION************************************/
+#if MD_RTU_CRC16_FAST_MODE
+static const uint16 crc16_table[256]=
+{
+ 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
+ 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
+ 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
+ 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
+ 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
+ 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
+ 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
+ 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
+ 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
+ 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
+ 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
+ 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
+ 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
+ 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
+ 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
+ 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
+ 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
+ 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
+ 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
+ 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
+ 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
+ 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
+ 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
+ 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
+ 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
+ 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
+ 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
+ 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
+ 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
+ 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
+ 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
+ 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
+};
+#endif
+/*********************************END******************************************/
+
+/**
+* @brief This function needs to get the value of CRC16 through cumulative calculation
+* @param[in] CRC CRC16 value calculated last time.
+* @param[in] byte Need to participate in the calculation of a byte.
+* @return None
+*/
+uint16 MD_CRC16Update(uint16 CRC, uint8 byte)
+{
+#if MD_RTU_CRC16_FAST_MODE
+ return ((CRC) >> 8) ^ crc16_table[((CRC) ^ byte) & 0xff];
+#else
+ int i;
+
+ CRC ^= byte;
+ for (i = 0; i < 8; ++i)
+ {
+ if (CRC & 1)
+ CRC = (CRC >> 1) ^ 0xA001;
+ else
+ CRC = (CRC >> 1);
+ }
+
+ return CRC;
+#endif
+}
diff --git a/mkrtos_user/lib/modbus/src/modbus_base/MD_RTU_MapTable.c b/mkrtos_user/lib/modbus/src/modbus_base/MD_RTU_MapTable.c
new file mode 100644
index 000000000..7b0f2851c
--- /dev/null
+++ b/mkrtos_user/lib/modbus/src/modbus_base/MD_RTU_MapTable.c
@@ -0,0 +1,61 @@
+/**@file MD_RTU_MapTable.c
+* @brief Modbus RTU Discrete mapping management module
+* @author zspace
+* @date 2020-4-10
+* @version V1.0
+**********************************************************************************
+* @par Open source address
+* https://github.com/lotoohe-space/XTinyModbus
+* @par modify log:
+*
+* | Date | Version | Author | Description
+* |
|---|
| 2020-4-10 | 1.0 | zspace | First version
+* |
+*
+**********************************************************************************
+*/
+/*********************************HEAD FILE************************************/
+#include "MD_RTU_MapTable.h"
+/*********************************END******************************************/
+
+/**
+* @brief Add a mapping to master or slave
+* @param[in] obj Slave or host object pointer
+* @param[in] pRegCoilItem Slave or host object pointer
+* @return
+* - TRUE success
+* - FALSE fail
+*/
+uint8 MapTableAdd(void* obj,PMapTableItem pMapTableItem,uint16 tabSize){
+ uint16 i=0;
+ PMapTableItem *pMapTableList=obj;
+ if(!obj){return FALSE;}
+ for(i=0;idata=data;
+ q->maxVal = maxVal;
+ q->front = q->rear = 0;
+ q->valid = TRUE;
+ return TRUE;
+}
+/**
+* @brief Get the length of the data in the queue
+* @param[in] q Queue object pointer
+* @return The length of valid data in the queue
+*/
+uint16 MDQueueLength(MDSqQueue* q) {
+ if (q == NULL) { return 0; }
+ return (q->rear - q->front + q->maxVal) % q->maxVal;
+}
+/**
+* @brief Queue reset (cleared)
+* @param q Queue object pointer
+* @return None
+*/
+void MDResetQueue(MDSqQueue* q) {
+ if (q == NULL) { return ; }
+ q->front = q->rear = 0;
+}
+/**
+* @brief Whether the queue is empty
+* @param q Queue object pointer
+* @return
+* - TRUE empty
+* - FALSE Not empty
+*/
+uint8 MDQueueEmpty(MDSqQueue* q) {
+ if (q == NULL) { return 1; }
+ return (q->front == q->rear);
+}
+/**
+* @brief Insert at the end of the queue
+* @param[in] q Queue object pointer
+* @param[in] e Inserted element
+* @return
+* - TRUE success
+* - FALSE fail
+*/
+uint8 MDenQueue(MDSqQueue* q, MDQueueDataType *e,SqQueueType type) {
+ if ((q->rear + 1) % q->maxVal == q->front) {
+ return FALSE;
+ }
+ q->rear = (q->rear + 1) % q->maxVal;
+ switch(type){
+ case CHAR_TYPE:
+ ((char*)(q->data))[q->rear] = *((char*)e);
+ break;
+ case UINT8_TYPE:
+ ((uint8*)(q->data))[q->rear] = *((uint8*)e);
+ break;
+ case SHORT_TYPE:
+ ((short*)(q->data))[q->rear] = *((short*)e);
+ break;
+ case INT_TYPE:
+ ((int*)(q->data))[q->rear] = *((int*)e);
+ break;
+ case FLOAT_TYPE:
+ ((float*)(q->data))[q->rear] = *((float*)e);
+ break;
+ }
+
+ return TRUE;
+}
+/**
+* @brief Queue head insertion
+* @param[in] q Queue object pointer
+* @param[in] e Inserted element
+* @return
+* - TRUE success
+* - FALSE fail
+*/
+uint8 MDenQueueH(MDSqQueue* q, MDQueueDataType *e,SqQueueType type){
+ if((q->front - 1 + q->maxVal) % q->maxVal == q->rear)
+ return FALSE;
+
+ switch(type){
+ case CHAR_TYPE:
+ ((char*)(q->data))[q->front] = *((char*)e);
+ break;
+ case UINT8_TYPE:
+ ((uint8*)(q->data))[q->front] = *((uint8*)e);
+ break;
+ case SHORT_TYPE:
+ ((short*)(q->data))[q->front] = *((short*)e);
+ break;
+ case INT_TYPE:
+ ((int*)(q->data))[q->front] = *((int*)e);
+ break;
+ case FLOAT_TYPE:
+ ((float*)(q->data))[q->front] = *((float*)e);
+ break;
+ }
+ q->front = (q->front - 1 + q->maxVal) % q->maxVal;
+ return TRUE;
+}
+/**
+* @brief Queue head out of the queue
+* @param[in] q Queue object pointer
+* @param[in] e Obtained elements
+* @return
+* - TRUE success
+* - FALSE fail
+*/
+uint8 MDdeQueue(MDSqQueue* q, MDQueueDataType *e,SqQueueType type) {
+ if (q->front == q->rear) { /*Empty, return an error*/
+ return FALSE;
+ }
+ q->front = (q->front + 1) % q->maxVal;
+
+ switch(type){
+ case CHAR_TYPE:
+ *((char*)e)=((char*)(q->data))[q->front];
+ break;
+ case UINT8_TYPE:
+ *((uint8*)e)=((uint8*)(q->data))[q->front];
+ break;
+ case SHORT_TYPE:
+ *((short*)e)=((short*)(q->data))[q->front];
+ break;
+ case INT_TYPE:
+ *((int*)e)=((int*)(q->data))[q->front];
+ break;
+ case FLOAT_TYPE:
+ *((int*)e)=((float*)(q->data))[q->front];
+ break;
+ }
+ return TRUE;
+}
+/**
+* @brief Queue tail out
+* @param[in] q Queue object pointer
+* @param[in] e Obtained elements
+* @return
+* - TRUE success
+* - FALSE fail
+*/
+uint8 MDdeQueueF(MDSqQueue* q, MDQueueDataType *e,SqQueueType type) {
+ if(q->front == q->rear){
+ return FALSE;
+ }
+ switch(type){
+ case CHAR_TYPE:
+ *((char*)e)=((char*)(q->data))[q->rear];
+ break;
+ case UINT8_TYPE:
+ *((uint8*)e)=((uint8*)(q->data))[q->rear];
+ break;
+ case SHORT_TYPE:
+ *((short*)e)=((short*)(q->data))[q->rear];
+ break;
+ case INT_TYPE:
+ *((int*)e)=((int*)(q->data))[q->rear];
+ break;
+ case FLOAT_TYPE:
+ *((int*)e)=((float*)(q->data))[q->rear];
+ break;
+ }
+ q->rear = (q->rear - 1 + q->maxVal) % q->maxVal;
+ return TRUE;
+}
+/**
+* @brief Get the element at the end of the queue without affecting the queue, only the element
+* @param[in] q Queue object pointer
+* @param[in] e Obtained elements
+* @return
+* - TRUE succes
+* - FALSE fail
+*/
+uint8 MDgetTailQueue(MDSqQueue* q, MDQueueDataType* e,SqQueueType type) {
+ if (q->front == q->rear) { /*Empty, return an error*/
+ return FALSE;
+ }
+
+ switch(type){
+ case CHAR_TYPE:
+ *((char*)e)=((char*)(q->data))[(q->front + 1) % q->maxVal];
+ break;
+ case UINT8_TYPE:
+ *((uint8*)e)=((uint8*)(q->data))[(q->front + 1) % q->maxVal];
+ break;
+ case SHORT_TYPE:
+ *((short*)e)=((short*)(q->data))[(q->front + 1) % q->maxVal];
+ break;
+ case INT_TYPE:
+ *((int*)e)=((int*)(q->data))[(q->front + 1) % q->maxVal];
+ break;
+ case FLOAT_TYPE:
+ *((int*)e)=((float*)(q->data))[(q->front + 1) % q->maxVal];
+ break;
+ }
+ return TRUE;
+}
+
+
diff --git a/mkrtos_user/lib/modbus/src/modbus_rtu_master/MDM_RTU_Fun.c b/mkrtos_user/lib/modbus/src/modbus_rtu_master/MDM_RTU_Fun.c
new file mode 100644
index 000000000..10b83740d
--- /dev/null
+++ b/mkrtos_user/lib/modbus/src/modbus_rtu_master/MDM_RTU_Fun.c
@@ -0,0 +1,1386 @@
+/********************************************************************************
+* @File name: MDM_RTU_Fun.c
+* @Author: zspace
+* @Emial: 1358745329@qq.com
+* @Version: 1.0
+* @Date: 2020-4-10
+* @Description: Modbus RTU host function module
+* Open source address: https://github.com/lotoohe-space/XTinyModbus
+********************************************************************************/
+
+/*********************************THE HEADER FILE CONTAINS************************************/
+#include "MDM_RTU_Fun.h"
+// #include "MDM_RTU_Serial.h"
+#include "MD_RTU_Tool.h"
+#include "MD_RTU_CRC16.h"
+#include "MD_RTU_SysInterface.h"
+#include "MD_RTU_Type.h"
+#include
+/*********************************END******************************************/
+
+/*********************************FUNCTION DECLARATION************************************/
+#if !MDM_USE_SEND_CACHE
+static void MDM_RTU_SendByte(PModbus_RTU pModbus_RTU,uint8 byte);
+#endif
+void MDM_RTU_RecvByte(void *obj,uint8 byte);
+/*********************************END******************************************/
+
+/*******************************************************
+*
+* Function name :MDM_RTU_Init
+* Description :Modbus RTU Host initialization
+* Parameter :
+* @pModbusRTU Host object pointer
+* @mdRTUSerialInitFun Serial port initialization function
+* @baud Baud rate
+* @dataBits Data bit
+* @stopBits Stop bit
+* @parity Parity bit
+* Return : reference[MDError]
+**********************************************************/
+MDError MDM_RTU_Init(
+ PModbus_RTU pModbusRTU,
+ MD_RTU_SerialInit mdRTUSerialInitFun,
+ uint32 baud,
+ uint8 dataBits,
+ uint8 stopBits,
+ uint8 parity
+){
+ float T;
+ uint8 i;
+ if(pModbusRTU==NULL){return ERR_VOID;}
+
+#if MD_RTU_USED_OS
+ if(pModbusRTU->mdRTUMsgHandle==NULL){
+ if(!MD_RTU_CreateMsg((PModbusBase)pModbusRTU, &(pModbusRTU->mdRTUMsgHandle),MD_RTU_MSG_BOX_LENGTH)){
+ return ERR_CTE_OBJ;
+ }
+ }
+ if(pModbusRTU->mdRTULockHandle==NULL){
+ if(!MD_RTU_CreateLock((PModbusBase)pModbusRTU, &(MD_RTU_LOCK_HANDLE_ARG(pModbusRTU)))){
+ return ERR_CTE_OBJ;
+ }
+ }
+ if(pModbusRTU->mdRTULockObjHandle==NULL){
+ if(!MD_RTU_CreateLock((PModbusBase)pModbusRTU, &(MD_RTU_LOCK_OBJ_HANDLE_ARG(pModbusRTU)))){
+ return ERR_CTE_OBJ;
+ }
+ }
+ if(pModbusRTU->mdRTULockObj1Handle==NULL){
+ if(!MD_RTU_CreateLock((PModbusBase)pModbusRTU, &(MD_RTU_LOCK_OBJ1_HANDLE_ARG(pModbusRTU)))){
+ return ERR_CTE_OBJ;
+ }
+ }
+ if(pModbusRTU->mdRTUTaskHandle==NULL){
+ if(!MD_RTU_CreateThread((PModbusBase)pModbusRTU,MDM_RTU_SysProcessTask,&MD_RTU_TASK_HANDLE_ARG(pModbusRTU))){
+ return ERR_CTE_OBJ;
+ }
+ }
+#endif
+
+ MD_RTU_LOCK((PModbusBase)pModbusRTU,MD_RTU_LOCK_HANDLE_ARG(pModbusRTU));
+ //MDInitQueue(&(pModbusRTU->mdSqQueue),UINT8_TYPE);
+ pModbusRTU->mdSqQueue.data=NULL;
+ pModbusRTU->mdSqQueue.maxVal=0;
+ MD_RTU_UNLOCK((PModbusBase)pModbusRTU,MD_RTU_LOCK_HANDLE_ARG(pModbusRTU));
+
+ MD_RTU_LOCK((PModbusBase)pModbusRTU,MD_RTU_LOCK_OBJ_HANDLE_ARG(pModbusRTU));
+ for(i=0;ipMapTableList[i] = NULL;
+ }
+ TO_MDBase(pModbusRTU)->mdRTUTimeHandlerFunction=MDM_RTU_TimeHandler;
+ /*Data sending and receiving related functions*/
+ TO_MDBase(pModbusRTU)->mdRTUSendBytesFunction=NULL;
+ TO_MDBase(pModbusRTU)->mdRTURecByteFunction=MDM_RTU_RecvByte;
+ TO_MDBase(pModbusRTU)->mdRTURecSendConv=NULL;
+#if MDM_USE_SEND_CACHE
+ pModbusRTU->serialSendCount=0;
+#endif
+ /*The time of the last reception, 0xFFFFFFF means that the detection frame has not started*/
+ pModbusRTU->lastTimesTick=0xFFFFFFFF;
+ /*Current real-time time unit 100US*/
+ pModbusRTU->timesTick=0;
+
+ T=(1.0/(float)baud)*10000;
+ uint16 time=0;
+ time=T*(dataBits+(parity?1:0));
+ if(stopBits==0){
+ time+=T;
+ }else if(stopBits==1){
+ time+=T*1.5f;
+ }else if(stopBits==2){
+ time+=T*2;
+ }
+ pModbusRTU->frameIntervalTime=time;/*This parameter needs to be set according to the baud rate*/
+
+ pModbusRTU->recvFlag=0;/*Receive flag*/
+ if(mdRTUSerialInitFun!=NULL){
+ mdRTUSerialInitFun(pModbusRTU,baud, dataBits,stopBits,parity);
+ }
+ MD_RTU_UNLOCK((PModbusBase)pModbusRTU,MD_RTU_LOCK_OBJ_HANDLE_ARG(pModbusRTU));
+ return ERR_NONE;
+}
+/**
+* @brief This function init queue.
+* @param[in] recvQueueData ????
+* @param[in] recvQueueSize ????
+* @result None
+*/
+void MDM_RTU_QueueInit(PModbus_RTU pModbus_RTU,
+ uint8* recvQueueData,
+ uint16 recvQueueSize
+){
+ if(pModbus_RTU==NULL){
+ return ;
+ }
+ MD_RTU_LOCK((PModbusBase)pModbus_RTU,MD_RTU_LOCK_HANDLE_ARG(pModbus_RTU));
+ MDInitQueue(&(pModbus_RTU->mdSqQueue),recvQueueData,recvQueueSize);
+ MD_RTU_UNLOCK((PModbusBase)pModbus_RTU,MD_RTU_LOCK_HANDLE_ARG(pModbus_RTU));
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_CB_Init
+* Description :Modbus RTU host sends the control block initialization,
+* the control block mainly contains information maintenance
+* such as the time and frequency of slave transmission
+* Parameter :
+* @pModbusRTUCB Send control block object pointer
+* @pModbusRTU Host object pointer
+* @sendIntervalTime Send interval time
+* @sendOverTime Send timeout
+* @RTTimes Number of retransmissions
+* Return : None
+**********************************************************/
+void MDM_RTU_CB_Init(
+ PModbus_RTU_CB pModbusRTUCB
+ ,PModbus_RTU pModbusRTU
+ ,uint32 sendIntervalTime
+ ,uint32 sendOverTime
+ ,uint8 RTTimes
+){
+ if(pModbusRTUCB==NULL){return ;}
+ MD_RTU_LOCK((PModbusBase)pModbusRTU,MD_RTU_LOCK_OBJ_HANDLE_ARG(pModbusRTU));
+ pModbusRTUCB->sendIntervalTime=sendIntervalTime;
+ pModbusRTUCB->pModbus_RTU=pModbusRTU;
+ pModbusRTUCB->sendTimeTick=MD_RTU_GetSysTick();
+ pModbusRTUCB->sendOverTime=sendOverTime;
+ pModbusRTUCB->RTTimes=RTTimes;
+ pModbusRTUCB->sendFlag=0;
+ pModbusRTU->parentObj=NULL;
+ MD_RTU_UNLOCK((PModbusBase)pModbusRTU,MD_RTU_LOCK_OBJ_HANDLE_ARG(pModbusRTU));
+}
+/*******************************************************
+*
+* Function name : MDM_RTU_CB_OverTimeReset
+* Description : Send control block timeout reset
+* Parameter :
+* @pModbusRTUCB Send control block object pointer
+* Return : None
+**********************************************************/
+void MDM_RTU_CB_OverTimeReset(PModbus_RTU_CB pModbusRTUCB){
+ if(pModbusRTUCB==NULL){return ;}
+ MD_RTU_LOCK((PModbusBase)(pModbusRTUCB->pModbus_RTU),MD_RTU_LOCK_OBJ_HANDLE_ARG((pModbusRTUCB->pModbus_RTU)));
+ pModbusRTUCB->RTCount=0;
+ pModbusRTUCB->sendFlag=0;
+ pModbusRTUCB->sendTimeTick=pModbusRTUCB->pModbus_RTU->timesTick;
+ MD_RTU_UNLOCK((PModbusBase)(pModbusRTUCB->pModbus_RTU),MD_RTU_LOCK_OBJ_HANDLE_ARG((pModbusRTUCB->pModbus_RTU)));
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_CB_ClrDisFlag
+* Description :Clear disconnection signs
+* Parameter :
+* @pModbusRTUCB Send control block object pointer
+* Return : ��
+**********************************************************/
+void MDM_RTU_CB_ClrDisFlag(PModbus_RTU_CB pModbusRTUCB){
+ if(pModbusRTUCB==NULL){return ;}
+ MD_RTU_LOCK((PModbusBase)(pModbusRTUCB->pModbus_RTU),MD_RTU_LOCK_OBJ_HANDLE_ARG((pModbusRTUCB->pModbus_RTU)));
+ MD_CB_CLR_DIS_FLAG(pModbusRTUCB);
+ MD_RTU_UNLOCK((PModbusBase)(pModbusRTUCB->pModbus_RTU),MD_RTU_LOCK_OBJ_HANDLE_ARG((pModbusRTUCB->pModbus_RTU)));
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_CB_SetDisPollEnFlag
+* Description : Set the offline polling enable flag bit.
+* Parameter :
+* @pModbusRTUCB Send control block object pointer.
+* @state The state to be set.
+* Return : None
+**********************************************************/
+void MDM_RTU_CB_SetDisPollEnFlag(PModbus_RTU_CB pModbusRTUCB,BOOL state){
+ if(pModbusRTUCB==NULL){return ;}
+ MD_RTU_LOCK((PModbusBase)(pModbusRTUCB->pModbus_RTU),MD_RTU_LOCK_OBJ_HANDLE_ARG((pModbusRTUCB->pModbus_RTU)));
+ if(state){
+ MD_CB_SET_DIS_FLAG_EN(pModbusRTUCB);
+ }else{
+ MD_CB_CLR_DIS_FLAG_EN(pModbusRTUCB);
+ }
+ MD_RTU_UNLOCK((PModbusBase)(pModbusRTUCB->pModbus_RTU),MD_RTU_LOCK_OBJ_HANDLE_ARG((pModbusRTUCB->pModbus_RTU)));
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_TimeHandler
+* Description :Timing processing function, timing unit 100US
+* Parameter :
+* @obj Host object pointer
+* Return : None
+**********************************************************/
+void MDM_RTU_TimeHandler(void *obj,uint32 timesTick){
+ PModbus_RTU pModbusRTU=obj;
+ if(!pModbusRTU){ return; }
+ //pModbusRTU->timesTick++;
+ MD_RTU_LOCK((PModbusBase)pModbusRTU,MD_RTU_LOCK_OBJ_HANDLE_ARG(pModbusRTU));
+ pModbusRTU->timesTick=timesTick;
+ /*No need to deal with*/
+ if(pModbusRTU->lastTimesTick==0xFFFFFFFF){
+ MD_RTU_UNLOCK((PModbusBase)pModbusRTU,MD_RTU_LOCK_OBJ_HANDLE_ARG(pModbusRTU));
+ return ;
+ }
+ if(pModbusRTU->timesTick-pModbusRTU->lastTimesTick>=pModbusRTU->frameIntervalTime){
+ if(pModbusRTU->CRC16Update!=0x0000){
+ /*CRC error*/
+ MD_RTU_LOCK((PModbusBase)(pModbusRTU),MD_RTU_LOCK_HANDLE_ARG((pModbusRTU)));
+ MDResetQueue(&(pModbusRTU->mdSqQueue));
+ MD_RTU_UNLOCK((PModbusBase)(pModbusRTU),MD_RTU_LOCK_HANDLE_ARG((pModbusRTU)));
+ pModbusRTU->lastTimesTick=0xFFFFFFFF;
+ MD_RTU_UNLOCK((PModbusBase)pModbusRTU,MD_RTU_LOCK_OBJ_HANDLE_ARG(pModbusRTU));
+ return ;
+ }
+ /*End of one frame*/
+ pModbusRTU->recvFlag=1;
+ pModbusRTU->lastTimesTick=0xFFFFFFFF;
+ }
+ MD_RTU_UNLOCK((PModbusBase)pModbusRTU,MD_RTU_LOCK_OBJ_HANDLE_ARG(pModbusRTU));
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_RecvByte
+* Description :This function receives data and puts it in the queue
+* Parameter :
+* @obj Host object pointer
+* @byte A byte received
+* Return : None
+**********************************************************/
+void MDM_RTU_RecvByte(void *obj,uint8 byte){
+ PModbus_RTU pModbusRTU=obj;
+ if(!pModbusRTU){ return; }
+ MD_RTU_LOCK((PModbusBase)(pModbusRTU),MD_RTU_LOCK_HANDLE_ARG((pModbusRTU)));
+ if(MDenQueue(&(pModbusRTU->mdSqQueue),&byte,UINT8_TYPE)==FALSE){
+ MD_RTU_UNLOCK((PModbusBase)(pModbusRTU),MD_RTU_LOCK_HANDLE_ARG((pModbusRTU)));
+ return ;
+ }
+ MD_RTU_UNLOCK((PModbusBase)(pModbusRTU),MD_RTU_LOCK_HANDLE_ARG((pModbusRTU)));
+ MD_RTU_LOCK((PModbusBase)pModbusRTU,MD_RTU_LOCK_OBJ_HANDLE_ARG(pModbusRTU));
+ if(pModbusRTU->lastTimesTick==0xFFFFFFFF){
+ pModbusRTU->CRC16Update=0xFFFF;
+ }
+ pModbusRTU->CRC16Update=MD_CRC16Update(pModbusRTU->CRC16Update,byte);
+ /*Save the timestamp of the last character received*/
+ pModbusRTU->lastTimesTick=pModbusRTU->timesTick;
+ MD_RTU_UNLOCK((PModbusBase)pModbusRTU,MD_RTU_LOCK_OBJ_HANDLE_ARG(pModbusRTU));
+}
+
+#if MD_RTU_USED_OS ///< used os
+void MDM_RTU_SysProcessTask(void *arg){
+ PModbus_RTU pModbusRTU=(PModbus_RTU)arg;
+ for(;;){
+ void *msg=NULL;
+ while(1){
+ if(MD_RTU_MSG_GET((PModbusBase)pModbusRTU,MD_RTU_MSG_HANDLE_ARG(pModbusRTU),&msg,0)){
+ MDM_RTU_RecvByte((void*)pModbusRTU,(uint8)(msg));
+ }else{
+ break;
+ }
+ }
+ MDM_RTU_TimeHandler((void*)pModbusRTU,MD_RTU_GetSysTick());
+ MD_RTU_Delay(5);
+ }
+}
+#endif
+
+#if !MDM_USE_SEND_CACHE
+/*******************************************************
+*
+* Function name :MDM_RTU_SendByte
+* Description :����һ���ֽ�
+* Parameter :
+* @pModbus_RTU ��������ָ��
+* @byte ���͵�һ���ֽ�
+* Return : ��
+**********************************************************/
+static void MDM_RTU_SendByte(PModbus_RTU pModbus_RTU,uint8 byte){
+ if(!pModbus_RTU){ return; }
+ TO_MDBase(pModbus_RTU)->mdRTUSendBytesFunction(&byte,1);
+}
+#endif
+/*******************************************************
+*
+* Function name :MDM_RTU_AddMapItem
+* Description :This function adds a mapping record to the discrete mapping table
+* Parameter :
+* @pModbusRTU Host structure pointer
+* @pRegCoilItem Items to be added
+* Return : None
+**********************************************************/
+BOOL MDM_RTU_AddMapItem(PModbus_RTU pModbusRTU,PMapTableItem pMapTableItem){
+ BOOL res;
+ if(pModbusRTU==NULL || pMapTableItem==NULL){
+ return FALSE;
+ }
+ MD_RTU_LOCK((PModbusBase)(pModbusRTU),MD_RTU_LOCK_OBJ_HANDLE_ARG((pModbusRTU)));
+ res=MapTableAdd(pModbusRTU->pMapTableList, pMapTableItem,MDM_REG_COIL_ITEM_NUM);
+ MD_RTU_UNLOCK((PModbusBase)(pModbusRTU),MD_RTU_LOCK_OBJ_HANDLE_ARG((pModbusRTU)));
+ return res;
+}
+
+/*******************************************************
+*
+* Function name :MDM_RTU_ReadByte
+* Description :Get data from the receiving queue
+* Parameter :
+* @pModbus_RTU Host object pointer
+* @res Get the data cache
+* @len The length of the data obtained
+* Return : None
+**********************************************************/
+MDError MDM_RTU_ReadByte(PModbus_RTU pModbusRTU,uint8 *res,uint8 len){
+ uint8 i;
+ uint8 resI;
+ if(res==NULL){return ERR_VOID;}
+ for(i=0;imdSqQueue),(res+i),UINT8_TYPE);
+ MD_RTU_UNLOCK((PModbusBase)(pModbusRTU),MD_RTU_LOCK_HANDLE_ARG((pModbusRTU)));
+ if(!resI){
+ return ERR_QUEUE;
+ }
+ }
+ return ERR_NONE;
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_ReadUint16
+* Description :Get data from the receiving queue
+* Parameter :
+* @pModbus_RTU Host object pointer
+* @res Get data cache
+* @len The length of the data obtained
+* Return : None
+**********************************************************/
+MDError MDM_RTU_ReadUint16(PModbus_RTU pModbusRTU,uint16 *res,uint8 len){
+ uint8 i;
+ uint8 byte;
+ if(res==NULL){return ERR_VOID;}
+ MD_RTU_LOCK((PModbusBase)(pModbusRTU),MD_RTU_LOCK_HANDLE_ARG((pModbusRTU)));
+ for(i=0;imdSqQueue),&byte,UINT8_TYPE)){
+ MD_RTU_UNLOCK((PModbusBase)(pModbusRTU),MD_RTU_LOCK_HANDLE_ARG((pModbusRTU)));
+ return ERR_QUEUE;
+ }
+ res[i]=byte<<8;
+ if(!MDdeQueue(&(pModbusRTU->mdSqQueue),&byte,UINT8_TYPE)){
+ MD_RTU_UNLOCK((PModbusBase)(pModbusRTU),MD_RTU_LOCK_HANDLE_ARG((pModbusRTU)));
+ return ERR_QUEUE;
+ }
+ res[i]|=byte;
+ }
+ MD_RTU_UNLOCK((PModbusBase)(pModbusRTU),MD_RTU_LOCK_HANDLE_ARG((pModbusRTU)));
+ return ERR_NONE;
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_ReadFun
+* Description :This function sends commands related to the read function
+* Parameter :
+* @pModbus_RTU Host object pointer
+* @funCode function code
+* @slaveAddr Slave address
+* @startAddr Read start address
+* @numOf Number of reads
+* Return : None
+**********************************************************/
+static void MDM_RTU_ReadFun(PModbus_RTU pModbus_RTU,uint8 funCode,uint8 slaveAddr,uint16 startAddr,uint16 numOf){
+ MD_RTU_SEND_MODE(pModbus_RTU);
+ MEM_RTU_START_EN(pModbus_RTU);
+ MEM_RTU_EN_QUEUE(pModbus_RTU,slaveAddr);
+ MEM_RTU_EN_QUEUE(pModbus_RTU,funCode);
+ MEM_RTU_EN_QUEUE(pModbus_RTU,MD_H_BYTE(startAddr));
+ MEM_RTU_EN_QUEUE(pModbus_RTU,MD_L_BYTE(startAddr));
+ MEM_RTU_EN_QUEUE(pModbus_RTU,MD_H_BYTE(numOf));
+ MEM_RTU_EN_QUEUE(pModbus_RTU,MD_L_BYTE(numOf));
+ MEM_RTU_END_EN(pModbus_RTU);
+ MD_RTU_RECV_MODE(pModbus_RTU);
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_WriteSingleFun
+* Description :Write single coil and register function
+* Parameter :
+* @pModbus_RTU Host object pointer
+* @funCode function code
+* @slaveAddr Slave address
+* @startAddr Write start address
+* @value Value written
+* Return : None
+**********************************************************/
+static void MDM_RTU_WriteSingleFun(PModbus_RTU pModbus_RTU,uint8 funCode,uint8 slaveAddr,uint16 startAddr,uint16 value){
+ MD_RTU_SEND_MODE(pModbus_RTU);
+ MEM_RTU_START_EN(pModbus_RTU);
+ MEM_RTU_EN_QUEUE(pModbus_RTU,slaveAddr);
+ MEM_RTU_EN_QUEUE(pModbus_RTU,funCode);
+ MEM_RTU_EN_QUEUE(pModbus_RTU,MD_H_BYTE(startAddr));
+ MEM_RTU_EN_QUEUE(pModbus_RTU,MD_L_BYTE(startAddr));
+ MEM_RTU_EN_QUEUE(pModbus_RTU,MD_H_BYTE(value));
+ MEM_RTU_EN_QUEUE(pModbus_RTU,MD_L_BYTE(value));
+ MEM_RTU_END_EN(pModbus_RTU);
+ MD_RTU_RECV_MODE(pModbus_RTU);
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_WriteFun
+* Description :Write multiple coils and multiple registers
+* Parameter :
+* @pModbus_RTU Host object pointer
+* @funCode function code
+* @slaveAddr Slave address
+* @startAddr Write start address
+* @numOf Number of data written
+* @data Data written
+* Return : None
+**********************************************************/
+static void MDM_RTU_WriteFun(PModbus_RTU pModbus_RTU,
+ uint8 funCode,uint8 slaveAddr,uint16 startAddr,uint8 numOf,uint8 *data){
+ uint16 i;
+ uint8 wLen;
+ MD_RTU_SEND_MODE(pModbus_RTU);
+ MEM_RTU_START_EN(pModbus_RTU);
+ MEM_RTU_EN_QUEUE(pModbus_RTU,slaveAddr);
+ MEM_RTU_EN_QUEUE(pModbus_RTU,funCode);
+ MEM_RTU_EN_QUEUE(pModbus_RTU,MD_H_BYTE(startAddr));
+ MEM_RTU_EN_QUEUE(pModbus_RTU,MD_L_BYTE(startAddr));
+ MEM_RTU_EN_QUEUE(pModbus_RTU,MD_H_BYTE(numOf));
+ MEM_RTU_EN_QUEUE(pModbus_RTU,MD_L_BYTE(numOf));
+ if(funCode==15){
+ wLen=(numOf>>3) + ((numOf%8)?1:0);
+ }else if(funCode==16){
+ wLen=numOf<<1;
+ }
+ MEM_RTU_EN_QUEUE(pModbus_RTU,wLen);
+ if(funCode == 15){
+ for(i=0;i>8));
+ MEM_RTU_EN_QUEUE(pModbus_RTU,(tempData[i]&0xff));
+ }
+ }
+ MEM_RTU_END_EN(pModbus_RTU);
+ MD_RTU_RECV_MODE(pModbus_RTU);
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_InsideWriteBits
+* Description :Write bits to the discrete map
+* Parameter :
+* @obj Host object pointer
+* @modbusAddr Discretely mapped modbus address
+* @numOf Write number
+* @bit Data written
+* @opAddrType Write address type (COILS_TYPE, INPUT_TYPE), see [AddrType]
+* Return : TRUE , FALSE
+**********************************************************/
+BOOL MDM_RTU_InsideWriteBits(
+ void* obj,
+ uint16 modbusAddr,
+ uint16 numOf,
+ uint8 *bit,
+ AddrType opAddrType,
+ uint8 devAddr
+){
+ uint16 i;
+ PModbus_RTU pModbus_RTU = obj;
+ if(pModbus_RTU==NULL){return FALSE;}
+ if(opAddrType != COILS_TYPE && opAddrType != INPUT_TYPE){return FALSE;}
+
+ for(i=0;ipMapTableList[i]==NULL){
+ continue;
+ }
+ /*Check the device number*/
+ if(devAddr!=pModbus_RTU->pMapTableList[i]->devAddr){continue;}
+
+ if(pModbus_RTU->pMapTableList[i]->modbusAddr<=modbusAddr&&
+ (pModbus_RTU->pMapTableList[i]->modbusAddr+pModbus_RTU->pMapTableList[i]->modbusDataSize)>=(modbusAddr+numOf)
+ ){
+ if(pModbus_RTU->pMapTableList[i]->addrType==opAddrType){/*Must be BIT type*/
+ uint16 offsetAddr=modbusAddr-MDS_RTU_REG_COIL_ITEM_ADDR(pModbus_RTU->pMapTableList[i]);
+ uint16 j;
+ MD_RTU_LOCK((PModbusBase)(pModbus_RTU),MD_RTU_LOCK_OBJ_HANDLE_ARG((pModbus_RTU)));
+ for(j=0;j>3] ,j%8)
+ ){
+ MD_SET_BIT(
+ MDS_RTU_REG_COIL_ITEM_DATA(
+ pModbus_RTU->pMapTableList[i])[(offsetAddr+j)>>4]
+ ,(j+offsetAddr)%16);
+ }else{
+ MD_CLR_BIT(
+ MDS_RTU_REG_COIL_ITEM_DATA(
+ pModbus_RTU->pMapTableList[i])[(offsetAddr+j)>>4]
+ ,(j+offsetAddr)%16);
+ }
+ }
+ MD_RTU_UNLOCK((PModbusBase)(pModbus_RTU),MD_RTU_LOCK_OBJ_HANDLE_ARG((pModbus_RTU)));
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_InsideWriteRegs
+* Description :Write discrete register
+* Parameter :
+* @obj Host object pointer
+* @modbusAddr Discretely mapped modbus address
+* @numOf Write number
+* @reg Data written
+* @isBigE Big-endian or little-endian
+* @opAddrType Write address type (HOLD_REGS_TYPE, INPUT_REGS_TYPE), see [AddrType]
+* Return : TRUE , FALSE
+**********************************************************/
+BOOL MDM_RTU_InsideWriteRegs(
+void* obj,
+uint16 modbusAddr,
+uint16 numOf,
+uint16 *reg,
+uint8 isBigE,
+AddrType opAddrType,
+uint8 devAddr
+){
+ uint16 i;
+ PModbus_RTU pModbus_RTU = obj;
+ if(pModbus_RTU==NULL){return FALSE;}
+ if(opAddrType != HOLD_REGS_TYPE && opAddrType != INPUT_REGS_TYPE){return FALSE;}
+
+ for(i=0;ipMapTableList[i]==NULL){
+ continue;
+ }
+ /*Check the device number*/
+ if(devAddr!=pModbus_RTU->pMapTableList[i]->devAddr){continue;}
+
+ if(pModbus_RTU->pMapTableList[i]->modbusAddr<=modbusAddr&&
+ (pModbus_RTU->pMapTableList[i]->modbusAddr+pModbus_RTU->pMapTableList[i]->modbusDataSize)>=(modbusAddr+numOf)
+ ){
+ if(pModbus_RTU->pMapTableList[i]->addrType==opAddrType){/*������REG����*/
+ uint16 offsetAddr=modbusAddr-MDS_RTU_REG_COIL_ITEM_ADDR(pModbus_RTU->pMapTableList[i]);
+ uint16 j=0;
+ MD_RTU_LOCK((PModbusBase)(pModbus_RTU),MD_RTU_LOCK_OBJ_HANDLE_ARG((pModbus_RTU)));
+ for(j=0;jpMapTableList[i])[offsetAddr+j]=
+ isBigE?MD_SWAP_HL(reg[j]):reg[j];
+ }
+ MD_RTU_UNLOCK((PModbusBase)(pModbus_RTU),MD_RTU_LOCK_OBJ_HANDLE_ARG((pModbus_RTU)));
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_NB_RW
+* Description :Non-blocking read and write
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @funCode Function code, see [ModbusFunCode]
+* @slaveAddr Slave address
+* @startAddr Read and write start address
+* @numOf Number of read and write data
+* @wData If it is a write function code, then it is the written data
+* Return : See [MDError]
+**********************************************************/
+static MDError MDM_RTU_NB_RW(
+ PModbus_RTU_CB pModbus_RTU_CB,
+ ModbusFunCode funCode,
+ uint8 slaveAddr,
+ uint16 startAddr,
+ uint16 numOf,
+ void *wData
+){
+ MDError errRes;
+ uint8 index;
+ uint16 wAddr;
+ errRes = ERR_NONE;
+ if(pModbus_RTU_CB==NULL){return ERR_VOID;}
+ if(pModbus_RTU_CB->pModbus_RTU==NULL){return ERR_VOID;}
+
+ if(MD_CB_GET_DIS_FLAG_EN(pModbus_RTU_CB)/*Enable the drop-off non-polling flag*/
+ &&MD_CB_GET_DIS_FLAG(pModbus_RTU_CB)){/*Device dropped*/
+ return ERR_DEV_DIS;
+ }
+
+ if( pModbus_RTU_CB->pModbus_RTU->parentObj!=NULL &&
+ pModbus_RTU_CB!=pModbus_RTU_CB->pModbus_RTU->parentObj){
+ //Check if you are using the current Modbus
+ return ERR_IDLE;
+ }
+ pModbus_RTU_CB->pModbus_RTU->blockMode=1;/*set to non-block*/
+ if(pModbus_RTU_CB->sendFlag==0){/*Has not been sent, or has been sent successfully*/
+ /*Clear the receive queue*/
+ MD_RTU_LOCK((PModbusBase)(pModbus_RTU_CB->pModbus_RTU),
+ MD_RTU_LOCK_HANDLE_ARG((pModbus_RTU_CB->pModbus_RTU)));
+ MDResetQueue(&(pModbus_RTU_CB->pModbus_RTU->mdSqQueue));
+ MD_RTU_UNLOCK((PModbusBase)(pModbus_RTU_CB->pModbus_RTU),
+ MD_RTU_LOCK_HANDLE_ARG((pModbus_RTU_CB->pModbus_RTU)));
+ if(funCode>=1 && funCode<=4){
+ /*Have not sent, then send*/
+ MDM_RTU_ReadFun(pModbus_RTU_CB->pModbus_RTU,funCode,slaveAddr,startAddr,numOf);
+ }
+ else if(funCode==5||funCode==6){
+ if(numOf>=1){/*The length must be greater than or equal to 1*/
+ MDM_RTU_WriteSingleFun(pModbus_RTU_CB->pModbus_RTU,funCode,slaveAddr,startAddr,((uint16*)(wData))[0]);
+ }
+ }else if(funCode==15||funCode==16){
+ MDM_RTU_WriteFun(pModbus_RTU_CB->pModbus_RTU,funCode,slaveAddr,startAddr,numOf,(uint8*)(wData));
+ }
+ /*Set the start point of timeout*/
+ pModbus_RTU_CB->sendTimeTick=pModbus_RTU_CB->pModbus_RTU->timesTick;
+
+ /*Data has been sent, waiting for timeout detection*/
+ //MD_SET_SENDED_FLAG(pModbus_RTU_CB);
+ pModbus_RTU_CB->sendFlag=1;
+ /*Set the block to be working*/
+ pModbus_RTU_CB->pModbus_RTU->parentObj=pModbus_RTU_CB;
+ return ERR_SEND_FIN;
+ }else if(pModbus_RTU_CB->RTCountRTTimes){/*It has been sent, and there is no sending error*/
+
+ if(pModbus_RTU_CB->pModbus_RTU->recvFlag){/*Data received*/
+ uint8 byte;
+ uint8 funCodeByte=0;
+ /*Clear sign*/
+ pModbus_RTU_CB->pModbus_RTU->recvFlag=0;
+ MD_RTU_LOCK((PModbusBase)(pModbus_RTU_CB->pModbus_RTU),
+ MD_RTU_LOCK_HANDLE_ARG((pModbus_RTU_CB->pModbus_RTU)));
+ if(!MDdeQueue(&(pModbus_RTU_CB->pModbus_RTU->mdSqQueue),&byte,UINT8_TYPE)){
+ errRes = ERR_DATA_LEN;
+ MD_RTU_UNLOCK((PModbusBase)(pModbus_RTU_CB->pModbus_RTU),
+ MD_RTU_LOCK_HANDLE_ARG((pModbus_RTU_CB->pModbus_RTU)));
+ goto _exit;
+ }
+ MD_RTU_UNLOCK((PModbusBase)(pModbus_RTU_CB->pModbus_RTU),
+ MD_RTU_LOCK_HANDLE_ARG((pModbus_RTU_CB->pModbus_RTU)));
+ /*If data is received, process the data*/
+ if(slaveAddr!=byte){
+ errRes = ERR_SLAVE_ADDR;
+ goto _exit;
+ }
+ MD_RTU_LOCK((PModbusBase)(pModbus_RTU_CB->pModbus_RTU),
+ MD_RTU_LOCK_HANDLE_ARG((pModbus_RTU_CB->pModbus_RTU)));
+ if(!MDdeQueue(&(pModbus_RTU_CB->pModbus_RTU->mdSqQueue),&funCodeByte,UINT8_TYPE)){
+ errRes = ERR_DATA_LEN;
+ MD_RTU_UNLOCK((PModbusBase)(pModbus_RTU_CB->pModbus_RTU),
+ MD_RTU_LOCK_HANDLE_ARG((pModbus_RTU_CB->pModbus_RTU)));
+ goto _exit;
+ }
+ MD_RTU_UNLOCK((PModbusBase)(pModbus_RTU_CB->pModbus_RTU),
+ MD_RTU_LOCK_HANDLE_ARG((pModbus_RTU_CB->pModbus_RTU)));
+ switch(funCodeByte){
+ case 0x1:/*Read the coil successfully*/
+ case 0x2:/*Read input discrete*/
+ {
+ uint16 i;
+ MD_RTU_LOCK((PModbusBase)(pModbus_RTU_CB->pModbus_RTU),
+ MD_RTU_LOCK_HANDLE_ARG((pModbus_RTU_CB->pModbus_RTU)));
+ MDdeQueue(&(pModbus_RTU_CB->pModbus_RTU->mdSqQueue),&byte,UINT8_TYPE);
+ if((byte+2)!=MDQueueLength(&(pModbus_RTU_CB->pModbus_RTU->mdSqQueue))){
+ /*Wrong length*/
+ errRes = ERR_DATA_LEN;
+ MD_RTU_UNLOCK((PModbusBase)(pModbus_RTU_CB->pModbus_RTU),
+ MD_RTU_LOCK_HANDLE_ARG((pModbus_RTU_CB->pModbus_RTU)));
+ goto _exit;
+ }
+ MD_RTU_UNLOCK((PModbusBase)(pModbus_RTU_CB->pModbus_RTU),
+ MD_RTU_LOCK_HANDLE_ARG((pModbus_RTU_CB->pModbus_RTU)));
+ index = numOf;
+ wAddr=startAddr;
+ for(i=0;ipModbus_RTU),
+ MD_RTU_LOCK_HANDLE_ARG((pModbus_RTU_CB->pModbus_RTU)));
+ if(!MDdeQueue(&(pModbus_RTU_CB->pModbus_RTU->mdSqQueue),&rByte,UINT8_TYPE)){
+ /*Wrong length*/
+ errRes = ERR_DATA_LEN;
+ MD_RTU_UNLOCK((PModbusBase)(pModbus_RTU_CB->pModbus_RTU),
+ MD_RTU_LOCK_HANDLE_ARG((pModbus_RTU_CB->pModbus_RTU)));
+ goto _exit;
+ }
+ MD_RTU_UNLOCK((PModbusBase)(pModbus_RTU_CB->pModbus_RTU),
+ MD_RTU_LOCK_HANDLE_ARG((pModbus_RTU_CB->pModbus_RTU)));
+ /*Single deposit is less than or equal to 8bit*/
+ if(!MDM_RTU_InsideWriteBits(pModbus_RTU_CB->pModbus_RTU,wAddr,((index<8)?index:8), &rByte,(AddrType)funCodeByte,slaveAddr)){
+ errRes= ERR_DATA_SAVE;
+ goto _exit;
+ }
+ wAddr += ((index<8)?index:8);
+ index-=8;
+ }
+// /*Release channel*/
+// pModbus_RTU_CB->pModbus_RTU->parentObj=NULL;
+ /*Received from the machine*/
+ pModbus_RTU_CB->sendFlag=2;
+ errRes= ERR_RW_FIN;
+ goto _exit;
+ }
+ case 0x3:/*Read holding register*/
+ case 0x4:/*Read input register*/
+ {
+ uint16 i;
+ uint16 len;
+ MD_RTU_LOCK((PModbusBase)(pModbus_RTU_CB->pModbus_RTU),
+ MD_RTU_LOCK_HANDLE_ARG((pModbus_RTU_CB->pModbus_RTU)));
+ MDdeQueue(&(pModbus_RTU_CB->pModbus_RTU->mdSqQueue),&byte,UINT8_TYPE);
+ MD_RTU_UNLOCK((PModbusBase)(pModbus_RTU_CB->pModbus_RTU),
+ MD_RTU_LOCK_HANDLE_ARG((pModbus_RTU_CB->pModbus_RTU)));
+ if((byte+2)!=MDQueueLength(&(pModbus_RTU_CB->pModbus_RTU->mdSqQueue))){
+ /*Wrong length*/
+ errRes= ERR_DATA_LEN;
+ goto _exit;
+ }
+ len=byte>>1;
+ for(i=0;ipModbus_RTU),
+ MD_RTU_LOCK_HANDLE_ARG((pModbus_RTU_CB->pModbus_RTU)));
+ MDdeQueue(&(pModbus_RTU_CB->pModbus_RTU->mdSqQueue),&rByte,UINT8_TYPE);
+ wTemp=(rByte<<8);
+ MDdeQueue(&(pModbus_RTU_CB->pModbus_RTU->mdSqQueue),&rByte,UINT8_TYPE);
+ wTemp|=rByte;
+ MD_RTU_UNLOCK((PModbusBase)(pModbus_RTU_CB->pModbus_RTU),
+ MD_RTU_LOCK_HANDLE_ARG((pModbus_RTU_CB->pModbus_RTU)));
+ if(!MDM_RTU_InsideWriteRegs(pModbus_RTU_CB->pModbus_RTU,startAddr+i,1,&wTemp,0,(AddrType)funCodeByte,slaveAddr)){
+ errRes= ERR_DATA_SAVE;
+ goto _exit;
+ }
+ }
+ pModbus_RTU_CB->sendFlag=2;
+ errRes= ERR_RW_FIN;
+ goto _exit;
+ }
+
+ case 0x5:/*Write single coil*/
+ case 0x6: /*Write a single register*/
+ {
+ uint16 res;
+ if(MDM_RTU_ReadUint16(pModbus_RTU_CB->pModbus_RTU,&res,1)!=ERR_NONE){
+ errRes= ERR_DATA_LEN;
+ goto _exit;
+ }
+ /*Return address mismatch error*/
+ if(res!=startAddr){
+ errRes= ERR_WRITE_COIL;
+ goto _exit;
+ }
+ if(MDM_RTU_ReadUint16(pModbus_RTU_CB->pModbus_RTU,&res,1)!=ERR_NONE){
+ errRes= ERR_DATA_LEN;
+ goto _exit;
+ }
+ /*Return data does not match*/
+ if(res!=*((uint16*)wData)){
+ errRes= ERR_WRITE_COIL;
+ goto _exit;
+ }
+ pModbus_RTU_CB->sendFlag=2;
+ errRes= ERR_RW_FIN;
+ goto _exit;
+ }
+ case 0x0F: /*Write multiple coils*/
+ case 0x10:{ /*Write multiple registers*/
+ uint16 res;
+ if(MDM_RTU_ReadUint16(pModbus_RTU_CB->pModbus_RTU,&res,1)!=ERR_NONE){
+ errRes= ERR_DATA_LEN;
+ goto _exit;
+ }
+ /*Return address mismatch error*/
+ if(res!=startAddr){
+ errRes= ERR_WRITE_COIL;
+ goto _exit;
+ }
+ if(MDM_RTU_ReadUint16(pModbus_RTU_CB->pModbus_RTU,&res,1)!=ERR_NONE){
+ errRes= ERR_DATA_LEN;
+ goto _exit;
+ }
+ /*Return data does not match*/
+ if(res!=numOf){
+ errRes= ERR_WRITE_COIL;
+ goto _exit;
+ }
+ pModbus_RTU_CB->sendFlag=2;
+ errRes= ERR_RW_FIN;
+ goto _exit;
+ }
+ case 0x81: pModbus_RTU_CB->sendFlag=3; errRes= ERR_READ_COIL; goto _exit; /*Abnormal reading coil*/
+ case 0x82: pModbus_RTU_CB->sendFlag=3; errRes= ERR_READ_INPUT; goto _exit; /*Read input discrete quantity abnormal*/
+ case 0x83: pModbus_RTU_CB->sendFlag=3; errRes= ERR_READ_HOLD_REG; goto _exit; /*Read holding register error*/
+ case 0x84: pModbus_RTU_CB->sendFlag=3; errRes= ERR_READ_INPUT_REG; goto _exit; /*Error reading input register*/
+ case 0x85: pModbus_RTU_CB->sendFlag=3; errRes= ERR_WRITE_COIL; goto _exit; /*Write single coil error*/
+ case 0x86: pModbus_RTU_CB->sendFlag=3; errRes= ERR_WRITE_REG; goto _exit; /*Error writing order*/
+ case 0x8F: pModbus_RTU_CB->sendFlag=3; errRes= ERR_WRITE_COIL; goto _exit; /*Write multiple coil error*/
+ case 0x90: pModbus_RTU_CB->sendFlag=3; errRes= ERR_WRITE_REG; goto _exit; /*Write multiple register error*/
+ }
+
+ }
+ if(pModbus_RTU_CB->sendFlag==2){/*If the sending is successful, send again*/
+ /*Timing resend processing*/
+ if(pModbus_RTU_CB->pModbus_RTU->timesTick-pModbus_RTU_CB->sendTimeTick
+ >=pModbus_RTU_CB->sendIntervalTime){
+ /*Resend*/
+ //MD_CLR_SENDED_FLAG(pModbus_RTU_CB);
+ pModbus_RTU_CB->sendFlag=0;
+ // /*Release channel*/
+ // pModbus_RTU_CB->pModbus_RTU->parentObj=NULL;
+ errRes= ERR_NONE;
+ goto _exit;
+ }
+ }else if(pModbus_RTU_CB->sendFlag==1 || pModbus_RTU_CB->sendFlag==3){/*�Ѿ������ˣ����ǻ�û�յ���������ִ�г�ʱ���*/
+ /*Receive timeout detection*/
+ if(pModbus_RTU_CB->pModbus_RTU->timesTick-pModbus_RTU_CB->sendTimeTick
+ >=pModbus_RTU_CB->sendOverTime){
+ /*Set the start point of timeout*/
+ pModbus_RTU_CB->sendTimeTick=pModbus_RTU_CB->pModbus_RTU->timesTick;
+ /*Resend*/
+ pModbus_RTU_CB->sendFlag=0;
+ /*Increase the number of retransmissions by 1*/
+ pModbus_RTU_CB->RTCount++;
+
+ /*Release channel*/
+ pModbus_RTU_CB->pModbus_RTU->parentObj=NULL;
+
+ if(pModbus_RTU_CB->RTCount>=pModbus_RTU_CB->RTTimes){
+ /*The number of retransmissions exceeded*/
+ errRes= ERR_RW_OV_TIME_ERR;
+ if(MD_CB_GET_DIS_FLAG_EN(pModbus_RTU_CB)){/*No polling when disconnected is enabled*/
+ MD_CB_SET_DIS_FLAG(pModbus_RTU_CB);/*Device disconnection*/
+ }
+ goto _exit;
+ }
+ /*Timed out*/
+ errRes= ERR_OVER_TIME;
+ goto _exit;
+ }
+ }
+ }else {
+ /*The number of retransmissions exceeded*/
+ errRes= ERR_RW_OV_TIME_ERR;
+ goto _exit;
+ }
+
+ if(pModbus_RTU_CB->sendFlag==1){/*If it has been sent, it will return the sending completion flag*/
+ return ERR_SEND_FIN;
+ }
+_exit:
+// MD_CLR_SENDED_FLAG(pModbus_RTU_CB);
+// if(errRes == ERR_RW_FIN){
+// pModbus_RTU_CB->RTCount=0;
+// }
+ /*Release channel*/
+ pModbus_RTU_CB->pModbus_RTU->parentObj=NULL;
+ return errRes;
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_RW
+* Description :Blocking read and write
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @funCode Function code, see [ModbusFunCode]
+* @slaveAddr Slave address
+* @startAddr Read and write start address
+* @numOf Number of read and write data
+* @wData If it is a write function code, then it is the written data
+* Return : See [MDError]
+**********************************************************/
+static MDError MDM_RTU_RW(
+ PModbus_RTU_CB pModbus_RTU_CB,
+ ModbusFunCode funCode,
+ uint8 slaveAddr,
+ uint16 startAddr,
+ uint16 numOf,
+ void *wData
+){
+ MDError res;
+ void* tempObj;
+ if(pModbus_RTU_CB==NULL){
+ return ERR_VOID;
+ }
+ MD_RTU_LOCK((PModbusBase)(pModbus_RTU_CB->pModbus_RTU),MD_RTU_LOCK_OBJ1_HANDLE_ARG((pModbus_RTU_CB->pModbus_RTU)));
+ tempObj=pModbus_RTU_CB->pModbus_RTU->parentObj;
+ pModbus_RTU_CB->pModbus_RTU->parentObj=NULL;/*Set to empty, so that non-blocking and blocking can be mixed calls*/
+ do{
+ res = MDM_RTU_NB_RW(pModbus_RTU_CB,funCode,slaveAddr,startAddr,numOf,wData);
+ if(res != ERR_RW_FIN){ /*An error occurred*/
+ if(res == ERR_RW_OV_TIME_ERR){ /*Retransmission timed out*/
+ MDM_RTU_CB_OverTimeReset(pModbus_RTU_CB);/*Enable retransmission*/
+ goto exit;
+ }else if(res==ERR_DEV_DIS){
+ goto exit;
+ }
+ }
+ #if MD_RTU_USED_OS
+ MD_RTU_Delay(5);
+ #endif
+ }while(res!=ERR_RW_FIN);
+ MDM_RTU_CB_OverTimeReset(pModbus_RTU_CB);
+ exit:
+ pModbus_RTU_CB->pModbus_RTU->parentObj=tempObj;/*Restore settings*/
+ MD_RTU_UNLOCK((PModbusBase)(pModbus_RTU_CB->pModbus_RTU),MD_RTU_LOCK_OBJ1_HANDLE_ARG((pModbus_RTU_CB->pModbus_RTU)));
+ return res;
+}
+/**
+* Clear the RTU parameters.
+*/
+void ModubusRTUClear(PModbus_RTU pOldModbus){
+ pOldModbus->lastTimesTick=0xFFFFFFF;
+ pOldModbus->recvFlag=0;
+ pOldModbus->serialSendCount=0;
+ pOldModbus->mdSqQueue.rear=pOldModbus->mdSqQueue.front=0;
+ pOldModbus->mdSqQueue.valid = TRUE;
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_RW_ex
+* Description :Blocking read and write
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @funCode Function code, see [ModbusFunCode]
+* @slaveAddr Slave address
+* @startAddr Read and write start address
+* @numOf Number of read and write data
+* @wData If it is a write function code, then it is the written data
+* Return : See [MDError]
+**********************************************************/
+static MDError MDM_RTU_RW_MIX(
+ PModbus_RTU_CB pModbus_RTU_CB,
+ ModbusFunCode funCode,
+ uint8 slaveAddr,
+ uint16 startAddr,
+ uint16 numOf,
+ void *wData
+){
+ MDError res;
+ void* tempObj;
+ if(pModbus_RTU_CB==NULL){
+ return ERR_VOID;
+ }
+ MD_RTU_LOCK((PModbusBase)(pModbus_RTU_CB->pModbus_RTU),MD_RTU_LOCK_OBJ1_HANDLE_ARG((pModbus_RTU_CB->pModbus_RTU)));
+
+ tempObj=pModbus_RTU_CB->pModbus_RTU->parentObj;
+ pModbus_RTU_CB->pModbus_RTU->parentObj=NULL;/*Set to empty, so that non-blocking and blocking can be mixed calls*/
+ if (pModbus_RTU_CB->pModbus_RTU->blockMode){
+ /*
+ * Last time in non-blocking mode.
+ * If the mode was previously non-blocking, all states need to
+ * be cleared and a delay may be required,
+ * as data may have been sent previously.
+ */
+ ModubusRTUClear(pModbus_RTU_CB->pModbus_RTU);
+ MDM_RTU_CB_OverTimeReset(pModbus_RTU_CB);
+ MD_RTU_Delay(MDM_MIX_CALL_DELAY);
+ }
+ pModbus_RTU_CB->pModbus_RTU->blockMode=0;/*Currently in blocking mode*/
+ do{
+ res = MDM_RTU_NB_RW(pModbus_RTU_CB,funCode,slaveAddr,startAddr,numOf,wData);
+ if(res != ERR_RW_FIN){ /*An error occurred*/
+ if(res == ERR_RW_OV_TIME_ERR){ /*Retransmission timed out*/
+ MDM_RTU_CB_OverTimeReset(pModbus_RTU_CB);/*Enable retransmission*/
+ goto exit;
+ }else if(res==ERR_DEV_DIS){
+ goto exit;
+ }
+ }
+ #if MD_RTU_USED_OS
+ MD_RTU_Delay(5);
+ #endif
+ }while(res!=ERR_RW_FIN);
+ MDM_RTU_CB_OverTimeReset(pModbus_RTU_CB);
+ exit:
+ ModubusRTUClear(pModbus_RTU_CB->pModbus_RTU);
+ pModbus_RTU_CB->pModbus_RTU->parentObj=tempObj;/*Restore settings*/
+ MD_RTU_UNLOCK((PModbusBase)(pModbus_RTU_CB->pModbus_RTU),MD_RTU_LOCK_OBJ1_HANDLE_ARG((pModbus_RTU_CB->pModbus_RTU)));
+ return res;
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_ReadCoil
+* Description :Read coil
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @slaveAddr Slave address
+* @startAddr Read start address
+* @numOf Number of read data
+* Return : See [MDError]
+**********************************************************/
+MDError MDM_RTU_ReadCoil(PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf){
+ return MDM_RTU_RW(pModbus_RTU_CB,READ_COIL,slaveAddr,startAddr,numOf,NULL);
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_ReadInput
+* Description :Read input
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @slaveAddr Slave address
+* @startAddr Read start address
+* @numOf Number of read data
+* Return : See [MDError]
+**********************************************************/
+MDError MDM_RTU_ReadInput(PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf){
+ return MDM_RTU_RW(pModbus_RTU_CB,READ_INPUT,slaveAddr,startAddr,numOf,NULL);
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_ReadHoldReg
+* Description :Read holding register
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @slaveAddr Slave address
+* @startAddr Read start address
+* @numOf Number of read data
+* Return : See [MDError]
+**********************************************************/
+MDError MDM_RTU_ReadHoldReg(PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf){
+ return MDM_RTU_RW(pModbus_RTU_CB,READ_HOLD_REG,slaveAddr,startAddr,numOf,NULL);
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_ReadInputReg
+* Description :Read input register
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @slaveAddr Slave address
+* @startAddr Read start address
+* @numOf Number of read data
+* Return : See [MDError]
+**********************************************************/
+MDError MDM_RTU_ReadInputReg(PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf){
+ return MDM_RTU_RW(pModbus_RTU_CB,READ_INPUT_REG,slaveAddr,startAddr,numOf,NULL);
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_WriteSingleCoil
+* Description :Write a single coil
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @slaveAddr Slave address
+* @startAddr Read start address
+* @boolVal TRUE , FALSE
+* Return : See [MDError]
+**********************************************************/
+MDError MDM_RTU_WriteSingleCoil(
+ PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,BOOL boolVal){
+ uint16 temp;
+ temp=boolVal?0xFF00:0x0000;
+ return MDM_RTU_RW(pModbus_RTU_CB,WRITE_SIN_COIL,slaveAddr,startAddr,1,(void*)(&temp));
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_WriteSingleReg
+* Description :Write a single register
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @slaveAddr Slave address
+* @startAddr Read start address
+* @boolVal TRUE , FALSE
+* Return : See [MDError]
+**********************************************************/
+MDError MDM_RTU_WriteSingleReg(
+ PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 val){
+ return MDM_RTU_RW(pModbus_RTU_CB,WRITE_SIN_REG,slaveAddr,startAddr,1,(void*)(&val));
+}
+
+/*******************************************************
+*
+* Function name :MDM_RTU_WriteCoils
+* Description :Write coil
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @slaveAddr Slave address
+* @startAddr Read start address
+* @numOf Number of write data
+* @boolVal TRUE , FALSE
+* Return : See [MDError]
+**********************************************************/
+MDError MDM_RTU_WriteCoils(
+ PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf,uint8* val){
+ return MDM_RTU_RW(pModbus_RTU_CB,WRITE_COILS,slaveAddr,startAddr,numOf,(void*)(val));
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_WriteRegs
+* Description :Write register
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @slaveAddr Slave address
+* @startAddr Read start address
+* @numOf Number of write data
+* @boolVal TRUE , FALSE
+* Return : See [MDError]
+**********************************************************/
+MDError MDM_RTU_WriteRegs(
+ PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf,uint16* val){
+ return MDM_RTU_RW(pModbus_RTU_CB,WRITE_REGS,slaveAddr,startAddr,numOf,(void*)(val));
+}
+
+
+/*******************************************************
+*
+* Function name :MDM_RTU_MixReadCoil
+* Description :Read coil
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @slaveAddr Slave address
+* @startAddr Read start address
+* @numOf Number of read data
+* Return : See [MDError]
+**********************************************************/
+MDError MDM_RTU_MixReadCoil(PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf){
+ return MDM_RTU_RW_MIX(pModbus_RTU_CB,READ_COIL,slaveAddr,startAddr,numOf,NULL);
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_MixReadInput
+* Description :Read input
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @slaveAddr Slave address
+* @startAddr Read start address
+* @numOf Number of read data
+* Return : See [MDError]
+**********************************************************/
+MDError MDM_RTU_MixReadInput(PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf){
+ return MDM_RTU_RW_MIX(pModbus_RTU_CB,READ_INPUT,slaveAddr,startAddr,numOf,NULL);
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_MixReadHoldReg
+* Description :Read holding register
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @slaveAddr Slave address
+* @startAddr Read start address
+* @numOf Number of read data
+* Return : See [MDError]
+**********************************************************/
+MDError MDM_RTU_MixReadHoldReg(PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf){
+ return MDM_RTU_RW_MIX(pModbus_RTU_CB,READ_HOLD_REG,slaveAddr,startAddr,numOf,NULL);
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_MixReadInputReg
+* Description :Read input register
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @slaveAddr Slave address
+* @startAddr Read start address
+* @numOf Number of read data
+* Return : See [MDError]
+**********************************************************/
+MDError MDM_RTU_MixReadInputReg(PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf){
+ return MDM_RTU_RW_MIX(pModbus_RTU_CB,READ_INPUT_REG,slaveAddr,startAddr,numOf,NULL);
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_MixWriteSingleCoil
+* Description :Write a single coil
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @slaveAddr Slave address
+* @startAddr Read start address
+* @boolVal TRUE , FALSE
+* Return : See [MDError]
+**********************************************************/
+MDError MDM_RTU_MixWriteSingleCoil(
+ PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,BOOL boolVal){
+ uint16 temp;
+ temp=boolVal?0xFF00:0x0000;
+ return MDM_RTU_RW_MIX(pModbus_RTU_CB,WRITE_SIN_COIL,slaveAddr,startAddr,1,(void*)(&temp));
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_MixWriteSingleReg
+* Description :Write a single register
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @slaveAddr Slave address
+* @startAddr Read start address
+* @boolVal TRUE , FALSE
+* Return : See [MDError]
+**********************************************************/
+MDError MDM_RTU_MixWriteSingleReg(
+ PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 val){
+ return MDM_RTU_RW_MIX(pModbus_RTU_CB,WRITE_SIN_REG
+ ,slaveAddr,startAddr,1,(void*)(&val));
+}
+
+/*******************************************************
+*
+* Function name :MDM_RTU_MixWriteCoils
+* Description :Write coil
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @slaveAddr Slave address
+* @startAddr Read start address
+* @numOf Number of write data
+* @boolVal TRUE , FALSE
+* Return : See [MDError]
+**********************************************************/
+MDError MDM_RTU_MixWriteCoils(
+ PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf,uint8* val){
+ return MDM_RTU_RW_MIX(pModbus_RTU_CB,WRITE_COILS,slaveAddr,startAddr,numOf,(void*)(val));
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_MixWriteRegs
+* Description :Write register
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @slaveAddr Slave address
+* @startAddr Read start address
+* @numOf Number of write data
+* @boolVal TRUE , FALSE
+* Return : See [MDError]
+**********************************************************/
+MDError MDM_RTU_MixWriteRegs(
+ PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf,uint16* val){
+ return MDM_RTU_RW_MIX(pModbus_RTU_CB,WRITE_REGS,slaveAddr,startAddr,numOf,(void*)(val));
+}
+
+/*******************************************************
+*
+* Function name :MDM_RTU_ReadCoil
+* Description :Non-blocking read coil
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @slaveAddr Slave address
+* @startAddr Read start address
+* @numOf Number of read data
+* Return : See [MDError]
+**********************************************************/
+MDError MDM_RTU_NB_ReadCoil(PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf){
+ return MDM_RTU_NB_RW(pModbus_RTU_CB,READ_COIL,slaveAddr,startAddr,numOf,NULL);
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_ReadInput
+* Description :Non-blocking read input
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @slaveAddr Slave address
+* @startAddr Read start address
+* @numOf Number of read data
+* Return : See [MDError]
+**********************************************************/
+MDError MDM_RTU_NB_ReadInput(PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf){
+ return MDM_RTU_NB_RW(pModbus_RTU_CB,READ_INPUT,slaveAddr,startAddr,numOf,NULL);
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_ReadHoldReg
+* Description :Non-blocking read holding register
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @slaveAddr Slave address
+* @startAddr Read start address
+* @numOf Number of read data
+* Return : See [MDError]
+**********************************************************/
+MDError MDM_RTU_NB_ReadHoldReg(PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf){
+ return MDM_RTU_NB_RW(pModbus_RTU_CB,READ_HOLD_REG,slaveAddr,startAddr,numOf,NULL);
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_ReadHoldReg
+* Description :Non-blocking read input register
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @slaveAddr Slave address
+* @startAddr Read start address
+* @numOf Number of read data
+* Return : See [MDError]
+**********************************************************/
+MDError MDM_RTU_NB_ReadInputReg(PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf){
+ return MDM_RTU_NB_RW(pModbus_RTU_CB,READ_INPUT_REG,slaveAddr,startAddr,numOf,NULL);
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_WriteSingleCoil
+* Description :Non-blocking write single coil
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @slaveAddr Slave address
+* @startAddr Read start address
+* @boolVal TRUE , FALSE
+* Return : See [MDError]
+**********************************************************/
+MDError MDM_RTU_NB_WriteSingleCoil(
+ PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,BOOL boolVal){
+ uint16 temp;
+ temp=boolVal?0xFF00:0x0000;
+ return MDM_RTU_NB_RW(pModbus_RTU_CB,WRITE_SIN_COIL,slaveAddr,startAddr,1,(void*)(&temp));
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_WriteSingleReg
+* Description :Non-blocking write to a single register
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @slaveAddr Slave address
+* @startAddr Read start address
+* @boolVal TRUE , FALSE
+* Return : See [MDError]
+**********************************************************/
+MDError MDM_RTU_NB_WriteSingleReg(
+ PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 val){
+ return MDM_RTU_NB_RW(pModbus_RTU_CB,WRITE_SIN_REG,slaveAddr,startAddr,1,(void*)(&val));
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_WriteCoils
+* Description :Non-blocking write coil
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @slaveAddr Slave address
+* @startAddr Read start address
+* @numOf Number of write data
+* @boolVal TRUE , FALSE
+* Return : See [MDError]
+**********************************************************/
+MDError MDM_RTU_NB_WriteCoils(
+ PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf,uint8* val){
+ return MDM_RTU_NB_RW(pModbus_RTU_CB,WRITE_COILS,slaveAddr,startAddr,numOf,(void*)(val));
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_WriteRegs
+* Description :Non-blocking write register
+* Parameter :
+* @pModbus_RTU_CB Write control block object pointer
+* @slaveAddr Slave address
+* @startAddr Read start address
+* @numOf Number of write data
+* @boolVal TRUE , FALSE
+* Return : See [MDError]
+**********************************************************/
+MDError MDM_RTU_NB_WriteRegs(
+ PModbus_RTU_CB pModbus_RTU_CB,uint8 slaveAddr,uint16 startAddr,uint16 numOf,uint16* val){
+ return MDM_RTU_NB_RW(pModbus_RTU_CB,WRITE_REGS,slaveAddr,startAddr,numOf,(void*)(val));
+}
+
diff --git a/mkrtos_user/lib/modbus/src/modbus_rtu_master/MDM_RTU_RW_Man.c b/mkrtos_user/lib/modbus/src/modbus_rtu_master/MDM_RTU_RW_Man.c
new file mode 100644
index 000000000..433a74b40
--- /dev/null
+++ b/mkrtos_user/lib/modbus/src/modbus_rtu_master/MDM_RTU_RW_Man.c
@@ -0,0 +1,158 @@
+/********************************************************************************
+ * @File name: MD_RTU_RW_Man.c
+ * @Author: zspace
+ * @Email: 1358745329@qq.com
+ * @Version: 1.0
+ * @Date: 2020-10-22
+ * @Description: ????
+ ********************************************************************************/
+
+#include "MDM_RTU_RW_Man.h"
+#include "MDM_RTU_Fun.h"
+#include "MD_RTU_Tool.h"
+
+MDM_RW_Ctrl MDM_RW_CtrlList[MDM_RW_CTRL_LIST_SIZE] = { 0 };
+
+/*******************************************************
+ *
+ * Function name: MDM_RW_CtrlNew
+ * Description: Create a new control block
+ * Parameter:
+ * None
+ * Return: New control block
+ **********************************************************/
+static PMDM_RW_Ctrl MDM_RW_CtrlNew(void) {
+ uint16 i;
+ for (i = 0; i < MDM_RW_CTRL_LIST_SIZE; i++) {
+ if (!MD_GET_BIT(MDM_RW_CtrlList[i].flag, 0)) {
+ MD_SET_BIT(MDM_RW_CtrlList[i].flag, 0);
+ return &(MDM_RW_CtrlList[i]);
+ }
+ }
+ return NULL;
+}
+
+/*******************************************************
+ *
+ * Function name: MDM_RW_CtrlFindByFunAddr
+ * Description: Find the control block by the function address
+ * Parameter:
+ * @cbFun A function pointer
+ * Return: Found function control block
+ ******************************************************/
+static PMDM_RW_Ctrl MDM_RW_CtrlFindByFunAddr(MDMSendReadCallBack cbFun) {
+ uint16 i;
+ for (i = 0; i < MDM_RW_CTRL_LIST_SIZE; i++) {
+ if (MD_GET_BIT(MDM_RW_CtrlList[i].flag, 0)) {
+ if (MDM_RW_CtrlList[i].MDMSendReadFun == cbFun) {
+ return &(MDM_RW_CtrlList[i]);
+ }
+ }
+ }
+ return NULL;
+}
+
+/*******************************************************
+ *
+ * Function name: MDM_RW_CtrlDelRW
+ * Description: Delete a RW interface
+ * Parameter:
+ * @pMDM_RW_Ctrl Which control block's interface needs to be removed
+ * Return: None
+ ******************************************************/
+void MDM_RW_CtrlDelRW(PMDM_RW_Ctrl pMDM_RW_Ctrl) {
+ if (pMDM_RW_Ctrl == NULL) {
+ return;
+ }
+ pMDM_RW_Ctrl->arg = NULL;
+ pMDM_RW_Ctrl->flag = 0;
+ pMDM_RW_Ctrl->MDMSendReadFun = NULL;
+ pMDM_RW_Ctrl->RWCtrlName = NULL;
+}
+
+/*******************************************************
+ *
+ * Function name: MDM_RW_CtrlAddRW
+ * Description: Add a read-write
+ * Parameter:
+ * @cbFun A function that is called in a loop
+ * @arg The parameters passed to the function
+ * @RWCtrlName Name of the control block
+ * Return: Returns a control block to the user
+ ******************************************************/
+PMDM_RW_Ctrl MDM_RW_CtrlAddRW(MDMSendReadCallBack cbFun, void *arg, const char *RWCtrlName) {
+ PMDM_RW_Ctrl pMDM_RW_Ctrl = MDM_RW_CtrlNew();
+ if (pMDM_RW_Ctrl == NULL) {
+ return NULL;
+ }
+ pMDM_RW_Ctrl->MDMSendReadFun = cbFun;
+ pMDM_RW_Ctrl->RWCtrlName = RWCtrlName;
+ pMDM_RW_Ctrl->arg = arg;
+ return pMDM_RW_Ctrl;
+}
+
+/*******************************************************
+ *
+ * Function name: MDM_RW_CtrlSetRWOnceFlag
+ * Description: Set whether to send once or cyclically
+ * Parameter:
+ * @pMDM_RW_Ctrl A pointer to a control block object
+ * @flag Whether read only or write once
+ * Return: None
+ ******************************************************/
+void MDM_RW_CtrlSetRWOnceFlag(PMDM_RW_Ctrl pMDM_RW_Ctrl, BOOL flag) {
+ if (pMDM_RW_Ctrl == NULL) {
+ return;
+ }
+ if (flag) {
+ MD_SET_BIT(pMDM_RW_Ctrl->flag, 1);
+ } else {
+ MD_CLR_BIT(pMDM_RW_Ctrl->flag, 1);
+ }
+}
+
+/*******************************************************
+ *
+ * Function name: MDM_RW_CtrlResetRetranFlag
+ * Description: Reset slave offline flag
+ * Parameter:
+ * @pMDM_RW_Ctrl A pointer to a control block object
+ * Return: None
+ ******************************************************/
+void MDM_RW_CtrlResetRetranFlag(PMDM_RW_Ctrl pMDM_RW_Ctrl) {
+ if (pMDM_RW_Ctrl == NULL) {
+ return;
+ }
+ MD_CLR_BIT(pMDM_RW_Ctrl->flag, 7);
+}
+
+/*******************************************************
+ *
+ * Function name: MDM_RW_CtrlLoop
+ * Description: This function cyclically processes the host bare-metal transceiver control function
+ * Parameter:
+ * None
+ * Return: None
+ ******************************************************/
+void MDM_RW_CtrlLoop(void) {
+ uint16 i;
+ MDM_RW_CtrlErr res;
+ for (i = 0; i < MDM_RW_CTRL_LIST_SIZE; i++) {
+ if (MD_GET_BIT(MDM_RW_CtrlList[i].flag,0) && (!MD_GET_BIT(MDM_RW_CtrlList[i].flag, 7)) // If the slave is disconnected or a single transmission is completed, it will no longer be traversed
+ ) {
+ if (MDM_RW_CtrlList[i].MDMSendReadFun == NULL) {
+ continue;
+ }
+
+ res = MDM_RW_CtrlList[i].MDMSendReadFun(MDM_RW_CtrlList[i].arg); // Loop call
+ if (res == RW_ERR) { // Do not send if sending fails
+ MD_SET_BIT(MDM_RW_CtrlList[i].flag, 7);
+ }
+ if (res != RW_NONE) { // Single send and send success or failure
+ if (MD_GET_BIT(MDM_RW_CtrlList[i].flag, 1)) { // Single send
+ MD_SET_BIT(MDM_RW_CtrlList[i].flag, 7);
+ }
+ }
+ }
+ }
+}
diff --git a/mkrtos_user/lib/modbus/src/modbus_rtu_master/MDM_RTU_User_Fun.c b/mkrtos_user/lib/modbus/src/modbus_rtu_master/MDM_RTU_User_Fun.c
new file mode 100644
index 000000000..d6040e772
--- /dev/null
+++ b/mkrtos_user/lib/modbus/src/modbus_rtu_master/MDM_RTU_User_Fun.c
@@ -0,0 +1,103 @@
+/********************************************************************************
+* @File name: MD_RTU_User_Fun.c
+* @Author: zspace
+* @Emial: 1358745329@qq.com
+* @Version: 1.0
+* @Date: 2020-4-10
+* @Description: Modbus RTU Host user call function
+* Open source address: https://github.com/lotoohe-space/XTinyModbus
+********************************************************************************/
+
+/*********************************HEAD FILE************************************/
+#include "MDM_RTU_User_Fun.h"
+#include "MDM_RTU_Fun.h"
+/*********************************END******************************************/
+
+/*******************************************************
+*
+* Function name :MDM_RTU_ReadBits
+* Description :Read discretely mapped bits, you can read one or multiple
+* Parameter :
+* @obj Host object pointer
+* @modbusAddr modbus address
+* @numOf The number to be read
+* @opAddrType Address type(COILS_TYPE,INPUT_TYPE),See[AddrType]
+* @devAddr Slave number to be read
+* Return :
+* @res Returned value TRUE success , FALSE fail
+**********************************************************/
+BOOL MDM_RTU_ReadBits(void* obj,uint16 modbusAddr,uint16 numOf, uint8 *res, AddrType opAddrType,uint8 devAddr){
+ uint16 i;
+ PModbus_RTU pModbusS_RTU = obj;
+ if(pModbusS_RTU==NULL){return FALSE;}
+ if(opAddrType != COILS_TYPE && opAddrType != INPUT_TYPE){return FALSE;}
+
+ for(i=0;ipMapTableList[i]==NULL){
+ continue;
+ }
+ /*Check the device number*/
+ if(devAddr!=pModbusS_RTU->pMapTableList[i]->devAddr){continue;}
+
+ if(pModbusS_RTU->pMapTableList[i]->modbusAddr<=modbusAddr&&
+ (pModbusS_RTU->pMapTableList[i]->modbusAddr+pModbusS_RTU->pMapTableList[i]->modbusDataSize)>=(modbusAddr+numOf)
+ ){
+ if(pModbusS_RTU->pMapTableList[i]->addrType==opAddrType){/*Must be Bit type*/
+ uint16 j;
+ uint16 offsetAddr=modbusAddr-MDS_RTU_REG_COIL_ITEM_ADDR(pModbusS_RTU->pMapTableList[i]);
+ for(j=offsetAddr; jpMapTableList[i])[j>>4],j%16)
+ ){
+ MD_SET_BIT(res[j>>3],j%8);
+ }else{
+ MD_CLR_BIT(res[j>>3],j%8);
+ }
+ }
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+/*******************************************************
+*
+* Function name :MDM_RTU_ReadRegs
+* Description :Read discretely mapped registers, you can read one or multiple
+* Parameter :
+* @obj Host object pointer
+* @modbusAddr modbus address
+* @numOf The number to be read
+* @opAddrType Address type(HOLD_REGS_TYPE,INPUT_REGS_TYPE),See[AddrType]
+* @devAddr Slave number to be read
+* Return :
+* @res TRUE success , FALSE fail
+**********************************************************/
+BOOL MDM_RTU_ReadRegs(void* obj,uint16 modbusAddr,uint16 numOf, uint16 *res, AddrType opAddrType,uint8 devAddr){
+ uint16 i;
+ PModbus_RTU pModbusS_RTU = obj;
+ if(pModbusS_RTU==NULL){return FALSE;}
+ if(opAddrType != HOLD_REGS_TYPE && opAddrType != INPUT_REGS_TYPE){return FALSE;}
+
+ for(i=0;ipMapTableList[i]==NULL){
+ continue;
+ }
+ /*Check the device number*/
+ if(devAddr!=pModbusS_RTU->pMapTableList[i]->devAddr){continue;}
+ if(pModbusS_RTU->pMapTableList[i]->modbusAddr<=modbusAddr&&
+ (pModbusS_RTU->pMapTableList[i]->modbusAddr+pModbusS_RTU->pMapTableList[i]->modbusDataSize)>=(modbusAddr+numOf)
+ ){
+ if(pModbusS_RTU->pMapTableList[i]->addrType==opAddrType){/*Must be BIT type*/
+ uint16 j;
+ uint16 offsetAddr=modbusAddr-MDS_RTU_REG_COIL_ITEM_ADDR(pModbusS_RTU->pMapTableList[i]);
+ for(j=0;jpMapTableList[i])[offsetAddr+j];
+ }
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
diff --git a/mkrtos_user/lib/modbus/src/modbus_rtu_slave/MDS_RTU_Fun.c b/mkrtos_user/lib/modbus/src/modbus_rtu_slave/MDS_RTU_Fun.c
new file mode 100644
index 000000000..48dc9851b
--- /dev/null
+++ b/mkrtos_user/lib/modbus/src/modbus_rtu_slave/MDS_RTU_Fun.c
@@ -0,0 +1,695 @@
+/********************************************************************************
+ * @File name: MD_RTU_Fun.c
+ * @Author: zspace
+ * @Emial: 1358745329@qq.com
+ * @Version: 1.0
+ * @Date: 2020-4-10
+ * @Description: Modbus RTU Slave slave receiving function.
+ ********************************************************************************/
+
+/*********************************HEAD FILE************************************/
+#include "MDS_RTU_Fun.h"
+#include "MD_RTU_CRC16.h"
+// #include "MDS_RTU_Serial.h"
+#include "MDS_RTU_User_Fun.h"
+/*********************************END******************************************/
+
+/**********************************FUNCTION DECLARATION*************************************/
+void MDS_RTU_RecvByte(void *obj, uint8 byte);
+void MDS_RTU_TimeHandler(void *obj, uint32 times);
+
+static void MDS_RTU_SendErrorCode(PModbusS_RTU pModbus_RTU, ANLCode anlCode, ErrorCode errCode);
+uint8 MDS_RTU_ReadDataProcess(PModbusS_RTU pModbus_RTU, uint16 reg, uint16 regNum, uint8 funCode);
+uint8 MDS_RTU_WriteDataProcess(PModbusS_RTU pModbus_RTU, uint16 reg, uint16 regNum, uint8 funCode, uint16 *data, uint8 byteCount);
+/*********************************END******************************************/
+
+/*******************************************************
+ *
+ * Function name :MDS_RTU_Init
+ * Description :Initialize a slave
+ * Parameter :
+ * @pModbusRTU Slave structure pointer
+ * @mdRTUSerialInitFun Hardware serial port initialization function
+ * @salveAddr Slave address
+ * @baud Baud rate
+ * @dataBits Data bit
+ * @stopBits Stop bit
+ * @parity Parity bit
+ * Return : None
+ **********************************************************/
+void MDS_RTU_Init(PModbusS_RTU pModbusRTU, MD_RTU_SerialInit mdRTUSerialInitFun, uint8 salveAddr,
+ uint32 baud, uint8 dataBits, uint8 stopBits, uint8 parity)
+{
+ uint8 i;
+ float T;
+ if (pModbusRTU == NULL)
+ {
+ return;
+ }
+ /*Init is queue.*/
+ pModbusRTU->mdMsgSqQueue.data = NULL;
+ pModbusRTU->mdMsgSqQueue.maxVal = 0;
+ pModbusRTU->mdSqQueue.data = NULL;
+ pModbusRTU->mdSqQueue.maxVal = 0;
+
+ pModbusRTU->salveAddr = salveAddr;
+ pModbusRTU->serialReadCount = 0;
+#if MDS_USE_SEND_CACHE
+ pModbusRTU->serialSendCount = 0;
+#endif
+ for (i = 0; i < MDS_REG_COIL_ITEM_NUM; i++)
+ {
+ pModbusRTU->pMapTableList[i] = NULL;
+ }
+
+ TO_MDBase(pModbusRTU)->mdRTUTimeHandlerFunction = MDS_RTU_TimeHandler;
+ TO_MDBase(pModbusRTU)->mdRTURecByteFunction = MDS_RTU_RecvByte;
+ TO_MDBase(pModbusRTU)->mdRTUSendBytesFunction = NULL;
+ TO_MDBase(pModbusRTU)->mdRTURecSendConv = NULL;
+
+ pModbusRTU->mdsWriteFun = NULL;
+ pModbusRTU->lastTimesTick = 0xFFFFFFFF;
+ pModbusRTU->lastSendTimes = 0x00000000;
+ pModbusRTU->timesTick = 0x00000000;
+
+ T = (1.0 / (float)baud) * 100000; // 100us
+ uint16 time = 0;
+ time = T * (dataBits + (parity ? 1 : 0));
+ if (stopBits == 0)
+ {
+ time += T;
+ }
+ else if (stopBits == 1)
+ {
+ time += T * 1.5f;
+ }
+ else if (stopBits == 2)
+ {
+ time += T * 2;
+ }
+ pModbusRTU->frameIntervalTime = time; /*This parameter needs to be set according to the baud rate*/
+
+ pModbusRTU->CRC16Update = 0xFFFF;
+
+ if (mdRTUSerialInitFun != NULL)
+ {
+ mdRTUSerialInitFun(pModbusRTU, baud, dataBits, stopBits, parity);
+ }
+ return;
+}
+/**
+ * @brief This function init queue.
+ * @param[in] recvQueueData ????
+ * @param[in] recvQueueSize ????
+ * @param[in] msgProcessQueueData ????
+ * @param[in] msgProcessQueueSize ????
+ * @result None
+ */
+void MDS_RTU_QueueInit(PModbusS_RTU pModbus_RTU,
+ uint8 *recvQueueData,
+ uint16 recvQueueSize,
+ uint8 *msgProcessQueueData,
+ uint16 msgProcessQueueSize)
+{
+ if (pModbus_RTU == NULL)
+ {
+ return;
+ }
+ MDInitQueue(&(pModbus_RTU->mdSqQueue), recvQueueData, recvQueueSize);
+ MDInitQueue(&(pModbus_RTU->mdMsgSqQueue), msgProcessQueueData, msgProcessQueueSize);
+}
+/*******************************************************
+ *
+ * Function name :MDS_RTU_SetWriteListenFun
+ * Description :This function can set a callback function, when the master writes the slave address, the set function will be called.
+ * Parameter :
+ * @pModbus_RTU Object pointer of slave
+ * @wFun Set callback function
+ * Return : ��
+ **********************************************************/
+void MDS_RTU_SetWriteListenFun(PModbusS_RTU pModbus_RTU, MDSWriteFunciton wFun)
+{
+ if (pModbus_RTU == NULL)
+ {
+ return;
+ }
+ pModbus_RTU->mdsWriteFun = wFun;
+}
+/*******************************************************
+ *
+ * Function name :MDS_RTU_TimeHandler
+ * Description :This function needs to be called in the timer interrupt, the interrupt interval time is 100US.
+ * Parameter :
+ * @obj Object pointer of slave
+ * Return : None
+ **********************************************************/
+void MDS_RTU_TimeHandler(void *obj, uint32 times)
+{
+ uint32 tempTick = 0;
+ uint8 overFlag = 0;
+ PModbusS_RTU pModbusRTU = obj;
+ if (!pModbusRTU)
+ {
+ return;
+ }
+
+ // pModbusRTU->timesTick++;
+ pModbusRTU->timesTick = times;
+
+ if (pModbusRTU->timesTick == 0xFFFFFFFF)
+ { /*Overflowed pModbusRTU->lastTimesTick==0xFFFFFFFF*/
+ tempTick = 0xFFFFFFFF - pModbusRTU->lastSendTimes;
+ pModbusRTU->timesTick = tempTick; /*System time offset*/
+ pModbusRTU->lastSendTimes = 0; /*Clear the last sending time*/
+ overFlag = 1;
+ }
+
+ if (pModbusRTU->lastTimesTick == 0xFFFFFFFF)
+ {
+ return;
+ } /*Has started receiving packets*/
+ if (overFlag)
+ {
+ pModbusRTU->timesTick += 0xFFFFFFFF - pModbusRTU->lastTimesTick; /*Time offset when sending*/
+ pModbusRTU->lastTimesTick = tempTick;
+ }
+ if ((pModbusRTU->timesTick - pModbusRTU->lastTimesTick >= pModbusRTU->frameIntervalTime))
+ {
+ uint16 msgLen;
+ uint16 i;
+ uint8 byte;
+ if (pModbusRTU->CRC16Update != 0x0000)
+ {
+ /*CRC error*/
+ MDResetQueue(&(pModbusRTU->mdSqQueue));
+ pModbusRTU->lastTimesTick = 0xFFFFFFFF;
+ return;
+ }
+ /*End of one frame*/
+ /*The messages of the data processing queue are moved to the message processing queue*/
+ msgLen = MDQueueLength(&(pModbusRTU->mdSqQueue));
+ MDenQueue(&(pModbusRTU->mdMsgSqQueue), &msgLen, UINT8_TYPE); /*Save frame length*/
+ for (i = 0; i < msgLen; i++)
+ {
+ /*take out*/
+ if (MDdeQueue(&(pModbusRTU->mdSqQueue), &byte, UINT8_TYPE) == FALSE)
+ {
+ return;
+ }
+ /*put in*/
+ if (MDenQueue(&(pModbusRTU->mdMsgSqQueue), &byte, UINT8_TYPE) == FALSE)
+ {
+ return;
+ }
+ }
+ pModbusRTU->lastTimesTick = 0xFFFFFFFF;
+ }
+}
+
+/*******************************************************
+ *
+ * Function name :MDS_RTU_RecvByte
+ * Description :This function is called in the serial port interrupt, when a byte is received, this function is called
+ * Parameter :
+ * @obj Object pointer of slave
+ * @byte Single byte received
+ * Return : None
+ **********************************************************/
+void MDS_RTU_RecvByte(void *obj, uint8 byte)
+{
+ PModbusS_RTU pModbusRTU = obj;
+ if (!pModbusRTU)
+ {
+ return;
+ }
+ /*Put in the queue here*/
+ if (MDenQueue(&(pModbusRTU->mdSqQueue), &byte, UINT8_TYPE) == FALSE)
+ {
+ return;
+ }
+ if (pModbusRTU->lastTimesTick == 0xFFFFFFFF)
+ {
+ pModbusRTU->CRC16Update = 0xFFFF;
+ }
+ pModbusRTU->CRC16Update = MD_CRC16Update(pModbusRTU->CRC16Update, byte);
+ /*Save the timestamp of the last character received*/
+ pModbusRTU->lastTimesTick = pModbusRTU->timesTick;
+}
+/*******************************************************
+ *
+ * Function name :MDS_RTU_AddMapItem
+ * Description :This function adds a mapping record to the discrete mapping table.
+ * Parameter :
+ * @obj Object pointer of slave
+ * @byte Mapping item added
+ * Return : None
+ **********************************************************/
+BOOL MDS_RTU_AddMapItem(PModbusS_RTU pModbusRTU, PMapTableItem pMapTableItem)
+{
+ if (pModbusRTU == NULL || pMapTableItem == NULL)
+ {
+ return FALSE;
+ }
+ return MapTableAdd(pModbusRTU->pMapTableList, pMapTableItem, MDS_REG_COIL_ITEM_NUM);
+}
+#if !MDS_USE_SEND_CACHE
+/*******************************************************
+ *
+ * Function name :MDS_RTU_SendByte
+ * Description :Slave sends a byte
+ * Parameter :
+ * @pModbusRTU Object pointer of slave
+ * @byte Bytes to be sent
+ * Return : TRUE success , FALSE fail
+ **********************************************************/
+static void MDS_RTU_SendByte(PModbusS_RTU pModbusRTU, uint8 byte)
+{
+ if (!pModbusRTU)
+ {
+ return;
+ }
+ TO_MDBase(pModbusRTU)->mdRTUSendBytesFunction(&byte, 1);
+}
+#endif
+/*******************************************************
+ *
+ * Function name :MDS_RTU_SerialProcess
+ * Description :This function is called internally to get a packet data received.
+ * Parameter :
+ * @pModbus_RTU Object pointer of slave
+ * Return : None
+ **********************************************************/
+static BOOL MDS_RTU_SerialProcess(PModbusS_RTU pModbus_RTU)
+{
+ uint8 byte;
+ uint8 recvLen;
+ uint16 i;
+ if (!pModbus_RTU)
+ {
+ return FALSE;
+ }
+
+ if (MDdeQueue(&(pModbus_RTU->mdMsgSqQueue), &recvLen, UINT8_TYPE) == FALSE)
+ {
+ return FALSE;
+ }
+ for (i = 0; i < recvLen; i++)
+ {
+ /*Read a byte from the queue*/
+ if (MDdeQueue(&(pModbus_RTU->mdMsgSqQueue), &byte, UINT8_TYPE) == FALSE)
+ {
+ return FALSE;
+ }
+ if (pModbus_RTU->serialReadCount > MDS_RTU_CMD_SIZE - 1)
+ { /**/
+ continue;
+ }
+ pModbus_RTU->serialReadCache[pModbus_RTU->serialReadCount] = byte; /*save a byte*/
+ pModbus_RTU->serialReadCount++;
+ }
+
+ if (pModbus_RTU->serialReadCount >= 1)
+ { /*Function code has been read*/
+ if (pModbus_RTU->serialReadCache[1] == 1 || pModbus_RTU->serialReadCache[1] == 2 || pModbus_RTU->serialReadCache[1] == 3 || pModbus_RTU->serialReadCache[1] == 4 || pModbus_RTU->serialReadCache[1] == 5 || pModbus_RTU->serialReadCache[1] == 6)
+ {
+ if (pModbus_RTU->serialReadCount == 8)
+ {
+ return TRUE;
+ }
+ }
+ else if (pModbus_RTU->serialReadCache[1] == 15 || pModbus_RTU->serialReadCache[1] == 16)
+ {
+ if (pModbus_RTU->serialReadCount >= 9)
+ {
+ uint8 bytesNum = MDS_RTU_BYTES_NUM(pModbus_RTU);
+ if (bytesNum + 9 == pModbus_RTU->serialReadCount)
+ {
+ return TRUE;
+ }
+ }
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+/*******************************************************
+ *
+ * Function name :MDS_RTU_Process
+ * Description :This function processes the received packet data
+ * Parameter :
+ * @pModbus_RTU Object pointer of slave
+ * Return : None
+ **********************************************************/
+void MDS_RTU_Process(PModbusS_RTU pModbus_RTU)
+{
+ BOOL res;
+ if (!pModbus_RTU)
+ {
+ return;
+ }
+
+ if (pModbus_RTU->timesTick - pModbus_RTU->lastSendTimes < pModbus_RTU->frameIntervalTime)
+ {
+ /*Frame interval time, 3.5T processing one frame*/
+ return;
+ }
+
+ res = MDS_RTU_SerialProcess(pModbus_RTU); /*Read an instruction from the queue*/
+ if (!res)
+ {
+ goto __exit;
+ }
+
+ if (
+ !(pModbus_RTU->serialReadCache[0] == 0x00 /*Broadcast address*/
+ ||
+ pModbus_RTU->serialReadCache[0] == pModbus_RTU->salveAddr))
+ {
+ /*Not belong to this slave, discard*/
+ goto __exit;
+ }
+
+ /*Function code 01-04 has a basically similar transmission structure*/
+ /*01 Read the coil status to obtain the current status of a group of logic coils (ON/OFF)*/
+ /*02 Read input status to obtain the current status of a group of switch inputs (ON/OFF)*/
+ /*03 Read the holding register Get the current binary value in one or more holding registers*/
+ /*04 Read input register Get the current binary value in one or more input registers*/
+ if (MDS_RTU_FUN_CODE(pModbus_RTU) >= 0x1 && MDS_RTU_FUN_CODE(pModbus_RTU) <= 0x4)
+ {
+ uint16 startReg = MDS_RTU_START_REG(pModbus_RTU);
+ uint16 regNum = MDS_RTU_REGS_NUM(pModbus_RTU);
+ MDS_RTU_ReadDataProcess(pModbus_RTU, startReg, regNum, MDS_RTU_FUN_CODE(pModbus_RTU));
+ }
+ else if (
+ MDS_RTU_FUN_CODE(pModbus_RTU) == 0x5 ||
+ MDS_RTU_FUN_CODE(pModbus_RTU) == 0x6)
+ {
+ /*05 Force a single coil to force the on-off status of a logic coil*/
+ /*06 Preset single register Load specific binary value into a holding register*/
+ uint16 startReg = MDS_RTU_START_REG(pModbus_RTU);
+ uint16 val = ((pModbus_RTU->serialReadCache[4]) << 8) | pModbus_RTU->serialReadCache[5];
+
+ MDS_RTU_WriteDataProcess(pModbus_RTU, startReg, 1, MDS_RTU_FUN_CODE(pModbus_RTU), &val, 2);
+ }
+ else if (
+ MDS_RTU_FUN_CODE(pModbus_RTU) == 15 ||
+ MDS_RTU_FUN_CODE(pModbus_RTU) == 16)
+ {
+ /*15 Force multiple coils to force a series of continuous logic coils on and off*/
+ /*16 Preset multiple registers to load specific binary values into a series of continuous holding registers*/
+ uint16 startReg = MDS_RTU_START_REG(pModbus_RTU);
+ uint16 regNum = MDS_RTU_REGS_NUM(pModbus_RTU);
+ uint8 bytesNum = MDS_RTU_BYTES_NUM(pModbus_RTU);
+ if (MDS_RTU_FUN_CODE(pModbus_RTU) == 15)
+ {
+ if (((regNum >> 3) + ((regNum % 8) ? 1 : 0)) != bytesNum)
+ {
+ MDS_RTU_SendErrorCode(pModbus_RTU, WRITE_COILS, ILLEGAL_DAT_VAL);
+ /*A length mismatch error occurred, discard it*/
+ goto __exit0;
+ }
+ }
+ else
+ { // 16
+ if ((regNum << 1) != bytesNum)
+ {
+ MDS_RTU_SendErrorCode(pModbus_RTU, WRITE_REGS, ILLEGAL_DAT_VAL);
+ /*A length mismatch error occurred, discard*/
+ goto __exit0;
+ }
+ }
+
+ MDS_RTU_WriteDataProcess(pModbus_RTU, startReg, regNum, MDS_RTU_FUN_CODE(pModbus_RTU),
+ (uint16 *)(&(pModbus_RTU->serialReadCache[7])), pModbus_RTU->serialReadCache[6]);
+ }
+
+__exit0:
+ pModbus_RTU->lastSendTimes = pModbus_RTU->timesTick;
+__exit:
+ pModbus_RTU->serialReadCount = 0;
+
+ return;
+}
+
+/*******************************************************
+ *
+ * Function name :MDS_RTU_SendErrorCode
+ * Description :This function returns the error code information received and processed to the host
+ * Parameter :
+ * @pModbus_RTU Object pointer of slave
+ * @anlCode Exception code, see [ANLCode]
+ * @errCode Error code, see [ErrorCode]
+ * Return : None
+ **********************************************************/
+static void MDS_RTU_SendErrorCode(PModbusS_RTU pModbus_RTU, ANLCode anlCode, ErrorCode errCode)
+{
+ MD_RTU_SEND_MODE(pModbus_RTU);
+ MDS_START_SEND(pModbus_RTU);
+ MDS_SEND_BYTE(pModbus_RTU, pModbus_RTU->salveAddr);
+ MDS_SEND_BYTE(pModbus_RTU, anlCode);
+ MDS_SEND_BYTE(pModbus_RTU, errCode);
+ MDS_SEND_END(pModbus_RTU);
+ MD_RTU_RECV_MODE(pModbus_RTU);
+}
+/*******************************************************
+ *
+ * Function name :MDS_RTU_ReadDataProcess
+ * Description :This function handles the host's read data request
+ * Parameter :
+ * @pModbus_RTU Object pointer of slave
+ * @reg Start of read address
+ * @regNum Number of data read
+ * @funCode Function code of operation
+ * Return : TRUE success , FALSE fail
+ **********************************************************/
+uint8 MDS_RTU_ReadDataProcess(PModbusS_RTU pModbus_RTU, uint16 reg, uint16 regNum, uint8 funCode)
+{
+ uint16 i = 0;
+ if (pModbus_RTU == NULL)
+ {
+ return FALSE;
+ }
+
+ for (i = 0; i < MDS_REG_COIL_ITEM_NUM; i++)
+ {
+ if (pModbus_RTU->pMapTableList[i] == NULL)
+ {
+ continue;
+ }
+ if (pModbus_RTU->pMapTableList[i]->modbusAddr <= reg &&
+ (pModbus_RTU->pMapTableList[i]->modbusAddr + pModbus_RTU->pMapTableList[i]->modbusDataSize) >= (reg + regNum))
+ {
+ /*Ensure that the read range is within the memory range*/
+ if ((funCode == 1 && pModbus_RTU->pMapTableList[i]->addrType == COILS_TYPE) ||
+ (funCode == 2 && pModbus_RTU->pMapTableList[i]->addrType == INPUT_TYPE))
+ {
+ /*Make sure it is the read BIT*/
+ /*Get bit offset*/
+ uint16 offsetAddr = reg - MDS_RTU_REG_COIL_ITEM_ADDR(pModbus_RTU->pMapTableList[i]);
+ uint16 j;
+ uint16 lastIndex = 0;
+ uint8 tempByte = 0;
+ MD_RTU_SEND_MODE(pModbus_RTU);
+ MDS_START_SEND(pModbus_RTU);
+ MDS_SEND_BYTE(pModbus_RTU, pModbus_RTU->salveAddr);
+ MDS_SEND_BYTE(pModbus_RTU, funCode);
+ MDS_SEND_BYTE(pModbus_RTU, (regNum >> 3) + ((regNum % 8) > 0 ? 1 : 0));
+ for (j = offsetAddr; j < offsetAddr + regNum; j++)
+ {
+ if (((j - offsetAddr) >> 3) != lastIndex)
+ {
+ MDS_SEND_BYTE(pModbus_RTU, tempByte);
+ tempByte = 0;
+ /*The current write byte position is different from the last time, it means that a byte needs to be sent*/
+ lastIndex = (j - offsetAddr) >> 3;
+ }
+ if (
+ MD_GET_BIT(
+ MDS_RTU_REG_COIL_ITEM_DATA(pModbus_RTU->pMapTableList[i])[j >> 4], j % 16))
+ {
+ MD_SET_BIT(tempByte, j % 8);
+ }
+ else
+ {
+ MD_CLR_BIT(tempByte, j % 8);
+ }
+ }
+ MDS_SEND_BYTE(pModbus_RTU, tempByte);
+ MDS_SEND_END(pModbus_RTU);
+ MD_RTU_RECV_MODE(pModbus_RTU);
+ }
+ else if ((funCode == 3 && pModbus_RTU->pMapTableList[i]->addrType == HOLD_REGS_TYPE) ||
+ (funCode == 4 && pModbus_RTU->pMapTableList[i]->addrType == INPUT_REGS_TYPE))
+ {
+ /*Make sure to read REG.*/
+ /*Get two bytes offset*/
+ uint16 j = 0;
+ uint16 offsetAddr = reg - MDS_RTU_REG_COIL_ITEM_ADDR(pModbus_RTU->pMapTableList[i]);
+ MD_RTU_SEND_MODE(pModbus_RTU);
+ MDS_START_SEND(pModbus_RTU);
+ MDS_SEND_BYTE(pModbus_RTU, pModbus_RTU->salveAddr);
+ MDS_SEND_BYTE(pModbus_RTU, funCode);
+ MDS_SEND_BYTE(pModbus_RTU, regNum << 1);
+ for (j = 0; j < regNum << 1; j += 2)
+ {
+ uint16 temp = MDS_RTU_REG_COIL_ITEM_DATA(pModbus_RTU->pMapTableList[i])[offsetAddr + (j >> 1)];
+ MDS_SEND_BYTE(pModbus_RTU, (temp >> 8) & 0xff);
+ MDS_SEND_BYTE(pModbus_RTU, (temp)&0xff);
+ }
+ MDS_SEND_END(pModbus_RTU);
+ MD_RTU_RECV_MODE(pModbus_RTU);
+ }
+ else
+ {
+ /*Address cannot be read*/
+ continue;
+ }
+ return TRUE;
+ }
+ }
+ /*Address is abnormal*/
+ MDS_RTU_SendErrorCode(pModbus_RTU, (ANLCode)(0x80 + funCode), ILLEGAL_DAT_ADDR);
+ return FALSE;
+}
+/*******************************************************
+ *
+ * Function name :MDS_RTU_WriteDataProcess
+ * Description :This function handles the host's write data request
+ * Parameter :
+ * @pModbus_RTU Object pointer of slave
+ * @reg Start of read address
+ * @regNum Number of data read
+ * @funCode Function code of operation
+ * @data Data written
+ * @byteCount How many bytes are the data written
+ * Return : TRUE success , FALSE fail
+ **********************************************************/
+uint8 MDS_RTU_WriteDataProcess(PModbusS_RTU pModbus_RTU, uint16 reg,
+ uint16 regNum, uint8 funCode, uint16 *data, uint8 byteCount)
+{
+ uint8 res = FALSE;
+ switch (funCode)
+ {
+ case 5: /*Write single coil*/
+ {
+ if (data[0] == 0xFF00 || data[0] == 0x0000)
+ {
+ if (data[0] == 0xFF00)
+ {
+ res = MDS_RTU_WriteBit(pModbus_RTU, reg, 1, COILS_TYPE);
+ }
+ else
+ {
+ res = MDS_RTU_WriteBit(pModbus_RTU, reg, 0, COILS_TYPE);
+ }
+ if (res)
+ {
+ MD_RTU_SEND_MODE(pModbus_RTU);
+ MDS_START_SEND(pModbus_RTU);
+ MDS_SEND_BYTE(pModbus_RTU, pModbus_RTU->salveAddr);
+ MDS_SEND_BYTE(pModbus_RTU, funCode);
+ MDS_SEND_BYTE(pModbus_RTU, (reg >> 8) & 0xff);
+ MDS_SEND_BYTE(pModbus_RTU, (reg)&0xff);
+ MDS_SEND_BYTE(pModbus_RTU, ((*data) >> 8) & 0xff);
+ MDS_SEND_BYTE(pModbus_RTU, (*data) & 0xff);
+ MDS_SEND_END(pModbus_RTU);
+ MD_RTU_RECV_MODE(pModbus_RTU);
+ if (pModbus_RTU->mdsWriteFun)
+ {
+ pModbus_RTU->mdsWriteFun(pModbus_RTU, reg, 1, COILS_TYPE);
+ }
+ }
+ else
+ {
+ MDS_RTU_SendErrorCode(pModbus_RTU, WRITE_SIN_COIL, ILLEGAL_DAT_ADDR);
+ }
+ }
+ else
+ {
+ MDS_RTU_SendErrorCode(pModbus_RTU, WRITE_SIN_COIL, ILLEGAL_DAT_VAL);
+ }
+ }
+ break;
+ case 15: /*Write multiple coils*/
+ res = MDS_RTU_WriteBits(pModbus_RTU, reg, regNum, data, COILS_TYPE);
+ if (res)
+ {
+ MD_RTU_SEND_MODE(pModbus_RTU);
+ MDS_START_SEND(pModbus_RTU);
+ MDS_SEND_BYTE(pModbus_RTU, pModbus_RTU->salveAddr);
+ MDS_SEND_BYTE(pModbus_RTU, funCode);
+ MDS_SEND_BYTE(pModbus_RTU, (reg >> 8) & 0xff);
+ MDS_SEND_BYTE(pModbus_RTU, (reg)&0xff);
+ MDS_SEND_BYTE(pModbus_RTU, ((regNum) >> 8) & 0xff);
+ MDS_SEND_BYTE(pModbus_RTU, (regNum)&0xff);
+ MDS_SEND_END(pModbus_RTU);
+ MD_RTU_RECV_MODE(pModbus_RTU);
+ if (pModbus_RTU->mdsWriteFun)
+ {
+ pModbus_RTU->mdsWriteFun(pModbus_RTU, reg, regNum, COILS_TYPE);
+ }
+ }
+ else
+ {
+ MDS_RTU_SendErrorCode(pModbus_RTU, WRITE_COILS, ILLEGAL_DAT_ADDR);
+ }
+ break;
+ case 6: /*Write single register*/
+ res = MDS_RTU_WriteReg(pModbus_RTU, reg, data[0], HOLD_REGS_TYPE);
+ if (res)
+ {
+ MD_RTU_SEND_MODE(pModbus_RTU);
+ MDS_START_SEND(pModbus_RTU);
+ MDS_SEND_BYTE(pModbus_RTU, pModbus_RTU->salveAddr);
+ MDS_SEND_BYTE(pModbus_RTU, funCode);
+ MDS_SEND_BYTE(pModbus_RTU, (reg >> 8) & 0xff);
+ MDS_SEND_BYTE(pModbus_RTU, (reg)&0xff);
+ MDS_SEND_BYTE(pModbus_RTU, ((*data) >> 8) & 0xff);
+ MDS_SEND_BYTE(pModbus_RTU, (*data) & 0xff);
+ MDS_SEND_END(pModbus_RTU);
+ MD_RTU_RECV_MODE(pModbus_RTU);
+ if (pModbus_RTU->mdsWriteFun)
+ {
+ pModbus_RTU->mdsWriteFun(pModbus_RTU, reg, 1, HOLD_REGS_TYPE);
+ }
+ }
+ else
+ {
+ MDS_RTU_SendErrorCode(pModbus_RTU, WRITE_SIN_REG, ILLEGAL_DAT_ADDR);
+ }
+ break;
+ case 16: /*Write multiple registers*/
+ res = MDS_RTU_WriteRegs(pModbus_RTU, reg, regNum, data, 1, HOLD_REGS_TYPE);
+ if (res)
+ {
+ MD_RTU_SEND_MODE(pModbus_RTU);
+ MDS_START_SEND(pModbus_RTU);
+ MDS_SEND_BYTE(pModbus_RTU, pModbus_RTU->salveAddr);
+ MDS_SEND_BYTE(pModbus_RTU, funCode);
+ MDS_SEND_BYTE(pModbus_RTU, (reg >> 8) & 0xff);
+ MDS_SEND_BYTE(pModbus_RTU, (reg)&0xff);
+ MDS_SEND_BYTE(pModbus_RTU, ((regNum) >> 8) & 0xff);
+ MDS_SEND_BYTE(pModbus_RTU, (regNum)&0xff);
+ MDS_SEND_END(pModbus_RTU);
+ MD_RTU_RECV_MODE(pModbus_RTU);
+ if (pModbus_RTU->mdsWriteFun)
+ {
+ pModbus_RTU->mdsWriteFun(pModbus_RTU, reg, regNum, HOLD_REGS_TYPE);
+ }
+ }
+ else
+ {
+ MDS_RTU_SendErrorCode(pModbus_RTU, WRITE_REGS, ILLEGAL_DAT_ADDR);
+ }
+ break;
+ }
+ if (!res)
+ {
+ return FALSE;
+ }
+ return TRUE;
+}
diff --git a/mkrtos_user/lib/modbus/src/modbus_rtu_slave/MDS_RTU_User_Fun.c b/mkrtos_user/lib/modbus/src/modbus_rtu_slave/MDS_RTU_User_Fun.c
new file mode 100644
index 000000000..c760bbbf9
--- /dev/null
+++ b/mkrtos_user/lib/modbus/src/modbus_rtu_slave/MDS_RTU_User_Fun.c
@@ -0,0 +1,225 @@
+/********************************************************************************
+* @File name: MD_RTU_User_Fun.c
+* @Author: zspace
+* @Emial: 1358745329@qq.com
+* @Version: 1.0
+* @Date: 2020-4-28
+* @Description: Modbus RTU user related functions
+* Open source address: https://github.com/lotoohe-space/XTinyModbus
+********************************************************************************/
+#include "MDS_RTU_User_Fun.h"
+#include "MDS_RTU_Fun.h"
+
+/*Read bits, you can read one or multiple*/
+BOOL MDS_RTU_ReadBits(void* obj,uint16 modbusAddr,uint16 numOf, uint8 *res, AddrType opAddrType){
+ uint16 i;
+ PModbusS_RTU pModbusS_RTU = obj;
+ if(pModbusS_RTU==NULL){return FALSE;}
+ /*Only operate bits*/
+ if(opAddrType != COILS_TYPE && opAddrType != INPUT_TYPE){return FALSE;}
+
+ for(i=0;ipMapTableList[i]==NULL){
+ continue;
+ }
+ if(pModbusS_RTU->pMapTableList[i]->modbusAddr<=modbusAddr&&
+ (pModbusS_RTU->pMapTableList[i]->modbusAddr+pModbusS_RTU->pMapTableList[i]->modbusDataSize)>=(modbusAddr+numOf)
+ ){
+ if(pModbusS_RTU->pMapTableList[i]->addrType==opAddrType){/*Specified type*/
+ uint16 j;
+ uint16 offsetAddr=modbusAddr-MDS_RTU_REG_COIL_ITEM_ADDR(pModbusS_RTU->pMapTableList[i]);
+ for(j=offsetAddr; jpMapTableList[i])[j>>4],j%16)
+ ){
+ MD_SET_BIT(res[j>>3],j%8);
+ }else{
+ MD_CLR_BIT(res[j>>3],j%8);
+ }
+ }
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+BOOL MDS_RTU_ReadRegs(void* obj,uint16 modbusAddr,uint16 numOf, uint16 *res, AddrType opAddrType){
+ uint16 i;
+ PModbusS_RTU pModbusS_RTU = obj;
+ if(pModbusS_RTU==NULL){return FALSE;}
+ /*Can only manipulate registers*/
+ if(opAddrType != HOLD_REGS_TYPE && opAddrType != INPUT_REGS_TYPE){return FALSE;}
+
+ for(i=0;ipMapTableList[i]==NULL){
+ continue;
+ }
+ if(pModbusS_RTU->pMapTableList[i]->modbusAddr<=modbusAddr&&
+ (pModbusS_RTU->pMapTableList[i]->modbusAddr+pModbusS_RTU->pMapTableList[i]->modbusDataSize)>=(modbusAddr+numOf)
+ ){
+ if(pModbusS_RTU->pMapTableList[i]->addrType == opAddrType){
+ uint16 j;
+ uint16 offsetAddr=modbusAddr-MDS_RTU_REG_COIL_ITEM_ADDR(pModbusS_RTU->pMapTableList[i]);
+ for(j=0;jpMapTableList[i])[offsetAddr+j];
+ }
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+BOOL MDS_RTU_WriteBit(void* obj,uint16 modbusAddr,uint8 bit, AddrType opAddrType){
+ uint16 i;
+ PModbusS_RTU pModbusS_RTU = obj;
+ if(pModbusS_RTU==NULL){return FALSE;}
+ if(opAddrType != COILS_TYPE && opAddrType != INPUT_TYPE){return FALSE;}
+
+ for(i=0;ipMapTableList[i]==NULL){
+ continue;
+ }
+ if(pModbusS_RTU->pMapTableList[i]->modbusAddr<=modbusAddr&&
+ (pModbusS_RTU->pMapTableList[i]->modbusAddr+pModbusS_RTU->pMapTableList[i]->modbusDataSize)>=(modbusAddr+1)
+ ){
+ if(pModbusS_RTU->pMapTableList[i]->addrType==opAddrType){
+ uint16 offsetAddr=modbusAddr-MDS_RTU_REG_COIL_ITEM_ADDR(pModbusS_RTU->pMapTableList[i]);
+ if(bit){
+ MD_SET_BIT(
+ MDS_RTU_REG_COIL_ITEM_DATA(pModbusS_RTU->pMapTableList[i])[offsetAddr>>4],offsetAddr%16);
+ }else{
+ MD_CLR_BIT(
+ MDS_RTU_REG_COIL_ITEM_DATA(pModbusS_RTU->pMapTableList[i])[offsetAddr>>4],offsetAddr%16);
+ }
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+BOOL MDS_RTU_WriteBits(void* obj,uint16 modbusAddr,uint16 numOf, uint16 *bit, AddrType opAddrType){
+ uint16 i;
+ PModbusS_RTU pModbusS_RTU = obj;
+ if(pModbusS_RTU==NULL){return FALSE;}
+ if(opAddrType != COILS_TYPE && opAddrType != INPUT_TYPE){return FALSE;}
+
+ for(i=0;ipMapTableList[i]==NULL){
+ continue;
+ }
+ if(pModbusS_RTU->pMapTableList[i]->modbusAddr<=modbusAddr&&
+ (pModbusS_RTU->pMapTableList[i]->modbusAddr+pModbusS_RTU->pMapTableList[i]->modbusDataSize)>=(modbusAddr+numOf)
+ ){
+ if(pModbusS_RTU->pMapTableList[i]->addrType==opAddrType){/*Must be BIT type*/
+ uint16 offsetAddr=modbusAddr-MDS_RTU_REG_COIL_ITEM_ADDR(pModbusS_RTU->pMapTableList[i]);
+ uint16 j;
+ for(j=0;j>3] ,j%8)
+ ){
+ MD_SET_BIT(
+ MDS_RTU_REG_COIL_ITEM_DATA(
+ pModbusS_RTU->pMapTableList[i])[(offsetAddr+j)>>4]
+ ,(j+offsetAddr)%16);
+ }else{
+ MD_CLR_BIT(
+ MDS_RTU_REG_COIL_ITEM_DATA(
+ pModbusS_RTU->pMapTableList[i])[(offsetAddr+j)>>4]
+ ,(j+offsetAddr)%16);
+ }
+ }
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+BOOL MDS_RTU_WriteReg(void* obj,uint16 modbusAddr,uint16 reg, AddrType opAddrType){
+ uint16 i;
+ PModbusS_RTU pModbusS_RTU = obj;
+ if(pModbusS_RTU==NULL){return FALSE;}
+ if(opAddrType != HOLD_REGS_TYPE && opAddrType != INPUT_REGS_TYPE){return FALSE;}
+
+ for(i=0;ipMapTableList[i]==NULL){
+ continue;
+ }
+ if(pModbusS_RTU->pMapTableList[i]->modbusAddr<=modbusAddr&&
+ (pModbusS_RTU->pMapTableList[i]->modbusAddr+pModbusS_RTU->pMapTableList[i]->modbusDataSize)>=(modbusAddr+1)
+ ){
+ if(pModbusS_RTU->pMapTableList[i]->addrType==opAddrType){
+ uint16 offsetAddr=modbusAddr-MDS_RTU_REG_COIL_ITEM_ADDR(pModbusS_RTU->pMapTableList[i]);
+ MDS_RTU_REG_COIL_ITEM_DATA(pModbusS_RTU->pMapTableList[i])[offsetAddr]=reg;
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+BOOL MDS_RTU_WriteRegs(void* obj,uint16 modbusAddr,uint16 numOf, uint16 *reg,uint8 isBigE, AddrType opAddrType){
+ uint16 i;
+ PModbusS_RTU pModbusS_RTU = obj;
+ if(pModbusS_RTU==NULL){return FALSE;}
+ if(opAddrType != HOLD_REGS_TYPE && opAddrType != INPUT_REGS_TYPE){return FALSE;}
+
+ for(i=0;ipMapTableList[i]==NULL){
+ continue;
+ }
+ if(pModbusS_RTU->pMapTableList[i]->modbusAddr<=modbusAddr&&
+ (pModbusS_RTU->pMapTableList[i]->modbusAddr+pModbusS_RTU->pMapTableList[i]->modbusDataSize)>=(modbusAddr+numOf)
+ ){
+ if(pModbusS_RTU->pMapTableList[i]->addrType==opAddrType){/*Must be REG type*/
+ uint16 offsetAddr=modbusAddr-MDS_RTU_REG_COIL_ITEM_ADDR(pModbusS_RTU->pMapTableList[i]);
+ uint16 j=0;
+ for(j=0;jpMapTableList[i])[offsetAddr+j]=
+ isBigE?MD_SWAP_HL(reg[j]):reg[j];
+ }
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+
+
+BOOL MDS_RTU_WriteCoil(void* obj,uint16 modbusAddr,uint8 bit){
+ return MDS_RTU_WriteBit( obj, modbusAddr, bit, COILS_TYPE);
+}
+BOOL MDS_RTU_WriteInput(void* obj,uint16 modbusAddr,uint8 bit){
+ return MDS_RTU_WriteBit( obj, modbusAddr, bit, INPUT_TYPE);
+}
+BOOL MDS_RTU_WriteCoils(void* obj,uint16 modbusAddr,uint16 numOf, uint16 *bit){
+ return MDS_RTU_WriteBits( obj, modbusAddr, numOf,bit, COILS_TYPE);
+}
+BOOL MDS_RTU_WriteInputs(void* obj,uint16 modbusAddr,uint16 numOf, uint16 *bit){
+ return MDS_RTU_WriteBits( obj, modbusAddr, numOf,bit, INPUT_TYPE);
+}
+BOOL MDS_RTU_WriteHoldReg(void* obj,uint16 modbusAddr,uint16 reg){
+ return MDS_RTU_WriteReg( obj, modbusAddr, reg, HOLD_REGS_TYPE);
+}
+BOOL MDS_RTU_WriteHoldRegs(void* obj,uint16 modbusAddr,uint16 numOf, uint16 *reg){
+ return MDS_RTU_WriteRegs( obj, modbusAddr, numOf, reg,0, HOLD_REGS_TYPE);
+}
+BOOL MDS_RTU_WriteInputReg(void* obj,uint16 modbusAddr,uint16 reg){
+ return MDS_RTU_WriteReg( obj, modbusAddr, reg, INPUT_REGS_TYPE);
+}
+BOOL MDS_RTU_WriteInputRegs(void* obj,uint16 modbusAddr,uint16 numOf, uint16 *reg){
+ return MDS_RTU_WriteRegs( obj, modbusAddr, numOf, reg,0, INPUT_REGS_TYPE);
+}
+BOOL MDS_RTU_ReadCoils(void *obj,uint16 modbusAddr,uint16 numOf,uint8 *res){
+ return MDS_RTU_ReadBits( obj, modbusAddr, numOf,res, COILS_TYPE);
+}
+BOOL MDS_RTU_ReadInput(void *obj,uint16 modbusAddr,uint16 numOf,uint8 *res){
+ return MDS_RTU_ReadBits( obj, modbusAddr, numOf,res, INPUT_TYPE);
+}
+BOOL MDS_RTU_ReadHoldRegs(void* obj,uint16 modbusAddr,uint16 numOf, uint16 *res){
+ return MDS_RTU_ReadRegs( obj, modbusAddr, numOf, res, HOLD_REGS_TYPE);
+}
+BOOL MDS_RTU_ReadInputRegs(void* obj,uint16 modbusAddr,uint16 numOf, uint16 *res){
+ return MDS_RTU_ReadRegs( obj, modbusAddr, numOf, res, INPUT_REGS_TYPE);
+}
diff --git a/mkrtos_user/lib/modbus/src/port/MD_RTU_SysInterface.c b/mkrtos_user/lib/modbus/src/port/MD_RTU_SysInterface.c
new file mode 100644
index 000000000..e74a8eebb
--- /dev/null
+++ b/mkrtos_user/lib/modbus/src/port/MD_RTU_SysInterface.c
@@ -0,0 +1,75 @@
+#include "MD_RTU_SysInterface.h"
+
+#if MD_RTU_USED_OS
+
+uint8 MD_RTU_CreateThread(PModbusBase pModbusBase,void(*funTask)(void* arg),MD_RTU_TASK_HANDLE *pTaskObj){
+ if(pModbusBase==NULL){
+ return FALSE;
+ }
+ *pTaskObj=OSCreateTask(funTask,pModbusBase,MD_RTU_TASK_LEVEL,MD_RTU_TASK_STACK_SIZE);
+ return (*pTaskObj)!=NULL;;
+}
+void MD_RTU_Delay(uint32 ms){
+ OSTaskDelay(ms);
+}
+uint8 MD_RTU_CreateMsg(PModbusBase pModbusBase, MD_RTU_MSG_HANDLE *pMsgObj,
+ uint32 msgBoxLength
+){
+ if(pModbusBase==NULL){
+ return FALSE;
+ }
+ *pMsgObj=MsgCreate();
+ return (*pMsgObj)!=NULL;
+}
+uint8 MD_RTU_MsgPut(PModbusBase pModbusBase, MD_RTU_MSG_HANDLE pMsgObj,void* msg,uint32 msgPutDelay){
+ return MsgPut(pMsgObj,msg,msgPutDelay);
+}
+uint8 MD_RTU_MsgGet(PModbusBase pModbusBase, MD_RTU_MSG_HANDLE pMsgObj,void **msg,uint32 msgGetDelay){
+ return MsgGet(pMsgObj,msg,msgGetDelay);
+}
+/**
+* @brief Create the locked object
+* @param[in] pModbusBase modbus object
+* @param[in] pLockObj Lock object pointer
+* @return
+* - TRUE success
+* - FALSE fail
+*/
+uint8 MD_RTU_CreateLock(PModbusBase pModbusBase, MD_RTU_LOCK_HANDLE *pLockObj){
+ if(pModbusBase==NULL){
+ return FALSE;
+ }
+ *pLockObj=MutexCreate();
+ return (*pLockObj)!=NULL;
+}
+/**
+* @brief Lock the modbus rtu object
+* @param[in] pModbusBase modbus object
+* @param[in] lockObj lock Object
+* @return
+* - TRUE success
+* - FALSE fail
+*/
+uint8 MD_RTU_Lock(PModbusBase pModbusBase, MD_RTU_LOCK_HANDLE lockObj,uint32 mutexWaitDelay){
+ return MutexLock(lockObj,mutexWaitDelay);
+}
+/**
+* @brief Unlock the modbus rtu object
+* @param[in] pModbusBase modbus object
+* @param[in] lockObj lock Object
+* @return
+* - TRUE success
+* - FALSE fail
+*/
+uint8 MD_RTU_Unlock(PModbusBase pModbusBase, MD_RTU_LOCK_HANDLE lockObj){
+ return MutexUnlock(lockObj);
+}
+/**
+* @brief Modbus RTU get system tick (100us).
+* @return system tick.
+*/
+uint32 MD_RTU_GetSysTick(void){
+ return sys_tick_100us;
+}
+#endif
+
diff --git a/mkrtos_user/lib/sys/inc/u_types.h b/mkrtos_user/lib/sys/inc/u_types.h
index 9288c6c1a..3e5eab8bd 100755
--- a/mkrtos_user/lib/sys/inc/u_types.h
+++ b/mkrtos_user/lib/sys/inc/u_types.h
@@ -12,6 +12,26 @@ typedef char bool_t;
typedef unsigned long obj_addr_t;
typedef unsigned long obj_handler_t;
typedef umword_t addr_t;
+
+/**
+ * @brief 资源描述符定义
+ *
+ */
+typedef umword_t sd_t; // 16bit(hd)|16bit(fd)
+typedef union mk_sd
+{
+ umword_t raw;
+ struct
+ {
+ uhmword_t hd;
+ uhmword_t fd;
+ };
+} mk_sd_t;
+#define mk_sd_init_raw(val) ((mk_sd_t){.raw = val})
+#define mk_sd_init3(h, f) ((mk_sd_t){.hd = h, .fd = f})
+#define mk_sd_get_hd(sd) ((obj_handler_t)((sd).hd))
+#define mk_sd_get_fd(sd) ((int)((sd).fd))
+
#ifndef NULL
#define NULL ((void *)0)
#endif
diff --git a/mkrtos_user/lib/sys/src/syscall.S b/mkrtos_user/lib/sys/src/syscall.S
index 3b6efd17d..fc8be995f 100644
--- a/mkrtos_user/lib/sys/src/syscall.S
+++ b/mkrtos_user/lib/sys/src/syscall.S
@@ -2,11 +2,11 @@
.text
/*
-int syscall(int nr, ...)
+int mk_syscall(int nr, ...)
*/
-.global syscall
-.type syscall, %function
-syscall:
+.global mk_syscall
+.type mk_syscall, %function
+mk_syscall:
push {r4-r7}
mov r7, r0
mov r0, r1
diff --git a/mkrtos_user/lib/sys/src/u_factory.c b/mkrtos_user/lib/sys/src/u_factory.c
index 2bea114e0..401af7c55 100644
--- a/mkrtos_user/lib/sys/src/u_factory.c
+++ b/mkrtos_user/lib/sys/src/u_factory.c
@@ -10,7 +10,7 @@ msg_tag_t factory_create_irq_sender(obj_handler_t obj, vpage_t vpage)
{
register volatile umword_t r0 asm("r0");
- syscall(syscall_prot_create(FACTORY_CREATE_KOBJ, FACTORY_PROT, obj),
+ mk_syscall(syscall_prot_create(FACTORY_CREATE_KOBJ, FACTORY_PROT, obj),
0,
IRQ_PROT,
vpage.raw,
@@ -25,7 +25,7 @@ msg_tag_t factory_create_thread(obj_handler_t obj, vpage_t vpage)
{
register volatile umword_t r0 asm("r0");
- syscall(syscall_prot_create(FACTORY_CREATE_KOBJ, FACTORY_PROT, obj),
+ mk_syscall(syscall_prot_create(FACTORY_CREATE_KOBJ, FACTORY_PROT, obj),
0,
THREAD_PROT,
vpage.raw,
@@ -40,7 +40,7 @@ msg_tag_t factory_create_task(obj_handler_t obj, vpage_t vpage)
{
register volatile umword_t r0 asm("r0");
- syscall(syscall_prot_create(FACTORY_CREATE_KOBJ, FACTORY_PROT, obj),
+ mk_syscall(syscall_prot_create(FACTORY_CREATE_KOBJ, FACTORY_PROT, obj),
0,
TASK_PROT,
vpage.raw,
@@ -55,7 +55,7 @@ msg_tag_t factory_create_ipc(obj_handler_t obj, vpage_t vpage)
{
register volatile umword_t r0 asm("r0");
- syscall(syscall_prot_create(FACTORY_CREATE_KOBJ, FACTORY_PROT, obj),
+ mk_syscall(syscall_prot_create(FACTORY_CREATE_KOBJ, FACTORY_PROT, obj),
0,
IPC_PROT,
vpage.raw,
diff --git a/mkrtos_user/lib/sys/src/u_ipc.c b/mkrtos_user/lib/sys/src/u_ipc.c
index 347cf5498..17b13b059 100644
--- a/mkrtos_user/lib/sys/src/u_ipc.c
+++ b/mkrtos_user/lib/sys/src/u_ipc.c
@@ -14,7 +14,7 @@ msg_tag_t ipc_bind(obj_handler_t obj, obj_handler_t tag_th, umword_t user_obj)
{
register volatile umword_t r0 asm("r0");
- syscall(syscall_prot_create(IPC_BIND, IPC_PROT, obj),
+ mk_syscall(syscall_prot_create(IPC_BIND, IPC_PROT, obj),
0,
tag_th,
user_obj,
@@ -34,7 +34,7 @@ msg_tag_t ipc_wait(obj_handler_t obj, umword_t *user_obj)
register volatile umword_t r0 asm("r0");
register volatile umword_t r1 asm("r1");
- syscall(syscall_prot_create(IPC_WAIT, IPC_PROT, obj),
+ mk_syscall(syscall_prot_create(IPC_WAIT, IPC_PROT, obj),
0,
0,
0,
@@ -55,7 +55,7 @@ msg_tag_t ipc_reply(obj_handler_t obj, msg_tag_t in_tag)
{
register volatile umword_t r0 asm("r0");
- syscall(syscall_prot_create(IPC_REPLY, IPC_PROT, obj),
+ mk_syscall(syscall_prot_create(IPC_REPLY, IPC_PROT, obj),
in_tag.raw,
0,
0,
@@ -74,7 +74,7 @@ msg_tag_t ipc_call(obj_handler_t obj, msg_tag_t in_tag, ipc_timeout_t timeout)
{
register volatile umword_t r0 asm("r0");
- syscall(syscall_prot_create(IPC_CALL, IPC_PROT, obj),
+ mk_syscall(syscall_prot_create(IPC_CALL, IPC_PROT, obj),
in_tag.raw,
timeout.raw,
0,
diff --git a/mkrtos_user/lib/sys/src/u_irq_sender.c b/mkrtos_user/lib/sys/src/u_irq_sender.c
index e4043f43d..f71493360 100644
--- a/mkrtos_user/lib/sys/src/u_irq_sender.c
+++ b/mkrtos_user/lib/sys/src/u_irq_sender.c
@@ -22,7 +22,7 @@ msg_tag_t uirq_bind(obj_handler_t obj_inx, umword_t irq_no, umword_t prio_sub_pr
{
register volatile umword_t r0 asm("r0");
- syscall(syscall_prot_create(BIND_IRQ, IRQ_PROT, obj_inx),
+ mk_syscall(syscall_prot_create(BIND_IRQ, IRQ_PROT, obj_inx),
0,
irq_no,
0,
@@ -41,7 +41,7 @@ msg_tag_t uirq_wait(obj_handler_t obj_inx, int flags)
{
register volatile umword_t r0 asm("r0");
- syscall(syscall_prot_create(WAIT_IRQ, IRQ_PROT, obj_inx),
+ mk_syscall(syscall_prot_create(WAIT_IRQ, IRQ_PROT, obj_inx),
0,
flags,
0,
@@ -60,7 +60,7 @@ msg_tag_t uirq_ack(obj_handler_t obj_inx, umword_t irq_no)
{
register volatile umword_t r0 asm("r0");
- syscall(syscall_prot_create(ACK_IRQ, IRQ_PROT, obj_inx),
+ mk_syscall(syscall_prot_create(ACK_IRQ, IRQ_PROT, obj_inx),
0,
irq_no,
0,
diff --git a/mkrtos_user/lib/sys/src/u_log.c b/mkrtos_user/lib/sys/src/u_log.c
index 5fd00f1dc..0ed6d5412 100644
--- a/mkrtos_user/lib/sys/src/u_log.c
+++ b/mkrtos_user/lib/sys/src/u_log.c
@@ -19,7 +19,7 @@ static msg_tag_t ulog_read_bytes_raw(obj_handler_t obj_inx, umword_t data[5], in
register volatile umword_t r3 asm("r3");
register volatile umword_t r4 asm("r4");
register volatile umword_t r5 asm("r5");
- syscall(syscall_prot_create(READ_DATA, LOG_PROT, obj_inx),
+ mk_syscall(syscall_prot_create(READ_DATA, LOG_PROT, obj_inx),
msg_tag_init4(0, 0, 0, 0).raw,
len,
0,
@@ -71,7 +71,7 @@ void ulog_write_bytes(obj_handler_t obj_inx, const uint8_t *data, umword_t len)
if (i > 0)
{
umword_t *write_word_buf = (umword_t *)write_buf;
- syscall(syscall_prot_create(WRITE_DATA, LOG_PROT, obj_inx),
+ mk_syscall(syscall_prot_create(WRITE_DATA, LOG_PROT, obj_inx),
msg_tag_init4(0, ROUND_UP(i, WORD_BYTES), 0, 0).raw,
write_word_buf[0],
write_word_buf[1],
diff --git a/mkrtos_user/lib/sys/src/u_mm.c b/mkrtos_user/lib/sys/src/u_mm.c
index 66d5e7251..6becbf2b2 100644
--- a/mkrtos_user/lib/sys/src/u_mm.c
+++ b/mkrtos_user/lib/sys/src/u_mm.c
@@ -16,7 +16,7 @@ void *mm_alloc_page(obj_handler_t obj_inx, umword_t pnf_nr, uint8_t attrs)
register volatile umword_t r1 asm("r1");
register volatile umword_t r2 asm("r2");
register volatile umword_t r3 asm("r3");
- syscall(syscall_prot_create(MM_ALLOC, MM_PROT, obj_inx),
+ mk_syscall(syscall_prot_create(MM_ALLOC, MM_PROT, obj_inx),
0,
pnf_nr,
attrs,
@@ -40,7 +40,7 @@ void *mm_alloc_page(obj_handler_t obj_inx, umword_t pnf_nr, uint8_t attrs)
}
void mm_free_page(obj_handler_t obj_inx, void *addr, umword_t pfn_nr)
{
- syscall(syscall_prot_create(MM_FREE, MM_PROT, obj_inx),
+ mk_syscall(syscall_prot_create(MM_FREE, MM_PROT, obj_inx),
0,
addr,
pfn_nr,
@@ -52,7 +52,7 @@ msg_tag_t mm_align_alloc(obj_handler_t obj_inx, void *addr, umword_t size)
{
register volatile umword_t r0 asm("r0");
- syscall(syscall_prot_create(MM_ALIGN_ALLOC, MM_PROT, obj_inx),
+ mk_syscall(syscall_prot_create(MM_ALIGN_ALLOC, MM_PROT, obj_inx),
0,
addr,
size,
diff --git a/mkrtos_user/lib/sys/src/u_sys.c b/mkrtos_user/lib/sys/src/u_sys.c
index cb0ae5ba4..e7ab82420 100644
--- a/mkrtos_user/lib/sys/src/u_sys.c
+++ b/mkrtos_user/lib/sys/src/u_sys.c
@@ -19,7 +19,7 @@ msg_tag_t sys_read_info(obj_handler_t obj, sys_info_t *info)
register volatile umword_t r1 asm("r1");
register volatile umword_t r2 asm("r2");
- syscall(syscall_prot_create(SYS_INFO_GET, SYS_PROT, obj),
+ mk_syscall(syscall_prot_create(SYS_INFO_GET, SYS_PROT, obj),
0,
0,
0,
diff --git a/mkrtos_user/lib/sys/src/u_task.c b/mkrtos_user/lib/sys/src/u_task.c
index 0640347be..1c5fc0824 100644
--- a/mkrtos_user/lib/sys/src/u_task.c
+++ b/mkrtos_user/lib/sys/src/u_task.c
@@ -12,7 +12,7 @@ msg_tag_t task_obj_valid(obj_handler_t dst_task, obj_handler_t obj_inx)
{
register volatile umword_t r0 asm("r0");
- syscall(syscall_prot_create(TASK_OBJ_MAP, TASK_PROT, dst_task),
+ mk_syscall(syscall_prot_create(TASK_OBJ_MAP, TASK_PROT, dst_task),
0,
obj_inx,
0,
@@ -32,7 +32,7 @@ msg_tag_t task_map(obj_handler_t dst_task, obj_handler_t src_obj, obj_handler_t
{
register volatile umword_t r0 asm("r0");
- syscall(syscall_prot_create(TASK_OBJ_MAP, TASK_PROT, dst_task),
+ mk_syscall(syscall_prot_create(TASK_OBJ_MAP, TASK_PROT, dst_task),
0,
src_obj,
dst_obj,
@@ -52,7 +52,7 @@ msg_tag_t task_unmap(obj_handler_t task_han, vpage_t vpage)
{
register volatile umword_t r0 asm("r0");
- syscall(syscall_prot_create(TASK_OBJ_UNMAP, TASK_PROT, task_han),
+ mk_syscall(syscall_prot_create(TASK_OBJ_UNMAP, TASK_PROT, task_han),
0,
vpage.raw,
0,
@@ -68,7 +68,7 @@ msg_tag_t task_alloc_ram_base(obj_handler_t task_han, umword_t size, addr_t *all
register volatile umword_t r0 asm("r0");
register volatile umword_t r1 asm("r1");
- syscall(syscall_prot_create(TASK_ALLOC_RAM_BASE, TASK_PROT, task_han),
+ mk_syscall(syscall_prot_create(TASK_ALLOC_RAM_BASE, TASK_PROT, task_han),
0,
size,
0,
diff --git a/mkrtos_user/lib/sys/src/u_thread.c b/mkrtos_user/lib/sys/src/u_thread.c
index 9256020b7..c18454359 100644
--- a/mkrtos_user/lib/sys/src/u_thread.c
+++ b/mkrtos_user/lib/sys/src/u_thread.c
@@ -15,7 +15,7 @@ msg_tag_t thread_msg_buf_set(obj_handler_t obj, void *msg)
register volatile umword_t r1 asm("r1");
register volatile umword_t r2 asm("r2");
- syscall(syscall_prot_create(MSG_BUG_SET, THREAD_PROT, obj),
+ mk_syscall(syscall_prot_create(MSG_BUG_SET, THREAD_PROT, obj),
0,
msg,
0,
@@ -34,7 +34,7 @@ msg_tag_t thread_msg_buf_get(obj_handler_t obj, umword_t *msg, umword_t *len)
register volatile umword_t r1 asm("r1");
register volatile umword_t r2 asm("r2");
- syscall(syscall_prot_create4(MSG_BUG_GET, THREAD_PROT, obj, TRUE),
+ mk_syscall(syscall_prot_create4(MSG_BUG_GET, THREAD_PROT, obj, TRUE),
0,
0,
0,
@@ -60,7 +60,7 @@ msg_tag_t thread_exec_regs(obj_handler_t obj, umword_t pc, umword_t sp, umword_t
{
register volatile umword_t r0 asm("r0");
- syscall(syscall_prot_create(SET_EXEC_REGS, THREAD_PROT, obj),
+ mk_syscall(syscall_prot_create(SET_EXEC_REGS, THREAD_PROT, obj),
0,
pc,
sp,
@@ -79,7 +79,7 @@ msg_tag_t thread_run(obj_handler_t obj, uint8_t prio)
{
register volatile umword_t r0 asm("r0");
- syscall(syscall_prot_create(RUN_THREAD, THREAD_PROT, obj),
+ mk_syscall(syscall_prot_create(RUN_THREAD, THREAD_PROT, obj),
0,
prio,
0,
@@ -94,7 +94,7 @@ msg_tag_t thread_bind_task(obj_handler_t obj, obj_handler_t tk_obj)
{
register volatile umword_t r0 asm("r0");
- syscall(syscall_prot_create(BIND_TASK, THREAD_PROT, obj),
+ mk_syscall(syscall_prot_create(BIND_TASK, THREAD_PROT, obj),
0,
tk_obj,
0,
diff --git a/mkrtos_user/lib/sys_svr/inc/ns_types.h b/mkrtos_user/lib/sys_svr/inc/ns_types.h
index a9a66f8e1..d8f92ad44 100644
--- a/mkrtos_user/lib/sys_svr/inc/ns_types.h
+++ b/mkrtos_user/lib/sys_svr/inc/ns_types.h
@@ -4,6 +4,10 @@
#define NAMESPACE_PATH_LEN 32
#define NAMESAPCE_NR 8
+/**
+ * @brief 非常简单的方式实现路径管理
+ *
+ */
typedef struct namespace_entry
{
char path[NAMESPACE_PATH_LEN]; //!< 服务的路径名
@@ -14,6 +18,6 @@ typedef struct ns
{
rpc_svr_obj_t svr;
namespace_entry_t ne_list[NAMESAPCE_NR]; //!< 服务列表
- obj_handler_t hd;
- obj_handler_t ipc_hd; //!< 服务的ipc hd
+ obj_handler_t hd; //!< 存储临时用于映射的hd
+ obj_handler_t ipc_hd; //!< 服务的ipc hd
} ns_t;
\ No newline at end of file
diff --git a/mkrtos_user/lib/sys_svr/src/fs_cli.c b/mkrtos_user/lib/sys_svr/src/fs_cli.c
index c4b29bc78..1c4f9153e 100644
--- a/mkrtos_user/lib/sys_svr/src/fs_cli.c
+++ b/mkrtos_user/lib/sys_svr/src/fs_cli.c
@@ -30,10 +30,11 @@ RPC_GENERATION_CALL3(fs_t, FS_LSEEK, lseek,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, fd,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, offs,
rpc_int_t, rpc_int_t, RPC_DIR_IN, RPC_TYPE_DATA, whence)
-int fs_open(const char *path, int flags, int mode)
+
+sd_t fs_open(const char *path, int flags, int mode)
{
obj_handler_t hd;
- int ret = ns_query("fs", &hd);
+ int ret = ns_query(path, &hd);
if (ret < 0)
{
@@ -59,15 +60,10 @@ int fs_open(const char *path, int flags, int mode)
return msg_tag_get_val(tag);
}
-int fs_read(int fd, void *buf, size_t len)
+int fs_read(sd_t _fd, void *buf, size_t len)
{
- obj_handler_t hd;
- int ret = ns_query("fs", &hd);
-
- if (ret < 0)
- {
- return ret;
- }
+ obj_handler_t hd = mk_sd_init_raw(_fd).hd;
+ int fd = mk_sd_init_raw(_fd).fd;
rpc_int_t rpc_fd = {
.data = fd,
@@ -102,15 +98,10 @@ int fs_read(int fd, void *buf, size_t len)
return rlen;
}
-int fs_write(int fd, void *buf, size_t len)
+int fs_write(sd_t _fd, void *buf, size_t len)
{
- obj_handler_t hd;
- int ret = ns_query("fs", &hd);
-
- if (ret < 0)
- {
- return ret;
- }
+ obj_handler_t hd = mk_sd_init_raw(_fd).hd;
+ int fd = mk_sd_init_raw(_fd).fd;
rpc_int_t rpc_fd = {
.data = fd,
@@ -143,15 +134,10 @@ int fs_write(int fd, void *buf, size_t len)
return wlen;
}
-int fs_close(int fd)
+int fs_close(sd_t _fd)
{
- obj_handler_t hd;
- int ret = ns_query("fs", &hd);
-
- if (ret < 0)
- {
- return ret;
- }
+ obj_handler_t hd = mk_sd_init_raw(_fd).hd;
+ int fd = mk_sd_init_raw(_fd).fd;
rpc_int_t rpc_fd = {
.data = fd,
@@ -165,15 +151,10 @@ int fs_close(int fd)
return msg_tag_get_val(tag);
}
-int fs_lseek(int fd, int offs, int whence)
+int fs_lseek(sd_t _fd, int offs, int whence)
{
- obj_handler_t hd;
- int ret = ns_query("fs", &hd);
-
- if (ret < 0)
- {
- return ret;
- }
+ obj_handler_t hd = mk_sd_init_raw(_fd).hd;
+ int fd =mk_sd_init_raw(_fd).fd;
rpc_int_t rpc_fd = {
.data = fd,
diff --git a/mkrtos_user/lib/sys_svr/src/ns_cli.c b/mkrtos_user/lib/sys_svr/src/ns_cli.c
index 08fcff208..2779d7ffa 100644
--- a/mkrtos_user/lib/sys_svr/src/ns_cli.c
+++ b/mkrtos_user/lib/sys_svr/src/ns_cli.c
@@ -23,7 +23,14 @@ typedef struct ns_cli_cache
static ns_cli_cache_t ns_cli_cache;
-static obj_handler_t find_hd(const char *path)
+/**
+ * @brief TODO:加锁
+ *
+ * @param path
+ * @param split_pos
+ * @return obj_handler_t
+ */
+static obj_handler_t find_hd(const char *path, int *split_pos)
{
int i = 0;
int empty = -1;
@@ -31,8 +38,13 @@ static obj_handler_t find_hd(const char *path)
{
if (ns_cli_cache.cache[i].path[0] != 0)
{
- if (strcmp(ns_cli_cache.cache[i].path, path) == 0)
+ char *new_str = strstr(ns_cli_cache.cache[i].path, path);
+ if (new_str && (new_str == ns_cli_cache.cache[i].path))
{
+ if (split_pos)
+ {
+ *split_pos = (int)(new_str - ns_cli_cache.cache[i].path);
+ }
return ns_cli_cache.cache[i].hd;
}
}
@@ -81,12 +93,13 @@ int ns_register(const char *path, obj_handler_t svr_hd)
}
int ns_query(const char *path, obj_handler_t *svr_hd)
{
+ int inx = 0;
assert(path);
assert(svr_hd);
obj_handler_t newfd;
- newfd = find_hd(path);
+ newfd = find_hd(path, &inx);
if (newfd != HANDLER_INVALID)
{
*svr_hd = newfd;
@@ -101,8 +114,8 @@ int ns_query(const char *path, obj_handler_t *svr_hd)
}
rpc_ref_array_uint32_t_uint8_t_32_t rpc_path = {
- .data = path,
- .len = strlen(path) + 1,
+ .data = &path[inx],
+ .len = strlen(&path[inx]) + 1,
};
rpc_obj_handler_t_t rpc_svr_hd = {
.data = newfd,
diff --git a/mkrtos_user/lib/sys_util/inc/u_rpc.h b/mkrtos_user/lib/sys_util/inc/u_rpc.h
index deca319dc..42eca4343 100644
--- a/mkrtos_user/lib/sys_util/inc/u_rpc.h
+++ b/mkrtos_user/lib/sys_util/inc/u_rpc.h
@@ -326,7 +326,7 @@ RPC_ARRAY_DEF(uint32_t, uint8_t, 32)
len += d->len * sizeof(d->data[0]); \
return len; \
} \
- RPC_CLI_BUF_TO_MSG_WITHOUT_IMPL(rpc_ref_array_uint32_t_uint8_t_32_t, int) \
+ RPC_CLI_BUF_TO_MSG_WITHOUT_IMPL(rpc_ref_array_##len_type##_##data_type##_##length##_t, int) \
{ \
if (rpc_align(len, __alignof(d->len)) > \
max) \
@@ -355,6 +355,8 @@ RPC_ARRAY_DEF(uint32_t, uint8_t, 32)
*
*/
RPC_REF_ARRAY_DEF(uint32_t, uint8_t, 32)
+RPC_REF_ARRAY_DEF(uint32_t, uint8_t, 48)
+RPC_REF_ARRAY_DEF(uint32_t, uint8_t, 64)
/**
* @brief Construct a new rpc type def object
diff --git a/mkrtos_user/lib/sys_util/src/u_app_loader.c b/mkrtos_user/lib/sys_util/src/u_app_loader.c
index 838d8b6b9..31fdd1352 100644
--- a/mkrtos_user/lib/sys_util/src/u_app_loader.c
+++ b/mkrtos_user/lib/sys_util/src/u_app_loader.c
@@ -107,12 +107,12 @@ int app_load(const char *name, uenv_t *cur_env)
{
goto end_del_obj;
}
- tag = task_map(hd_task, LOG_PROT, LOG_PROT, 0);
+ tag = task_map(hd_task, LOG_PROT, LOG_PROT, KOBJ_DELETE_RIGHT);
if (msg_tag_get_prot(tag) < 0)
{
goto end_del_obj;
}
- tag = task_map(hd_task, SYS_PROT, SYS_PROT, 0);
+ tag = task_map(hd_task, SYS_PROT, SYS_PROT, KOBJ_DELETE_RIGHT);
if (msg_tag_get_prot(tag) < 0)
{
goto end_del_obj;
@@ -127,12 +127,12 @@ int app_load(const char *name, uenv_t *cur_env)
{
goto end_del_obj;
}
- tag = task_map(hd_task, FACTORY_PROT, FACTORY_PROT, 0);
+ tag = task_map(hd_task, FACTORY_PROT, FACTORY_PROT, KOBJ_DELETE_RIGHT);
if (msg_tag_get_prot(tag) < 0)
{
goto end_del_obj;
}
- tag = task_map(hd_task, MM_PROT, MM_PROT, 0);
+ tag = task_map(hd_task, MM_PROT, MM_PROT, KOBJ_DELETE_RIGHT);
if (msg_tag_get_prot(tag) < 0)
{
goto end_del_obj;
diff --git a/mkrtos_user/server/app/CMakeLists.txt b/mkrtos_user/server/app/CMakeLists.txt
index 8bc4dbda3..209082b58 100644
--- a/mkrtos_user/server/app/CMakeLists.txt
+++ b/mkrtos_user/server/app/CMakeLists.txt
@@ -16,6 +16,7 @@ target_link_libraries(app.elf
sys
sys_util
sys_svr
+ xtinymodbus
stm32f1_bsp
${GCC_LIB_PATH}/libgcc.a
)
@@ -28,6 +29,16 @@ target_include_directories(
${CMAKE_SOURCE_DIR}/mkrtos_user/server/app/drv
${CMAKE_SOURCE_DIR}/mkrtos_user/server/app/test
+ ${CMAKE_SOURCE_DIR}/mkrtos_user/server/app/modbus
+#xtinymodbus
+ ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/modbus/inc/modbus_base
+ ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/modbus/inc/modbus_rtu_master
+ ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/modbus/inc/modbus_rtu_slave
+ ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/modbus/inc/port
+ ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/modbus/inc/serial
+ ${CMAKE_SOURCE_DIR}/mkrtos_user/lib/modbus/inc
+#end
+
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/arch/arm/
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/arch/generic
${CMAKE_SOURCE_DIR}/mkrtos_user/lib/mlibc/obj/src/internal
diff --git a/mkrtos_user/server/app/drv/drv.c b/mkrtos_user/server/app/drv/drv.c
index a5de1e47a..ce50c5cd8 100644
--- a/mkrtos_user/server/app/drv/drv.c
+++ b/mkrtos_user/server/app/drv/drv.c
@@ -19,14 +19,15 @@
#include "wk2xx_hw.h"
#include "hmi_lcd_process.h"
#include "music_control.h"
+#include "MDM_RTU_APP.h"
#include
void music2_send_bytes(u8 *bytes, int len)
{
- /*在下面调用bsp的发送函数*/
- wk_TxChars(2,len,bytes);
- //等待发送完成
- wk_wait_tx_done(2);
+ /*在下面调用bsp的发送函数*/
+ wk_TxChars(2, len, bytes);
+ // 等待发送完成
+ wk_wait_tx_done(2);
}
void drv_init(void)
@@ -40,7 +41,6 @@ void drv_init(void)
init_usart2(115200);
init_usart3(115200);
init_uart4(115200);
- init_uart5(115200);
ext_input_check();
wk2xx_hw_init();
Wk_DeInit(1);
@@ -65,4 +65,6 @@ void drv_init(void)
bluetooth_init_cfg(0, usart2_send_bytes);
bluetooth_init_cfg(1, music2_send_bytes);
+
+ MDM_RTU_APPInit();
}
diff --git a/mkrtos_user/server/app/modbus/MDM_RTU_APP.c b/mkrtos_user/server/app/modbus/MDM_RTU_APP.c
new file mode 100644
index 000000000..fff733e9e
--- /dev/null
+++ b/mkrtos_user/server/app/modbus/MDM_RTU_APP.c
@@ -0,0 +1,229 @@
+/**
+ * @file MDM_RTU_APP.c
+ * @author zhangzheng (1358745329@qq.com)
+ * @brief https://github.com/lotoohe-space/XTinyModbus
+ * @version 0.1
+ * @date 2023-10-03
+ *
+ * @copyright Copyright (c) 2023
+ *
+ */
+
+/*********************************HEAD FILE************************************/
+#include "MDM_RTU_APP.h"
+#include "MDM_RTU_Fun.h"
+#include "MDM_RTU_Serial.h"
+#include "MDM_RTU_User_Fun.h"
+#include "MDM_RTU_RW_Man.h"
+#include "u_sys.h"
+#include "sysinfo.h"
+/*********************************END******************************************/
+#define USE_RS485_DB 1
+/*********************************全局变量************************************/
+uint16 regDataMaster0[32] = {0};
+MapTableItem mapTableItemMaster0 = {
+ .modbusAddr = 0x0000, /*MODBUS中的地址*/
+ .modbusData = regDataMaster0, /*映射的内存单元*/
+ .modbusDataSize = 32, /*映射的大小*/
+ .addrType = HOLD_REGS_TYPE, /*映射的类型*/
+ .devAddr = 6, /*被哪个从机使用*/
+};
+uint16 regDataMaster1[32] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
+MapTableItem mapTableItemMaster1 = {
+ .modbusAddr = 0x0000, /*MODBUS中的地址*/
+ .modbusData = regDataMaster1, /*映射的内存单元*/
+ .modbusDataSize = 32, /*映射的大小*/
+ .addrType = HOLD_REGS_TYPE, /*映射的类型*/
+ .devAddr = 7, /*被哪个从机使用*/
+};
+uint16 regDataMaster2[32] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
+MapTableItem mapTableItemMaster2 = {
+ .modbusAddr = 0x0000, /*MODBUS中的地址*/
+ .modbusData = regDataMaster2, /*映射的内存单元*/
+ .modbusDataSize = 32, /*映射的大小*/
+ .addrType = HOLD_REGS_TYPE, /*映射的类型*/
+ .devAddr = 8, /*被哪个从机使用*/
+};
+
+Modbus_RTU modbus_RTU = {0};
+Modbus_RTU_CB modbusRWRTUCB = {0};
+Modbus_RTU_CB modbusRWRTUCB1 = {0};
+Modbus_RTU_CB modbusRWRTUCB2 = {0};
+Modbus_RTU_CB modbusRWRTUCB3 = {0};
+Modbus_RTU_CB modbusRWRTUCB4 = {0};
+static uint8_t recv_buf[257];
+/*********************************结束******************************************/
+
+/*******************************************************
+ *
+ * Function name :MDM_RTU_APPInit
+ * Description :主机用户APP初始化函数
+ * Parameter :无
+ * Return : TRUE success , FALSE fail
+ **********************************************************/
+BOOL MDM_RTU_APPInit(void)
+{
+ if (MDM_RTU_Init(&modbus_RTU, MDMInitSerial, 9600, 8, 1, 0) != ERR_NONE)
+ {
+ return FALSE;
+ }
+ MDM_RTU_QueueInit(&modbus_RTU,
+ recv_buf,
+ sizeof(recv_buf));
+
+ if (MDM_RTU_AddMapItem(&modbus_RTU, &mapTableItemMaster0) == FALSE)
+ {
+ return FALSE;
+ }
+ if (MDM_RTU_AddMapItem(&modbus_RTU, &mapTableItemMaster1) == FALSE)
+ {
+ return FALSE;
+ }
+ if (MDM_RTU_AddMapItem(&modbus_RTU, &mapTableItemMaster2) == FALSE)
+ {
+ return FALSE;
+ }
+
+ /*RW控制块*/
+ MDM_RTU_CB_Init(&modbusRWRTUCB, &modbus_RTU, 3000, 3000, 1);
+ MDM_RTU_CB_Init(&modbusRWRTUCB1, &modbus_RTU, 3000, 3000, 1);
+ MDM_RTU_CB_Init(&modbusRWRTUCB2, &modbus_RTU, 3000, 3000, 1);
+ MDM_RTU_CB_Init(&modbusRWRTUCB3, &modbus_RTU, 3000, 3000, 1);
+ MDM_RTU_CB_Init(&modbusRWRTUCB4, &modbus_RTU, 3000, 3000, 1);
+ return TRUE;
+}
+// uint16 temp = ~(0x5555);
+// uint16 temp2 = 0x5555;
+// uint16 temp1 = 1234;
+// uint16 data1[] = {1, 2, 3, 4, 5, 6};
+#define MD_NB_MODE_TEST 1
+/*用户读取数据*/
+static void MDM_RTUUserRead(void)
+{
+ uint16 resTemp;
+#if USE_RS485_DB
+#if MD_NB_MODE_TEST
+ MDError res;
+ res = MDM_RTU_NB_ReadHoldReg(&modbusRWRTUCB, 6, 0, 11);
+ if (res != ERR_IDLE)
+ {
+ if (res != ERR_RW_FIN)
+ { /*出现错误*/
+ if (res == ERR_RW_OV_TIME_ERR)
+ { /*超时了*/
+ /*使能重传*/
+ MDM_RTU_CB_OverTimeReset(&modbusRWRTUCB);
+ }
+ }
+ else
+ {
+
+ /*读成功*/
+ MDM_RTU_ReadRegs(modbusRWRTUCB.pModbus_RTU, 0x0000, 1, &resTemp, HOLD_REGS_TYPE, 6);
+ sys_info.noise[0] = (float)(resTemp) / 10.0f;
+
+ MDM_RTU_ReadRegs(modbusRWRTUCB.pModbus_RTU, 10, 1, &resTemp, HOLD_REGS_TYPE, 6);
+ sys_info.noise_temp[0] = (float)(resTemp);
+ }
+ }
+ res = MDM_RTU_NB_ReadHoldReg(&modbusRWRTUCB1, 7, 0, 11);
+ if (res != ERR_IDLE)
+ {
+ if (res != ERR_RW_FIN)
+ { /*出现错误*/
+ if (res == ERR_RW_OV_TIME_ERR)
+ { /*超时了*/
+ /*使能重传*/
+ MDM_RTU_CB_OverTimeReset(&modbusRWRTUCB1);
+ }
+ }
+ else
+ {
+ /*读成功*/
+ MDM_RTU_ReadRegs(modbusRWRTUCB1.pModbus_RTU, 0x0000, 1, &resTemp, HOLD_REGS_TYPE, 7);
+ sys_info.noise[1] = (float)(resTemp) / 10.0f;
+
+ MDM_RTU_ReadRegs(modbusRWRTUCB1.pModbus_RTU, 10, 1, &resTemp, HOLD_REGS_TYPE, 7);
+ sys_info.noise_temp[1] = (float)(resTemp);
+ }
+ }
+ res = MDM_RTU_NB_ReadHoldReg(&modbusRWRTUCB2, 8, 0, 11);
+ if (res != ERR_IDLE)
+ {
+ if (res != ERR_RW_FIN)
+ { /*出现错误*/
+ if (res == ERR_RW_OV_TIME_ERR)
+ { /*超时了*/
+ /*使能重传*/
+ MDM_RTU_CB_OverTimeReset(&modbusRWRTUCB2);
+ }
+ }
+ else
+ {
+ /*读成功*/
+ MDM_RTU_ReadRegs(modbusRWRTUCB2.pModbus_RTU, 0x0000, 1, &resTemp, HOLD_REGS_TYPE, 8);
+ sys_info.noise[2] = (float)(resTemp) / 10.0f;
+
+ MDM_RTU_ReadRegs(modbusRWRTUCB2.pModbus_RTU, 10, 1, &resTemp, HOLD_REGS_TYPE, 8);
+ sys_info.noise_temp[2] = (float)(resTemp);
+ }
+ }
+#else
+
+ if (MDM_RTU_ReadCoil(&modbusRWRTUCB, 0x1, 0x0000, 16) == ERR_RW_FIN)
+ {
+ MDM_RTU_ReadBits(modbusRWRTUCB.pModbus_RTU, 0x0000, 16, (uint8 *)&resTemp, COILS_TYPE, 0x1);
+ resTemp = resTemp;
+ }
+#endif
+#endif
+}
+
+// static void MDM_RTUUserWrite(void)
+// {
+// MDError res;
+// #if MD_NB_MODE_TEST
+// res = MDM_RTU_NB_WriteCoils(&modbusRWRTUCB1, 0x1, 0, 16, (uint8 *)(&temp));
+// if (res != ERR_IDLE)
+// {
+// if (res != ERR_RW_FIN)
+// { /*出现错误*/
+// if (res == ERR_RW_OV_TIME_ERR)
+// { /*超时了*/
+// /*使能重传*/
+// MDM_RTU_CB_OverTimeReset(&modbusRWRTUCB1);
+// }
+// }
+// }
+// res = MDM_RTU_NB_WriteCoils(&modbusRWRTUCB4, 0x1, 0, 16, (uint8 *)(&temp2));
+// if (res != ERR_IDLE)
+// {
+// if (res != ERR_RW_FIN)
+// { /*出现错误*/
+// if (res == ERR_RW_OV_TIME_ERR)
+// { /*超时了*/
+// /*使能重传*/
+// MDM_RTU_CB_OverTimeReset(&modbusRWRTUCB4);
+// }
+// }
+// }
+// #else
+// MDM_RTU_WriteCoils(&modbusRWRTUCB1, 0x1, 0, 16, (uint8 *)(&temp));
+// MDM_RTU_WriteCoils(&modbusRWRTUCB4, 0x1, 0, 16, (uint8 *)(&temp2));
+
+// // MDM_RTU_WriteRegs(&modbusRWRTUCB4,0x1,0,6,data1);
+// #endif
+// }
+/*用户数据的读写*/
+static void MDM_RTU_UserUpdate(void)
+{
+ MDM_RTUUserRead();
+ // MDM_RTUUserWrite();
+}
+
+/*Loop call*/
+void MDM_RTU_Loop(void)
+{
+ MDMTimeHandler100US(sys_read_tick() * 10);
+ MDM_RTU_UserUpdate();
+}
diff --git a/mkrtos_user/server/app/modbus/MDM_RTU_APP.h b/mkrtos_user/server/app/modbus/MDM_RTU_APP.h
new file mode 100644
index 000000000..b7fec4c2f
--- /dev/null
+++ b/mkrtos_user/server/app/modbus/MDM_RTU_APP.h
@@ -0,0 +1,8 @@
+#ifndef _MDM_RTU_APP_H__
+#define _MDM_RTU_APP_H__
+#include "MD_RTU_Type.h"
+
+BOOL MDM_RTU_APPInit(void);
+void MDM_RTU_Loop(void);
+
+#endif
diff --git a/mkrtos_user/server/app/modbus/MDM_RTU_Serial.c b/mkrtos_user/server/app/modbus/MDM_RTU_Serial.c
new file mode 100644
index 000000000..7dc2e8b58
--- /dev/null
+++ b/mkrtos_user/server/app/modbus/MDM_RTU_Serial.c
@@ -0,0 +1,124 @@
+/********************************************************************************
+ * @File name: MD_RTU_Serial.c
+ * @Author: zspace
+ * @Emial: 1358745329@qq.com
+ * @Version: 1.0
+ * @Date: 2020-4-10
+ * @Description: Modbus RTU Serial related modules
+ * Open source address: https://github.com/lotoohe-space/XTinyModbus
+ ********************************************************************************/
+
+/*********************************HEAD FILE************************************/
+#include "MDM_RTU_Serial.h"
+#include "MD_RTU_Tool.h"
+#include "wk2xx_hw.h"
+#include "uart5.h"
+#include "rs485.h"
+#include
+/*User-related header files*/
+
+/*********************************END******************************************/
+#define WK_UART_NUM1 4
+/*********************************GLOBAL VARIABLE************************************/
+PModbusBase pModbusMBase = NULL; /*Modbus of the current serial port*/
+/*********************************END******************************************/
+
+/*********************************FUNCTION DECLARATION************************************/
+
+// void MDMTimeHandler100US(void);
+/*********************************END******************************************/
+
+/*******************************************************
+ *
+ * Function name :MDMInitSerial
+ * Description :Hardware initialization function, you can initialize the serial port here
+ * Parameter :
+ * @obj Host object pointer
+ * @baud Baud rate
+ * @dataBits Data bit
+ * @stopBit Stop bit
+ * @parity Parity bit
+ * Return :None
+ **********************************************************/
+void MDMInitSerial(void *obj, uint32 baud, uint8 dataBits, uint8 stopBit, uint8 parity)
+{
+ pModbusMBase = obj;
+ if (obj == NULL)
+ {
+ return;
+ }
+
+ pModbusMBase->mdRTUSendBytesFunction = MDMSerialSendBytes;
+ pModbusMBase->mdRTURecSendConv = MDMSerialSWRecv_Send;
+
+ /*Hardware initialization*/
+ assert(baud == 9600);
+ Wk_SetBaud(WK_UART_NUM1, B9600);
+ init_uart5(B9600);
+}
+/*******************************************************
+ *
+ * Function name :MDMTimeHandler100US
+ * Description :Call this function in the timer
+ * Parameter :None
+ * Return :None
+ **********************************************************/
+void MDMTimeHandler100US(uint32 times)
+{
+ if (pModbusMBase == NULL)
+ {
+ return;
+ }
+ pModbusMBase->mdRTUTimeHandlerFunction(pModbusMBase, times);
+}
+/*******************************************************
+ *
+ * Function name :MDMSerialRecvByte
+ * Description :Bsp layer serial port interrupt receiving call this function
+ * Parameter :
+ * @byte Byte received
+ * Return : None
+ **********************************************************/
+void MDMSerialRecvByte(uint8 byte)
+{
+ if (pModbusMBase == NULL)
+ {
+ return;
+ }
+ pModbusMBase->mdRTURecByteFunction(pModbusMBase, byte);
+}
+/*******************************************************
+ *
+ * Function name :MDMSerialRecvByte
+ * Description :Switch to receive or send
+ * Parameter :
+ * @mode TRUE send, FALSE receive
+ * Return : None
+ **********************************************************/
+void MDMSerialSWRecv_Send(uint8 mode)
+{
+ /*Send and receive conversion*/
+ /*Fill in the converted code below*/
+ RS4850_RW_CONV = mode;
+ RS4851_RW_CONV = mode;
+ /*Different hardware may require a little delay after setting conversion*/
+}
+/*******************************************************
+ *
+ * Function name :MDMSerialSendBytes
+ * Description :Send function
+ * Parameter :
+ * @bytes Data sent
+ * @num How many bytes to send
+ * Return : None
+ **********************************************************/
+void MDMSerialSendBytes(uint8 *bytes, uint16 num)
+{
+
+ uart5_send_bytes(bytes, num);
+
+ /*在下面调用bsp的发送函数*/
+ wk_TxChars(WK_UART_NUM1, num, bytes);
+ // 等待发送完成
+ wk_wait_tx_done(WK_UART_NUM1);
+}
diff --git a/mkrtos_user/server/app/modbus/MDM_RTU_Serial.h b/mkrtos_user/server/app/modbus/MDM_RTU_Serial.h
new file mode 100644
index 000000000..33326abaf
--- /dev/null
+++ b/mkrtos_user/server/app/modbus/MDM_RTU_Serial.h
@@ -0,0 +1,30 @@
+/********************************************************************************
+ * @File name: MD_RTU_Serial.h
+ * @Author: zspace
+ * @Emial: 1358745329@qq.com
+ * @Version: 1.0
+ * @Date: 2020-4-10
+ * @Description: Modbus RTU Serial related modules
+ ********************************************************************************/
+
+#ifndef _MDM_RTU_SERIAL_H__
+#define _MDM_RTU_SERIAL_H__
+
+/*********************************HEAD FILE************************************/
+#include "MD_RTU_Type.h"
+#include "MD_RTU_Config.h"
+/*********************************END******************************************/
+
+/*********************************Function declaration************************************/
+/*Hardware initialization function, you can initialize the serial port here*/
+void MDMInitSerial(void *obj, uint32 baud, uint8 dataBits, uint8 stopBit, uint8 parity);
+/*Bsp layer interrupt receiving call this function*/
+void MDMSerialRecvByte(uint8 byte);
+/*Call this function in the timer*/
+void MDMTimeHandler100US(uint32 times);
+
+void MDMSerialSendBytes(uint8 *bytes, uint16 num);
+void MDMSerialSWRecv_Send(uint8 mode);
+/*********************************END******************************************/
+
+#endif
diff --git a/mkrtos_user/server/fs/fatfs/main.c b/mkrtos_user/server/fs/fatfs/main.c
index f85fe6646..2eed07216 100644
--- a/mkrtos_user/server/fs/fatfs/main.c
+++ b/mkrtos_user/server/fs/fatfs/main.c
@@ -17,13 +17,14 @@ int main(int args, char *argv[])
obj_handler_t ipc_hd;
int ret = rpc_creaite_bind_ipc(THREAD_MAIN, NULL, &ipc_hd);
assert(ret >= 0);
- ns_register("fs", ipc_hd);
+ ns_register("/mnt", ipc_hd);
fs_svr_init(ipc_hd);
FRESULT res = f_mount(&fs, "0:", 1);
if (res != FR_OK)
{
+ assert(sizeof(FIL) >= FF_MAX_SS);
res = f_mkfs("0:", &defopt, file_temp_buf_get(), FF_MAX_SS); // 第三个参数可以设置成NULL,默认使用heap memory
if (res != FR_OK)
{
diff --git a/mkrtos_user/server/hello/src/main.c b/mkrtos_user/server/hello/src/main.c
index 9310d92e6..4f923ddcd 100644
--- a/mkrtos_user/server/hello/src/main.c
+++ b/mkrtos_user/server/hello/src/main.c
@@ -1,8 +1,10 @@
-#include
+// #include
#include "u_log.h"
+#include "u_env.h"
int main(int argc, char *args[])
{
- printf("Hello world.\n");
+ // printf("Hello world.\n");
+ ulog_write_str(u_get_global_env()->log_hd, "Hello world.\n");
return 0;
}
diff --git a/mkrtos_user/server/init/src/main.c b/mkrtos_user/server/init/src/main.c
index 75145a3cb..60060effe 100644
--- a/mkrtos_user/server/init/src/main.c
+++ b/mkrtos_user/server/init/src/main.c
@@ -56,9 +56,7 @@ int main(int argc, char *args[])
printf("app load fail, 0x%x\n", ret);
}
// u_sleep_ms(500);
-
// u_sleep_ms(500);
-
ret = app_load("hello", &env);
if (ret < 0)
{
diff --git a/mkrtos_user/server/init/src/namespace.c b/mkrtos_user/server/init/src/namespace.c
index 07cecafb5..c14d72856 100644
--- a/mkrtos_user/server/init/src/namespace.c
+++ b/mkrtos_user/server/init/src/namespace.c
@@ -68,10 +68,11 @@ int namespace_query(const char *path, obj_handler_t *hd)
{
if (ns.ne_list[i].hd != HANDLER_INVALID)
{
- if (strncmp(ns.ne_list[i].path, path, NAMESPACE_PATH_LEN) == 0)
+ char *split_str = strstr(ns.ne_list[i].path, path);
+ if (split_str && (split_str == ns.ne_list[i].path))
{
*hd = ns.ne_list[i].hd;
- return 0;
+ return (int)(split_str - ns.ne_list[i].path);
}
}
}