|
nanoMODBUS
|
#include <stdbool.h>#include <stdint.h>#include <string.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_MAX 2000 |
| #define | NMBS_BITFIELD_BYTES_MAX (NMBS_BITFIELD_MAX / 8) |
| #define | nmbs_bitfield_read(bf, b) ((bool) ((bf)[(b) >> 3] & (0x1 << ((b) & (8 - 1))))) |
| #define | nmbs_bitfield_set(bf, b) (((bf)[(b) >> 3]) = (((bf)[(b) >> 3]) | (0x1 << ((b) & (8 - 1))))) |
| #define | nmbs_bitfield_unset(bf, b) (((bf)[(b) >> 3]) = (((bf)[(b) >> 3]) & ~(0x1 << ((b) & (8 - 1))))) |
| #define | nmbs_bitfield_write(bf, b, v) ((bf)[(b) >> 3] = ((bf)[(b) >> 3] & ~(1 << ((b) & 7))) | ((v) << ((b) & 7))) |
| #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[NMBS_BITFIELD_BYTES_MAX] |
| 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) >> 3] & (0x1 << ((b) & (8 - 1))))) |
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) >> 3]) = (((bf)[(b) >> 3]) | (0x1 << ((b) & (8 - 1))))) |
Set a bit of the nmbs_bitfield bf at position b
| #define nmbs_bitfield_unset | ( | bf, | |
| b | |||
| ) | (((bf)[(b) >> 3]) = (((bf)[(b) >> 3]) & ~(0x1 << ((b) & (8 - 1))))) |
Reset a bit of the nmbs_bitfield bf at position b
| #define nmbs_bitfield_write | ( | bf, | |
| b, | |||
| v | |||
| ) | ((bf)[(b) >> 3] = ((bf)[(b) >> 3] & ~(1 << ((b) & 7))) | ((v) << ((b) & 7))) |
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[NMBS_BITFIELD_BYTES_MAX] |
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 infinite timeout. With a value == 0 for byte_timeout_ms, the method should read/write once in a non-blocking fashion and return immediately.
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 |