User-level real time programming in BBB

Hello,

I am writing a program which enables BBB to communicate with other controllers via CAN bus with Socket-CAN.

Basically, socket-can supports primitive operations for single CAN message send/receive.

But most CAN messages should be sent periodically (e.g. every 10ms). So I need a way to send such message in real time.

So it would be very appreciate if anyone can tell me how to write a real-time programi in user level or any way to access socketcan layer in PRU for real-time programming.

Thanks a lot.

Windows 10¿ë ¸ÞÀÏ¿¡¼­ º¸³¿

On Tue, 26 Jun 2018 12:39:09 +0000, Hee-cheol Yang
<heecheol.yang@outlook.com> declaimed the
following:

But most CAN messages should be sent periodically (e.g. every 10ms). So I need a way to send such message in real time.

  10ms is a rather large chunk of time... How precise within that time
span do the messages need to be? That is:

  Does message "A" need to be sent exactly on 0, 10, 20, 30... while
message "B" gets sent exactly on 2, 12, 22, 32...

  Or is it sufficient that both message "A" and "B" are sent sometime
within each 10ms block (which could mean sending on 0, 19, 21, 30).

  Are some messages sent at different rates from others?

So it would be very appreciate if anyone can tell me how to write a real-time programi in user level or any way to access socketcan layer in PRU for real-time programming.

  The simplest is probably to define a master frame -- which is the least
common multiple of all the message rates. You then determine a schedule of
evenly-spaced sub-frames (individual messages) which fills the master
frame.

  Say you have messages that need to go out on:

mA 0, 10, 20...
mB 1, 4, 7, 10, 13, 16, 19, ...
mC 0, 5, 10, 15, 20...

(note that the 1, 4, 7 is spaced at 3ms with a 1ms offset); use 3ms for LCM
computation) The LCM is 30, so that defines your master frame as being 30ms
long; a minor frame is 1ms (there will be many minor frames where nothing
happens)

epoch = time.now()
while True:
  for sf in range(30):
    epoch = epoch + 0.001 #1ms
    time.sleep(epoch - time.now()) #sleep until start of next subframe

    if sf in (0, 10, 20):
      #send 10ms spaced mA
    if sf in (1, 4, 7, 10, 13, 16, 19, 22, 25 28):
      #send 3ms spaced mB, offset by 1ms
    if sf in (0, 5, 10, 15, 20, 25):
      #send 5ms spaced mC

  This will result in sending:

sf messages
0 mA, mC
1 mB
2
3
4 mB
5 mC
6
7 mB
8
9
10 mA, mB, mC
11
12
13 mB
14
15 mC
16 mB
17
18
19 mB
20 mA, mC
21
22 mB
23
24
25 mB, mC
26
27
28 mB
29

  The loop runs as a thread/task which ideally spends most of its time
sleeping (make sure it is not a busy-wait! -- so the rest of the code can
process data). Each scheduled message buffer will be updated external to
the loop (so you might need to put mutex locks around the actual
sending/updating of a given message -- that /might/ add some minor timing
effects, but with a 1ms subframe, I'd hope update locking would be much
shorter duration and all messages still go out (the worst case above is
subframe 10, where a copy of all three messages need to be sent).

{You could perhaps use a busy wait if the major frame loop is running on a
PRU, while the message buffers are populated by code on the ARM -- but if
the frame loop runs on a processor used for other tasks you need a sleep
that does not block the other tasks}.

  The biggest concern is what time-slice the OS uses -- and is that
controllable? The frame loop likely needs to be at a higher priority so
that it can be woken up rapidly when the sleep expires -- otherwise it
would just be shoved to the end of the tasks waiting for a time-slice...
And Linux time-slices are rather large.