nanoMODBUS
Loading...
Searching...
No Matches
nanomodbus.h
Go to the documentation of this file.
1/*
2 nanoMODBUS - A compact MODBUS RTU/TCP C library for microcontrollers
3
4 MIT License
5
6 Copyright (c) 2024 Valerio De Benedetto (@debevv)
7
8 Permission is hereby granted, free of charge, to any person obtaining a copy
9 of this software and associated documentation files (the "Software"), to deal
10 in the Software without restriction, including without limitation the rights
11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 copies of the Software, and to permit persons to whom the Software is
13 furnished to do so, subject to the following conditions:
14
15 The above copyright notice and this permission notice shall be included in all
16 copies or substantial portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 SOFTWARE.
25*/
26
27
40#ifndef NANOMODBUS_H
41#define NANOMODBUS_H
42
43#include <stdbool.h>
44#include <stdint.h>
45#include <string.h>
46
47#ifdef __cplusplus
48extern "C" {
49#endif
50
73
74
79#define nmbs_error_is_exception(e) ((e) > 0 && (e) < 5)
80
81#ifndef NMBS_BITFIELD_MAX
82#define NMBS_BITFIELD_MAX 2000
83#endif
84
85/* check coil count divisible by 8 */
86#if ((NMBS_BITFIELD_MAX & 7) > 0)
87#error "NMBS_BITFIELD_MAX must be divisible by 8"
88#endif
89
90#define NMBS_BITFIELD_BYTES_MAX (NMBS_BITFIELD_MAX / 8)
91
95typedef uint8_t nmbs_bitfield[NMBS_BITFIELD_BYTES_MAX];
96
100typedef uint8_t nmbs_bitfield_256[32];
101
105#define nmbs_bitfield_read(bf, b) ((bool) ((bf)[(b) >> 3] & (0x1 << ((b) & (8 - 1)))))
106
110#define nmbs_bitfield_set(bf, b) (((bf)[(b) >> 3]) = (((bf)[(b) >> 3]) | (0x1 << ((b) & (8 - 1)))))
111
115#define nmbs_bitfield_unset(bf, b) (((bf)[(b) >> 3]) = (((bf)[(b) >> 3]) & ~(0x1 << ((b) & (8 - 1)))))
116
120#define nmbs_bitfield_write(bf, b, v) ((bf)[(b) >> 3] = ((bf)[(b) >> 3] & ~(1 << ((b) & 7))) | ((v) << ((b) & 7)))
124#define nmbs_bitfield_reset(bf) memset(bf, 0, sizeof(bf))
125
129typedef enum nmbs_transport {
130 NMBS_TRANSPORT_RTU = 1,
131 NMBS_TRANSPORT_TCP = 2,
133
134
158typedef struct nmbs_platform_conf {
160 int32_t (*read)(uint8_t* buf, uint16_t count, int32_t byte_timeout_ms,
161 void* arg);
162 int32_t (*write)(const uint8_t* buf, uint16_t count, int32_t byte_timeout_ms,
163 void* arg);
164 uint16_t (*crc_calc)(const uint8_t* data, uint32_t length,
165 void* arg);
166 void* arg;
167 uint32_t initialized;
169
170
179typedef struct nmbs_callbacks {
180#ifndef NMBS_SERVER_DISABLED
181#ifndef NMBS_SERVER_READ_COILS_DISABLED
182 nmbs_error (*read_coils)(uint16_t address, uint16_t quantity, nmbs_bitfield coils_out, uint8_t unit_id, void* arg);
183#endif
184
185#ifndef NMBS_SERVER_READ_DISCRETE_INPUTS_DISABLED
186 nmbs_error (*read_discrete_inputs)(uint16_t address, uint16_t quantity, nmbs_bitfield inputs_out, uint8_t unit_id,
187 void* arg);
188#endif
189
190#if !defined(NMBS_SERVER_READ_HOLDING_REGISTERS_DISABLED) || !defined(NMBS_SERVER_READ_WRITE_REGISTERS_DISABLED)
191 nmbs_error (*read_holding_registers)(uint16_t address, uint16_t quantity, uint16_t* registers_out, uint8_t unit_id,
192 void* arg);
193#endif
194
195#ifndef NMBS_SERVER_READ_INPUT_REGISTERS_DISABLED
196 nmbs_error (*read_input_registers)(uint16_t address, uint16_t quantity, uint16_t* registers_out, uint8_t unit_id,
197 void* arg);
198#endif
199
200#ifndef NMBS_SERVER_WRITE_SINGLE_COIL_DISABLED
201 nmbs_error (*write_single_coil)(uint16_t address, bool value, uint8_t unit_id, void* arg);
202#endif
203
204#ifndef NMBS_SERVER_WRITE_SINGLE_REGISTER_DISABLED
205 nmbs_error (*write_single_register)(uint16_t address, uint16_t value, uint8_t unit_id, void* arg);
206#endif
207
208#ifndef NMBS_SERVER_WRITE_MULTIPLE_COILS_DISABLED
209 nmbs_error (*write_multiple_coils)(uint16_t address, uint16_t quantity, const nmbs_bitfield coils, uint8_t unit_id,
210 void* arg);
211#endif
212
213#if !defined(NMBS_SERVER_WRITE_MULTIPLE_REGISTERS_DISABLED) || !defined(NMBS_SERVER_READ_WRITE_REGISTERS_DISABLED)
214 nmbs_error (*write_multiple_registers)(uint16_t address, uint16_t quantity, const uint16_t* registers,
215 uint8_t unit_id, void* arg);
216#endif
217
218#ifndef NMBS_SERVER_READ_FILE_RECORD_DISABLED
219 nmbs_error (*read_file_record)(uint16_t file_number, uint16_t record_number, uint16_t* registers, uint16_t count,
220 uint8_t unit_id, void* arg);
221#endif
222
223#ifndef NMBS_SERVER_WRITE_FILE_RECORD_DISABLED
224 nmbs_error (*write_file_record)(uint16_t file_number, uint16_t record_number, const uint16_t* registers,
225 uint16_t count, uint8_t unit_id, void* arg);
226#endif
227
228#ifndef NMBS_SERVER_READ_DEVICE_IDENTIFICATION_DISABLED
229#define NMBS_DEVICE_IDENTIFICATION_STRING_LENGTH 128
230 nmbs_error (*read_device_identification)(uint8_t object_id, char buffer[NMBS_DEVICE_IDENTIFICATION_STRING_LENGTH]);
231 nmbs_error (*read_device_identification_map)(nmbs_bitfield_256 map);
232#endif
233#endif
234
235 void* arg; // User data, will be passed to functions above
236 uint32_t initialized; // Reserved, workaround for older user code not calling nmbs_callbacks_create()
238
239
244typedef struct nmbs_t {
245 struct {
246 uint8_t buf[260];
247 uint16_t buf_idx;
248
249 uint8_t unit_id;
250 uint8_t fc;
251 uint16_t transaction_id;
252 bool broadcast;
253 bool ignored;
254 bool complete;
255 } msg;
256
257 nmbs_callbacks callbacks;
258
259 int32_t byte_timeout_ms;
260 int32_t read_timeout_ms;
261
262 nmbs_platform_conf platform;
263
264 uint8_t address_rtu;
265 uint8_t dest_address_rtu;
266 uint16_t current_tid;
268
272static const uint8_t NMBS_BROADCAST_ADDRESS = 0;
273
281void nmbs_set_read_timeout(nmbs_t* nmbs, int32_t timeout_ms);
282
287void nmbs_set_byte_timeout(nmbs_t* nmbs, int32_t timeout_ms);
288
293
298void nmbs_set_platform_arg(nmbs_t* nmbs, void* arg);
299
300#ifndef NMBS_SERVER_DISABLED
305
314nmbs_error nmbs_server_create(nmbs_t* nmbs, uint8_t address_rtu, const nmbs_platform_conf* platform_conf,
315 const nmbs_callbacks* callbacks);
316
325
330void nmbs_set_callbacks_arg(nmbs_t* nmbs, void* arg);
331#endif
332
333#ifndef NMBS_CLIENT_DISABLED
340nmbs_error nmbs_client_create(nmbs_t* nmbs, const nmbs_platform_conf* platform_conf);
341
346void nmbs_set_destination_rtu_address(nmbs_t* nmbs, uint8_t address);
347
356nmbs_error nmbs_read_coils(nmbs_t* nmbs, uint16_t address, uint16_t quantity, nmbs_bitfield coils_out);
357
366nmbs_error nmbs_read_discrete_inputs(nmbs_t* nmbs, uint16_t address, uint16_t quantity, nmbs_bitfield inputs_out);
367
376nmbs_error nmbs_read_holding_registers(nmbs_t* nmbs, uint16_t address, uint16_t quantity, uint16_t* registers_out);
377
386nmbs_error nmbs_read_input_registers(nmbs_t* nmbs, uint16_t address, uint16_t quantity, uint16_t* registers_out);
387
395nmbs_error nmbs_write_single_coil(nmbs_t* nmbs, uint16_t address, bool value);
396
404nmbs_error nmbs_write_single_register(nmbs_t* nmbs, uint16_t address, uint16_t value);
405
414nmbs_error nmbs_write_multiple_coils(nmbs_t* nmbs, uint16_t address, uint16_t quantity, const nmbs_bitfield coils);
415
424nmbs_error nmbs_write_multiple_registers(nmbs_t* nmbs, uint16_t address, uint16_t quantity, const uint16_t* registers);
425
435nmbs_error nmbs_read_file_record(nmbs_t* nmbs, uint16_t file_number, uint16_t record_number, uint16_t* registers,
436 uint16_t count);
437
447nmbs_error nmbs_write_file_record(nmbs_t* nmbs, uint16_t file_number, uint16_t record_number, const uint16_t* registers,
448 uint16_t count);
449
461nmbs_error nmbs_read_write_registers(nmbs_t* nmbs, uint16_t read_address, uint16_t read_quantity,
462 uint16_t* registers_out, uint16_t write_address, uint16_t write_quantity,
463 const uint16_t* registers);
464
474nmbs_error nmbs_read_device_identification_basic(nmbs_t* nmbs, char* vendor_name, char* product_code,
475 char* major_minor_revision, uint8_t buffers_length);
476
487nmbs_error nmbs_read_device_identification_regular(nmbs_t* nmbs, char* vendor_url, char* product_name, char* model_name,
488 char* user_application_name, uint8_t buffers_length);
489
502nmbs_error nmbs_read_device_identification_extended(nmbs_t* nmbs, uint8_t object_id_start, uint8_t* ids, char** buffers,
503 uint8_t ids_length, uint8_t buffer_length,
504 uint8_t* objects_count_out);
505
514nmbs_error nmbs_read_device_identification(nmbs_t* nmbs, uint8_t object_id, char* buffer, uint8_t buffer_length);
515
525nmbs_error nmbs_send_raw_pdu(nmbs_t* nmbs, uint8_t fc, const uint8_t* data, uint16_t data_len);
526
534nmbs_error nmbs_receive_raw_pdu_response(nmbs_t* nmbs, uint8_t* data_out, uint8_t data_out_len);
535#endif
536
541uint16_t nmbs_crc_calc(const uint8_t* data, uint32_t length, void* arg);
542
543#ifndef NMBS_STRERROR_DISABLED
549const char* nmbs_strerror(nmbs_error error);
550#endif
551
552#ifdef __cplusplus
553} // extern "C"
554#endif
555
556#endif //NANOMODBUS_H
nmbs_error nmbs_read_input_registers(nmbs_t *nmbs, uint16_t address, uint16_t quantity, uint16_t *registers_out)
Definition nanomodbus.c:2027
nmbs_error
Definition nanomodbus.h:55
@ NMBS_ERROR_INVALID_UNIT_ID
Definition nanomodbus.h:58
@ NMBS_ERROR_NONE
Definition nanomodbus.h:65
@ NMBS_ERROR_INVALID_ARGUMENT
Definition nanomodbus.h:64
@ NMBS_EXCEPTION_ILLEGAL_DATA_ADDRESS
Definition nanomodbus.h:69
@ NMBS_ERROR_TRANSPORT
Definition nanomodbus.h:61
@ NMBS_ERROR_INVALID_TCP_MBAP
Definition nanomodbus.h:59
@ NMBS_ERROR_INVALID_REQUEST
Definition nanomodbus.h:57
@ NMBS_ERROR_INVALID_RESPONSE
Definition nanomodbus.h:63
@ NMBS_EXCEPTION_ILLEGAL_DATA_VALUE
Definition nanomodbus.h:70
@ NMBS_ERROR_TIMEOUT
Definition nanomodbus.h:62
@ NMBS_EXCEPTION_ILLEGAL_FUNCTION
Definition nanomodbus.h:68
@ NMBS_EXCEPTION_SERVER_DEVICE_FAILURE
Definition nanomodbus.h:71
@ NMBS_ERROR_CRC
Definition nanomodbus.h:60
nmbs_error nmbs_write_multiple_registers(nmbs_t *nmbs, uint16_t address, uint16_t quantity, const uint16_t *registers)
Definition nanomodbus.c:2108
nmbs_error nmbs_write_single_register(nmbs_t *nmbs, uint16_t address, uint16_t value)
Definition nanomodbus.c:2054
nmbs_error nmbs_send_raw_pdu(nmbs_t *nmbs, uint8_t fc, const uint8_t *data, uint16_t data_len)
Definition nanomodbus.c:2377
void nmbs_callbacks_create(nmbs_callbacks *callbacks)
Definition nanomodbus.c:1896
nmbs_error nmbs_client_create(nmbs_t *nmbs, const nmbs_platform_conf *platform_conf)
Definition nanomodbus.c:1962
nmbs_error nmbs_read_device_identification_regular(nmbs_t *nmbs, char *vendor_url, char *product_name, char *model_name, char *user_application_name, uint8_t buffers_length)
Definition nanomodbus.c:2286
void nmbs_set_byte_timeout(nmbs_t *nmbs, int32_t timeout_ms)
Definition nanomodbus.c:256
nmbs_error nmbs_read_holding_registers(nmbs_t *nmbs, uint16_t address, uint16_t quantity, uint16_t *registers_out)
Definition nanomodbus.c:2022
void nmbs_set_destination_rtu_address(nmbs_t *nmbs, uint8_t address)
Definition nanomodbus.c:269
nmbs_error nmbs_receive_raw_pdu_response(nmbs_t *nmbs, uint8_t *data_out, uint8_t data_out_len)
Definition nanomodbus.c:2391
nmbs_error nmbs_server_poll(nmbs_t *nmbs)
Definition nanomodbus.c:1921
const char * nmbs_strerror(nmbs_error error)
Definition nanomodbus.c:2419
uint8_t nmbs_bitfield[NMBS_BITFIELD_BYTES_MAX]
Definition nanomodbus.h:95
nmbs_error nmbs_read_device_identification_basic(nmbs_t *nmbs, char *vendor_name, char *product_code, char *major_minor_revision, uint8_t buffers_length)
Definition nanomodbus.c:2250
void nmbs_platform_conf_create(nmbs_platform_conf *platform_conf)
Definition nanomodbus.c:261
nmbs_error nmbs_write_file_record(nmbs_t *nmbs, uint16_t file_number, uint16_t record_number, const uint16_t *registers, uint16_t count)
Definition nanomodbus.c:2172
nmbs_error nmbs_write_multiple_coils(nmbs_t *nmbs, uint16_t address, uint16_t quantity, const nmbs_bitfield coils)
Definition nanomodbus.c:2074
void nmbs_set_callbacks_arg(nmbs_t *nmbs, void *arg)
Definition nanomodbus.c:1955
nmbs_error nmbs_read_device_identification_extended(nmbs_t *nmbs, uint8_t object_id_start, uint8_t *ids, char **buffers, uint8_t ids_length, uint8_t buffer_length, uint8_t *objects_count_out)
Definition nanomodbus.c:2322
nmbs_error nmbs_server_create(nmbs_t *nmbs, uint8_t address_rtu, const nmbs_platform_conf *platform_conf, const nmbs_callbacks *callbacks)
Definition nanomodbus.c:1902
nmbs_error nmbs_read_coils(nmbs_t *nmbs, uint16_t address, uint16_t quantity, nmbs_bitfield coils_out)
Definition nanomodbus.c:1990
nmbs_error nmbs_read_file_record(nmbs_t *nmbs, uint16_t file_number, uint16_t record_number, uint16_t *registers, uint16_t count)
Definition nanomodbus.c:2142
void nmbs_set_read_timeout(nmbs_t *nmbs, int32_t timeout_ms)
Definition nanomodbus.c:251
void nmbs_set_platform_arg(nmbs_t *nmbs, void *arg)
Definition nanomodbus.c:274
nmbs_error nmbs_read_write_registers(nmbs_t *nmbs, uint16_t read_address, uint16_t read_quantity, uint16_t *registers_out, uint16_t write_address, uint16_t write_quantity, const uint16_t *registers)
Definition nanomodbus.c:2207
uint16_t nmbs_crc_calc(const uint8_t *data, uint32_t length, void *arg)
Definition nanomodbus.c:279
nmbs_transport
Definition nanomodbus.h:129
uint8_t nmbs_bitfield_256[32]
Definition nanomodbus.h:100
nmbs_error nmbs_write_single_coil(nmbs_t *nmbs, uint16_t address, bool value)
Definition nanomodbus.c:2032
nmbs_error nmbs_read_discrete_inputs(nmbs_t *nmbs, uint16_t address, uint16_t quantity, nmbs_bitfield inputs_out)
Definition nanomodbus.c:1995
nmbs_error nmbs_read_device_identification(nmbs_t *nmbs, uint8_t object_id, char *buffer, uint8_t buffer_length)
Definition nanomodbus.c:2358
Definition nanomodbus.h:179
Definition nanomodbus.h:158
int32_t(* read)(uint8_t *buf, uint16_t count, int32_t byte_timeout_ms, void *arg)
Definition nanomodbus.h:160
uint32_t initialized
Definition nanomodbus.h:167
uint16_t(* crc_calc)(const uint8_t *data, uint32_t length, void *arg)
Definition nanomodbus.h:164
void * arg
Definition nanomodbus.h:166
nmbs_transport transport
Definition nanomodbus.h:159
int32_t(* write)(const uint8_t *buf, uint16_t count, int32_t byte_timeout_ms, void *arg)
Definition nanomodbus.h:162
Definition nanomodbus.h:244