A lightweight MODBUS C library designed specifically for embedded systems.
The library completely separates the MODBUS protocol core from the transport layer, allowing the exact same core implementation to run seamlessly over different communication interfaces.
- MODBUS RTU
- MODBUS TCP
- Dual Mode: Supports both MODBUS Master and Slave.
- Transport Flexibility: Full MODBUS RTU and TCP support.
- Embedded Friendly: Zero dynamic memory allocation (
malloc). - Highly Portable: Compliant with the C99 standard.
- Customizable: Configurable function code support to optimize footprint size.
You can configure the operating mode as either Master or Slave inside mb.h or directly via compiler definitions.
Option 1: In mb.h file
#define MB_MODE MB_MODE_SLAVEOption 2: Via GCC compiler flag
gcc ... -DMB_MODE=MB_MODE_MASTERTo minimize code size, only one transport layer should be compiled at a time. The MODBUS core remains entirely agnostic of the underlying hardware interface.
mb-rtu.c– Handles serial communication.mb-tcp.c– Handles network communication.
Received UART bytes must be passed to the library byte-by-byte:
mb_rx_new_data(Byte);Since the library does not generate timeout events internally, your application must call the timeout handler whenever an RTU frame timeout occurs ( for reset rx buffer index if received packet was brok! ) :
mb_rx_timeout_handler();Received TCP frames must be passed as a complete data buffer:
mb_tcp_receive(buffer, length);Note: TCP does not require CRC checking or MODBUS timeout handling, as packet integrity is automatically managed by the TCP/IP stack.
You need to register the transport layer's transmit function so the core can send packets out:
mb_set_tx_handler(tx_function);Example Implementation:
void send_data(uint8_t *Data, uint16_t Len)
{
// Implementation: Send data through UART or TCP socket
}In Master mode, incoming packets are not processed automatically. You must register a response handler callback:
mb_set_master_process_handler(callback);Example Implementation:
void master_process(mb_packet_s Packet)
{
// Implementation: Process the received response from the slave
}| Category | File | Description |
|---|---|---|
| Common | mb.h |
Common configurations, definitions, and core data types. |
mb.c |
Core MODBUS protocol implementation. | |
mb-packet.c |
Packet creation, formatting, and parsing logic. | |
mb-crc.c |
CRC-16 calculation utilities. | |
| Transport | mb-rtu.c |
MODBUS RTU transport layer implementation. |
mb-tcp.c |
MODBUS TCP transport layer implementation. | |
| Slave Core | mb-check.c |
Validation and verification of received requests. |
mb-process.c |
Execution and processing of MODBUS function codes. | |
mb-table.c |
Slave register database maps. |
| Code | Function Name |
|---|---|
| 0x01 | Read Coils |
| 0x02 | Read Discrete Inputs |
| 0x03 | Read Holding Registers |
| 0x04 | Read Input Registers |
| 0x05 | Write Single Coil |
| 0x06 | Write Single Register |
| 0x07 | Read Exception Status |
| 0x0F | Write Multiple Coils |
| 0x10 | Write Multiple Registers |
| 0x17 | Read/Write Multiple Registers |
| 0x2B | Encapsulated Interface Transport |
To build all available test cases, navigate to the test directory and run make:
cd test
makeslave– MODBUS RTU Slave test application.master– MODBUS RTU Master test application.server– MODBUS TCP Slave test application.client– MODBUS TCP Master test application.
# Run Slave
make slave
# Run Master
make masterDefault TCP Port used: 1502
# Start the TCP Server
make server
./server
# In another terminal, start the TCP Client
make client
./client