Speed while sending out CAN-signals

4-Channel CAN Router with Data Logger
ckessle2
Posts: 14
Joined: Wed 15. Mar 2017, 11:44

Speed while sending out CAN-signals

Post by ckessle2 » Mon 3. Apr 2017, 13:57

I have a four CAN Peak Router Pro and are using
two input (Chan1 and Chan2) channels with 132 Messages repeated every 50 ms (total of 20 x 132 Messages per second)
The load of Chan1 and Chan1 is around 85% per channel. All with 500kb/s CAN normal. no extended, no FD.

I want to extract half of the messages from each channel and combine in a third channel
The output load on Chan3 is around 65% with 138 messages every 50 ms.

It looks like the program is not fast enough to transport all channels from 1+2 to channel 3 (see code below).
The effect is that some signals have 100, 150, 250 millisec time difference instead of around 50 millisec. So some signals are just DROPPED.

My question: Is there a limitation on how much the processor can do?

Regards
C.

Code: Select all

int main ( void)
{
	HW_Init();
	CAN_UserInit();
	SYSTIME_Init();
	HW_SetLED ( HW_LED_CAN1, HW_LED_OFF);
	HW_SetLED ( HW_LED_CAN2, HW_LED_OFF);
	HW_SetLED ( HW_LED_CAN3, HW_LED_OFF);
	HW_SetLED ( HW_LED_CAN4, HW_LED_OFF);
	main_greeting();
	u32_t FakeRightScanIndex=0,FakeLeftScanIndex=0;
	//radar_initialize();
	u32_t timenow,timeRight=0,timeLeft=0;
	timenow = SYSTIME_NOW;  //u32_t
	while ( 1)
	{
		CANMsg_t  RxMsg, TxMsg;
		// process messages from CAN1
		if ( CAN_UserRead ( CAN_BUS1, &RxMsg) != 0)
		{
			if ( RxMsg.Id == 0x7E7  &&  RxMsg.Type == CAN_MSG_STANDARD) 
			{
				main_check_flashmode ( &RxMsg);
			} // this block must stay in CAN_BUS1
			if (RxMsg.Id >= 0x400 && RxMsg.Id <= 0x43F) // 
			{
				RxMsg.Id = RxMsg.Id + 0x200; // from 300 to 600
				CAN_UserWrite(CAN_BUS3, &RxMsg);
				if (RxMsg.Id == 0x63F )// 
				{ 
					RightDet64 = 1; 
					LED_toggleCAN1 ^= 1;
					if (LED_toggleCAN1)
					{
						HW_SetLED(HW_LED_CAN1, HW_LED_OFF);
					}
					else
					{
						HW_SetLED(HW_LED_CAN1, HW_LED_GREEN);
					}
				}
			}
			if (RxMsg.Id == 0x1C0 && RightDet64)  // send status
			{ 
				RightDet64 = 0;
				FakeRightScanIndex++;
				RxMsg.Id   = 0x4E0; //
				CAN_UserWrite(CAN_BUS3, &RxMsg);
				RxMsg.Id   = 0x4E1;  //
				CAN_UserWrite(CAN_BUS3, &RxMsg); 
				RxMsg.Data32[0]= 0x00000822;  
				RxMsg.Data32[1]= 0x6600F026; //third
				RxMsg.Id   = 0x4E2;  // 
				CAN_UserWrite(CAN_BUS3, &RxMsg);
				RxMsg.Id   = 0x4E3; // 
				CAN_UserWrite(CAN_BUS3, &RxMsg); 
				RxMsg.Id   = 0x4E4; // 
				CAN_UserWrite(CAN_BUS3, &RxMsg); 
			} // Detections from CAN1 send to CAN3 end
		} // -------------------- end CAN1 --------------------------
		if ( CAN_UserRead ( CAN_BUS2, &RxMsg) != 0)
		{
			// Detections from CAN2 send to CAN3
			if (RxMsg.Id >= 0x300 && RxMsg.Id <= 0x33F) // 
			{
				RxMsg.Id = RxMsg.Id + 0x200; // from 300 to 500 Left side
				CAN_UserWrite(CAN_BUS3, &RxMsg);

				if (RxMsg.Id == 0x53F )// 
				{ 
					LeftDet64 = 1; 

					LED_toggleCAN2 ^= 1;
					if (LED_toggleCAN2)
					{
						HW_SetLED(HW_LED_CAN2, HW_LED_OFF);
					}
					else
					{
						HW_SetLED(HW_LED_CAN2, HW_LED_GREEN);
					}
				}
			}
			if (RxMsg.Id == 0x180 && LeftDet64)  // send status
			{ 
				LeftDet64 = 0;
				RxMsg.Id   = 0x4D0; //
				CAN_UserWrite(CAN_BUS3, &RxMsg);

				RxMsg.Id   = 0x4D1;  //
				CAN_UserWrite(CAN_BUS3, &RxMsg); 

				RxMsg.Data32[0]= 0x00000822;  
				RxMsg.Data32[1]= 0x6600F026; //third
				RxMsg.Id   = 0x4D2;  // 
				CAN_UserWrite(CAN_BUS3, &RxMsg);

				RxMsg.Id   = 0x4D3; // 
				CAN_UserWrite(CAN_BUS3, &RxMsg); 

				RxMsg.Id   = 0x4D4; // 
				CAN_UserWrite(CAN_BUS3, &RxMsg); 
				LED_toggleCAN3 ^= 1;
				if (LED_toggleCAN3)
				{
					HW_SetLED(HW_LED_CAN3, HW_LED_OFF);
				}
				else
				{
					HW_SetLED(HW_LED_CAN3, HW_LED_GREEN);
				}
			}
		} // CAN_user read 2
	} //while 1
Last edited by M.Gerber on Tue 4. Apr 2017, 16:05, edited 1 time in total.
Reason: Inserted Code tag for better readability

User avatar
S.Schott
Hardware Development
Hardware Development
Posts: 32
Joined: Mon 4. Oct 2010, 16:50

Re: Speed while sending out CAN-signals

Post by S.Schott » Mon 3. Apr 2017, 15:43

Hi there.

It looks like this program creates a message burst (lots of messages at the same time).
The receive queue can hold 56 messages, the transmit queue 100 messages.
Any beyond are lost, some already at reception, some others when sending...

When they all come in at the same time, it's a matter of SW queue size,
the uController itself would be fast enough to process them all...

There's some internal variables to check what is happening inside:
Build some debug messages on the free 4.th channel:
- F0h (SpecialIn) -> RxMsgCountCan1
- F0h (SpecialIn) -> CANRxQueueOverrunCan1
- F0h (SpecialIn) -> CanDataOverrunCan1
- F0h (SpecialIn) -> TxMsgCountCan3
- F0h (SpecialIn) -> CANTxQueueOverrunCan3
resp. for the other CANs.

As a rule of thumb: a CAN500k will transport 4 messages per msec.
This is also the rate for decreasing your queue levels...

WHAT TO DO:
1.) Reduce your config to the reception part, and compare the message count you sent in with the RxMsgCount.
Maybe some are already lost -here-.
2.) Then change your config to do the transmit part only and see if all comes out what you expect.
Again some may get lost here.

3.) Try to spread the incoming and outgoing messages to different points on the timeline,
but still with 50msec cycle, like:
20 at 50msec, 20 at 65msec, 20 at 70msec, 20 at 75msec, 20 at 80msec, 'til done,
then again the first 20 at 100msec, the second 20 at 105msec and so on.

ckessle2
Posts: 14
Joined: Wed 15. Mar 2017, 11:44

Re: Speed while sending out CAN-signals

Post by ckessle2 » Mon 3. Apr 2017, 17:06

Danke! Hört sich sehr verständlich an.

Was beduetet Anzahl Messages (56 und 100) ? Ist das für den Prozessor oder für jeden der vier Kanäle?

Evtl kann ich auf zwei Kanälen output senden und per y-Kabel zusammensetzen?? Die Nachrichten-IDs sind schön getrennt.
Gruesse
C.

ckessle2
Posts: 14
Joined: Wed 15. Mar 2017, 11:44

Re: Speed while sending out CAN-signals

Post by ckessle2 » Tue 4. Apr 2017, 08:42

English again:
Thanks for the clear message!
More questions:
the 56 and 100 message queue - is it per device or per CAN-channel?
Where do I find the h-File for the SpecialIn addresses of the internal variables?

In CAN.h I see a filter mechanism - would that help to reduce the load for the incoming queue ? Half of the incoming message on Ch1 and Ch2 are not needed.
Regards
C.

ckessle2
Posts: 14
Joined: Wed 15. Mar 2017, 11:44

Re: Speed while sending out CAN-signals

Post by ckessle2 » Tue 4. Apr 2017, 13:22

Sorry, new questions:
I try to filter to avoid the overrun:

Code: Select all

//Filter setup 
 	u32_t IdStart, IdEnd;
	CANStatus_t  FilterStat;
 FilterStat = CAN_InitFilters ();
	IdStart = 0x400;
	IdEnd   = 0x43e;
FilterStat = CAN_FilterAddId (	CAN_BUS2, FILTER_11BIT_ID, IdStart,IdEnd);
FilterStat= CAN_SetFilterMode (	AF_ON);
while (1) ....
this compiles etc but I cannot flash the router again after that, so I have to set the ID-switch to F. Removing the filter commands and flashing lets me do again the normal routine of flashing (activate/flash/deactivate) with the ID set to 0.
Last edited by M.Gerber on Tue 4. Apr 2017, 16:07, edited 1 time in total.
Reason: Inserted Code tag for better readability

User avatar
S.Schott
Hardware Development
Hardware Development
Posts: 32
Joined: Mon 4. Oct 2010, 16:50

Re: Speed while sending out CAN-signals

Post by S.Schott » Tue 4. Apr 2017, 14:33

Hallo.

Die Empfangsqueue ist eine gemeinsame für alle 4 Kanäle (56 Plätze),
die Ausgangsseite hat 4 Queues a 100 Plätze.

Filtern geht über Funktionen aus der "can.h", z.B.
CAN_FilterAddId
CAN_SetFilterMode
etc.

Wenn man die 0x7e7 ausschließt, geht flashen nicht mehr.

Interne Variablen wie "TxMsgCount" existieren nur in der "großen" Firmware,
nicht in selbstgeschriebenen Versionen.

ckessle2
Posts: 14
Joined: Wed 15. Mar 2017, 11:44

Re: Speed while sending out CAN-signals

Post by ckessle2 » Tue 4. Apr 2017, 15:10

CAN-Flashing is working again - seems to be that init needs to be called after the filter
All three filter commands do not seem to work. Maybe my idea of filter is wrong?
Filter on: I guess it will not let commands thru in channel 2. I hope they would also not fill the buffer.
But somehow - no change of AF_On etc changes anything.

Code: Select all

	// init hardware
	HW_Init();
	//Filter setup 
 	u32_t IdStart, IdEnd;
	CANStatus_t  FilterStat;
    CAN_InitFilters ();
	IdStart = 0x400;
	IdEnd   = 0x43e;
	CAN_FilterAddId (	CAN_BUS2, FILTER_11BIT_ID_RANGE, IdStart,IdEnd );
	CAN_SetFilterMode (	AF_ON ); //AF_ON does not filter 
	CAN_SetFilterMode (	AF_ON_BYPASS_ON ) ; // does not filter
//	CAN_SetFilterMode (	AF_OFF ) ; //  does not filter
	//Filter end

	// init CAN
	CAN_UserInit();
Last edited by M.Gerber on Tue 4. Apr 2017, 16:08, edited 1 time in total.
Reason: Inserted Code tag for better readability

ckessle2
Posts: 14
Joined: Wed 15. Mar 2017, 11:44

Re: Speed while sending out CAN-signals

Post by ckessle2 » Wed 5. Apr 2017, 13:08

Thanks, again for the clarification.
I would like to test the filtering for getting a better performance.
The following compiles bit the code does not filter the CAN-Message ids.
What am I doing wrong?
Is there a special sequence of other commands needed to activate filtering?

Code: Select all

int main ( void)
{

	// init hardware
	HW_Init();
	//Filter setup 
	u32_t IdStart, IdEnd;
	CANStatus_t  FilterStat;
	CAN_InitFilters ();
	IdStart = 0x400;
	IdEnd   = 0x410;
	CAN_FilterAddId (	CAN_BUS1, FILTER_11BIT_ID_RANGE, IdStart,IdEnd );
	CAN_FilterAddId (	CAN_BUS2, FILTER_11BIT_ID_RANGE, IdStart,IdEnd );
	CAN_FilterAddId (	CAN_BUS2, FILTER_11BIT_ID, 0x411);

	CAN_SetFilterMode (	AF_ON ); //AF_ON does not filter 
	// init CAN
	CAN_UserInit();
	// Set green LEDs for CAN1 to CAN4
	HW_SetLED ( HW_LED_CAN1, HW_LED_OFF);
	HW_SetLED ( HW_LED_CAN2, HW_LED_OFF);
	HW_SetLED ( HW_LED_CAN3, HW_LED_OFF);
	HW_SetLED ( HW_LED_CAN4, HW_LED_OFF);
	// send the greeting message
	main_greeting();
	//u32_t FakeRightScanIndex=0,FakeLeftScanIndex=0;
	//u32_t waitmsec=0, result=0;
	//radar_initialize();
	while ( 1)
	{
	

		CANMsg_t  RxMsg, TxMsg;
		// process messages from CAN1
		if ( CAN_UserRead ( CAN_BUS1, &RxMsg) != 0)
		{

User avatar
P.Steil
Hardware Development
Hardware Development
Posts: 32
Joined: Fri 14. Jan 2011, 10:27

Re: Speed while sending out CAN-signals

Post by P.Steil » Thu 6. Apr 2017, 13:56

Hi,

here are some hints:

Take a look into can_user.h , there are some queue sizes for TX and RX Queues. Possibly one or more of them
are too small and you get e.g. overruns on TX-queue due to larger message bursts.

For filtering change the sequence from CAN_UserInit() in can_user.c from

CAN_InitFilters();
CAN_SetFilterMode ( AF_ON_BYPASS_ON);

into

CAN_InitFilters();

CAN_FilterAddId ( .....);
CAN_FilterAddId ( .....);
....

CAN_SetFilterMode ( AF_ON);


Regards
--------------------------------------------
PEAK-System HW development Team
support@peak-system.com
phone: +49-6151-8173-20
fax: +49-6151-8173-29
--------------------------------------------

ckessle2
Posts: 14
Joined: Wed 15. Mar 2017, 11:44

Re: Speed while sending out CAN-signals

Post by ckessle2 » Thu 6. Apr 2017, 17:41

thanks! Always a pleasure to find something new from PEAK.

I have changed can_user.c and no result. And removed the filter code from main.f

Code: Select all

	// init hardware
	HW_Init();
	//Filter setup see can_user.c 
	// init CAN
	CAN_UserInit();
	// Set green LEDs for CAN1 to CAN4
	HW_SetLED ( HW_LED_CAN1, HW_LED_OFF);
	HW_SetLED ( HW_LED_CAN2, HW_LED_OFF);
	HW_SetLED ( HW_LED_CAN3, HW_LED_OFF);
	HW_SetLED ( HW_LED_CAN4, HW_LED_OFF);
	// send the greeting message
	main_greeting();
	//u32_t FakeRightScanIndex=0,FakeLeftScanIndex=0;
	//u32_t waitmsec=0, result=0;
I just could not anymore flash without reset of the address switch.
Then I reverted to the old can_user.c and now I need always to put 12V to the CAN4-bit to start the Gateway. But the flashing without switch works again.

Code: Select all

//ckessle2
	can_user.c 
	u32_t IdStart, IdEnd;
	CANStatus_t  FilterStat;
	CAN_InitFilters ();
	IdStart = 0x400;
	IdEnd   = 0x410;
	// CAN_FilterAddId (	CAN_BUS1, FILTER_11BIT_ID_RANGE, IdStart,IdEnd );
	CAN_FilterAddId (	CAN_BUS2, FILTER_11BIT_ID_RANGE, 0x400, 0x600 );
	CAN_SetFilterMode (	AF_ON ); 
	
	//ckessle2 
I will drop the idea with filtering - there might be something else wrong...

Now I am trying the idea with the Queue-Size. In can-user.h I found the lines

Code: Select all

// defines
#define  CAN1_TX_QUEUE_SIZE	8
#define  CAN1_RX_QUEUE_SIZE	16

#define  CAN2_TX_QUEUE_SIZE	8
#define  CAN2_RX_QUEUE_SIZE	16

#define  CAN3_TX_QUEUE_SIZE	8
#define  CAN3_RX_QUEUE_SIZE	16

#define  CAN4_TX_QUEUE_SIZE	8
#define  CAN4_RX_QUEUE_SIZE	16
Does this mean the current setup only has a16 Message or 16 Byte buffer for receiving?
Is this the 56 or 100 message buffer you mentioned earlier?
I will try some doubling tomorrow - only the RX-Queue at first.
Thanks again for your time - I am looking forward to the buffer tests.

Post Reply