Page 1 of 1

Messages delay in tx and rx on one can with PCAN Router FD

Posted: Mon 7. Apr 2025, 15:18
by saikoniki
Hello,

I have developed an application for PCAN Router FD. I have six messages with following cycle times.
Rx from CAN2 on PCAN Router:
Message 1: 10ms
Message 2: 100ms
Message 3: 500ms

Tx to CAN1 on PCAN Router:
Message 1: 2ms
Message 2: 100ms
Message 3: 500ms

Technically, I am receiving 10ms message and convert it to 2ms message and send it to CAN1.
I am seeing 2 second to 5 second delay on hardware connected to CAN1 (Baudrate: 500kbps).

Not sure what's causing the delay, I also have attached a source code below. Please help me out if I can remove the delay.

Code: Select all

#include <stdint.h>
#include "ARMCM4_FP.h"
#include "can.h"
#include "can_user.h"
#include "hardware.h"
#include "lpc407x_8x_177x_8x.h"
#include "systime.h"

#define VEHICLE_CAN_BUS 	0		// CAN_BUS_1
#define ACTUATOR_CAN_BUS 	1		// CAN_BUS_2

#define DIAG_ENABLE 0

// identifier is needed by PEAK-Flash.exe -> do not delete
const char Ident[] __attribute__ ((used)) = { "PCAN-Router_FD"};


// Defining Cyclic Messages
#define	MSG_10_PERIOD_US		2000
#define	MSG_100_PERIOD_US		100000
#define	MSG_300_PERIOD_US		500000
#define	MSG_1C_PERIOD_US		10000
#define	MSG_104_PERIOD_US		100000
#define	MSG_22_PERIOD_US		500000

// variables for LED toggle
static uint8_t LED_toggleCAN1;
static uint8_t LED_toggleCAN2;

static SYSTIME_t  timenow;

// variables for cyclic message transmission
static SYSTIME_t  Msg_10_LastCycleMsg;
static SYSTIME_t  Msg_1C_LastCycleMsg;
static SYSTIME_t  Msg_104_LastCycleMsg;
static SYSTIME_t  Msg_22_LastCycleMsg;

static CANTxMsg_t  MSG_10_CycleMsg;
static CANTxMsg_t  MSG_1C_CycleMsg;
static CANTxMsg_t  MSG_104_CycleMsg;
static CANTxMsg_t  MSG_22_CycleMsg;

static uint8_t msg_10_data8_1 = 0x00;
static uint8_t msg_10_data8_2 = 0x00;
static uint8_t msg_10_data8_3 = 0x00;
static uint8_t msg_10_data8_4 = 0x00;
static uint8_t msg_10_data8_5 = 0x00;
static uint8_t msg_10_data8_6 = 0x00;
static uint8_t msg_10_data8_7 = 0x00;

static uint32_t msg_1C_data32_0 = 0x00;
static uint32_t msg_1C_data32_1 = 0x00;

static uint32_t msg_104_data32_0 = 0x00;
static uint32_t msg_104_data32_1 = 0x00;

static uint32_t msg_22_data32_0 = 0x00;
static uint32_t msg_22_data32_1 = 0x00;



static uint8_t calculate_checksum(uint8_t chks, uint8_t pl_byte)
{
	return 0;
}



// main()
// entry point from startup
int  main ( void)
{
	// init hardware and timer 0. Timer 0 is free running
	// with 1 us resolution without any IRQ.
	HW_Init();
	
	// init CAN
	CAN_UserInit();
	
	// set green LEDs for CAN1 and CAN2
	HW_SetLED ( HW_LED_CAN1, HW_LED_GREEN);
	HW_SetLED ( HW_LED_CAN2, HW_LED_GREEN);
	
	// configure the Message 10 cyclic message
	MSG_10_CycleMsg.bufftype = CAN_BUFFER_TX_MSG;
	MSG_10_CycleMsg.id = 0x10;
	MSG_10_CycleMsg.dlc = CAN_LEN8_DLC;
	MSG_10_CycleMsg.msgtype = CAN_MSGTYPE_STANDARD;
	MSG_10_CycleMsg.data16[0] = 0;
	MSG_10_CycleMsg.data16[1] = 0;
	MSG_10_CycleMsg.data16[2] = 0;
	MSG_10_CycleMsg.data16[3] = 0;

	// configure the Message 1C cyclic message
	MSG_1C_CycleMsg.bufftype = CAN_BUFFER_TX_MSG;
	MSG_1C_CycleMsg.id = 0x1C;
	MSG_1C_CycleMsg.dlc = CAN_LEN8_DLC;
	MSG_1C_CycleMsg.msgtype = CAN_MSGTYPE_STANDARD;
	MSG_1C_CycleMsg.data32[0] = 0;
	MSG_1C_CycleMsg.data32[1] = 0;


	// configure the Message 104 cyclic message
	MSG_104_CycleMsg.bufftype = CAN_BUFFER_TX_MSG;
	MSG_104_CycleMsg.id = 0x104;
	MSG_104_CycleMsg.dlc = CAN_LEN8_DLC;
	MSG_104_CycleMsg.msgtype = CAN_MSGTYPE_STANDARD;
	MSG_104_CycleMsg.data32[0] = 0;
	MSG_104_CycleMsg.data32[1] = 0;

	// configure the Message 22 cyclic message
	MSG_22_CycleMsg.bufftype = CAN_BUFFER_TX_MSG;
	MSG_22_CycleMsg.id = 0x22;
	MSG_22_CycleMsg.dlc = CAN_LEN8_DLC;
	MSG_22_CycleMsg.msgtype = CAN_MSGTYPE_STANDARD;
	MSG_22_CycleMsg.data32[0] = 0;
	MSG_22_CycleMsg.data32[1] = 0;

	Msg_10_LastCycleMsg = SYSTIME_NOW;
	Msg_1C_LastCycleMsg = SYSTIME_NOW;
	Msg_104_LastCycleMsg = SYSTIME_NOW;
	Msg_22_LastCycleMsg = SYSTIME_NOW;

	// main loop
	while ( 1)
	{
		CANRxMsg_t  RxMsg;

		// process messages from CAN1
		if ( CAN_UserRead ( VEHICLE_CAN_BUS, &RxMsg) == CAN_ERR_OK)
		{
			// message received from CAN1
			LED_toggleCAN1 ^= 1;

			if ( LED_toggleCAN1)
			{
				HW_SetLED ( HW_LED_CAN1, HW_LED_ORANGE);
			}
			
			else
			{
				HW_SetLED ( HW_LED_CAN1, HW_LED_GREEN);
			}
			
			if (RxMsg.id == 0x100 && RxMsg.msgtype == CAN_MSGTYPE_STANDARD)
			{
				
				CAN_Write(ACTUATOR_CAN_BUS, &RxMsg);
			}
			else if (RxMsg.id == 0x300 && RxMsg.msgtype == CAN_MSGTYPE_STANDARD)
			{
				CAN_Write(ACTUATOR_CAN_BUS, &RxMsg);
			}

		}
			
		// process messages from CAN2
		if ( CAN_UserRead ( ACTUATOR_CAN_BUS, &RxMsg) == CAN_ERR_OK)
		{
			// message received from CAN2
			LED_toggleCAN2 ^= 1;

			if ( LED_toggleCAN2)
			{
				HW_SetLED ( HW_LED_CAN2, HW_LED_ORANGE);
			}
			
			else
			{
				HW_SetLED ( HW_LED_CAN2, HW_LED_GREEN);
			}

		}
		
		timenow = SYSTIME_NOW;
		if (SYSTIME_DIFF ( Msg_10_LastCycleMsg, timenow) >= MSG_10_PERIOD_US)
		{
			CAN_UserRead ( VEHICLE_CAN_BUS, &RxMsg);
			Msg_10_LastCycleMsg += MSG_10_PERIOD_US;
			if (RxMsg.id == 0x14 && RxMsg.msgtype == CAN_MSGTYPE_STANDARD)
			{
				msg_10_data8_1 = (RxMsg.data8[1] >> 4) & 0x0F;
				msg_10_data8_2 = RxMsg.data8[2];
				msg_10_data8_3 = RxMsg.data8[3];
				msg_10_data8_4 = RxMsg.data8[4];
				msg_10_data8_5 = RxMsg.data8[5];
				msg_10_data8_6 = RxMsg.data8[6];
				msg_10_data8_7 = RxMsg.data8[7];
			}
			

			MSG_10_CycleMsg.data8[0] = 0;
			
			MSG_10_CycleMsg.data8[2] = msg_10_data8_2;
			MSG_10_CycleMsg.data8[3] = msg_10_data8_3;
			MSG_10_CycleMsg.data8[4] = msg_10_data8_4;
			MSG_10_CycleMsg.data8[5] = msg_10_data8_5;
			MSG_10_CycleMsg.data8[6] = msg_10_data8_6;
			MSG_10_CycleMsg.data8[7] = msg_10_data8_7;

			CAN_Write(ACTUATOR_CAN_BUS, &MSG_10_CycleMsg);
		}		
		
		if (SYSTIME_DIFF ( Msg_1C_LastCycleMsg, timenow) >= MSG_1C_PERIOD_US)
		{
			CAN_UserRead ( ACTUATOR_CAN_BUS, &RxMsg);
			Msg_1C_LastCycleMsg += MSG_1C_PERIOD_US;
			if (RxMsg.id == 0x16 && RxMsg.msgtype == CAN_MSGTYPE_STANDARD)
			{
				msg_1C_data32_0 = RxMsg.data32[0];
				msg_1C_data32_1 = RxMsg.data32[1];

			}
			MSG_1C_CycleMsg.data32[0]	= msg_1C_data32_0;
			MSG_1C_CycleMsg.data32[1]	= msg_1C_data32_1;
			CAN_Write(VEHICLE_CAN_BUS, &MSG_1C_CycleMsg);
		}		

		if (SYSTIME_DIFF ( Msg_104_LastCycleMsg, timenow) >= MSG_104_PERIOD_US)
		{
			CAN_UserRead ( ACTUATOR_CAN_BUS, &RxMsg);
			Msg_104_LastCycleMsg += MSG_104_PERIOD_US;
			if (RxMsg.id == 0x102 && RxMsg.msgtype == CAN_MSGTYPE_STANDARD)
			{
				msg_104_data32_0 = RxMsg.data32[0];
				msg_104_data32_1 = RxMsg.data32[1];

			}
			MSG_104_CycleMsg.data32[0]	= msg_104_data32_0;
			MSG_104_CycleMsg.data32[1]	= msg_104_data32_1;
			CAN_Write(VEHICLE_CAN_BUS, &MSG_104_CycleMsg);
		}	

		if (SYSTIME_DIFF ( Msg_22_LastCycleMsg, timenow) >= MSG_22_PERIOD_US)
		{
			CAN_UserRead ( ACTUATOR_CAN_BUS, &RxMsg);
			Msg_22_LastCycleMsg += MSG_22_PERIOD_US;
			if (RxMsg.id == 0x20 && RxMsg.msgtype == CAN_MSGTYPE_STANDARD)
			{
				msg_22_data32_0 = RxMsg.data32[0];
				msg_22_data32_1 = RxMsg.data32[1];

			}
			MSG_22_CycleMsg.data32[0]	= msg_22_data32_0;
			MSG_22_CycleMsg.data32[1]	= msg_22_data32_1;
			CAN_Write(VEHICLE_CAN_BUS, &MSG_22_CycleMsg);
		}	
	}
}
Best Regards.
sai.

Re: Messages delay in tx and rx on one can with PCAN Router FD

Posted: Mon 7. Apr 2025, 16:15
by M.Maidhof
Hi,

please check you code again. You call "CAN_UserRead ( VEHICLE_CAN_BUS, &RxMsg)" without checking the return value. This is not a good idea. What is the reason for this?

regards

Michael

Re: Messages delay in tx and rx on one can with PCAN Router FD

Posted: Mon 7. Apr 2025, 17:56
by saikoniki
Hi,

I am trying to read the message from VEHICLE_CAN_BUS at cycle time.

best Regards,
Sai.

Re: Messages delay in tx and rx on one can with PCAN Router FD

Posted: Mon 7. Apr 2025, 19:51
by saikoniki
My assumption is that CAN communication is working, that's why I did not compare if it has any error or not. Actually, my application is working perfectly but it is slow.

Re: Messages delay in tx and rx on one can with PCAN Router FD

Posted: Tue 8. Apr 2025, 08:27
by M.Maidhof
Hi,

yes, because the logic in your code doesn't fit. Why do you call the CAN_UserRead again without checking if there was a message received or not?

regards

Michael

Re: Messages delay in tx and rx on one can with PCAN Router FD

Posted: Tue 8. Apr 2025, 21:53
by saikoniki
Ok. I will Modify it. Anything else I should be consider to remove the delay I am facing?

Re: Messages delay in tx and rx on one can with PCAN Router FD

Posted: Wed 9. Apr 2025, 10:08
by M.Maidhof
Hi,

start with the examples we provide in the PEAK-Dev package, and modify it step by step when you are unsure what the code does.

regards

Michael

Re: Messages delay in tx and rx on one can with PCAN Router FD

Posted: Wed 9. Apr 2025, 21:01
by saikoniki
I did that part, I took a timer example as a baseline and added couple of other timers and it is delaying now. That's why, I am looking for a solution if you have any example with multiple timers. Could you please share?

Re: Messages delay in tx and rx on one can with PCAN Router FD

Posted: Thu 10. Apr 2025, 16:18
by G.Bohlen
Hello,

if you call "CAN_UserRead()" you will get a received message from the receive fifo (or nothing if the fifo is empty). This message is then removed from the receive-fifo.
In your code you call

Code: Select all

CAN_UserRead ( VEHICLE_CAN_BUS, &RxMsg)

at the beginning of the main-loop, and again cyclic every 2000 us. This will not work, because one of the calls already removes that message from the receive-fifo.
Once you read a message, you need to process it, otherwise the message is lost.

Make sure you only use one CAN_UserRead() per bus in your firmware.
Hint for your application:
Store the databytes of the 10ms receive-message in some variables. Maybe verify that the reception every 10ms is working (remember last reception timestamp)
TX every 2ms:
- Use a cyclic timer of 2ms to transmit the message.
- Use the data from the variables above.
- Maybe check that the last receive time of the 10ms receive message is not too outdated (maybe not older than 15ms). Otherwise the 2ms message will be transmitted even if the receive-Message is not received anymore.

Regards,
Gunnar Bohlen