|
NetBurner 3.5.7
PDF Version |
Example Path: examples/serial/SerialReceiveModbus
This NetBurner embedded application demonstrates the timing requirements for receiving Modbus RTU serial data. It uses a serial receive callback to timestamp each incoming byte and software-based idle detection to identify frame boundaries. The console output shows per-byte timing analysis with inter-character gap measurements and violation detection.
The application monitors a serial port configured for Modbus RTU communication (9600 baud, 8E1) and provides detailed timing analysis of each received frame, including:
Modbus RTU uses timing-based frame delimiting rather than special start/end characters:
The example uses a serial receive callback registered via UartData[].m_pPutCharFunc. This ISR-level callback:
StopWatch::GetTime() (sub-microsecond resolution)The main loop pends on the semaphore, then prints the complete frame with per-byte timing analysis.
The default serial port is selected automatically based on the platform:
Default: port 2 (UART0)
These platforms have two types of serial peripheral: USART (ports 0-1) and UART (ports 2-6). This example uses a UART port because USART ports use DMA for receive, which batches incoming bytes and prevents accurate per-byte timing measurement. UART ports at baud rates <= 230400 use per-byte RXRDY interrupts, giving true wire-level timestamps.
| Port | Peripheral | Notes |
|---|---|---|
| 0 | USART0 | Typically stdio. Uses DMA – not suitable for per-byte timing |
| 1 | USART1 | Uses DMA – not suitable for per-byte timing |
| 2 | UART0 | Default for this example |
| 3 | UART1 | |
| 4 | UART2 | |
| 5 | UART3 | |
| 6 | UART4 |
Default: port 1 (LPUART2)
All LPUART ports use per-byte receive interrupts, so any port works for accurate timing.
| Port | Peripheral | Notes |
|---|---|---|
| 0 | LPUART3 | Typically stdio |
| 1 | LPUART2 | Default for this example |
| 2 | LPUART4 | |
| 3-6 | LPUART5-8 |
Default: port 1 (LPUART2)
All LPUART ports use per-byte receive interrupts, so any port works for accurate timing.
| Port | Peripheral | Notes |
|---|---|---|
| 0 | LPUART1 | Typically stdio |
| 1 | LPUART2 | Default for this example |
| 2 | LPUART3 | |
| 3-10 | LPUART5-12 |
To change the port, modify the MODBUS_SERIAL_PORT define in main.cpp.
A test script (test_modbus_timing.py) is included that sends various valid and invalid Modbus RTU frames to exercise the timing analysis. It requires a USB-to-serial adapter connected to the selected port.
OpenSerial() – Opens the serial port with 8E1 Modbus RTU framingUartData[].m_pPutCharFunc – ISR-level receive callback registrationStopWatch – High-resolution timestamping (sub-microsecond resolution)