Modbus Server Protocol
MODBUS Overview
Modbus is a communication protocol used to transmit data across serial lines between various electronic devices. The protocol is open-source and can be used for major in industrial applications such as PLCs, variable speed drives, HMIs, Data acquisition systems etc. This is probably utilized for the connection of a system controlling using an RTU in SCADA in the power domain.
Embien offers Modbus Stack for both use in server and client configurations. Our implementation supports all the function codes defined by the protocol and supports extension via APIs too. Physical layers supported include RTU, ASCII and TCP/IP.
- Some of the salient features of RAPIDSEA Modbus protocol stack are
Single/Multiple Read/Write functionalities.
Coils/Holding Registers and Input Registers.
Supports major baud rates from 9600 to 115200 bauds and beyond
RTU/ASCII modes can be operated with and without parity and configurable Stop bits.
Server and Client Mode of operation.
Royalty Free Licensing Model.
Highly Optimized for MCU’s.
Uses less amount of RAM and ROM.
Runs on Linux, Windows and with/without RTOS.
The implementation is fully configurable and is offered for both server and client mode of operation.
Modbus Server
RAPIDSEA implements Modbus server where multiple clients can connect and communicate with it to obtain information.
Supported Functionalities
Following services are supported in the Modbus Stack
Function Code |
Register Type |
Value Type |
Access Type |
---|---|---|---|
01 (0x01) |
Read Coil Status |
Discrete |
Read |
02 (0x02) |
Read Input Status |
Discrete |
Read |
03 (0x03) |
Read Holding Registers |
16 Bit |
Read |
04 (0x04) |
Read Input Registers |
16 Bit |
Read |
05 (0x05) |
Write Single Coil |
16 Bit |
Read |
06 (0x06) |
Write Single Holding Register |
16 Bit |
Write |
15 (0x0F) |
Write Multiple Coils |
Discrete |
Write |
16 (0x10) |
Write Multiple Holding Registers |
16 Bit |
Write |
Application Interface
While the RAPIDSEA Modbus server stack can handle most of the functionality such as client request validation, if it has error request, proper intimation to the client. The RAPIDSEA Modbus server clearly defines API and callback functions that are essential for the user to use/implement.
The below table captures the function that are to be called from the application logic.
Function |
Description |
---|---|
rs_modbus_server_open |
To Initialize the serial/socket configuration. |
rs_modbus_server_run |
To set the state to be open |
rs_modbus_server_process |
To be called periodically to prepare the client response. |
rs_modbus_server_reconfig |
To restart the server application by reconfiguring modbus server |
The below table contains rcb calls to perform the server stack.
Function |
Description |
---|---|
rcb_mb_set_holding_register |
Called to set the holding register value |
rcb_mb_set_coil_status_value |
Called to set the coil status value |
rcb_mb_get_coil_status_value |
Called to get the coil status value |
rcb_mb_get_holding_reg_val |
Called to get the holding register value |
rcb_mb_get_input_register_value |
Called to get the input register value |
rcb_mb_get_discrete_input_value |
Called to get the discrete input value |
rcb_modbus_serial |
Called to handle serial timeouts |
Only a millisecond timer is sufficient for the stack to run.
Implementation Guide
This section explains how to implement the Modbus client stack using the RAPIDSEA stack, the steps to be followed are
Initially start the Modbus server task from the application layer.
Then the server task state is in idle condition, until Modbus server starts.
Modbus server starts change the state from idle to state open.
In Modbus server process, process the client request and prepare the response for the client.
In case of a request failing, error code will be sent from the server response.
The below diagram captures the high level sequence of operations associated with the Modbus server RTU.

High level flow chart is depicted below for Modbus server:

Modbus Supported Modes
Modbus RTU (Remote Terminal Unit)
To establish protocol communication, this represents data in a binary format and is mostly utilized in serial communication. The messages in this version are divided by idle periods. The format that is followed in the RTU version is a cyclic redundancy check to verify mechanism and this makes sure of data reliability.
Serial communication header details refer to the serial interface page for more details Serial Interface
Modbus TCP/IP (Transmission Control Protocol)
This version of Modbus is implemented for communications through TCP/IP networks linking over port 502. This variant does not require any kind of checksum calculation as lower levels itself provides this. Modbus TCP protocol uses a 10 Mbps Ethernet standard to convey the entire structure of Modbus messages.
Socket communication header details refer to the socket interface page for more details Socket Interface
Modbus Server Stack Memory Usage
The Modbus server stack has a size of 22588 bytes.
Modbus Server Stack RAM Consumption
The RAM consumption is different for each of the interfaces.
Interface |
Size |
---|---|
RTU |
944 bytes |
ASCII |
1716 bytes |
TCP |
3232 bytes |
RTU Interface
- The memory (944 bytes) needed can be separated as follows:
256 bytes - buffer space for RX/TX in Modbus
256 bytes - buffer space for handling the RX FIFO buffer by the interface layer
256 bytes - buffer space for handling the TX FIFO buffer by the interface layer
176 bytes - other configuration related memory
ASCII Interface
- The memory (1716 bytes) needed can be separated as follows:
513 bytes - buffer space for RX/TX in Modbus
513 bytes - buffer space for handling the RX FIFO buffer by the interface layer
513 bytes - buffer space for handling the TX FIFO buffer by the interface layer
197 bytes - other configuration related memory
TCP Interface
- The memory (3232 bytes) needed can be separated as follows:
2600 bytes - buffer space for RX/TX in Modbus for 10 client connections
632 bytes - other configuration related memory
Modbus Server Header Details
Documentation from the relevant server header as follows:
Modbus server Module.
This file contains the APIs for using MODBUS server feature
- Author
Embien RAPIDSEA Team
- Copyright
Embien Technologies India Pvt. Ltd.
Defines
-
RS_MODBUS_ERROR_INVALID_FUNCTION
Modbus error codes.
-
RS_MODBUS_ERROR_INVALID_DATA_ADDR
-
RS_MODBUS_ERROR_INVALID_VALUE
-
RS_MODBUS_ERROR_SLAVE_DEVICE_FAILURE
-
RS_MODBUS_ERROR_TIMEOUT
-
RS_MODBUS_ERROR_SLAVE_DEVICE_BC
-
RS_MODBUS_ERROR_PARITY
-
RS_MODBUS_COMM_TYPE_RTU
Modbus Communication Type (RTU, ASCII and TCP)
-
RS_MODBUS_COMM_TYPE_ASCII
-
RS_MODBUS_COMM_TYPE_TCP_IP
-
RS_TRANSPORT_INTERFACE_ADDR_LEN
Modbus server transport interface(RTU/TCP) address length.
-
RS_MODBUS_ASCII_BUF_MAX_LEN
Maximum buffer length - ASCII mode.
-
RS_MODBUS_RTU_BUF_MAX_LEN
Maximum buffer length - RTU mode.
-
RS_MODBUS_TCP_BUF_MAX_LEN
Maximum buffer length - TCP Mode.
-
RS_MODBUS_ASCII_FIFO_BUF_MAX_LEN
Maximum FIFO buffer length - ASCII mode.
-
RS_MODBUS_RTU_FIFO_BUF_MAX_LEN
Maximum FIFO buffer length - RTU mode.
-
RS_MODBUS_MAX_NUM_OF_CLIENT
Typedefs
-
typedef struct tag_rs_modbus_server_config rs_modbus_server_config_t
Contains information about server configuration.
-
typedef struct tag_rs_modbus_server_instance rs_modbus_server_instance_t
Contains information about server.
-
typedef struct tag_rs_modbus_rtu_server_instance rs_modbus_rtu_server_instance_t
Contains information about RTU server.
-
typedef struct tag_rs_modbus_ascii_server_instance rs_modbus_ascii_server_instance_t
Contains information about ASCII server.
-
typedef struct tag_rs_modbus_tcp_conn_instance rs_modbus_tcp_conn_instance_t
-
typedef struct tag_rs_modbus_tcp_server_instance rs_modbus_tcp_server_instance_t
Contains information about TCP server.
Functions
-
rs_handle_t rs_modbus_server_open(rs_modbus_server_instance_t *ptr_instance, rs_modbus_server_config_t *ptr_config)
-
rs_ret_val_t rs_modbus_server_process(rs_handle_t handle)
Perform maintenance process on the Modbus Server instance.
This function handles the Modbus server process functionality such as state machine etc. Must be called periodically
- Parameters:
handle – [in] - Handle to the Modbus server
- Returns:
Zero on success or error code on failure
-
rs_ret_val_t rs_modbus_server_tcp_comm_handler(rs_handle_t handle)
Perform maintenance TCP communication and client connection process on the Modbus Server instance.
This function handles the Modbus TCP communication and client connection process functionality such as state machine etc. Must be called periodically
- Parameters:
handle – [in] - Handle to the Modbus server
- Returns:
Zero on success or error code on failure
-
rs_ret_val_t rs_modbus_server_reconfig(rs_handle_t handle)
Re-configures the Modbus server instance.
This function reconfigure the Modbus server as per the latest configuration
- Parameters:
handle – [in] - Handle to the Modbus server
- Returns:
Zero on success or error code on failure
-
rs_ret_val_t rs_modbus_server_run(rs_handle_t handle, uint32_t u32_run)
Starts or Stops the Modbus server.
This function starts the Modbus server or stop it based on the input arguments. Though the instance will be running, it will be in idle state without attempting to input data from clients
- Parameters:
handle – [in] - Handle to the Modbus server
u32_run – [in] - Start or Stop state requested.
- Returns:
Zero on success or error code on failure
-
rs_ret_val_t rcb_mb_set_coil_status_value(rs_handle_t handle, uint16_t u16_reg_addr, uint8_t *ptr_reg_value)
Set the coil register value.
This function, to be implemented by the business logic is used to set the coil register value based on client request
- Parameters:
handle – [in] - Handle to the Modbus server
u16_reg_addr – [in] - Server register address
ptr_reg_value – [out] - Pointer to the value
- Returns:
0 on success or error code
-
rs_ret_val_t rcb_mb_get_discrete_input_value(rs_handle_t handle, uint16_t u16_reg_addr, uint8_t *ptr_reg_value)
Get the discrete register value.
This function, to be implemented by the business logic is used to get the discrete register value based on client request
- Parameters:
handle – [in] - Handle to the Modbus server
u16_reg_addr – [in] - Server register address
ptr_reg_value – [out] - Pointer to the value
- Returns:
0 on success or error code
-
rs_ret_val_t rcb_mb_get_coil_status_value(rs_handle_t handle, uint16_t u16_reg_addr, uint8_t *ptr_reg_value)
Get the coil register value.
This function, to be implemented by the business logic is used to get the coils register value
- Parameters:
handle – [in] - Handle to the Modbus server
u16_reg_addr – [in] - Server register address
ptr_reg_value – [out] - Pointer to the value
- Returns:
0 on success or error code
-
rs_ret_val_t rcb_mb_set_holding_register(rs_handle_t handle, uint16_t u16_reg_addr, uint16_t *ptr_reg_value)
Sets the holding register value.
This function, to be implemented by the business logic is used to set the holding register value
- Parameters:
handle – [in] - Handle to the Modbus server
u16_reg_addr – [in] - Server register address
ptr_reg_value – [out] - Pointer to the value
- Returns:
0 on success or error code
-
rs_ret_val_t rcb_mb_get_input_register_value(rs_handle_t handle, uint16_t u16_reg_addr, uint16_t *ptr_reg_value)
Gets the input register value.
This function, to be implemented by the business logic is used to get the input register value
- Parameters:
handle – [in] - Handle to the Modbus server
u16_reg_addr – [in] - Server register address
ptr_reg_value – [out] - Pointer to the value
- Returns:
0 on success or error code
-
rs_ret_val_t rcb_mb_get_holding_reg_val(rs_handle_t handle, uint16_t u16_reg_addr, uint16_t *ptr_reg_value)
Gets the holding register value.
This function, to be implemented by the business logic is used to get the holding register value
- Parameters:
handle – [in] - Handle to the Modbus server
u16_reg_addr – [in] - Server register address
ptr_reg_value – [out] - Pointer to the value
- Returns:
0 on success or error code
-
rs_ret_val_t rcb_mb_handle_custom_request(rs_handle_t handle, uint8_t *ptr_buff)
Callback for handling custom request.
This function, to be implemented by the business logic is used to handle the request
- Parameters:
handle – [in] - Handle to the Modbus server
ptr_buff – [out] - Pointer to the buffer
- Returns:
0 on success or error code
-
struct tag_rs_modbus_server_config
- #include <rs_modbus_server.h>
Contains information about server configuration.
Public Members
-
uint8_t server_id
Slave address.
-
uint8_t comm_type
RTU / ASCII / TCP/IP.
-
uint8_t addr[RS_TRANSPORT_INTERFACE_ADDR_LEN]
IP Address or serial port name.
-
uint8_t parity
Parity for serial mode.
-
uint8_t flow_ctrl
Flow Control settings.
-
uint8_t data_length
Data length.
-
uint8_t stop_bits
Stop bits.
-
uint16_t port
Server Port number for TCP IP.
-
uint32_t baud_rate
Baud Rate for serial mode.
-
uint16_t num_conn_accept
Number of connections to accept for TCP.
-
rs_handle_t comm_handle
Transport interface handle (RTU/TCP)
-
rs_handle_t accept_handle
Modbus socket accept handle.
-
uint8_t server_id
-
struct tag_rs_modbus_server_instance
- #include <rs_modbus_server.h>
Contains information about server.
Public Members
-
rs_modbus_server_config_t *ptr_config
Pointer to containing server configuration.
-
void *ptr_user_data
Pointer to user data by flint.
-
rs_handle_t transport_handle
Handle to the Modbus server interface (RTU/TCP)
-
uint32_t data_len
Data length of RX/TX packet.
-
uint8_t state
Modbus server process state.
-
uint8_t run_state
Modbus server run state.
-
uint8_t reconfigure
Modbus server reconfiguration flag.
-
uint32_t comm_time_out
Modbus server timeout for RX/TX.
-
uint8_t *ptr_buff
Pointer to the buffer for RX/TX.
-
uint16_t buf_len
Buffer length for RX/TX.
-
rs_handle_t modbus_handle
Handle to the Modbus server interface visible to the user.
-
rs_modbus_server_config_t *ptr_config
-
struct tag_rs_modbus_rtu_server_instance
- #include <rs_modbus_server.h>
Contains information about RTU server.
Public Members
-
rs_modbus_server_instance_t server_instance
Common server instance(Information)
-
rs_serial_config_t rtu_serial_config
RTU serial configuration.
-
rs_serial_instance_t rtu_serial_instance
RTU serial instance(Information)
-
uint8_t buff[RS_MODBUS_RTU_BUF_MAX_LEN]
RTU data buffer of RX/TX.
-
uint8_t tx_fifo[RS_MODBUS_RTU_FIFO_BUF_MAX_LEN]
RTU FIFO data buffer of TX.
-
uint8_t rx_fifo[RS_MODBUS_RTU_FIFO_BUF_MAX_LEN]
RTU FIFO data buffer of RX.
-
rs_modbus_server_instance_t server_instance
-
struct tag_rs_modbus_ascii_server_instance
- #include <rs_modbus_server.h>
Contains information about ASCII server.
Public Members
-
rs_modbus_server_instance_t server_instance
Common server instance(Information)
-
rs_serial_config_t ascii_serial_config
ASCII serial configuration.
-
rs_serial_instance_t ascii_serial_instance
ASCII serial instance(Information)
-
uint8_t buff[RS_MODBUS_ASCII_BUF_MAX_LEN]
ASCII data buffer of RX/TX.
-
uint8_t tx_fifo[RS_MODBUS_ASCII_FIFO_BUF_MAX_LEN]
ASCII FIFO data buffer of TX.
-
uint8_t rx_fifo[RS_MODBUS_ASCII_FIFO_BUF_MAX_LEN]
ASCII FIFO data buffer of RX.
-
rs_modbus_server_instance_t server_instance
-
struct tag_rs_modbus_tcp_conn_instance
Public Members
-
rs_modbus_server_instance_t server_instance
Common server instance(Information)
-
uint8_t buff[RS_MODBUS_TCP_BUF_MAX_LEN]
TCP data buffer of RX/TX.
-
rs_handle_t client_handle
Handle to the Modbus connection instance per client connection.
-
rs_modbus_server_instance_t server_instance
-
struct tag_rs_modbus_tcp_server_instance
- #include <rs_modbus_server.h>
Contains information about TCP server.
Public Members
-
rs_modbus_server_instance_t server_instance
Common server instance(Information)
-
rs_socket_config_t tcp_socket_config
TCP socket configuration.
-
rs_tcp_server_instance_t tcp_socket_instance
TCP socket instance(Information)
-
uint32_t num_of_clients
Number of client connection available.
-
rs_modbus_tcp_conn_instance_t client_inst[RS_MODBUS_MAX_NUM_OF_CLIENT]
TCP connection instance.
-
rs_modbus_server_instance_t server_instance