RT-LAB + QNX CAN Driver Design for PCM3680 (CAN 2.0B)
🚀 Introduction #
RT-LAB is a model-based real-time simulation platform widely used in aerospace, automotive, and defense systems. Its Host/Target architecture enables execution of Simulink models on real-time targets running QNX, supporting distributed simulation, rapid prototyping, and hardware-in-the-loop (HIL) testing.
Although RT-LAB provides support for many hardware platforms, custom device drivers are often required for specific boards. This article presents the design and implementation of a CAN 2.0B driver for the PCM3680 board, developed for a HIL simulation system.
The solution combines MATLAB/Simulink S-Functions on the host side with a low-level QNX driver on the target side.
🧩 RT-LAB Driver Architecture #
RT-LAB driver development follows a layered architecture:
Host Layer (MATLAB/Simulink) #
- Implements S-Functions to interface with simulation models
- Converts Simulink models into C code via RTW
- Provides a high-level abstraction for hardware interaction
Target Layer (QNX) #
- Handles direct hardware access
- Implements CAN communication, interrupts, and memory mapping
- Exposes APIs invoked by S-Functions
This separation ensures modularity, maintainability, and real-time determinism.
🖥️ PCM3680 Hardware Overview #
Hardware Composition #
The PCM3680 board includes:
- SJA1000 CAN controller
- 82C250 CAN transceiver
- Opto-isolation circuitry
- Address decoding logic
This architecture supports reliable CAN communication in embedded environments.
Address Mapping and Interrupt Configuration #
The board operates in memory-mapped mode:
- Address range:
0xC8000 – 0xEFFFF(ISA-compatible)
Register allocation:
0x00–0xFF: SJA1000 registers0x100–0x1FF: Write operations trigger hardware reset
Interrupt selection:
- IRQ3–7, IRQ9–12, IRQ15
- Configured via hardware jumpers
Proper address configuration is essential to avoid conflicts with other devices.
🔌 MATLAB S-Function Implementation #
Four S-Function modules encapsulate CAN functionality:
CAN Initialization Module #
- Initializes hardware and configuration
- Key functions:
canInitHW_c()canConfig_c()canNormalRun_c()
- Lifecycle managed via
mdlInitializeConditionsandmdlTerminate
CAN Send Module #
- Sends CAN messages cyclically
- Implemented in
mdlOutputs - Workflow:
- Populate
CANMSGstructure - Call
canSendMsg_c()
- Populate
CAN Receive Module #
- Receives CAN messages via polling
- Uses
canReceiveMsg_c() - Outputs structured data to Simulink
CAN External Interrupt Module #
- Handles interrupt-based reception
- Reads interrupt flags for synchronization
All S-Functions invoke corresponding APIs implemented in the QNX driver.
⚙️ QNX Low-Level Driver Design #
Core Data Structures #
typedef unsigned char BYTE;
typedef unsigned long UL;
typedef unsigned short UI;
typedef struct {
int sff;
BYTE id[4];
int rtr;
int dlen;
BYTE data[8];
} CANMSG;
typedef struct {
int filter_num;
BYTE acc_code[4];
BYTE acc_mask[4];
BYTE b0;
BYTE b1;
} CANCFG;
These structures define CAN messages and configuration parameters.
Key QNX System Interfaces #
mmap_device_memory()— maps hardware registers into process spaceInterruptAttach()— installs interrupt service routines- Low-level register access — controls SJA1000 controller
Driver Architecture #
The driver is organized into four logical components:
- CAN841Setup — initialization and configuration
- CAN841Send — message transmission
- CAN841Receive — message reception
- CAN841Sync — interrupt handling
This modular design improves maintainability and scalability.
Build and Deployment #
After implementation:
-
Compile under QNX
-
Generate:
can841_qnx.olibcan841_qnx.a
-
Deploy to target system (e.g.,
/usr/opalrt/RT_LAB/lib)
Ensure correct linkage with RT-LAB runtime libraries.
📊 Integration in HIL Systems #
The driver was deployed in a hardware-in-the-loop simulation system with the following results:
- Stable CAN communication under real-time constraints
- Reliable interrupt handling
- Seamless integration with Simulink models
This validates the design for complex real-time simulation environments.
🧠 Key Design Insights #
- Separation of S-Function and driver logic simplifies debugging
- Memory-mapped I/O improves performance
- Interrupt-driven design reduces latency
- Modular architecture enhances extensibility
These practices are broadly applicable to RT-LAB and QNX driver development.
✅ Conclusion #
This article demonstrates the complete development of a CAN 2.0B driver for the PCM3680 board using RT-LAB and QNX. By combining S-Function integration with a robust low-level driver, the system achieves reliable real-time performance in HIL environments.
The approach can be extended to other hardware platforms and communication interfaces, making it a practical reference for advanced embedded system development.
Reference: RT-LAB + QNX CAN Driver Design for PCM3680 (CAN 2.0B)