nanoMODBUS
|
#include <stdbool.h>
#include <stdint.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_platform_conf_create (nmbs_platform_conf *platform_conf) |
void | nmbs_set_platform_arg (nmbs_t *nmbs, void *arg) |
void | nmbs_callbacks_create (nmbs_callbacks *callbacks) |
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 buffers_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 buffers_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, void *arg) |
const char * | nmbs_strerror (nmbs_error error) |
#define nmbs_bitfield_read | ( | bf, | |
b | |||
) | ((bool) ((bf)[(b) / 8] & (0x1 << ((b) % 8)))) |
Read a bit from the nmbs_bitfield bf at position b
#define nmbs_bitfield_reset | ( | bf | ) | memset(bf, 0, sizeof(bf)) |
Reset (zero) the whole bitfield
#define nmbs_bitfield_set | ( | bf, | |
b | |||
) | (((bf)[(b) / 8]) = (((bf)[(b) / 8]) | (0x1 << ((b) % 8)))) |
Set a bit of the nmbs_bitfield bf at position b
#define nmbs_bitfield_unset | ( | bf, | |
b | |||
) | (((bf)[(b) / 8]) = (((bf)[(b) / 8]) & ~(0x1 << ((b) % 8)))) |
Reset a bit of the nmbs_bitfield bf at position b
#define nmbs_bitfield_write | ( | bf, | |
b, | |||
v | |||
) | (((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
#define nmbs_error_is_exception | ( | e | ) | ((e) > 0 && (e) < 5) |
Return whether the nmbs_error is a modbus exception nmbs_error to check
typedef uint8_t nmbs_bitfield[250] |
Bitfield consisting of 2000 coils/discrete inputs
typedef uint8_t nmbs_bitfield_256[32] |
Bitfield consisting of 256 values
typedef struct nmbs_callbacks 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.
typedef enum nmbs_error nmbs_error |
nanoMODBUS errors. Values <= 0 are library errors, > 0 are modbus exceptions.
typedef struct nmbs_platform_conf 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/writtenbyte_timeout_ms >= 0
, expiresA 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.
Additionally, an optional crc_calc() function can be defined to override the default nanoMODBUS CRC calculation function.
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().
nanoMODBUS client/server instance type. All struct members are to be considered private, it is not advisable to read/write them directly.
typedef enum nmbs_transport nmbs_transport |
Modbus transport type.
enum nmbs_error |
nanoMODBUS errors. Values <= 0 are library errors, > 0 are modbus exceptions.
enum nmbs_transport |
Modbus transport type.
void nmbs_callbacks_create | ( | nmbs_callbacks * | callbacks | ) |
Create a new nmbs_callbacks struct.
callbacks | pointer to the nmbs_callbacks instance |
nmbs_error nmbs_client_create | ( | nmbs_t * | nmbs, |
const nmbs_platform_conf * | platform_conf | ||
) |
Create a new Modbus client.
nmbs | pointer to the nmbs_t instance where the client will be created. |
platform_conf | nmbs_platform_conf struct with platform configuration. It may be discarded after calling this method. |
uint16_t nmbs_crc_calc | ( | const uint8_t * | data, |
uint32_t | length, | ||
void * | arg | ||
) |
Calculate the Modbus CRC of some data.
data | Data |
length | Length of the data |
void nmbs_platform_conf_create | ( | nmbs_platform_conf * | platform_conf | ) |
Create a new nmbs_platform_conf struct.
platform_conf | pointer to the nmbs_platform_conf instance |
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
nmbs | pointer to the nmbs_t instance |
address | starting address |
quantity | quantity of coils |
coils_out | nmbs_bitfield where the coils will be stored |
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)
nmbs | pointer to the nmbs_t instance |
object_id | requested Object Id |
buffer | char array where the resulting value will be stored |
buffer_length | length of the char array |
nmbs_error nmbs_read_device_identification_basic | ( | nmbs_t * | nmbs, |
char * | vendor_name, | ||
char * | product_code, | ||
char * | major_minor_revision, | ||
uint8_t | buffers_length | ||
) |
Send a FC 43 / 14 (0x2B / 0x0E) Read Device Identification to read all Basic Object Id values (Read Device ID code 1)
nmbs | pointer to the nmbs_t instance |
vendor_name | char array where the read VendorName value will be stored |
product_code | char array where the read ProductCode value will be stored |
major_minor_revision | char array where the read MajorMinorRevision value will be stored |
buffers_length | length of every char array |
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)
nmbs | pointer to the nmbs_t instance |
object_id_start | Object Id to start reading from |
ids | array where the read Object Ids will be stored |
buffers | array of char arrays where the read values will be stored |
ids_length | length of the ids array and buffers array |
buffer_length | length of each char array |
objects_count_out | retrieved Object Ids count |
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 | ||
) |
Send a FC 43 / 14 (0x2B / 0x0E) Read Device Identification to read all Regular Object Id values (Read Device ID code 2)
nmbs | pointer to the nmbs_t instance |
vendor_url | char array where the read VendorUrl value will be stored |
product_name | char array where the read ProductName value will be stored |
model_name | char array where the read ModelName value will be stored |
user_application_name | char array where the read UserApplicationName value will be stored |
buffers_length | length of every char array |
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
nmbs | pointer to the nmbs_t instance |
address | starting address |
quantity | quantity of inputs |
inputs_out | nmbs_bitfield where the discrete inputs will be stored |
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
nmbs | pointer to the nmbs_t instance |
file_number | file number (1 to 65535) |
record_number | record number from file (0000 to 9999) |
registers | array of registers to read |
count | count of 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
nmbs | pointer to the nmbs_t instance |
address | starting address |
quantity | quantity of registers |
registers_out | array where the registers will be stored |
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
nmbs | pointer to the nmbs_t instance |
address | starting address |
quantity | quantity of registers |
registers_out | array where the registers will be stored |
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
nmbs | pointer to the nmbs_t instance |
read_address | starting read address |
read_quantity | quantity of registers to read |
registers_out | array where the read registers will be stored |
write_address | starting write address |
write_quantity | quantity of registers to write |
registers | array of registers values to write |
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.
nmbs | pointer to the nmbs_t instance |
data_out | response data. It's up to the caller to convert this data to host byte order. Can be NULL. |
data_out_len | number of bytes to receive |
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.
nmbs | pointer to the nmbs_t instance |
fc | request function code |
data | request data. It's up to the caller to convert this data to network byte order |
data_len | length of the data parameter |
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.
nmbs | pointer to the nmbs_t instance where the client will be created. |
address_rtu | RTU address of this server. Can be 0 if transport is not RTU. |
platform_conf | nmbs_platform_conf struct with platform configuration. It may be discarded after calling this method. |
callbacks | nmbs_callbacks struct with server request callbacks. It may be discarded after calling this method. |
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).
nmbs | pointer to the nmbs_t instance |
void nmbs_set_byte_timeout | ( | nmbs_t * | nmbs, |
int32_t | timeout_ms | ||
) |
Set the timeout between the reception/transmission of two consecutive bytes.
nmbs | pointer to the nmbs_t instance |
timeout_ms | timeout in milliseconds. If < 0, the timeout is disabled. |
void nmbs_set_callbacks_arg | ( | nmbs_t * | nmbs, |
void * | arg | ||
) |
Set the pointer to user data argument passed to server request callbacks.
nmbs | pointer to the nmbs_t instance |
arg | user data argument |
void nmbs_set_destination_rtu_address | ( | nmbs_t * | nmbs, |
uint8_t | address | ||
) |
Set the recipient server address of the next request on RTU transport.
nmbs | pointer to the nmbs_t instance |
address | server address |
void nmbs_set_platform_arg | ( | nmbs_t * | nmbs, |
void * | arg | ||
) |
Set the pointer to user data argument passed to platform functions.
nmbs | pointer to the nmbs_t instance |
arg | user data argument |
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.
nmbs | pointer to the nmbs_t instance |
timeout_ms | timeout in milliseconds. If < 0, the timeout is disabled. |
const char * nmbs_strerror | ( | nmbs_error | error | ) |
Convert a nmbs_error to string
error | error to be converted |
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
nmbs | pointer to the nmbs_t instance |
file_number | file number (1 to 65535) |
record_number | record number from file (0000 to 9999) |
registers | array of registers to write |
count | count of registers |
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
nmbs | pointer to the nmbs_t instance |
address | starting address |
quantity | quantity of coils |
coils | bitfield of coils values |
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
nmbs | pointer to the nmbs_t instance |
address | starting address |
quantity | quantity of registers |
registers | array of registers values |
nmbs_error nmbs_write_single_coil | ( | nmbs_t * | nmbs, |
uint16_t | address, | ||
bool | value | ||
) |
Send a FC 05 (0x05) Write Single Coil request
nmbs | pointer to the nmbs_t instance |
address | coil address |
value | coil value |
nmbs_error nmbs_write_single_register | ( | nmbs_t * | nmbs, |
uint16_t | address, | ||
uint16_t | value | ||
) |
Send a FC 06 (0x06) Write Single Register request
nmbs | pointer to the nmbs_t instance |
address | register address |
value | register value |