liblightmodbus 3.0
A lightweight, header-only, hardware-agnostic Modbus RTU/TCP library
Loading...
Searching...
No Matches
master.impl.h
Go to the documentation of this file.
1#ifndef LIGHTMODBUS_MASTER_IMPL_H
2#define LIGHTMODBUS_MASTER_IMPL_H
3
4#include "master.h"
5#include "master_func.h"
6
19{
20#if defined(LIGHTMODBUS_F01M) || defined(LIGHTMODBUS_MASTER_FULL)
22#endif
23
24#if defined(LIGHTMODBUS_F02M) || defined(LIGHTMODBUS_MASTER_FULL)
26#endif
27
28#if defined(LIGHTMODBUS_F03M) || defined(LIGHTMODBUS_MASTER_FULL)
30#endif
31
32#if defined(LIGHTMODBUS_F04M) || defined(LIGHTMODBUS_MASTER_FULL)
34#endif
35
36#if defined(LIGHTMODBUS_F05M) || defined(LIGHTMODBUS_MASTER_FULL)
38#endif
39
40#if defined(LIGHTMODBUS_F06M) || defined(LIGHTMODBUS_MASTER_FULL)
42#endif
43
44#if defined(LIGHTMODBUS_F15M) || defined(LIGHTMODBUS_MASTER_FULL)
46#endif
47
48#if defined(LIGHTMODBUS_F16M) || defined(LIGHTMODBUS_MASTER_FULL)
50#endif
51
52#if defined(LIGHTMODBUS_F22M) || defined(LIGHTMODBUS_MASTER_FULL)
54#endif
55
56 // Guard - prevents 0 size array
57 {0, NULL}
58};
59
64
80 ModbusMaster *status,
81 ModbusDataCallback dataCallback,
82 ModbusMasterExceptionCallback exceptionCallback,
83 ModbusAllocator allocator,
84 const ModbusMasterFunctionHandler *functions,
85 uint8_t functionCount)
86{
87 status->dataCallback = dataCallback;
88 status->exceptionCallback = exceptionCallback;
89 status->functions = functions;
90 status->functionCount = functionCount;
91 status->context = NULL;
92
93 return modbusBufferInit(&status->request, allocator);
94}
95
106
116
125
135
142{
144 &status->request.data[0],
145 status->request.length,
146 address);
147
148 if (err != MODBUS_OK)
150
151 return MODBUS_NO_ERROR();
152}
153
163
171LIGHTMODBUS_RET_ERROR modbusEndRequestTCP(ModbusMaster *status, uint16_t transactionID, uint8_t unitID)
172{
174 &status->request.data[0],
175 status->request.length,
176 transactionID,
177 unitID);
178
179 if (err != MODBUS_OK)
181
182 return MODBUS_NO_ERROR();
183}
184
199 ModbusMaster *status,
200 uint8_t address,
201 const uint8_t *request,
202 uint8_t requestLength,
203 const uint8_t *response,
204 uint8_t responseLength)
205{
206 // Check if lengths are ok
207 if (!requestLength || requestLength > MODBUS_PDU_MAX)
208 return MODBUS_REQUEST_ERROR(LENGTH);
209 if (!responseLength || responseLength > MODBUS_PDU_MAX)
210 return MODBUS_RESPONSE_ERROR(LENGTH);
211
212 uint8_t function = response[0];
213
214 // Handle exception frames
215 if (function & 0x80 && responseLength == 2)
216 {
217 if (status->exceptionCallback)
218 status->exceptionCallback(
219 status,
220 address,
221 function & 0x7f,
222 (ModbusExceptionCode) response[1]);
223
224 return MODBUS_NO_ERROR();
225 }
226
227 // Check if function code matches the one in request frame
228 if (function != request[0])
229 return MODBUS_RESPONSE_ERROR(FUNCTION);
230
231 // Find a parsing function
232 for (uint16_t i = 0; i < status->functionCount; i++)
233 if (function == status->functions[i].id)
234 return status->functions[i].ptr(
235 status,
236 address,
237 function,
238 request,
239 requestLength,
240 response,
241 responseLength);
242
243 // No matching function handler
244 return MODBUS_GENERAL_ERROR(FUNCTION);
245}
246
261 ModbusMaster *status,
262 const uint8_t *request,
263 uint16_t requestLength,
264 const uint8_t *response,
265 uint16_t responseLength)
266{
267 // Unpack request
268 const uint8_t *requestPDU;
269 uint16_t requestPDULength;
270 uint8_t requestAddress;
272 request,
273 requestLength,
274#ifdef LIGHTMODBUS_MASTER_OMIT_REQUEST_CRC
275 0,
276#else
277 1,
278#endif
279 &requestPDU,
280 &requestPDULength,
281 &requestAddress);
282
283 if (err != MODBUS_OK)
285
286 // Unpack response
287 const uint8_t *responsePDU;
288 uint16_t responsePDULength;
289 uint8_t responseAddress;
290 err = modbusUnpackRTU(
291 response,
292 responseLength,
293 1,
294 &responsePDU,
295 &responsePDULength,
296 &responseAddress);
297
298 if (err != MODBUS_OK)
300
301 // Check addresses - response to a broadcast request or bad response address
302 if (requestAddress == 0 || requestAddress != responseAddress)
303 return MODBUS_RESPONSE_ERROR(ADDRESS);
304
305 // Parse the PDU itself
307 status,
308 requestAddress,
309 requestPDU,
310 requestPDULength,
311 responsePDU,
312 responsePDULength);
313}
314
330 ModbusMaster *status,
331 const uint8_t *request,
332 uint16_t requestLength,
333 const uint8_t *response,
334 uint16_t responseLength)
335{
336 // Unpack request
337 const uint8_t *requestPDU;
338 uint16_t requestPDULength;
339 uint16_t requestTransactionID;
340 uint8_t requestUnitID;
342 request,
343 requestLength,
344 &requestPDU,
345 &requestPDULength,
346 &requestTransactionID,
347 &requestUnitID);
348
349 if (err != MODBUS_OK)
351
352 // Unpack response
353 const uint8_t *responsePDU;
354 uint16_t responsePDULength;
355 uint16_t responseTransactionID;
356 uint8_t responseUnitID;
357 err = modbusUnpackTCP(
358 response,
359 responseLength,
360 &responsePDU,
361 &responsePDULength,
362 &responseTransactionID,
363 &responseUnitID);
364
365 if (err != MODBUS_OK)
367
368 // Check if transaction IDs match
369 if (requestTransactionID != responseTransactionID)
370 return MODBUS_RESPONSE_ERROR(BAD_TRANSACTION);
371
372 // Check if unit IDs match
373 if (requestUnitID != responseUnitID)
374 return MODBUS_RESPONSE_ERROR(ADDRESS);
375
376 // Parse the PDU itself
378 status,
379 requestUnitID,
380 requestPDU,
381 requestPDULength,
382 responsePDU,
383 responsePDULength);
384}
385
386#endif
ModbusExceptionCode
Represents a Modbus exception code.
Definition base.h:230
#define MODBUS_REQUEST_ERROR(e)
Constructs a ModbusErrorInfo where source is set to MODBUS_ERROR_SOURCE_REQUESTL and the error code i...
Definition base.h:100
#define MODBUS_RESPONSE_ERROR(e)
Constructs a ModbusErrorInfo where source is set to MODBUS_ERROR_SOURCE_RESPONSE and the error code i...
Definition base.h:107
static ModbusError modbusPackTCP(uint8_t *frame, uint16_t length, uint16_t transactionID, uint8_t unitID)
Sets up the MBAP header in a Modbus TCP frame.
Definition base.h:592
ModbusError
Represtents different kinds of errors.
Definition base.h:137
@ MODBUS_OK
No error.
Definition base.h:143
#define MODBUS_ERROR_SOURCE_REQUEST
The request frame contains errors.
Definition base.h:62
static ModbusError modbusUnpackRTU(const uint8_t *frame, uint16_t length, uint8_t checkCRC, const uint8_t **pdu, uint16_t *pduLength, uint8_t *address)
Unpacks data from a Modbus RTU frame and optionally checks CRC.
Definition base.h:489
ModbusErrorInfo modbusBufferInit(ModbusBuffer *buffer, ModbusAllocator allocator)
Initializes a buffer for use.
Definition base.impl.h:51
#define MODBUS_NO_ERROR()
Construcs a ModbusErrorInfo object for which modbusIsOK() is guaranteed to return true.
Definition base.h:86
#define MODBUS_ERROR_SOURCE_RESPONSE
The response frame contains errors.
Definition base.h:68
static ModbusError modbusUnpackTCP(const uint8_t *frame, uint16_t length, const uint8_t **pdu, uint16_t *pduLength, uint16_t *transactionID, uint8_t *unitID)
Unpacks data from a Modbus TCP frame.
Definition base.h:553
static void modbusBufferModePDU(ModbusBuffer *buffer)
Prepares buffer to only store a Modbus PDU.
Definition base.h:303
#define MODBUS_ERROR_SOURCE_GENERAL
General library error - can be caused by providing an incorrect argument or a internal library error.
Definition base.h:56
#define LIGHTMODBUS_RET_ERROR
Return type for library functions returning ModbusErrorInfo that should be handled properly.
Definition base.h:49
ModbusError(* ModbusAllocator)(struct ModbusBuffer *buffer, uint16_t size, void *context)
Pointer to a memory allocator function.
Definition base.h:259
#define MODBUS_MAKE_ERROR(s, e)
Constructs a ModbusErrorInfo object from a ModbusErrorCode and a MODBUS_ERROR_SOURCE_* macro.
Definition base.h:80
void modbusBufferDestroy(ModbusBuffer *buffer, void *context)
Equivalent of modbusBufferFree() \copydetail modbusBufferFree()
Definition base.impl.h:78
#define MODBUS_GENERAL_ERROR(e)
Constructs a ModbusErrorInfo where source is set to MODBUS_ERROR_SOURCE_GENERAL and the error code is...
Definition base.h:93
static void modbusBufferModeRTU(ModbusBuffer *buffer)
Prepares buffer to store a Modbus RTU message.
Definition base.h:312
static void modbusBufferModeTCP(ModbusBuffer *buffer)
Prepares buffer to store a Modbus TCP message.
Definition base.h:321
static ModbusError modbusPackRTU(uint8_t *frame, uint16_t length, uint8_t address)
Sets up address and CRC in a Modbus RTU frame.
Definition base.h:522
#define MODBUS_PDU_MAX
Maximum length of a PDU.
Definition base.h:33
Master's types and basic functions (header)
static void * modbusMasterGetUserPointer(const ModbusMaster *status)
Retreieves the custom context pointer.
Definition master.h:152
ModbusError(* ModbusDataCallback)(const ModbusMaster *status, const ModbusDataCallbackArgs *args)
A pointer to a callback used for handling data incoming to master.
Definition master.h:52
ModbusError(* ModbusMasterExceptionCallback)(const ModbusMaster *status, uint8_t address, uint8_t function, ModbusExceptionCode code)
A pointer to a callback called when a Modbus exception is generated (for master)
Definition master.h:60
ModbusErrorInfo modbusParseResponseRTU(ModbusMaster *status, const uint8_t *request, uint16_t requestLength, const uint8_t *response, uint16_t responseLength)
Parses a Modbus RTU slave response.
Definition master.impl.h:260
ModbusErrorInfo modbusEndRequestRTU(ModbusMaster *status, uint8_t address)
Finalizes a Modbus RTU request.
Definition master.impl.h:141
ModbusErrorInfo modbusParseResponseTCP(ModbusMaster *status, const uint8_t *request, uint16_t requestLength, const uint8_t *response, uint16_t responseLength)
Parses a Modbus TCP slave response.
Definition master.impl.h:329
void modbusMasterDestroy(ModbusMaster *status)
Deinitializes a ModbusMaster struct.
Definition master.impl.h:102
ModbusErrorInfo modbusEndRequestTCP(ModbusMaster *status, uint16_t transactionID, uint8_t unitID)
Finalizes a Modbus TCP request.
Definition master.impl.h:171
ModbusErrorInfo modbusEndRequestPDU(ModbusMaster *status)
Finalizes a PDU-only request.
Definition master.impl.h:121
ModbusMasterFunctionHandler modbusMasterDefaultFunctions[]
Default array of supported functions. Length is stored in modbusMasterDefaultFunctionCount.
Definition master.impl.h:18
const uint8_t modbusMasterDefaultFunctionCount
Stores length of modbusMasterDefaultFunctions array.
Definition master.impl.h:63
ModbusErrorInfo modbusBeginRequestPDU(ModbusMaster *status)
Begins a PDU-only request.
Definition master.impl.h:111
ModbusErrorInfo modbusParseResponsePDU(ModbusMaster *status, uint8_t address, const uint8_t *request, uint8_t requestLength, const uint8_t *response, uint8_t responseLength)
Parses a PDU section of a slave response.
Definition master.impl.h:198
ModbusErrorInfo modbusBeginRequestRTU(ModbusMaster *status)
Begins a RTU request.
Definition master.impl.h:130
ModbusErrorInfo modbusMasterInit(ModbusMaster *status, ModbusDataCallback dataCallback, ModbusMasterExceptionCallback exceptionCallback, ModbusAllocator allocator, const ModbusMasterFunctionHandler *functions, uint8_t functionCount)
Initializes a ModbusMaster struct.
Definition master.impl.h:79
ModbusErrorInfo modbusBeginRequestTCP(ModbusMaster *status)
Begins a TCP request.
Definition master.impl.h:158
Master's functions for building requests and parsing responses (header)
ModbusErrorInfo modbusParseResponse1516(ModbusMaster *status, uint8_t address, uint8_t function, const uint8_t *requestPDU, uint8_t requestLength, const uint8_t *responsePDU, uint8_t responseLength)
Parses response to requests 15 and 16 (write mutliple regsiters/coils)
Definition master_func.impl.h:172
ModbusErrorInfo modbusParseResponse0506(ModbusMaster *status, uint8_t address, uint8_t function, const uint8_t *requestPDU, uint8_t requestLength, const uint8_t *responsePDU, uint8_t responseLength)
Parses response to requests 05 and 06.
Definition master_func.impl.h:132
ModbusErrorInfo modbusParseResponse22(ModbusMaster *status, uint8_t address, uint8_t function, const uint8_t *requestPDU, uint8_t requestLength, const uint8_t *responsePDU, uint8_t responseLength)
Parses response to request 22.
Definition master_func.impl.h:226
ModbusErrorInfo modbusParseResponse01020304(ModbusMaster *status, uint8_t address, uint8_t function, const uint8_t *requestPDU, uint8_t requestLength, const uint8_t *responsePDU, uint8_t responseLength)
Parses response to requests 01, 02, 03 and 04.
Definition master_func.impl.h:28
uint16_t length
Length of the entire frame (PDU size + padding)
Definition base.h:282
uint8_t * data
Pointer to the frame buffer.
Definition base.h:280
Associates Modbus function ID with a pointer to a response parsing function.
Definition master.h:31
uint8_t id
Definition master.h:32
ModbusResponseParsingFunction ptr
Definition master.h:33
Master device status.
Definition master.h:73
ModbusDataCallback dataCallback
A pointer to data callback (required)
Definition master.h:74
void * context
User's context pointer.
Definition master.h:83
const ModbusMasterFunctionHandler * functions
A non-owning pointer to array of function handlers.
Definition master.h:77
ModbusMasterExceptionCallback exceptionCallback
A pointer to an exception callback (optional)
Definition master.h:75
ModbusBuffer request
Stores master's request for slave.
Definition master.h:81
uint8_t functionCount
Size of functions array.
Definition master.h:78