Main Site Documentation

EMX cycles are slow (processing CAN messages)?


#1

hi,

i am trying to process ~800 CAN messages per second, the processing is just arranging the bytes into a different structure, how ever profiling it i can see it takes about 3 msec to decode each message, this seems wrong…

two things to mention

  1. i am using pulling inside a thread
  2. i used to DateTime to profile the timing

the code below, please advise…


public void Init()
{
    int BRP = 12;
    int T1 = 6;
    int T2 = 5;
 
    // create CAN object
    m_CAN = new CAN(CAN.Channel.Channel_2, (uint)(((T2 - 1) << 20) | ((T1 - 1) << 16) | ((BRP - 1) << 0)));

    // create worker thread
    m_WorkerThread = new Thread(CANThread);
    m_WorkerThread.Priority = ThreadPriority.Highest;
    m_WorkerThread.Start();
}

private void CANThread()
{
    // loop until thread is terminated
    while (m_WorkerThread.ThreadState == ThreadState.Running)
    {
        int TempMsgsCount = m_CAN.GetMessages(m_MsgList, 0, m_CAN.ReceivedMessagesCount);
                
        if (TempMsgsCount > 0)
        {
            //==========================================
            for (int Index = 0; Index < TempMsgsCount; Index++)
            {
                CAN.Message TempMsg = m_MsgList[Index];
                m_SW.Reset();
                // decode regular message
                if ((TempMsg.ArbID >= 0x1001) && (TempMsg.ArbID <= 0x1008))
                {
                    // get Device index from message id
                    int DeviceIndex = (int)TempMsg.ArbID - 0x101;
                            
                    DeviceData TempDevice = m_Device[DeviceIndex];

                    // set Device current mode
                    TempDevice.Mode = TempMsg.Data[0];
                    // set Device current event code
                    TempDevice.Event = TempMsg.Data[1];
                    // process Device data accoring to current mode
                    switch ((DeviceMode)TempMsg.Data[0])
                    {
                        // handle Device operational mode and its likes
                        case DeviceMode.Operational:
                            TempDevice.V1 = (UInt16)((TempMsg.Data[2] & 0x0F) << 8 + TempMsg.Data[3]);
                            TempDevice.V2 = (UInt16)((TempMsg.Data[2] & 0xF0) + (TempMsg.Data[3] & 0x0F));
                            TempDevice.V3 = (UInt16)((TempMsg.Data[4] << 8) + (TempMsg.Data[5]));
                            TempDevice.V4 = (UInt16)(((TempMsg.Data[6] & 0xF0) << 8) + (TempMsg.Data[7]));
                            break;
                    }
                    m_Device[DeviceIndex] = TempDevice;
                }
                      
                        
                double timepercycle = m_SW.ElapsedSec;
                if (timepercycle > 0.1)
                {
                }
            }
        }
        else
            Thread.Sleep(50);
    }
}


#2

Hi

I afraid that this won’t be possible unless doing RLP.


#3

Thanks, I was afraid so
what would be best in terms of architecture, receive CAN messages in .NETMF and process in RPL or just move this whole section to RLP?
where can I find examples of CAN using RLP?


#4

Haven’t seen any. But I somewhat doubt it would help. Your function is rather simple, not the best candidate for RLP.

I also receive from 500 to 1000 CAN messages per second. Not easy to handle :frowning:


#5

Receiving the messages (all of them) wasn’t easy but I managed, now decoding them in real-time seems to be the issue, I will give RLP a chance!

I guess I will need to convert CAN message structure to unsafe c, right? since I am planning to pass the entire messages block to RLP function to decode


#6

Yes, you have to pass an array to the RLP.

I’ll be very interested to see your results, as I was also thinking of passing CAN stuff to RLP.


#7

CAN.Message is a class not a packed record, so I am not sure that is even feasible, any ideas? I was thinking on passing only the data porting of the message into a RLP code


#8

I am not sure what you mean by options

actually my only option (as I see it) is to pass RLP two byte array and do some kinds of manipulation on it, not the most nice/easy solution

any ideas?


#9

What’s are the count numbers between the msg count comming in and the ones matching ((TempMsg.ArbID >= 0x1001) && (TempMsg.ArbID <= 0x1008))? is this 100%? (meaning did you set your filters?)


#10

Yes I did set the filters right, this is only a safety line which can be removed.

I also tried using RLP to handle just the bit/byte shifting, the RLP procedure was called for each can message which caused it to slow down too much and didn’t get the results I expected

currently the only thing that gains speed it changing the bit/byte manipulation to integer/uint manipulation but this only doesn’t reach full requirement of ~1000 messages per second

i believe the best way would be to transfer the entire can messages list to RLP and process it there, it will save the switching time to/from RLP and will allow fast bit/byte manipulation, the one thing that prevents me from doing so it the fast the

 CAN.Message

is a class not a structure as I understand it

how can I transfer

 []CAN.Message

array into RLP ???
or it there any other approach?

Thanks in advance