Files
ModTOS/README.md
2025-11-24 06:00:43 +00:00

111 lines
3.1 KiB
Markdown

# ModTOS
**Modbus RTU Driver for STM32 + FreeRTOS**
*Interrupt driven frame handling with RS485 GPIO direction control*
---
## Overview
**ModTOS** is a lightweight dependency free Modbus RTU slave implementation designed for STM32 microcontrollers running FreeRTOS. It acts as a cooperative background task minimizing CPU load and avoiding interference with timing critical logic.
The driver leverages **UART interrupt with idle line detection** to capture Modbus RTU frames without polling. RS485 direction is controlled via GPIO enabling half duplex communication commonly found in industrial systems.
ModTOS exposes a flat holding register table accessible through standard Modbus function codes `0x03` Read Holding Registers and `0x10` Write Multiple Holding Registers.
---
## Features
- Modbus RTU Slave one unit ID per UART
- **Function Code 0x03** Read Holding Registers
- **Function Code 0x10** Write Multiple Holding Registers
- CRC 16 Modbus validation on all frames
- Modbus Exception Handling:
- `0x01` ILLEGAL_FUNCTION
- `0x02` ILLEGAL_DATA_ADDRESS
- `0x03` ILLEGAL_DATA_VALUE
- Flat register buffer 128 x uint16_t
- Task based integration with FreeRTOS
- Zero dynamic memory allocation
- Uses **UART Receive to Idle** mode no polling
- Portable to bare metal & polling environments with minimal changes
---
## High Level Design
### 1 Global Modbus Register Table
- Represents Modbus holding registers starting at address 0
- Accessible directly by application code or via Modbus transactions
### 2 UART RX & TX Buffers
- `request_frame` holds raw Modbus RTU request bytes
- `response_frame` used to construct replies
- Both statically sized for worst case message sizes
### 3 RS485 Direction Control
- DE and RE pin sets transceiver mode:
- **RX default**
- **TX only during response transmission**
---
## Execution Flow
### 1 Initialization
- Clears buffers
- Sets RS485 to **RX mode**
- Enables UART in **idle line receive** mode
### 2 Receiving a Frame
- UART receives bytes into `request_frame`
- Idle line detection triggers reception complete callback
- Application must implement callback to forward the frame for parsing
### 3 Processing the Request
- Frame validation:
- Minimum length
- Slave ID match
- CRC 16 check
- Dispatch to appropriate handler:
- `0x03` Read holding registers
- `0x10` Write multiple holding registers
- Others Modbus exception
---
## Function Code Handlers
### FC 0x03 Read Holding Registers
- Parses `startAddr` and `numRegs`
- Validates bounds
- Builds response:
- Slave ID
- Function code
- Byte count
- Register values High byte Low byte per register
- CRC
### FC 0x10 Write Multiple Holding Registers
- Parses `startAddr` `numRegs` and `byteCount`
- Validates range and byte consistency
- Writes values to register table
- Responds with echo:
- Slave ID
- Function code
- Start address
- Quantity
---
## Response Transmission
- Appends CRC to `response_frame`
- Sets RS485 to **TX mode**
- Sends frame via **blocking UART**
- Switches RS485 back to **RX mode**
- TX timeout currently fixed at **100 ms**
---