This example shows how to use the AUTOSAR CAN Driver on the FRDM-A-S32K118 to exchange CAN frames between two boards. One board sends frames periodically and the other receives them, with status reported on the LPUART console and signaled via the RGB LED.
This example was developed using the S32K1 Real-Time Drivers (RTD) package for S32 Design Studio. To download and install the complete software and tools ecosystem use the link below:
- S32 Design Studio for S32 Platform 3.6.5 or later.
- 2x FRDM-A-S32K118
- 2x USB Type-C cables (power supply and debug)
- 1x CAN bus cable (twisted-pair wire for CAN_H / CAN_L or DB9 connector cable)
- Connect each board to the PC with a Micro-USB cable for power and debug.
- Connect the CAN_H and CAN_L lines between the two boards through the CAN bus J12 connectors:

- Ensure proper bus termination (120 ohm at each physical end) to avoid reflections.
-
Open S32 Design Studio IDE, in the Dashboard Panel, choose Import project from Application Code Hub.
-
Search for the demo by name. Open the project, click the GitHub link from this window; S32 Design Studio IDE will automatically retrieve project attributes, then click Next>.
-
Select the main branch and click Next>.
-
Choose your local path in Destination -> Directory and click Next>.
-
Select Import existing Eclipse projects then click Next>.
-
Select the project and click Finish.
-
In Project Explorer, right-click the project and select Update Code and Build Project. This generates the RTD configuration (Pins, Clocks, Peripherals) and builds the project. Make sure the build completes and the
Press Yes in the SDK Component Management pop-up window to continue.*.elfis generated without errors. -
Go to Debug -> Debug Configurations. A configuration is provided for this project:
Configuration Name Description ------------------------------- ----------------------- $(example)_debug_flash_pemicro Debug the FLASH configuration using PEmicro probeSelect the configuration and click Debug to start the debug session. Use the toolbar controls to run, pause, or step through the program.
-
Open a serial terminal (e.g. Tera Term or PuTTY) on the COM port of each board:
- Baud rate: 115200
- Data bits: 8, Parity: None, Stop bits: 1, Flow control: None
-
Click Resume (F8) on both boards. The sender starts transmitting frames immediately.
Open src/main.c and locate the following line near the top of main():
boolean boardOne = FALSE;| Value | Board role | Behavior |
|---|---|---|
TRUE |
SENDER | Sends one CAN frame (ID 0x100) every 500 ms |
FALSE |
RECEIVER | Waits for incoming frames and logs them via UART |
Flash one board with boardOne = TRUE (sender) and the other with boardOne = FALSE (receiver).
Once both boards are powered and the CAN bus is connected, the following behavior is expected.
Sender board — one block of messages is printed every 500 ms:
[INIT] CAN initialized and started
[INIT] Board role: SENDER
[CAN TX] Sending ID=0x100 len=8 ...
[CAN TX] OK - frame confirmed
[CAN TX] Sending ID=0x100 len=8 ...
[CAN TX] OK - frame confirmed
Each transmission attempt prints the frame header before the write call.
After the FlexCAN driver confirms the frame was placed on the bus,
CanIf_TxConfirmation fires and prints the confirmation line.
Receiver board — one block of messages is printed per received frame:
[INIT] CAN initialized and started
[INIT] Board role: RECEIVER
[CAN RX] ID=0x100 len=8 data: 00 02 03 04 05 06 07 08
[CAN RX] ID=0x100 len=8 data: 01 02 03 04 05 06 07 08
[CAN RX] ID=0x100 len=8 data: 02 02 03 04 05 06 07 08
payload[0] is a rolling counter (0x00, 0x01, 0x02 ...) that increments on every frame,
making it easy to spot lost frames. The remaining seven bytes are static
(0x02 0x03 0x04 0x05 0x06 0x07 0x08).
Error condition — if a transmission is not acknowledged within the polling timeout:
[CAN TX] TIMEOUT - no confirmation received
Bus-Off event — if the FlexCAN controller enters Bus-Off state:
[CAN ERR] Bus-Off detected on controller
| LED color | Event |
|---|---|
| BLUE ON | Sender: CAN frame write submitted, waiting for Tx confirmation |
| BLUE OFF | Sender: CanIf_TxConfirmation received, frame is on the bus |
| GREEN ON | Receiver: new CAN frame received (CanIf_RxIndication) |
| GREEN OFF | Receiver: 200 ms visual flash completed, LED cleared in main loop |
| RED ON | Error: Tx polling timeout OR Bus-Off condition detected |
| Field | Value / Description |
|---|---|
| CAN ID | 0x100 (11-bit standard identifier) |
| DLC | 8 bytes |
| payload[0] | Rolling sequence counter (increments every frame) |
| payload[1..7] | Static pattern: 0x02 0x03 0x04 0x05 0x06 0x07 0x08 |
| Tx period | 500 ms |
| Rx LED flash | 200 ms |
The following module-level variables in can_app.c can be added as watch expressions in S32
Design Studio to monitor activity without additional instrumentation:
| Variable | Type | Description |
|---|---|---|
s_u8TxCount |
uint8 (static) |
Number of successfully confirmed Tx frames |
s_u8RxCount |
uint8 (static) |
Number of frames received via CanIf_RxIndication |
s_bTxDone |
volatile boolean (static) |
Current Tx confirmation flag state |
App_bNewRxFrame |
volatile boolean |
Set by ISR callback; cleared by the main loop |
App_RxCanId |
uint32 |
CAN ID of the last received frame |
App_RxLength |
uint8 |
DLC of the last received frame |
App_RxData[8] |
uint8[] |
Payload bytes of the last received frame |
For general technical questions related to NXP microcontrollers, please use the NXP Community Forum.
Questions regarding the content/correctness of this example can be entered as Issues within this GitHub repository.
Note: For more general technical questions regarding NXP Microcontrollers and the difference in expected functionality, enter your questions on the NXP Community Forum
| Version | Description / Update | Date |
|---|---|---|
| 1.0 | Initial release on Application Code Hub | September 21th 2026 |




