Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: Nucleo_modbus_protocol_test
ModbusSlaveRTU.h
00001 /** Modbus Slave RTU 00002 * Copyright (c) 2015 Gabriel Rivas 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #ifndef _MODBUS_SLAVE_RTU_H_ 00018 #define _MODBUS_SLAVE_RTU_H_ 00019 00020 #include "mbed.h" 00021 #include "rtos.h" 00022 #include "MessageQueue.h" 00023 00024 #define MODBUS_MAX_LEN (256) 00025 00026 struct ThreadSafeArray_t { 00027 Mutex mutex; 00028 uint8_t *data; 00029 uint32_t length; 00030 }; 00031 00032 /** 00033 * Modbus RTU class for slave devices. It shares data with other software components via a Message queue object, 00034 * and can exist more than one Modbus Slave RTU instances in a application program. 00035 */ 00036 class ModbusSlaveRTU 00037 { 00038 public: 00039 /*! Status of the internal modbus FSM. */ 00040 enum MbStatusTypes_t { 00041 LISTENING = 0x20, /**< Listening for incomming requests.*/ 00042 PROCESSING = 0x21, /**< Processing received request.*/ 00043 SENDING = 0x23 /**< Sending generated response.*/ 00044 }; 00045 00046 private: 00047 /*! Modbus response message bytes indexes. */ 00048 enum MbByteIndex_t { 00049 ADDRESS = 0x00, /**< Modbus address position.*/ 00050 FUNCTION = 0x01, /**< Modbus function position.*/ 00051 BYTE_COUNT = 0x02, /**< Byte count high byte position.*/ 00052 DATA_START = 0x03, /**< Returned data start position.*/ 00053 BYTE_OFFSET = 0x02, /**< Starting register in bytes, high byte position.*/ 00054 REGISTER_COUNT = 0x04 /**< Number of registers to be read, high byte position.*/ 00055 }; 00056 00057 /*! Modbus errors reported during message processing. */ 00058 enum MbReceivedMessageErrors_t { 00059 NO_ERROR = 0x10, /**< No error.*/ 00060 ADDRESS_ERROR = 0x11, /**< Wrong slave address.*/ 00061 CRC_ERROR = 0x12, /**< CRC from received message doesn't match with locally calculated CRC.*/ 00062 OFFSET_ERROR = 0x13, /**< Offset is out of range.*/ 00063 BYTE_COUNT_ERROR = 0x14 /**< Byte count requested is out of range.*/ 00064 }; 00065 00066 /*! Internal modbus FSM states. */ 00067 enum MbSlaveRTUStates_t { 00068 WAIT_REQUEST_MESSAGE = 0x00, /**< Idle while bytes are being received.*/ 00069 GET_RECEIVED_BYTES = 0x01, /**< Copy received bytes into the internal buffer.*/ 00070 BUILD_RESPONSE_MESSAGE = 0x02, /**< Building response message.*/ 00071 TRANSMIT_RESPONSE_MESSAGE = 0x03 /**< Transmitting response message.*/ 00072 }; 00073 00074 /*! Modbus function codes. */ 00075 enum MbFunctionCodes_t { 00076 READ_COIL_STATUS = 0x01, /**< Function to read a single coil status.*/ 00077 READ_INPUT_STATUS = 0x02, /**< Function to read input register.*/ 00078 READ_HOLDING_REGISTERS = 0x03, /**< Function to read one or more internal holding resgisters.*/ 00079 READ_INPUT_REGISTERS = 0x04, /**< Function to read one or more input resgisters.*/ 00080 FORCE_SINGLE_COIL = 0x05, /**< Function to write a value into a single discrete output.*/ 00081 PRESET_SINGLE_REGISTER = 0x06, /**< Function to write a value into a single holding register.*/ 00082 READ_EXCEPTION_STATUS = 0x07, /**< Function to request the value of the status byte.*/ 00083 LOOPBACK_TEST = 0x08, /**< Function to test the communications interface. Returns the same message.*/ 00084 FORCE_MULTIPLE_COILS = 0x0F /**< Function to set more than one coil to a given value*/ 00085 }; 00086 00087 /*! Modbus frame structure elements. */ 00088 struct MbSlaveRTUFrame_t { 00089 uint8_t mAddress; /**< Slave device address.*/ 00090 MbFunctionCodes_t mFunction; /**< Requested function of type MbFunctionCodes_t.*/ 00091 uint16_t mOffset; /**< Offset in bytes from the starting address.*/ 00092 uint16_t mByteCount; /**< Number of bytes to respond.*/ 00093 uint8_t mCRCH; /**< CRC high byte.*/ 00094 uint8_t mCRCL; /**< CRC low byte.*/ 00095 uint16_t mSize; /**< Size of the frame in bytes.*/ 00096 }; 00097 00098 /*! Memory map structure. */ 00099 struct MemoryMap_t { 00100 ThreadSafeArray_t *coilRegisters; /**< Pointer to the coil registers array.*/ 00101 ThreadSafeArray_t *holdingRegisters; /**< Pointer to the holding registers array.*/ 00102 ThreadSafeArray_t *inputRegisters; /**< Pointer to the input registers array.*/ 00103 }; 00104 00105 public: 00106 /** 00107 * Creates a Modbus Slave RTU object. 00108 * @param id Mosbus address. 00109 * @param txQueue Message queue to write modbus responses into. 00110 * @param rxQueue Message queue to read modbus requests from. 00111 * @param *coilRegisters Pointer to the memory space reserved for the coil registers. 00112 * @param *inputRegisters Pointer to the memory space reserved for the input registers. 00113 * @param *inputRegisters Pointer to the memory space reserved for the holding registers. 00114 */ 00115 ModbusSlaveRTU( uint8_t id, 00116 MessageQueue<uint8_t>* txQueue, 00117 MessageQueue<uint8_t>* rxQueue, 00118 ThreadSafeArray_t *coilRegisters, 00119 ThreadSafeArray_t *inputRegisters, 00120 ThreadSafeArray_t *holdingRegisters); 00121 00122 public: 00123 /** 00124 * Function to start the Modbus RTU Slave engine. 00125 */ 00126 void trigger(void); 00127 00128 /** 00129 * Gets the status of the internal FSM. 00130 * @return Status value as defined in MbStatusTypes_t. 00131 */ 00132 MbStatusTypes_t getStatus(void); 00133 00134 /** 00135 * Internal FSM process. 00136 */ 00137 void FSM(void); 00138 00139 private: 00140 /** 00141 * Handler for read holding registers function request. 00142 * @return Error or success code as defined in MbReceivedMessageErrors_t. 00143 */ 00144 MbReceivedMessageErrors_t readHoldingRegistersHandler(void); 00145 00146 /** 00147 * Handler for read coil registers function request. 00148 * @return Error or success code as defined in MbReceivedMessageErrors_t. 00149 */ 00150 MbReceivedMessageErrors_t readCoilRegistersHandler(void); 00151 00152 /** 00153 * Builds response message. 00154 * @return Error or success code as defined in MbReceivedMessageErrors_t. 00155 */ 00156 MbReceivedMessageErrors_t buildResponse(void); 00157 00158 /** 00159 * Function that computes the CRC of a Modbus message. 00160 * @param *data Pointer to the message data. 00161 * @param uint8_t Length of the message. 00162 * @return The CRC Code. 00163 */ 00164 uint16_t getCRC(uint8_t * data,uint8_t len); 00165 00166 /** 00167 * Verifies the CRC value of a message to determine it has been received correctly. 00168 * @param *data Pointer to the message data. 00169 * @return Returns 1 if the message has been well received, 0 otherwise. 00170 */ 00171 uint8_t checkMessageCRC(uint8_t * data); 00172 00173 /** 00174 * Function that appends the header and tail bytes for a response message. 00175 * @return void. 00176 */ 00177 void appendHeaderAndTailToMessage(void); 00178 00179 /** 00180 * Function that checks for error in the received message. 00181 * @param *array Safe array being processed depending on the modbus function. 00182 * @return The error or success code as defined in MbReceivedMessageErrors_t. 00183 */ 00184 MbReceivedMessageErrors_t checkReceivedMessageErrors(ThreadSafeArray_t *array); 00185 00186 private: 00187 /** Internal state of the modbus FSM. 00188 */ 00189 MbSlaveRTUStates_t m_state; 00190 00191 /** Response frame. 00192 */ 00193 MbSlaveRTUFrame_t m_frame; 00194 00195 /** Modbus address. 00196 */ 00197 uint8_t m_address; 00198 00199 /** Modbus process status. 00200 */ 00201 MbStatusTypes_t m_status; 00202 00203 /** Memory map for registers. 00204 */ 00205 MemoryMap_t m_memoryMap; 00206 00207 /** Queue to write response data. 00208 */ 00209 MessageQueue<uint8_t>* m_bTxQueue; 00210 00211 /** Queue to read incomming requests from. 00212 */ 00213 MessageQueue<uint8_t>* m_bRxQueue; 00214 00215 /** Internal byte array to copy incomming requests. 00216 */ 00217 uint8_t m_receivedMessage[MODBUS_MAX_LEN]; 00218 00219 /** Internal byte array to generate responses. 00220 */ 00221 uint8_t m_responseMessage[MODBUS_MAX_LEN]; 00222 }; 00223 #endif
Generated on Thu Jul 14 2022 20:27:53 by
1.7.2