small_modbus_base.h 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. /*
  2. * Change Logs:
  3. * Date Author Notes
  4. * 2020-08-21 chenbin small modbus the first version
  5. * 2021-06-02 chenbin small modbus
  6. * 2021-08-06 chenbin small modbus
  7. */
  8. #ifndef _SMALL_MODBUS_BASE_H_
  9. #define _SMALL_MODBUS_BASE_H_
  10. #include "stdint.h"
  11. #include "stdio.h"
  12. #include "string.h"
  13. /* function codes */
  14. enum functionCode
  15. {
  16. MODBUS_FC_READ_HOLDING_COILS = 0x01,
  17. MODBUS_FC_READ_INPUTS_COILS = 0x02,
  18. MODBUS_FC_READ_HOLDING_REGISTERS = 0x03,
  19. MODBUS_FC_READ_INPUT_REGISTERS = 0x04,
  20. MODBUS_FC_WRITE_SINGLE_COIL = 0x05,
  21. MODBUS_FC_WRITE_SINGLE_REGISTER = 0x06,
  22. MODBUS_FC_READ_EXCEPTION_STATUS = 0x07,
  23. MODBUS_FC_WRITE_MULTIPLE_COILS = 0x0F,
  24. MODBUS_FC_WRITE_MULTIPLE_REGISTERS = 0x10,
  25. MODBUS_FC_REPORT_SLAVE_ID = 0x11,
  26. MODBUS_FC_MASK_WRITE_REGISTER = 0x16,
  27. MODBUS_FC_WRITE_AND_READ_REGISTERS = 0x17,
  28. };
  29. ///* Protocol exceptions */
  30. // enum exceptionsCode{
  31. // MODBUS_EXCEPTION_SLAVE_OR_SERVER_FAILURE,
  32. // MODBUS_EXCEPTION_ACKNOWLEDGE,
  33. // MODBUS_EXCEPTION_SLAVE_OR_SERVER_BUSY,
  34. // MODBUS_EXCEPTION_NEGATIVE_ACKNOWLEDGE,
  35. // MODBUS_EXCEPTION_MEMORY_PARITY,
  36. // MODBUS_EXCEPTION_NOT_DEFINED,
  37. // MODBUS_EXCEPTION_GATEWAY_PATH,
  38. // MODBUS_EXCEPTION_GATEWAY_TARGET,
  39. // MODBUS_EXCEPTION_MAX
  40. // };
  41. enum returnCode
  42. {
  43. MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE = -0x83,
  44. MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS = -0x82,
  45. MODBUS_EXCEPTION_ILLEGAL_FUNCTION = -0x81,
  46. MODBUS_EXCEPTION = -0x80,
  47. MODBUS_ERROR_CONTEXT = -0x0A,
  48. MODBUS_ERROR_WAIT = -9,
  49. MODBUS_ERROR_READ = -8,
  50. MODBUS_FAIL_CHECK = -7,
  51. MODBUS_FAIL_ADRR = -6,
  52. MODBUS_FAIL_HANDLE = -5,
  53. MODBUS_FAIL_CONFIRM = -4,
  54. MODBUS_FAIL_REQUEST = -3,
  55. MODBUS_TIMEOUT = -2,
  56. MODBUS_FAIL = -1,
  57. MODBUS_OK = 0
  58. };
  59. enum waitCode
  60. {
  61. MODBUS_WAIT_FOREVER = -1,
  62. MODBUS_WAIT_NO = 0
  63. };
  64. enum coreType
  65. {
  66. MODBUS_CORE_NONE = 0,
  67. MODBUS_CORE_RTU = 1,
  68. MODBUS_CORE_TCP = 2
  69. };
  70. enum portType
  71. {
  72. MODBUS_PORT_NONE = 0,
  73. MODBUS_PORT_DEVICE = 1,
  74. MODBUS_PORT_SOCKET = 2
  75. };
  76. enum deviceType
  77. {
  78. MODBUS_DEVICE_NONE = 0,
  79. MODBUS_DEVICE_SLAVE = 1,
  80. MODBUS_DEVICE_MASTER = 2
  81. };
  82. enum modbusMagic
  83. {
  84. MODBUS_MAGIC = 0x4243424D, //"MBCB"
  85. MODBUS_CORE_MAGIC = 0x4343424D, //"MBCC"
  86. MODBUS_PORT_MAGIC = 0x5050424D, //"MBPP"
  87. };
  88. #define MODBUS_BROADCAST_ADDRESS 0
  89. /* Modbus_Application_Protocol_V1_1b.pdf (chapter 6 section 1 page 12)
  90. * Quantity of Coils to read (2 bytes): 1 to 2000 (0x7D0)
  91. * (chapter 6 section 11 page 29)
  92. * Quantity of Coils to write (2 bytes): 1 to 1968 (0x7B0)
  93. */
  94. #define MODBUS_MAX_READ_BITS 2000
  95. #define MODBUS_MAX_WRITE_BITS 1968
  96. /* Modbus_Application_Protocol_V1_1b.pdf (chapter 6 section 3 page 15)
  97. * Quantity of Registers to read (2 bytes): 1 to 125 (0x7D)
  98. * (chapter 6 section 12 page 31)
  99. * Quantity of Registers to write (2 bytes) 1 to 123 (0x7B)
  100. * (chapter 6 section 17 page 38)
  101. * Quantity of Registers to write in R/W registers (2 bytes) 1 to 121 (0x79)
  102. */
  103. #define MODBUS_MAX_READ_REGISTERS 125
  104. #define MODBUS_MAX_WRITE_REGISTERS 123
  105. #define MODBUS_MAX_WR_WRITE_REGISTERS 121
  106. #define MODBUS_MAX_WR_READ_REGISTERS 125
  107. /* The size of the MODBUS PDU is limited by the size constraint inherited from
  108. * the first MODBUS implementation on Serial Line network (max. RS485 ADU = 256
  109. * bytes). Therefore, MODBUS PDU for serial line communication = 256 - Server
  110. * address (1 byte) - CRC (2 bytes) = 253 bytes.
  111. */
  112. #define MODBUS_MAX_PDU_LENGTH 253
  113. /* Consequently:
  114. * - RTU MODBUS ADU = 253 bytes + Server address (1 byte) + CRC (2 bytes) = 256
  115. * bytes.
  116. * - TCP MODBUS ADU = 253 bytes + MBAP (7 bytes) = 260 bytes.
  117. * so the maximum of both backend in 260 bytes. This size can used to allocate
  118. * an array of bytes to store responses and it will be compatible with the two
  119. * backends.
  120. */
  121. #define MODBUS_MAX_ADU_LENGTH 260
  122. /*
  123. *bit max 2000
  124. *reg max 125
  125. */
  126. #define MODBUS_MAX_SWAP_LENGTH 250 // data length
  127. /* It's not really the minimal length (the real one is report slave ID
  128. * in RTU (4 bytes)) but it's a convenient size to use in RTU or TCP
  129. * communications to read many values or write a single one.
  130. * Maximum between :
  131. * - HEADER_LENGTH_TCP (7) + function (1) + address (2) + number (2)
  132. * - HEADER_LENGTH_RTU (1) + function (1) + address (2) + number (2) + CRC (2)
  133. */
  134. #define _MIN_REQ_LENGTH 12
  135. #define _REPORT_SLAVE_ID 180
  136. #define _MODBUS_EXCEPTION_RSP_LENGTH 5
  137. typedef struct _small_modbus small_modbus_t;
  138. typedef struct _small_modbus_core small_modbus_core_t; // modbus core (modbus-rtu,modbus-tcp)
  139. typedef struct _small_modbus_port small_modbus_port_t; // modbus port (rtthread ,linux ,win32) serial socket
  140. struct _small_modbus_core
  141. {
  142. const uint32_t magic;
  143. const uint16_t type;
  144. const uint16_t len_header;
  145. const uint16_t len_checksum;
  146. const uint16_t len_adu_max;
  147. int (*build_request_header)(small_modbus_t *smb, uint8_t *buff, int slave, int fun, int reg, int num);
  148. int (*build_response_header)(small_modbus_t *smb, uint8_t *buff, int slave, int fun);
  149. int (*check_send_pre)(small_modbus_t *smb, uint8_t *buff, int length);
  150. int (*check_wait_request)(small_modbus_t *smb, uint8_t *buff, int length);
  151. int (*check_wait_response)(small_modbus_t *smb, uint8_t *buff, int length);
  152. };
  153. struct _small_modbus_port
  154. {
  155. const uint32_t magic;
  156. const uint32_t type;
  157. int (*open)(small_modbus_t *smb);
  158. int (*close)(small_modbus_t *smb);
  159. int (*read)(small_modbus_t *smb, uint8_t *data, uint16_t length);
  160. int (*write)(small_modbus_t *smb, uint8_t *data, uint16_t length);
  161. int (*flush)(small_modbus_t *smb);
  162. int (*wait)(small_modbus_t *smb, int timeout);
  163. };
  164. struct _small_modbus
  165. {
  166. uint32_t modbus_magic;
  167. uint16_t device_mode;
  168. uint8_t slave_addr;
  169. uint8_t debug_level;
  170. uint16_t transfer_id;
  171. uint16_t protocol_id;
  172. int status;
  173. int error_code;
  174. uint32_t timeout_frame; //帧超时时间ms
  175. uint32_t timeout_byte; //字节超时时间ms
  176. uint8_t read_buff[MODBUS_MAX_ADU_LENGTH]; // modbus读缓冲区
  177. uint8_t write_buff[MODBUS_MAX_ADU_LENGTH]; // modbus写缓冲区
  178. small_modbus_core_t *core; // modbus core (modbus-rtu,modbus-tcp)
  179. small_modbus_port_t *port; // modbus port (rtthread ,linux ,win32) serial socket
  180. };
  181. int _modbus_init(small_modbus_t *smb);
  182. int _modbus_debug(small_modbus_t *smb, int level, const char *fmt, ...);
  183. #define modbus_debug(smb, ...) _modbus_debug(smb, 3, __VA_ARGS__)
  184. #define modbus_debug_info(smb, ...) _modbus_debug(smb, 2, __VA_ARGS__)
  185. #define modbus_debug_error(smb, ...) _modbus_debug(smb, 1, __VA_ARGS__)
  186. /* base api */
  187. int modbus_connect(small_modbus_t *smb);
  188. int modbus_disconnect(small_modbus_t *smb);
  189. int modbus_write(small_modbus_t *smb, uint8_t *data, uint16_t length);
  190. int modbus_read(small_modbus_t *smb, uint8_t *data, uint16_t length);
  191. int modbus_flush(small_modbus_t *smb);
  192. int modbus_wait(small_modbus_t *smb, int timeout);
  193. int modbus_error_recovery(small_modbus_t *smb);
  194. int modbus_error_exit(small_modbus_t *smb, int code);
  195. int modbus_set_frame_timeout(small_modbus_t *smb, int timeout_ms);
  196. int modbus_set_byte_timeout(small_modbus_t *smb, int timeout_ms);
  197. int modbus_set_slave(small_modbus_t *smb, int slave);
  198. int modbus_set_debug(small_modbus_t *smb, int level);
  199. /* master mode api */
  200. /* master start request */
  201. int modbus_start_request(small_modbus_t *smb, uint8_t *request, int function, int addr, int num, void *write_data);
  202. /* master wait for confirmation message */
  203. int modbus_wait_confirm(small_modbus_t *smb, uint8_t *response);
  204. /* master handle confirmation message */
  205. int modbus_handle_confirm(small_modbus_t *smb, uint8_t *request, uint16_t request_len, uint8_t *response, uint16_t response_len, void *read_data);
  206. /* master read */
  207. int modbus_read_bits(small_modbus_t *smb, int addr, int num, uint8_t *read_data);
  208. int modbus_read_input_bits(small_modbus_t *smb, int addr, int num, uint8_t *read_data);
  209. int modbus_read_registers(small_modbus_t *smb, int addr, int num, uint16_t *read_data);
  210. int modbus_read_input_registers(small_modbus_t *smb, int addr, int num, uint16_t *read_data);
  211. /* master write */
  212. int modbus_write_bit(small_modbus_t *smb, int addr, int write_status);
  213. int modbus_write_register(small_modbus_t *smb, int addr, int write_value);
  214. int modbus_write_bits(small_modbus_t *smb, int addr, int num, uint8_t *write_data);
  215. int modbus_write_registers(small_modbus_t *smb, int addr, int num, uint16_t *write_data);
  216. /* master write and read */
  217. int modbus_mask_write_register(small_modbus_t *smb, int addr, uint16_t and_mask, uint16_t or_mask);
  218. int modbus_write_and_read_registers(small_modbus_t *smb, int write_addr, int write_nb, uint16_t *src, int read_addr, int read_nb, uint16_t *dest);
  219. /* slave callback */
  220. typedef int (*small_modbus_slave_callback_t)(small_modbus_t *smb, int function_code, int addr, int num, void *read_write_data);
  221. /* slave mode api */
  222. /* slave wait query data */
  223. int modbus_slave_wait(small_modbus_t *smb, uint8_t *request, int32_t waittime);
  224. /* slave handle query data for callback */
  225. int modbus_slave_handle(small_modbus_t *smb, uint8_t *request, uint16_t request_len, small_modbus_slave_callback_t slave_callback);
  226. /* slave wait and handle query for callback */
  227. int modbus_slave_wait_handle(small_modbus_t *smb, small_modbus_slave_callback_t slave_callback, int32_t waittime);
  228. #endif /* _SMALL_MODBUS_BASE_H_ */