All of lore.kernel.org
 help / color / mirror / Atom feed
* BCM periodic send
@ 2013-03-28 16:11 Boris Baskevitch
  2013-03-28 21:18 ` Oliver Hartkopp
  0 siblings, 1 reply; 6+ messages in thread
From: Boris Baskevitch @ 2013-03-28 16:11 UTC (permalink / raw)
  To: linux-can

Hello all,
This is my first message on this list, reading it already helped me a lot,
thank you to the contributors here.
I need some help on 2 issues, I'm using Socket-CAN BCM feature to send and
receive periodic messages:
I configured some periodic TX messages as shown below. It works great except
the fact that the actual period on the bus doesn't exactly match the
programmed period, it's a little slower, so I need to add a correction
factor to get the right period. I guess it's my system timer which is
incorrectly configured (I use a Fujitsu SoC with ARM Cortex A9). I don't set
the Jiffie parameter during the boot, so it's recalculated each time I
power-up the board. I don't know what is the time reference for Socket-CAN
(jiffies or something else?), do you know where should I look to correct it
?
Second point, I would like to change the content of the periodic frames at
runtime without reconfiguring the timer, ID and flags. What is the most
elegant way to do it ?
Thanks for your help !

Here's my periodic TX frame setup:

void CanBus::StartPeriodicSend(void)
{
     struct {
	struct bcm_msg_head msg_head;
	struct can_frame frame[1];
     } msg;
    
     
    msg.msg_head.opcode = TX_SETUP;
    msg.msg_head.flags = SETTIMER|STARTTIMER|TX_CP_CAN_ID|TX_COUNTEVT;
    msg.msg_head.count = 0;
    msg.msg_head.ival1.tv_sec = 0;
    msg.msg_head.ival1.tv_usec = 0;
    msg.msg_head.ival2.tv_sec = 0;
    msg.msg_head.ival2.tv_usec = 450000*0.979;		/* interval for the
following frames with correction factor */
    msg.msg_head.can_id = CAN_ID_ETAT_COMB;
    msg.msg_head.nframes = 1;
    msg.frame[0].can_id = CAN_ID_ETAT_COMB;
    msg.frame[0].can_dlc = 8;
    msg.frame[0].data[0] = 0;
    msg.frame[0].data[1] = 0;
    msg.frame[0].data[2] = 0;
    msg.frame[0].data[3] = 0;
    msg.frame[0].data[4] = 0;
    msg.frame[0].data[5] = 0;
    msg.frame[0].data[6] = 0;
    msg.frame[0].data[7] = 0;

    if (write(m_fd, &msg, sizeof(msg)) < 0){
	DiagnosticPlatform::ConsoleOut("CAN: ERROR: send BCM message !\n");
    }
}


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: BCM periodic send
  2013-03-28 16:11 BCM periodic send Boris Baskevitch
@ 2013-03-28 21:18 ` Oliver Hartkopp
  2013-04-03  9:46   ` Boris Baskevitch
  0 siblings, 1 reply; 6+ messages in thread
From: Oliver Hartkopp @ 2013-03-28 21:18 UTC (permalink / raw)
  To: Boris Baskevitch; +Cc: linux-can

On 28.03.2013 17:11, Boris Baskevitch wrote:

> I need some help on 2 issues, I'm using Socket-CAN BCM feature to send and
> receive periodic messages:
> I configured some periodic TX messages as shown below. It works great except
> the fact that the actual period on the bus doesn't exactly match the
> programmed period, it's a little slower, so I need to add a correction
> factor to get the right period. I guess it's my system timer which is
> incorrectly configured (I use a Fujitsu SoC with ARM Cortex A9). I don't set
> the Jiffie parameter during the boot, so it's recalculated each time I
> power-up the board. I don't know what is the time reference for Socket-CAN
> (jiffies or something else?), do you know where should I look to correct it
> ?


The BCM has been moved from jiffies to Linux hrtimers a long time ago in 2.6.26.

What Linux kernel version do you use?

Btw. have you tried a virtual CAN interface? Do you have similar problems there?

> Second point, I would like to change the content of the periodic frames at
> runtime without reconfiguring the timer, ID and flags. What is the most
> elegant way to do it ?


Send a TX_SETUP without "SETTIMER|STARTTIMER" in msg_head.flags, is the really
most elegant way :-)

The flags are parsed when TX_SETUP is consumed.

But the CAN frame content has to be complete, so you can modify your second
TX_SETUP like this:


>>     msg.msg_head.opcode = TX_SETUP;
>>     msg.msg_head.flags = TX_CP_CAN_ID;

// you even do not need TX_CP_CAN_ID as you set both values below.

>>     msg.msg_head.count = 0;

// When count is zero, there's no use of TX_COUNTEVT

>>     msg.msg_head.ival1.tv_sec = 0;
>>     msg.msg_head.ival1.tv_usec = 0;
>>     msg.msg_head.ival2.tv_sec = 0;
>>     msg.msg_head.ival2.tv_usec = 0;

// These values are not used as SETTIMER is not set

>>     msg.msg_head.can_id = CAN_ID_ETAT_COMB;
>>     msg.msg_head.nframes = 1;
>>     msg.frame[0].can_id = CAN_ID_ETAT_COMB;

// Setting this value can be omitted when TX_CP_CAN_ID is set, which takes it
from msg.msg_head.can_id then.

>>     msg.frame[0].can_dlc = 8;
>>     msg.frame[0].data[0] = 0;
>>     msg.frame[0].data[1] = 0;
>>     msg.frame[0].data[2] = 0;
>>     msg.frame[0].data[3] = 0;
>>     msg.frame[0].data[4] = 0;
>>     msg.frame[0].data[5] = 0;
>>     msg.frame[0].data[6] = 0;
>>     msg.frame[0].data[7] = 0;

Regards,
Oliver

> Thanks for your help !
> 
> Here's my periodic TX frame setup:
> 
> void CanBus::StartPeriodicSend(void)
> {
>      struct {
> 	struct bcm_msg_head msg_head;
> 	struct can_frame frame[1];
>      } msg;
>     
>      
>     msg.msg_head.opcode = TX_SETUP;
>     msg.msg_head.flags = SETTIMER|STARTTIMER|TX_CP_CAN_ID|TX_COUNTEVT;
>     msg.msg_head.count = 0;
>     msg.msg_head.ival1.tv_sec = 0;
>     msg.msg_head.ival1.tv_usec = 0;
>     msg.msg_head.ival2.tv_sec = 0;
>     msg.msg_head.ival2.tv_usec = 450000*0.979;		/* interval for the
> following frames with correction factor */
>     msg.msg_head.can_id = CAN_ID_ETAT_COMB;
>     msg.msg_head.nframes = 1;
>     msg.frame[0].can_id = CAN_ID_ETAT_COMB;
>     msg.frame[0].can_dlc = 8;
>     msg.frame[0].data[0] = 0;
>     msg.frame[0].data[1] = 0;
>     msg.frame[0].data[2] = 0;
>     msg.frame[0].data[3] = 0;
>     msg.frame[0].data[4] = 0;
>     msg.frame[0].data[5] = 0;
>     msg.frame[0].data[6] = 0;
>     msg.frame[0].data[7] = 0;
> 
>     if (write(m_fd, &msg, sizeof(msg)) < 0){
> 	DiagnosticPlatform::ConsoleOut("CAN: ERROR: send BCM message !\n");
>     }
> }
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-can" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: BCM periodic send
  2013-03-28 21:18 ` Oliver Hartkopp
@ 2013-04-03  9:46   ` Boris Baskevitch
  2013-04-03 18:29     ` Oliver Hartkopp
  2013-04-04 12:24     ` Boris Baskevitch
  0 siblings, 2 replies; 6+ messages in thread
From: Boris Baskevitch @ 2013-04-03  9:46 UTC (permalink / raw)
  To: 'Oliver Hartkopp'; +Cc: linux-can

Hi Olivier,

> > I need some help on 2 issues, I'm using Socket-CAN BCM feature to send
> > and receive periodic messages:
> > I configured some periodic TX messages as shown below. It works great
> > except the fact that the actual period on the bus doesn't exactly
> > match the programmed period, it's a little slower, so I need to add a
> > correction factor to get the right period. I guess it's my system
> > timer which is incorrectly configured (I use a Fujitsu SoC with ARM
> > Cortex A9). I don't set the Jiffie parameter during the boot, so it's
> > recalculated each time I power-up the board. I don't know what is the
> > time reference for Socket-CAN (jiffies or something else?), do you
> > know where should I look to correct it ?
> 
> 
> The BCM has been moved from jiffies to Linux hrtimers a long time ago in
> 2.6.26.
> What Linux kernel version do you use?

I use Linux 3.0.3

> Btw. have you tried a virtual CAN interface? Do you have similar problems
> there?

Yes. It must be linked to my  CLOCK_TICK_RATE constant. I'm using a 66.66MHz
reference clock, so probably a rounding issue. I'm doing some investigation
on this point.

> > Second point, I would like to change the content of the periodic
> > frames at runtime without reconfiguring the timer, ID and flags. What
> > is the most elegant way to do it ?
> 
> 
> Send a TX_SETUP without "SETTIMER|STARTTIMER" in msg_head.flags, is the
> really most elegant way :-)

OK, thanks.

Now I have a new issue, the BCM report a RX_TIMEOUT for all periodic
messages, even if the message is present on the bus with a shorter period
than the one I configured in the BCM.
The message is correctly received as I can get the RX_CHANGED message for
the corresponding IDs.
If I use RX_FILTER_ID option, I get a RX_CHANGED and RX_TIMEOUT for each
message seen the bus (which is correct for RX_CHANGED, but not for
RX_TIMEOUT).
By the way, for a periodic RX message, which parameter is the period, ival1
or ival2 ? (I had both set for the tests)

Boris.



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: BCM periodic send
  2013-04-03  9:46   ` Boris Baskevitch
@ 2013-04-03 18:29     ` Oliver Hartkopp
  2013-04-04 12:24     ` Boris Baskevitch
  1 sibling, 0 replies; 6+ messages in thread
From: Oliver Hartkopp @ 2013-04-03 18:29 UTC (permalink / raw)
  To: Boris Baskevitch; +Cc: linux-can

On 03.04.2013 11:46, Boris Baskevitch wrote:

> Now I have a new issue, the BCM report a RX_TIMEOUT for all periodic
> messages, even if the message is present on the bus with a shorter period
> than the one I configured in the BCM.


I assume you set STARTIMER too, which fires the RX timeout timer immediately.

> The message is correctly received as I can get the RX_CHANGED message for
> the corresponding IDs.
> If I use RX_FILTER_ID option, I get a RX_CHANGED and RX_TIMEOUT for each
> message seen the bus (which is correct for RX_CHANGED, but not for
> RX_TIMEOUT).
> By the way, for a periodic RX message, which parameter is the period, ival1
> or ival2 ? (I had both set for the tests)


ival1

Please look into

http://svn.berlios.de/wsvn/socketcan/trunk/test/tst-bcm-dump.c

You can download it from the old BerliOS SVN here:

http://developer.berlios.de/svn/?group_id=6475

An here is, what it does:

hartko@keffi-oh:~$ tst-bcm-dump -?
tst-bcm-dump: invalid option -- '?'

Usage: tst-bcm-dump [options]
Options: -i <interface> (CAN interface. Default: 'vcan0')
         -c <can_id>    (used CAN ID. Default: 0x042)
         -o <timeout>   (Timeout value in nsecs. Default: 0)
         -t <throttle>  (Throttle value in nsecs. Default: 0)
         -q <msgs>      (Quit after receiption of #msgs)
         -s             (set STARTTIMER flag. Default: off)

hartko@keffi-oh:~$ tst-bcm-dump -o 500000
[1365012787.346834] Writing RX_SETUP with RX_FILTER_ID for can_id <042>
[1365012800.057653] (1365012800.057338) RX_CHANGED
[1365012800.557701] RX_TIMEOUT
^C
hartko@keffi-oh:~$ tst-bcm-dump -o 500000 -s
[1365012821.448782] Writing RX_SETUP with RX_FILTER_ID for can_id <042>
[1365012821.948974] RX_TIMEOUT
^C

In the first case the RX_TIMEOUT is 500000ns behind the reception of the
frame. In the second case (with STARTTIMER set) the RX_TIMEOUT emerges even
when there was no reception of any frame.

You can use

cangen vcan0 -I 042 -g400

to test the functionality of above "tst-bcm-dump -o 500000"

When cangen is termintated, the RX_TIMEOUT appears.

Regards,
Oliver


^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: BCM periodic send
  2013-04-03  9:46   ` Boris Baskevitch
  2013-04-03 18:29     ` Oliver Hartkopp
@ 2013-04-04 12:24     ` Boris Baskevitch
  2013-04-04 18:44       ` Oliver Hartkopp
  1 sibling, 1 reply; 6+ messages in thread
From: Boris Baskevitch @ 2013-04-04 12:24 UTC (permalink / raw)
  To: 'Oliver Hartkopp'; +Cc: linux-can

> Now I have a new issue, the BCM report a RX_TIMEOUT for all periodic
> messages, even if the message is present on the bus with a shorter period
> than the one I configured in the BCM.
> The message is correctly received as I can get the RX_CHANGED message for
> the corresponding IDs.
> If I use RX_FILTER_ID option, I get a RX_CHANGED and RX_TIMEOUT for each
> message seen the bus (which is correct for RX_CHANGED, but not for
> RX_TIMEOUT).
> By the way, for a periodic RX message, which parameter is the period,
ival1 or
> ival2 ? (I had both set for the tests)

I finally found out in a German documentation the actual meaning of ival1,
ival2 and data (mask) fields in RX_SETUP.
I didn't see it in English, is there a reference documentation that I
missed?
I also have to note for other users the fact that when you get a RX_TIMEOUT
you have to check msg_head.can_id to find out the offending message ID and
not frame[0].can_id which is not updated.
So now the timeout feature works in my application but I still have the
issue with both RX_TIMEOUT and RX_CHANGED flags always set together.
This issue is masked when I use the following structure:
if (msg.msg_head.opcode & RX_CHANGED) {
// extract data from frame and send to process
} else if (msg.msg_head.opcode & RX_TIMEOUT) {
// tell process that the frame is absent
}
But if I replace the "else if" by a simple "if" I have wrong timeout
signaling for each frame received.
Is it a normal behavior?

I'm still working on my timer inaccuracy issue. It's not linked to
CLOCK_TICK_RATE which is OK. It's probably not directly linked to the BCM,
but still if anybody has any hints, I'm taking.
Boris.



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: BCM periodic send
  2013-04-04 12:24     ` Boris Baskevitch
@ 2013-04-04 18:44       ` Oliver Hartkopp
  0 siblings, 0 replies; 6+ messages in thread
From: Oliver Hartkopp @ 2013-04-04 18:44 UTC (permalink / raw)
  To: Boris Baskevitch; +Cc: linux-can

On 04.04.2013 14:24, Boris Baskevitch wrote:

> I finally found out in a German documentation the actual meaning of ival1,
> ival2 and data (mask) fields in RX_SETUP.
> I didn't see it in English, is there a reference documentation that I
> missed?


Hm - no.

Daniele Venzano suggested to add some documentation for the BCM:

http://www.brownhat.org/docs/socketcan.html

And i started the documentation split in the old BerliOS SVN:

http://svn.berlios.de/wsvn/socketcan/trunk/kernel/2.6/Documentation/networking/can/

But unfortunately this didn't go further ... 

> I also have to note for other users the fact that when you get a RX_TIMEOUT
> you have to check msg_head.can_id to find out the offending message ID and
> not frame[0].can_id which is not updated.


The RX_TIMEOUT message has no struct can_frame.

It only consists of a struct bcm_msg_head!

That's why frame[0].can_id is not updated at all in RX_TIMEOUT messages :-)

> So now the timeout feature works in my application but I still have the
> issue with both RX_TIMEOUT and RX_CHANGED flags always set together.


Flags?

RX_TIMEOUT and RX_CHANGED are two different messages (with different sizes).

> This issue is masked when I use the following structure:
> if (msg.msg_head.opcode & RX_CHANGED) {
> // extract data from frame and send to process
> } else if (msg.msg_head.opcode & RX_TIMEOUT) {
> // tell process that the frame is absent
> }
> But if I replace the "else if" by a simple "if" I have wrong timeout
> signaling for each frame received.
> Is it a normal behavior?


Your if statement is wrong.

Use
 
	if (msg.msg_head.opcode == RX_CHANGED)

instead of

	if (msg.msg_head.opcode & RX_CHANGED)

The opcode is a enum value and not a bit field.

> 
> I'm still working on my timer inaccuracy issue. It's not linked to
> CLOCK_TICK_RATE which is OK. It's probably not directly linked to the BCM,
> but still if anybody has any hints, I'm taking.


No idea so far.

Regards,
Oliver


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2013-04-04 18:44 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-03-28 16:11 BCM periodic send Boris Baskevitch
2013-03-28 21:18 ` Oliver Hartkopp
2013-04-03  9:46   ` Boris Baskevitch
2013-04-03 18:29     ` Oliver Hartkopp
2013-04-04 12:24     ` Boris Baskevitch
2013-04-04 18:44       ` Oliver Hartkopp

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.