EMX cycles are slow (processing CAN messages)?

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);
    }
}

Hi

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

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?

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:

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

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.

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

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?

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?)

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