Modbus.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. /*
  2. * Modbus.h
  3. *
  4. * Created on: May 5, 2020
  5. * Author: Alejandro Mera
  6. */
  7. #ifndef THIRD_PARTY_MODBUS_INC_MODBUS_H_
  8. #define THIRD_PARTY_MODBUS_INC_MODBUS_H_
  9. #include "ModbusConfig.h"
  10. #include <inttypes.h>
  11. #include <stdbool.h>
  12. #include "FreeRTOS.h"
  13. #include "cmsis_os.h"
  14. #include "task.h"
  15. #include "queue.h"
  16. #include "timers.h"
  17. typedef enum
  18. {
  19. USART_HW = 1,
  20. USB_CDC_HW = 2,
  21. TCP_HW = 3,
  22. USART_HW_DMA = 4,
  23. }mb_hardware_t ;
  24. typedef enum
  25. {
  26. MB_SLAVE = 3,
  27. MB_MASTER = 4
  28. }mb_masterslave_t ;
  29. /**
  30. * @enum MB_FC
  31. * @brief
  32. * Modbus function codes summary.
  33. * These are the implement function codes either for Master or for Slave.
  34. *
  35. * @see also fctsupported
  36. * @see also modbus_t
  37. */
  38. typedef enum MB_FC
  39. {
  40. MB_FC_READ_COILS = 1, /*!< FCT=1 -> read coils or digital outputs */
  41. MB_FC_READ_DISCRETE_INPUT = 2, /*!< FCT=2 -> read digital inputs */
  42. MB_FC_READ_REGISTERS = 3, /*!< FCT=3 -> read registers or analog outputs */
  43. MB_FC_READ_INPUT_REGISTER = 4, /*!< FCT=4 -> read analog inputs */
  44. MB_FC_WRITE_COIL = 5, /*!< FCT=5 -> write single coil or output */
  45. MB_FC_WRITE_REGISTER = 6, /*!< FCT=6 -> write single register */
  46. MB_FC_WRITE_MULTIPLE_COILS = 15, /*!< FCT=15 -> write multiple coils or outputs */
  47. MB_FC_WRITE_MULTIPLE_REGISTERS = 16 /*!< FCT=16 -> write multiple registers */
  48. }mb_functioncode_t;
  49. typedef struct
  50. {
  51. uint8_t uxBuffer[MAX_BUFFER];
  52. uint8_t u8start;
  53. uint8_t u8end;
  54. uint8_t u8available;
  55. bool overflow;
  56. }modbusRingBuffer_t;
  57. /**
  58. * @enum MESSAGE
  59. * @brief
  60. * Indexes to telegram frame positions
  61. */
  62. typedef enum MESSAGE
  63. {
  64. ID = 0, //!< ID field
  65. FUNC, //!< Function code position
  66. ADD_HI, //!< Address high byte
  67. ADD_LO, //!< Address low byte
  68. NB_HI, //!< Number of coils or registers high byte
  69. NB_LO, //!< Number of coils or registers low byte
  70. BYTE_CNT //!< byte counter
  71. }mb_message_t;
  72. typedef enum COM_STATES
  73. {
  74. COM_IDLE = 0,
  75. COM_WAITING = 1,
  76. }mb_com_state_t;
  77. typedef enum ERR_LIST
  78. {
  79. ERR_NOT_MASTER = -1,
  80. ERR_POLLING = -2,
  81. ERR_BUFF_OVERFLOW = -3,
  82. ERR_BAD_CRC = -4,
  83. ERR_EXCEPTION = -5,
  84. ERR_BAD_SIZE = -6,
  85. ERR_BAD_ADDRESS = -7,
  86. ERR_TIME_OUT = -8,
  87. ERR_BAD_SLAVE_ID = -9,
  88. ERR_BAD_TCP_ID = -10,
  89. ERR_OK_QUERY = -11
  90. }mb_errot_t;
  91. enum
  92. {
  93. EXC_FUNC_CODE = 1,
  94. EXC_ADDR_RANGE = 2,
  95. EXC_REGS_QUANT = 3,
  96. EXC_EXECUTE = 4
  97. };
  98. typedef union {
  99. uint8_t u8[4];
  100. uint16_t u16[2];
  101. uint32_t u32;
  102. } bytesFields ;
  103. /**
  104. * @struct modbus_t
  105. * @brief
  106. * Master query structure:
  107. * This structure contains all the necessary fields to make the Master generate a Modbus query.
  108. * A Master may keep several of these structures and send them cyclically or
  109. * use them according to program needs.
  110. */
  111. typedef struct
  112. {
  113. uint8_t u8id; /*!< Slave address between 1 and 247. 0 means broadcast */
  114. mb_functioncode_t u8fct; /*!< Function code: 1, 2, 3, 4, 5, 6, 15 or 16 */
  115. uint16_t u16RegAdd; /*!< Address of the first register to access at slave/s */
  116. uint16_t u16CoilsNo; /*!< Number of coils or registers to access */
  117. uint16_t *u16reg; /*!< Pointer to memory image in master */
  118. uint32_t *u32CurrentTask; /*!< Pointer to the task that will receive notifications from Modbus */
  119. #if ENABLE_TCP ==1
  120. uint32_t xIpAddress;
  121. uint16_t u16Port;
  122. uint8_t u8clientID;
  123. #endif
  124. }
  125. modbus_t;
  126. #if ENABLE_TCP == 1
  127. typedef struct
  128. {
  129. struct netconn *conn;
  130. uint32_t aging;
  131. }
  132. tcpclients_t;
  133. #endif
  134. /**
  135. * @struct modbusHandler_t
  136. * @brief
  137. * Modbus handler structure
  138. * Contains all the variables required for Modbus daemon operation
  139. */
  140. typedef struct
  141. {
  142. mb_masterslave_t uModbusType;
  143. UART_HandleTypeDef *port; //HAL Serial Port handler
  144. uint8_t u8id; //!< 0=master, 1..247=slave number
  145. GPIO_TypeDef* EN_Port; //!< flow control pin: 0=USB or RS-232 mode, >1=RS-485 mode
  146. uint16_t EN_Pin; //!< flow control pin: 0=USB or RS-232 mode, >1=RS-485 mode
  147. mb_errot_t i8lastError;
  148. uint8_t u8Buffer[MAX_BUFFER]; //Modbus buffer for communication
  149. uint8_t u8BufferSize;
  150. uint8_t u8lastRec;
  151. uint16_t *u16regs;
  152. uint16_t u16InCnt, u16OutCnt, u16errCnt; //keep statistics of Modbus traffic
  153. uint16_t u16timeOut;
  154. uint16_t u16regsize;
  155. uint8_t dataRX;
  156. int8_t i8state;
  157. //FreeRTOS components
  158. //Queue Modbus Telegram
  159. osMessageQueueId_t QueueTelegramHandle;
  160. //Task Modbus slave
  161. osThreadId_t myTaskModbusAHandle;
  162. //Timer RX Modbus
  163. xTimerHandle xTimerT35;
  164. //Timer MasterTimeout
  165. xTimerHandle xTimerTimeout;
  166. //Semaphore for Modbus data
  167. osSemaphoreId_t ModBusSphrHandle;
  168. // RX ring buffer for USART
  169. modbusRingBuffer_t xBufferRX;
  170. // type of hardware TCP, USB CDC, USART
  171. mb_hardware_t xTypeHW;
  172. #if ENABLE_TCP == 1
  173. tcpclients_t newconns[NUMBERTCPCONN];
  174. struct netconn *conn;
  175. uint32_t xIpAddress;
  176. uint16_t u16TransactionID;
  177. uint16_t uTcpPort; // this is only used for the slave (i.e., the server)
  178. uint8_t newconnIndex;
  179. #endif
  180. }
  181. modbusHandler_t;
  182. enum
  183. {
  184. RESPONSE_SIZE = 6,
  185. EXCEPTION_SIZE = 3,
  186. CHECKSUM_SIZE = 2
  187. };
  188. modbusHandler_t *mHandlers[MAX_M_HANDLERS];
  189. // Function prototypes
  190. void ModbusInit(modbusHandler_t * modH);
  191. void ModbusStart(modbusHandler_t * modH);
  192. #if ENABLE_USB_CDC == 1
  193. void ModbusStartCDC(modbusHandler_t * modH);
  194. #endif
  195. void setTimeOut( uint16_t u16timeOut); //!<write communication watch-dog timer
  196. uint16_t getTimeOut(); //!<get communication watch-dog timer value
  197. bool getTimeOutState(); //!<get communication watch-dog timer state
  198. void ModbusQuery(modbusHandler_t * modH, modbus_t telegram ); // put a query in the queue tail
  199. void ModbusQueryInject(modbusHandler_t * modH, modbus_t telegram); //put a query in the queue head
  200. void StartTaskModbusSlave(void *argument); //slave
  201. void StartTaskModbusMaster(void *argument); //master
  202. uint16_t calcCRC(uint8_t *Buffer, uint8_t u8length);
  203. #if ENABLE_TCP == 1
  204. void ModbusCloseConn(struct netconn *conn); //close the TCP connection
  205. #endif
  206. //Function prototypes for ModbusRingBuffer
  207. void RingAdd(modbusRingBuffer_t *xRingBuffer, uint8_t u8Val); // adds a byte to the ring buffer
  208. uint8_t RingGetAllBytes(modbusRingBuffer_t *xRingBuffer, uint8_t *buffer); // gets all the available bytes into buffer and return the number of bytes read
  209. uint8_t RingGetNBytes(modbusRingBuffer_t *xRingBuffer, uint8_t *buffer, uint8_t uNumber); // gets uNumber of bytes from ring buffer, returns the actual number of bytes read
  210. uint8_t RingCountBytes(modbusRingBuffer_t *xRingBuffer); // return the number of available bytes
  211. void RingClear(modbusRingBuffer_t *xRingBuffer); // flushes the ring buffer
  212. extern uint8_t numberHandlers; //global variable to maintain the number of concurrent handlers
  213. /* prototypes of the original library not implemented
  214. uint16_t getInCnt(); //!<number of incoming messages
  215. uint16_t getOutCnt(); //!<number of outcoming messages
  216. uint16_t getErrCnt(); //!<error counter
  217. uint8_t getID(); //!<get slave ID between 1 and 247
  218. uint8_t getState();
  219. uint8_t getLastError(); //!<get last error message
  220. void setID( uint8_t u8id ); //!<write new ID for the slave
  221. void setTxendPinOverTime( uint32_t u32overTime );
  222. void ModbusEnd(); //!<finish any communication and release serial communication port
  223. */
  224. #endif /* THIRD_PARTY_MODBUS_INC_MODBUS_H_ */