Skip to content

Commit 8fafaa3

Browse files
committed
New *_create() APIs
1 parent 67bd7b2 commit 8fafaa3

File tree

13 files changed

+169
-65
lines changed

13 files changed

+169
-65
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# nanoMODBUS - A compact MODBUS RTU/TCP C library for embedded/microcontrollers
22

3-
**If you found this library useful, buy me a coffee on** [<img src='https://storage.ko-fi.com/cdn/brandasset/logo_white_stroke.png' width='80'>](https://ko-fi.com/B0B2LK779)
3+
**If you found this library useful, buy me a coffee on
4+
** [<img src='https://storage.ko-fi.com/cdn/brandasset/logo_white_stroke.png' width='80'>](https://ko-fi.com/B0B2LK779)
45

56
nanoMODBUS is a small C library that implements the Modbus protocol. It is especially useful in embedded and
67
resource-constrained systems like microcontrollers.
@@ -52,6 +53,7 @@ int main(int argc, char* argv[]) {
5253

5354
// my_transport_read() and my_transport_write() are implemented by the user
5455
nmbs_platform_conf platform_conf;
56+
nmbs_platform_conf_create(&platform_conf);
5557
platform_conf.transport = NMBS_TRANSPORT_TCP;
5658
platform_conf.read = my_transport_read;
5759
platform_conf.write = my_transport_write;

examples/arduino/client-rtu/client-rtu.ino

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ void setup() {
4242

4343
void loop() {
4444
nmbs_platform_conf platform_conf;
45+
nmbs_platform_conf_create(&platform_conf);
4546
platform_conf.transport = NMBS_TRANSPORT_RTU;
4647
platform_conf.read = read_serial;
4748
platform_conf.write = write_serial;

examples/arduino/server-rtu/server-rtu.ino

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,14 @@ void setup() {
103103

104104
void loop() {
105105
nmbs_platform_conf platform_conf;
106+
nmbs_platform_conf_create(&platform_conf);
106107
platform_conf.transport = NMBS_TRANSPORT_RTU;
107108
platform_conf.read = read_serial;
108109
platform_conf.write = write_serial;
109110
platform_conf.arg = NULL;
110111

111-
nmbs_callbacks callbacks = {0};
112+
nmbs_callbacks callbacks;
113+
nmbs_callbacks_create(&callbacks);
112114
callbacks.read_coils = handle_read_coils;
113115
callbacks.write_multiple_coils = handle_write_multiple_coils;
114116
callbacks.read_holding_registers = handler_read_holding_registers;

examples/linux/client-tcp.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ int main(int argc, char* argv[]) {
2626
}
2727

2828
nmbs_platform_conf platform_conf;
29+
nmbs_platform_conf_create(&platform_conf);
2930
platform_conf.transport = NMBS_TRANSPORT_TCP;
3031
platform_conf.read = read_fd_linux;
3132
platform_conf.write = write_fd_linux;

examples/linux/server-tcp.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,13 +182,15 @@ int main(int argc, char* argv[]) {
182182
return 1;
183183
}
184184

185-
nmbs_platform_conf platform_conf = {0};
185+
nmbs_platform_conf platform_conf;
186+
nmbs_platform_conf_create(&platform_conf);
186187
platform_conf.transport = NMBS_TRANSPORT_TCP;
187188
platform_conf.read = read_fd_linux;
188189
platform_conf.write = write_fd_linux;
189190
platform_conf.arg = NULL; // We will set the arg (socket fd) later
190191

191-
nmbs_callbacks callbacks = {0};
192+
nmbs_callbacks callbacks;
193+
nmbs_callbacks_create(&callbacks);
192194
callbacks.read_coils = handle_read_coils;
193195
callbacks.write_multiple_coils = handle_write_multiple_coils;
194196
callbacks.read_holding_registers = handler_read_holding_registers;

examples/win32/modbus_cli.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ void onError(nmbs_error err) {
4747
void ReadRegister(uint16_t reg) {
4848

4949
nmbs_platform_conf platform_conf;
50+
nmbs_platform_conf_create(&platform_conf);
5051
platform_conf.transport = NMBS_TRANSPORT_RTU;
5152
platform_conf.read = read_serial;
5253
platform_conf.write = write_serial;

nanomodbus.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
#include <stdint.h>
3131
#include <string.h>
3232

33+
#define NMBS_UNUSED_PARAM(x) ((x) = (x))
34+
3335
#ifdef NMBS_DEBUG
3436
#include <stdio.h>
3537
#define NMBS_DEBUG_PRINT(...) printf(__VA_ARGS__)
@@ -178,7 +180,7 @@ nmbs_error nmbs_create(nmbs_t* nmbs, const nmbs_platform_conf* platform_conf) {
178180
nmbs->byte_timeout_ms = -1;
179181
nmbs->read_timeout_ms = -1;
180182

181-
if (!platform_conf)
183+
if (!platform_conf || platform_conf->initialized != 0xFFFFDEBE)
182184
return NMBS_ERROR_INVALID_ARGUMENT;
183185

184186
if (platform_conf->transport != NMBS_TRANSPORT_RTU && platform_conf->transport != NMBS_TRANSPORT_TCP)
@@ -203,6 +205,14 @@ void nmbs_set_byte_timeout(nmbs_t* nmbs, int32_t timeout_ms) {
203205
}
204206

205207

208+
void nmbs_platform_conf_create(nmbs_platform_conf* platform_conf) {
209+
memset(platform_conf, 0, sizeof(nmbs_platform_conf));
210+
platform_conf->crc_calc = nmbs_crc_calc;
211+
// Workaround for older user code not calling nmbs_platform_conf_create()
212+
platform_conf->initialized = 0xFFFFDEBE;
213+
}
214+
215+
206216
void nmbs_set_destination_rtu_address(nmbs_t* nmbs, uint8_t address) {
207217
nmbs->dest_address_rtu = address;
208218
}
@@ -213,7 +223,8 @@ void nmbs_set_platform_arg(nmbs_t* nmbs, void* arg) {
213223
}
214224

215225

216-
uint16_t nmbs_crc_calc(const uint8_t* data, uint32_t length) {
226+
uint16_t nmbs_crc_calc(const uint8_t* data, uint32_t length, void* arg) {
227+
NMBS_UNUSED_PARAM(arg);
217228
uint16_t crc = 0xFFFF;
218229
for (uint32_t i = 0; i < length; i++) {
219230
crc ^= (uint16_t) data[i];
@@ -270,7 +281,7 @@ static nmbs_error recv_msg_footer(nmbs_t* nmbs) {
270281
NMBS_DEBUG_PRINT("\n");
271282

272283
if (nmbs->platform.transport == NMBS_TRANSPORT_RTU) {
273-
uint16_t crc = nmbs_crc_calc(nmbs->msg.buf, nmbs->msg.buf_idx);
284+
uint16_t crc = nmbs->platform.crc_calc(nmbs->msg.buf, nmbs->msg.buf_idx, nmbs->platform.arg);
274285

275286
nmbs_error err = recv(nmbs, 2);
276287
if (err != NMBS_ERROR_NONE)
@@ -381,7 +392,7 @@ static nmbs_error send_msg(nmbs_t* nmbs) {
381392
NMBS_DEBUG_PRINT("\n");
382393

383394
if (nmbs->platform.transport == NMBS_TRANSPORT_RTU) {
384-
uint16_t crc = nmbs_crc_calc(nmbs->msg.buf, nmbs->msg.buf_idx);
395+
uint16_t crc = nmbs->platform.crc_calc(nmbs->msg.buf, nmbs->msg.buf_idx, nmbs->platform.arg);
385396
put_2(nmbs, crc);
386397
}
387398

@@ -1839,11 +1850,20 @@ static nmbs_error handle_req_fc(nmbs_t* nmbs) {
18391850
}
18401851

18411852

1853+
void nmbs_callbacks_create(nmbs_callbacks* callbacks) {
1854+
memset(callbacks, 0, sizeof(nmbs_callbacks));
1855+
callbacks->initialized = 0xFFFFDEBE;
1856+
}
1857+
1858+
18421859
nmbs_error nmbs_server_create(nmbs_t* nmbs, uint8_t address_rtu, const nmbs_platform_conf* platform_conf,
18431860
const nmbs_callbacks* callbacks) {
18441861
if (platform_conf->transport == NMBS_TRANSPORT_RTU && address_rtu == 0)
18451862
return NMBS_ERROR_INVALID_ARGUMENT;
18461863

1864+
if (!callbacks || callbacks->initialized != 0xFFFFDEBE)
1865+
return NMBS_ERROR_INVALID_ARGUMENT;
1866+
18471867
nmbs_error ret = nmbs_create(nmbs, platform_conf);
18481868
if (ret != NMBS_ERROR_NONE)
18491869
return ret;

nanomodbus.h

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,8 @@ typedef enum nmbs_transport {
139139
* A return value between `0` and `count - 1` will be treated as if a timeout occurred on the transport side. All other
140140
* values will be treated as transport errors.
141141
*
142+
* Additionally, an optional crc_calc() function can be defined to override the default nanoMODBUS CRC calculation function.
143+
*
142144
* These methods accept a pointer to arbitrary user-data, which is the arg member of this struct.
143145
* After the creation of an instance it can be changed with nmbs_set_platform_arg().
144146
*/
@@ -148,7 +150,10 @@ typedef struct nmbs_platform_conf {
148150
void* arg); /*!< Bytes read transport function pointer */
149151
int32_t (*write)(const uint8_t* buf, uint16_t count, int32_t byte_timeout_ms,
150152
void* arg); /*!< Bytes write transport function pointer */
151-
void* arg; /*!< User data, will be passed to functions above */
153+
uint16_t (*crc_calc)(const uint8_t* data, uint32_t length,
154+
void* arg); /*!< CRC calculation function pointer. Optional */
155+
void* arg; /*!< User data, will be passed to functions above */
156+
uint32_t initialized; /*!< Reserved, workaround for older user code not calling nmbs_platform_conf_create() */
152157
} nmbs_platform_conf;
153158

154159

@@ -216,7 +221,8 @@ typedef struct nmbs_callbacks {
216221
#endif
217222
#endif
218223

219-
void* arg; // User data, will be passed to functions above
224+
void* arg; // User data, will be passed to functions above
225+
uint32_t initialized; // Reserved, workaround for older user code not calling nmbs_callbacks_create()
220226
} nmbs_callbacks;
221227

222228

@@ -268,13 +274,23 @@ void nmbs_set_read_timeout(nmbs_t* nmbs, int32_t timeout_ms);
268274
*/
269275
void nmbs_set_byte_timeout(nmbs_t* nmbs, int32_t timeout_ms);
270276

277+
/** Create a new nmbs_platform_conf struct.
278+
* @param platform_conf pointer to the nmbs_platform_conf instance
279+
*/
280+
void nmbs_platform_conf_create(nmbs_platform_conf* platform_conf);
281+
271282
/** Set the pointer to user data argument passed to platform functions.
272283
* @param nmbs pointer to the nmbs_t instance
273284
* @param arg user data argument
274285
*/
275286
void nmbs_set_platform_arg(nmbs_t* nmbs, void* arg);
276287

277288
#ifndef NMBS_SERVER_DISABLED
289+
/** Create a new nmbs_callbacks struct.
290+
* @param callbacks pointer to the nmbs_callbacks instance
291+
*/
292+
void nmbs_callbacks_create(nmbs_callbacks* callbacks);
293+
278294
/** Create a new Modbus server.
279295
* @param nmbs pointer to the nmbs_t instance where the client will be created.
280296
* @param address_rtu RTU address of this server. Can be 0 if transport is not RTU.
@@ -510,7 +526,7 @@ nmbs_error nmbs_receive_raw_pdu_response(nmbs_t* nmbs, uint8_t* data_out, uint8_
510526
* @param data Data
511527
* @param length Length of the data
512528
*/
513-
uint16_t nmbs_crc_calc(const uint8_t* data, uint32_t length);
529+
uint16_t nmbs_crc_calc(const uint8_t* data, uint32_t length, void* arg);
514530

515531
#ifndef NMBS_STRERROR_DISABLED
516532
/** Convert a nmbs_error to string

tests/client_disabled.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,15 @@ int main(int argc, char* argv[]) {
2727

2828
nmbs_t nmbs;
2929

30-
nmbs_platform_conf platform_conf_empty = {
31-
.transport = NMBS_TRANSPORT_TCP,
32-
.read = read_empty,
33-
.write = write_empty,
34-
};
3530

36-
nmbs_callbacks callbacks_empty = {0};
31+
nmbs_platform_conf platform_conf_empty;
32+
nmbs_platform_conf_create(&platform_conf_empty);
33+
platform_conf_empty.transport = NMBS_TRANSPORT_TCP;
34+
platform_conf_empty.read = read_empty;
35+
platform_conf_empty.write = write_empty;
36+
37+
nmbs_callbacks callbacks_empty;
38+
nmbs_callbacks_create(&callbacks_empty);
3739

3840
nmbs_error err = nmbs_server_create(&nmbs, 1, &platform_conf_empty, &callbacks_empty);
3941
if (err != 0)

tests/multi_server_rtu.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ int main(int argc, char* argv[]) {
122122
nmbs_set_read_timeout(&client, 5000);
123123
nmbs_set_byte_timeout(&client, 100);
124124

125-
nmbs_callbacks callbacks = {0};
125+
nmbs_callbacks callbacks;
126+
nmbs_callbacks_create(&callbacks);
126127
callbacks.read_coils = read_coils;
127128

128129
err = nmbs_server_create(&server1, 33, &s1_conf, &callbacks);

0 commit comments

Comments
 (0)