Modbus Client 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 Client

RAPIDSEA implements Modbus client where different types of requests such as READ_HOLDING, WRITE_INPUT etc can be orginated to the server address configured.

Supported Functionalities

Following services are supported in the Modbus Stack

Supported Functionalities

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 client stack can handle most of the functionality such as server response validation, validate client request formation, once submit the request, properly release the given request,etc. The RAPIDSEA Modbus client 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.

The below table contains API calls to perform the client stack.

API Functions

Function

Description

rs_modbus_client_open

To Initialize the serial/socket configuration.

rs_modbus_client_run

To set the state to be open

rs_modbus_client_process

To be called periodically to process the request.

rs_modbus_client_get_free_req

To get a free available request from Modbus channel.

rs_modbus_client_submit_req

To submit the given request for the given channel.

rs_modbus_client_is_req_done

To return the current status of the given request.

rs_modbus_client_put_req

To release the given request for further use.

rs_modbus_client_reconfig

To restart the client application by reconfiguring modbus client.

rs_modbus_client_close

To close the Modbus client.

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 client init to start the Modbus stack.

  • Then client task state is in idle condition, until Modbus client start.

  • Modbus client start change the state from idle to state open.

  • In Modbus client process, initially get the free available request from the Modbus channel by giving the Modbus handle.

  • Modbus client process called periodically to form the client request.

  • Once form the request, Submit the given request to the given channel.

  • Properly release the given request for further use.

The below diagram captures the high level sequence of operations associated with the Modbus client RTU

Modbus Sequence Diagram

High level state machine of modbus client is depicted below

Modbus State Machine

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)

To establish protocol communication, this represents data in a binary format and is mostly utilized in internet communication. The messages in this version are divided by idle periods. The format that is followed in the TCP version is a longitudinal redundancy check to verify mechanism and this makes sure of data reliability.

Socket communication header details refer to the socket interface page for more details Socket Interface

Modbus Client Header Details

Documentation from the relevant client header as follows:

Modbus Client Module.

This file contains the APIs for using MODBUS client feature

Author

Embien RAPIDSEA Team

Copyright

Embien Technologies India Pvt. Ltd.

Defines

RS_MODBUS_REQ_TYPE_READ_COILS

Modbus Request Types.

RS_MODBUS_REQ_TYPE_READ_DISCRETE_INPUT
RS_MODBUS_REQ_TYPE_READ_HOLDING_REGISTERS
RS_MODBUS_REQ_TYPE_READ_INPUT_REGISTERS
RS_MODBUS_REQ_TYPE_WRITE_SINGLE_COIL
RS_MODBUS_REQ_TYPE_WRITE_SINGLE_REGISTER
RS_MODBUS_REQ_TYPE_WRITE_MULTIPLE_COILS
RS_MODBUS_REQ_TYPE_WRITE_MULTIPLE_REGISTERS
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 client 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.

Typedefs

typedef struct tag_rs_modbus_client_req rs_modbus_client_req_t

Contains information about client request.

typedef struct tag_rs_modbus_client_config rs_modbus_client_config_t

Contains information about client configuration.

typedef struct tag_rs_modbus_client_instance rs_modbus_client_instance_t

Contains information about client.

typedef struct tag_rs_modbus_rtu_client_instance rs_modbus_rtu_client_instance_t

Contains information about rtu client.

typedef struct tag_rs_modbus_ascii_client_instance rs_modbus_ascii_client_instance_t

Contains information about ASCII client.

typedef struct tag_rs_modbus_client_info rs_modbus_tcp_client_instance_t

Contains information about TCP client.

Functions

rs_handle_t rs_modbus_client_open(rs_modbus_client_instance_t *ptr_instance, rs_modbus_client_config_t *ptr_config)

Initializes the Modbus client Channel for further communication.

This function opens the underlying communication channel and prepares it for further communication with the salve

Parameters:
  • ptr_instance[in] - Pointer to the Modbus client run time data

  • ptr_config[in] - Pointer to the Modbus client configuration information

Returns:

Handle on success or negative error code

rs_ret_val_t rs_modbus_client_process(rs_handle_t handle)

Perform maintenance process on the Modbus client instance.

This function handles the Modbus client process functionality such as state machine etc. Must be called periodically

Parameters:

handle[in] - Handle to the Modbus client

Returns:

Zero on success or error code on failure

rs_ret_val_t rs_modbus_client_reconfig(rs_handle_t handle)

Re-configures the Modbus client instance.

This function reconfigure the Modbus client as per the latest configuration

Parameters:

handle[in] - Handle to the Modbus client

Returns:

Zero on success or error code on failure

rs_ret_val_t rs_modbus_client_run(rs_handle_t handle, uint32_t u32_run)

Starts or Stops the Modbus client.

This function starts the Modbus client or stop it based on the input arguments.

Parameters:
  • handle[in] - Handle to the Modbus client

  • u32_run[in] - Start or Stop state requested.

Returns:

Zero on success or error code on failure

rs_modbus_client_req_t *rs_modbus_client_get_free_req(rs_handle_t handle)

Gets a free available request from Modbus channel.

This function returns a free request for the given channel if one is free. Must be released via rs_modbus_client_put_free_req

Parameters:

handle[in] - Handle to the Modbus client

Returns:

Pointer to a free request buffer or NULL if not available

rs_ret_val_t rs_modbus_client_submit_req(rs_handle_t handle, rs_modbus_client_req_t *ptr_mb_req)

Submits a request to given Modbus channel.

This function submits the given request for the given channel

Parameters:
  • handle[in] - Handle to the Modbus client

  • ptr_mb_req[in] - Pointer to request to be processed

Returns:

0 on success or error code

rs_ret_val_t rs_modbus_client_is_req_done(rs_handle_t handle, rs_modbus_client_req_t *ptr_mb_req)

Checks the status of the given request.

This function returns the current status of the given request

Parameters:
  • handle[in] - Handle to the Modbus client

  • ptr_mb_req[in] - Pointer to request to be processed

Returns:

RS_ERR_OK if processed without error, RS_ERR_BUSY if still processing or error code of the request handling

rs_ret_val_t rs_modbus_client_put_req(rs_handle_t handle, rs_modbus_client_req_t *ptr_mb_req)

Releases the given request for further use.

This function releases the given request

Parameters:
  • handle[in] - Handle to the Modbus client

  • ptr_mb_req[in] - Pointer to request to be processed

Returns:

0 on success or error code

struct tag_rs_modbus_client_req
#include <rs_modbus_client.h>

Contains information about client request.

Public Members

uint8_t slave_id

Modbus slave id.

uint8_t req_type

Request command type - read holding/write holding.

uint16_t address

Starting address.

uint16_t num_reg

Number of registers to be read/written.

uint8_t request

Request Command.

int8_t status

Response Status. Positive value to process 0 & negative for response result.

void *ptr_value

Pointer to values to be read/written.

struct tag_rs_modbus_client_config
#include <rs_modbus_client.h>

Contains information about client configuration.

Public Members

uint8_t comm_type

RTU vs ASCII vs TCP/IP.

uint16_t port

Server Port number for TCP IP.

uint8_t addr[RS_TRANSPORT_INTERFACE_ADDR_LEN]

IP Address or serial port name.

uint32_t baud_rate

Baud Rate for serial mode.

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 bit.

uint32_t slave_resp_timeout

Server response timeout.

rs_handle_t comm_handle

Transport interface handle (RTU/TCP)

struct tag_rs_modbus_client_instance
#include <rs_modbus_client.h>

Contains information about client.

Public Members

rs_modbus_client_config_t *ptr_config

Pointer to buffer containing client configuration.

rs_modbus_client_req_t *ptr_requests

Pointer to buffer containing client requests.

rs_modbus_client_req_t *ptr_active_request

Pointer to active request.

rs_handle_t transport_handle

Handle to the Modbus client interface (RTU/ASCII/TCP)

uint32_t data_len

Data length of RX/TX packet.

uint16_t num_req

Number of requests.

uint8_t state

Modbus client process state.

uint8_t run_state

Modbus client run state.

uint8_t reconfigure

Modbus client reconfiguration flag.

uint32_t comm_time_out

Modbus client timeout for RX/TX.

uint8_t *ptr_buff

Pointer to the buffer for RX/TX.

uint16_t buf_len

Buffer length for RX/TX.

uint16_t num_tx

Number of TX done.

uint16_t num_rx

Number of RX done.

uint32_t last_resp_time

Last slave response timeout.

int32_t req_read_index

Circular FIFO read index.

int32_t req_write_index

Circular FIFO write index.

struct tag_rs_modbus_rtu_client_instance
#include <rs_modbus_client.h>

Contains information about rtu client.

Public Members

rs_modbus_client_instance_t client_instance

Common client 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.

struct tag_rs_modbus_ascii_client_instance
#include <rs_modbus_client.h>

Contains information about ASCII client.

Public Members

rs_modbus_client_instance_t client_instance

Common client 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.

struct tag_rs_modbus_client_info
#include <rs_modbus_client.h>

Contains information about TCP client.

Public Members

rs_modbus_client_instance_t client_instance

Common client instance(Information)

rs_socket_config_t tcp_socket_config

TCP socket configuration.

rs_tcp_conn_instance_t tcp_socket_instance

TCP socket instance(Information)

uint8_t buff[RS_MODBUS_TCP_BUF_MAX_LEN]

TCP data buffer of RX/TX.