nanoMODBUS
Data Structures | Macros | Typedefs | Enumerations | Functions
nanomodbus.h File Reference
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
Include dependency graph for nanomodbus.h:

Go to the source code of this file.

Data Structures

struct  nmbs_platform_conf
 
struct  nmbs_callbacks
 
struct  nmbs_t
 

Macros

#define nmbs_error_is_exception(e)   ((e) > 0 && (e) < 5)
 
#define nmbs_bitfield_read(bf, b)   ((bool) ((bf)[(b) / 8] & (0x1 << ((b) % 8))))
 
#define nmbs_bitfield_set(bf, b)   (((bf)[(b) / 8]) = (((bf)[(b) / 8]) | (0x1 << ((b) % 8))))
 
#define nmbs_bitfield_unset(bf, b)   (((bf)[(b) / 8]) = (((bf)[(b) / 8]) & ~(0x1 << ((b) % 8))))
 
#define nmbs_bitfield_write(bf, b, v)    (((bf)[(b) / 8]) = ((v) ? (((bf)[(b) / 8]) | (0x1 << ((b) % 8))) : (((bf)[(b) / 8]) & ~(0x1 << ((b) % 8)))))
 
#define nmbs_bitfield_reset(bf)   memset(bf, 0, sizeof(bf))
 
#define NMBS_DEVICE_IDENTIFICATION_STRING_LENGTH   128
 

Typedefs

typedef enum nmbs_error nmbs_error
 
typedef uint8_t nmbs_bitfield[250]
 
typedef uint8_t nmbs_bitfield_256[32]
 
typedef enum nmbs_transport nmbs_transport
 
typedef struct nmbs_platform_conf nmbs_platform_conf
 
typedef struct nmbs_callbacks nmbs_callbacks
 
typedef struct nmbs_t nmbs_t
 

Enumerations

enum  nmbs_error {
  NMBS_ERROR_INVALID_REQUEST = -8 , NMBS_ERROR_INVALID_UNIT_ID = -7 , NMBS_ERROR_INVALID_TCP_MBAP = -6 , NMBS_ERROR_CRC = -5 ,
  NMBS_ERROR_TRANSPORT = -4 , NMBS_ERROR_TIMEOUT = -3 , NMBS_ERROR_INVALID_RESPONSE = -2 , NMBS_ERROR_INVALID_ARGUMENT = -1 ,
  NMBS_ERROR_NONE = 0 , NMBS_EXCEPTION_ILLEGAL_FUNCTION = 1 , NMBS_EXCEPTION_ILLEGAL_DATA_ADDRESS = 2 , NMBS_EXCEPTION_ILLEGAL_DATA_VALUE = 3 ,
  NMBS_EXCEPTION_SERVER_DEVICE_FAILURE = 4
}
 
enum  nmbs_transport { NMBS_TRANSPORT_RTU = 1 , NMBS_TRANSPORT_TCP = 2 }
 

Functions

void nmbs_set_read_timeout (nmbs_t *nmbs, int32_t timeout_ms)
 
void nmbs_set_byte_timeout (nmbs_t *nmbs, int32_t timeout_ms)
 
void nmbs_set_platform_arg (nmbs_t *nmbs, void *arg)
 
nmbs_error nmbs_server_create (nmbs_t *nmbs, uint8_t address_rtu, const nmbs_platform_conf *platform_conf, const nmbs_callbacks *callbacks)
 
nmbs_error nmbs_server_poll (nmbs_t *nmbs)
 
void nmbs_set_callbacks_arg (nmbs_t *nmbs, void *arg)
 
nmbs_error nmbs_client_create (nmbs_t *nmbs, const nmbs_platform_conf *platform_conf)
 
void nmbs_set_destination_rtu_address (nmbs_t *nmbs, uint8_t address)
 
nmbs_error nmbs_read_coils (nmbs_t *nmbs, uint16_t address, uint16_t quantity, nmbs_bitfield coils_out)
 
nmbs_error nmbs_read_discrete_inputs (nmbs_t *nmbs, uint16_t address, uint16_t quantity, nmbs_bitfield inputs_out)
 
nmbs_error nmbs_read_holding_registers (nmbs_t *nmbs, uint16_t address, uint16_t quantity, uint16_t *registers_out)
 
nmbs_error nmbs_read_input_registers (nmbs_t *nmbs, uint16_t address, uint16_t quantity, uint16_t *registers_out)
 
nmbs_error nmbs_write_single_coil (nmbs_t *nmbs, uint16_t address, bool value)
 
nmbs_error nmbs_write_single_register (nmbs_t *nmbs, uint16_t address, uint16_t value)
 
nmbs_error nmbs_write_multiple_coils (nmbs_t *nmbs, uint16_t address, uint16_t quantity, const nmbs_bitfield coils)
 
nmbs_error nmbs_write_multiple_registers (nmbs_t *nmbs, uint16_t address, uint16_t quantity, const uint16_t *registers)
 
nmbs_error nmbs_read_file_record (nmbs_t *nmbs, uint16_t file_number, uint16_t record_number, uint16_t *registers, uint16_t count)
 
nmbs_error nmbs_write_file_record (nmbs_t *nmbs, uint16_t file_number, uint16_t record_number, const uint16_t *registers, uint16_t count)
 
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)
 
nmbs_error nmbs_read_device_identification_basic (nmbs_t *nmbs, char *vendor_name, char *product_code, char *major_minor_revision, uint8_t buffer_length)
 
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 buffer_length)
 
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)
 
nmbs_error nmbs_read_device_identification (nmbs_t *nmbs, uint8_t object_id, char *buffer, uint8_t buffer_length)
 
nmbs_error nmbs_send_raw_pdu (nmbs_t *nmbs, uint8_t fc, const uint8_t *data, uint16_t data_len)
 
nmbs_error nmbs_receive_raw_pdu_response (nmbs_t *nmbs, uint8_t *data_out, uint8_t data_out_len)
 
uint16_t nmbs_crc_calc (const uint8_t *data, uint32_t length)
 
const char * nmbs_strerror (nmbs_error error)
 

Macro Definition Documentation

◆ nmbs_bitfield_read

#define nmbs_bitfield_read (   bf,
 
)    ((bool) ((bf)[(b) / 8] & (0x1 << ((b) % 8))))

Read a bit from the nmbs_bitfield bf at position b

◆ nmbs_bitfield_reset

#define nmbs_bitfield_reset (   bf)    memset(bf, 0, sizeof(bf))

Reset (zero) the whole bitfield

◆ nmbs_bitfield_set

#define nmbs_bitfield_set (   bf,
 
)    (((bf)[(b) / 8]) = (((bf)[(b) / 8]) | (0x1 << ((b) % 8))))

Set a bit of the nmbs_bitfield bf at position b

◆ nmbs_bitfield_unset

#define nmbs_bitfield_unset (   bf,
 
)    (((bf)[(b) / 8]) = (((bf)[(b) / 8]) & ~(0x1 << ((b) % 8))))

Reset a bit of the nmbs_bitfield bf at position b

◆ nmbs_bitfield_write

#define nmbs_bitfield_write (   bf,
  b,
 
)     (((bf)[(b) / 8]) = ((v) ? (((bf)[(b) / 8]) | (0x1 << ((b) % 8))) : (((bf)[(b) / 8]) & ~(0x1 << ((b) % 8)))))

Write value v to the nmbs_bitfield bf at position b

◆ nmbs_error_is_exception

#define nmbs_error_is_exception (   e)    ((e) > 0 && (e) < 5)

Return whether the nmbs_error is a modbus exception nmbs_error to check

Typedef Documentation

◆ nmbs_bitfield

typedef uint8_t nmbs_bitfield[250]

Bitfield consisting of 2000 coils/discrete inputs

◆ nmbs_bitfield_256

typedef uint8_t nmbs_bitfield_256[32]

Bitfield consisting of 256 values

◆ nmbs_callbacks

Modbus server request callbacks. Passed to nmbs_server_create().

These methods accept a pointer to arbitrary user data, which is the arg member of the nmbs_platform_conf that was passed to nmbs_server_create together with this struct.

unit_id is the RTU unit ID of the request sender. It is always 0 on TCP.

◆ nmbs_error

typedef enum nmbs_error nmbs_error

nanoMODBUS errors. Values <= 0 are library errors, > 0 are modbus exceptions.

◆ nmbs_platform_conf

nanoMODBUS platform configuration struct. Passed to nmbs_server_create() and nmbs_client_create().

read() and write() are the platform-specific methods that read/write data to/from a serial port or a TCP connection.

Both methods should block until either:

  • count bytes of data are read/written
  • the byte timeout, with byte_timeout_ms >= 0, expires

A value < 0 for byte_timeout_ms means no timeout.

Their return value should be the number of bytes actually read/written, or < 0 in case of error. A return value between 0 and count - 1 will be treated as if a timeout occurred on the transport side. All other values will be treated as transport errors.

These methods accept a pointer to arbitrary user-data, which is the arg member of this struct. After the creation of an instance it can be changed with nmbs_set_platform_arg().

◆ nmbs_t

typedef struct nmbs_t nmbs_t

nanoMODBUS client/server instance type. All struct members are to be considered private, it is not advisable to read/write them directly.

◆ nmbs_transport

Modbus transport type.

Enumeration Type Documentation

◆ nmbs_error

enum nmbs_error

nanoMODBUS errors. Values <= 0 are library errors, > 0 are modbus exceptions.

Enumerator
NMBS_ERROR_INVALID_REQUEST 

Received invalid request from client

NMBS_ERROR_INVALID_UNIT_ID 

Received invalid unit ID in response from server

NMBS_ERROR_INVALID_TCP_MBAP 

Received invalid TCP MBAP

NMBS_ERROR_CRC 

Received invalid CRC

NMBS_ERROR_TRANSPORT 

Transport error

NMBS_ERROR_TIMEOUT 

Read/write timeout occurred

NMBS_ERROR_INVALID_RESPONSE 

Received invalid response from server

NMBS_ERROR_INVALID_ARGUMENT 

Invalid argument provided

NMBS_ERROR_NONE 

No error

NMBS_EXCEPTION_ILLEGAL_FUNCTION 

Modbus exception 1

NMBS_EXCEPTION_ILLEGAL_DATA_ADDRESS 

Modbus exception 2

NMBS_EXCEPTION_ILLEGAL_DATA_VALUE 

Modbus exception 3

NMBS_EXCEPTION_SERVER_DEVICE_FAILURE 

Modbus exception 4

◆ nmbs_transport

Modbus transport type.

Function Documentation

◆ nmbs_client_create()

nmbs_error nmbs_client_create ( nmbs_t nmbs,
const nmbs_platform_conf platform_conf 
)

Create a new Modbus client.

Parameters
nmbspointer to the nmbs_t instance where the client will be created.
platform_confnmbs_platform_conf struct with platform configuration. It may be discarded after calling this method.
Returns
NMBS_ERROR_NONE if successful, NMBS_ERROR_INVALID_ARGUMENT otherwise.

◆ nmbs_crc_calc()

uint16_t nmbs_crc_calc ( const uint8_t *  data,
uint32_t  length 
)

Calculate the Modbus CRC of some data.

Parameters
dataData
lengthLength of the data

◆ nmbs_read_coils()

nmbs_error nmbs_read_coils ( nmbs_t nmbs,
uint16_t  address,
uint16_t  quantity,
nmbs_bitfield  coils_out 
)

Send a FC 01 (0x01) Read Coils request

Parameters
nmbspointer to the nmbs_t instance
addressstarting address
quantityquantity of coils
coils_outnmbs_bitfield where the coils will be stored
Returns
NMBS_ERROR_NONE if successful, other errors otherwise.

◆ nmbs_read_device_identification()

nmbs_error nmbs_read_device_identification ( nmbs_t nmbs,
uint8_t  object_id,
char *  buffer,
uint8_t  buffer_length 
)

Send a FC 43 / 14 (0x2B / 0x0E) Read Device Identification to retrieve a single Object Id value (Read Device ID code 4)

Parameters
nmbspointer to the nmbs_t instance
object_idrequested Object Id
bufferchar array where the resulting value will be stored
buffer_lengthlength of the char array
Returns
NMBS_ERROR_NONE if successful, other errors otherwise.

◆ nmbs_read_device_identification_basic()

nmbs_error nmbs_read_device_identification_basic ( nmbs_t nmbs,
char *  vendor_name,
char *  product_code,
char *  major_minor_revision,
uint8_t  buffer_length 
)

Send a FC 43 / 14 (0x2B / 0x0E) Read Device Identification to read all Basic Object Id values (Read Device ID code 1)

Parameters
nmbspointer to the nmbs_t instance
vendor_namechar array where the read VendorName value will be stored
product_codechar array where the read ProductCode value will be stored
major_minor_revisionchar array where the read MajorMinorRevision value will be stored
buffer_lengthlength of every char array
Returns
NMBS_ERROR_NONE if successful, other errors otherwise.

◆ nmbs_read_device_identification_extended()

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 
)

Send a FC 43 / 14 (0x2B / 0x0E) Read Device Identification to read all Extended Object Id values (Read Device ID code 3)

Parameters
nmbspointer to the nmbs_t instance
object_id_startObject Id to start reading from
idsarray where the read Object Ids will be stored
buffersarray of char arrays where the read values will be stored
ids_lengthlength of the ids array and buffers array
buffer_lengthlength of each char array
objects_count_outretrieved Object Ids count
Returns
NMBS_ERROR_NONE if successful, NMBS_INVALID_ARGUMENT if buffers_count is less than retrieved Object Ids count, other errors otherwise.

◆ nmbs_read_device_identification_regular()

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  buffer_length 
)

Send a FC 43 / 14 (0x2B / 0x0E) Read Device Identification to read all Regular Object Id values (Read Device ID code 2)

Parameters
nmbspointer to the nmbs_t instance
vendor_urlchar array where the read VendorUrl value will be stored
product_namechar array where the read ProductName value will be stored
model_namechar array where the read ModelName value will be stored
user_application_namechar array where the read UserApplicationName value will be stored
buffer_lengthlength of every char array
Returns
NMBS_ERROR_NONE if successful, other errors otherwise.

◆ nmbs_read_discrete_inputs()

nmbs_error nmbs_read_discrete_inputs ( nmbs_t nmbs,
uint16_t  address,
uint16_t  quantity,
nmbs_bitfield  inputs_out 
)

Send a FC 02 (0x02) Read Discrete Inputs request

Parameters
nmbspointer to the nmbs_t instance
addressstarting address
quantityquantity of inputs
inputs_outnmbs_bitfield where the discrete inputs will be stored
Returns
NMBS_ERROR_NONE if successful, other errors otherwise.

◆ nmbs_read_file_record()

nmbs_error nmbs_read_file_record ( nmbs_t nmbs,
uint16_t  file_number,
uint16_t  record_number,
uint16_t *  registers,
uint16_t  count 
)

Send a FC 20 (0x14) Read File Record

Parameters
nmbspointer to the nmbs_t instance
file_numberfile number (1 to 65535)
record_numberrecord number from file (0000 to 9999)
registersarray of registers to read
countcount of registers
Returns
NMBS_ERROR_NONE if successful, other errors otherwise.

◆ nmbs_read_holding_registers()

nmbs_error nmbs_read_holding_registers ( nmbs_t nmbs,
uint16_t  address,
uint16_t  quantity,
uint16_t *  registers_out 
)

Send a FC 03 (0x03) Read Holding Registers request

Parameters
nmbspointer to the nmbs_t instance
addressstarting address
quantityquantity of registers
registers_outarray where the registers will be stored
Returns
NMBS_ERROR_NONE if successful, other errors otherwise.

◆ nmbs_read_input_registers()

nmbs_error nmbs_read_input_registers ( nmbs_t nmbs,
uint16_t  address,
uint16_t  quantity,
uint16_t *  registers_out 
)

Send a FC 04 (0x04) Read Input Registers request

Parameters
nmbspointer to the nmbs_t instance
addressstarting address
quantityquantity of registers
registers_outarray where the registers will be stored
Returns
NMBS_ERROR_NONE if successful, other errors otherwise.

◆ nmbs_read_write_registers()

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 
)

Send a FC 23 (0x17) Read Write Multiple registers

Parameters
nmbspointer to the nmbs_t instance
read_addressstarting read address
read_quantityquantity of registers to read
registers_outarray where the read registers will be stored
write_addressstarting write address
write_quantityquantity of registers to write
registersarray of registers values to write
Returns
NMBS_ERROR_NONE if successful, other errors otherwise.

◆ nmbs_receive_raw_pdu_response()

nmbs_error nmbs_receive_raw_pdu_response ( nmbs_t nmbs,
uint8_t *  data_out,
uint8_t  data_out_len 
)

Receive a raw response Modbus PDU.

Parameters
nmbspointer to the nmbs_t instance
data_outresponse data. It's up to the caller to convert this data to host byte order. Can be NULL.
data_out_lennumber of bytes to receive
Returns
NMBS_ERROR_NONE if successful, other errors otherwise.

◆ nmbs_send_raw_pdu()

nmbs_error nmbs_send_raw_pdu ( nmbs_t nmbs,
uint8_t  fc,
const uint8_t *  data,
uint16_t  data_len 
)

Send a raw Modbus PDU. CRC on RTU will be calculated and sent by this function.

Parameters
nmbspointer to the nmbs_t instance
fcrequest function code
datarequest data. It's up to the caller to convert this data to network byte order
data_lenlength of the data parameter
Returns
NMBS_ERROR_NONE if successful, other errors otherwise.

◆ nmbs_server_create()

nmbs_error nmbs_server_create ( nmbs_t nmbs,
uint8_t  address_rtu,
const nmbs_platform_conf platform_conf,
const nmbs_callbacks callbacks 
)

Create a new Modbus server.

Parameters
nmbspointer to the nmbs_t instance where the client will be created.
address_rtuRTU address of this server. Can be 0 if transport is not RTU.
platform_confnmbs_platform_conf struct with platform configuration. It may be discarded after calling this method.
callbacksnmbs_callbacks struct with server request callbacks. It may be discarded after calling this method.
Returns
NMBS_ERROR_NONE if successful, NMBS_ERROR_INVALID_ARGUMENT otherwise.

◆ nmbs_server_poll()

nmbs_error nmbs_server_poll ( nmbs_t nmbs)

Handle incoming requests to the server. This function should be called in a loop in order to serve any incoming request. Its maximum duration, in case of no received request, is the value set with nmbs_set_read_timeout() (unless set to < 0).

Parameters
nmbspointer to the nmbs_t instance
Returns
NMBS_ERROR_NONE if successful, other errors otherwise.

◆ nmbs_set_byte_timeout()

void nmbs_set_byte_timeout ( nmbs_t nmbs,
int32_t  timeout_ms 
)

Set the timeout between the reception/transmission of two consecutive bytes.

Parameters
nmbspointer to the nmbs_t instance
timeout_mstimeout in milliseconds. If < 0, the timeout is disabled.

◆ nmbs_set_callbacks_arg()

void nmbs_set_callbacks_arg ( nmbs_t nmbs,
void *  arg 
)

Set the pointer to user data argument passed to server request callbacks.

Parameters
nmbspointer to the nmbs_t instance
arguser data argument

◆ nmbs_set_destination_rtu_address()

void nmbs_set_destination_rtu_address ( nmbs_t nmbs,
uint8_t  address 
)

Set the recipient server address of the next request on RTU transport.

Parameters
nmbspointer to the nmbs_t instance
addressserver address

◆ nmbs_set_platform_arg()

void nmbs_set_platform_arg ( nmbs_t nmbs,
void *  arg 
)

Set the pointer to user data argument passed to platform functions.

Parameters
nmbspointer to the nmbs_t instance
arguser data argument

◆ nmbs_set_read_timeout()

void nmbs_set_read_timeout ( nmbs_t nmbs,
int32_t  timeout_ms 
)

Set the request/response timeout. If the target instance is a server, sets the timeout of the nmbs_server_poll() function. If the target instance is a client, sets the response timeout after sending a request. In case of timeout, the called method will return NMBS_ERROR_TIMEOUT.

Parameters
nmbspointer to the nmbs_t instance
timeout_mstimeout in milliseconds. If < 0, the timeout is disabled.

◆ nmbs_strerror()

const char* nmbs_strerror ( nmbs_error  error)

Convert a nmbs_error to string

Parameters
errorerror to be converted
Returns
string representation of the error

◆ nmbs_write_file_record()

nmbs_error nmbs_write_file_record ( nmbs_t nmbs,
uint16_t  file_number,
uint16_t  record_number,
const uint16_t *  registers,
uint16_t  count 
)

Send a FC 21 (0x15) Write File Record

Parameters
nmbspointer to the nmbs_t instance
file_numberfile number (1 to 65535)
record_numberrecord number from file (0000 to 9999)
registersarray of registers to write
countcount of registers
Returns
NMBS_ERROR_NONE if successful, other errors otherwise.

◆ nmbs_write_multiple_coils()

nmbs_error nmbs_write_multiple_coils ( nmbs_t nmbs,
uint16_t  address,
uint16_t  quantity,
const nmbs_bitfield  coils 
)

Send a FC 15 (0x0F) Write Multiple Coils

Parameters
nmbspointer to the nmbs_t instance
addressstarting address
quantityquantity of coils
coilsbitfield of coils values
Returns
NMBS_ERROR_NONE if successful, other errors otherwise.

◆ nmbs_write_multiple_registers()

nmbs_error nmbs_write_multiple_registers ( nmbs_t nmbs,
uint16_t  address,
uint16_t  quantity,
const uint16_t *  registers 
)

Send a FC 16 (0x10) Write Multiple Registers

Parameters
nmbspointer to the nmbs_t instance
addressstarting address
quantityquantity of registers
registersarray of registers values
Returns
NMBS_ERROR_NONE if successful, other errors otherwise.

◆ nmbs_write_single_coil()

nmbs_error nmbs_write_single_coil ( nmbs_t nmbs,
uint16_t  address,
bool  value 
)

Send a FC 05 (0x05) Write Single Coil request

Parameters
nmbspointer to the nmbs_t instance
addresscoil address
valuecoil value
Returns
NMBS_ERROR_NONE if successful, other errors otherwise.

◆ nmbs_write_single_register()

nmbs_error nmbs_write_single_register ( nmbs_t nmbs,
uint16_t  address,
uint16_t  value 
)

Send a FC 06 (0x06) Write Single Register request

Parameters
nmbspointer to the nmbs_t instance
addressregister address
valueregister value
Returns
NMBS_ERROR_NONE if successful, other errors otherwise.