I am attempting to send EMX firmware over CAN bus. Firmware is about 700kB. With a bitrate of 250kb/s I would expect in theory 22s. In practice it takes 170s to send the file.
Moreover using a lawicell canusb it seems that there’s some missing frames…
Here’s the code I am using.
int i = 0;
if (File.Exists(path))
{
FileStream f = new FileStream(path, FileMode.Open, FileAccess.Read,FileShare.None, 8);
long size = f.Length;
long bytesRemaining;
int bytesRead;
byte[] data;
bytesRemaining = f.Length;
Debug.Print("Size of FW to send:" + bytesRemaining);
int nb_mess = (int)f.Length / 8;
CAN.Message[] mess = new CAN.Message[100];
while(bytesRemaining > 0)
{
i = 0;
while (bytesRemaining > 0 && i < 100)
{
mess[i] = new CAN.Message();
data = new byte[(bytesRemaining > 8) ? 8 : bytesRemaining];
bytesRead = f.Read(data, 0, data.Length);
//Thread.Sleep(60);
mess[i].ArbID = 0x17FF0101;
mess[i].Data[0] = data[0];
mess[i].Data[1] = data[1];
mess[i].Data[2] = data[2];
mess[i].Data[3] = data[3];
mess[i].Data[4] = data[4];
mess[i].Data[5] = data[5];
mess[i].Data[6] = data[6];
mess[i].Data[7] = data[7];
mess[i].DLC = 8;
mess[i].IsEID = true;
mess[i].IsRTR = false;
i++;
bytesRemaining -= bytesRead;
}
int numberOfMessagesPosted = can.PostMessages(mess, 0, i);
}
f.Close();
f.Dispose();
}
Is there’s something to do to speed up this process?
If I understand well, placing a message in the queue does not mean that message will be written on the bus. If you build an array of message how to know which one has been sent or not?
Most examples (if not all) on the forum use postmessage with only a single message to send… why using an array of message would be relevant???
Instead of using :
int numberOfMessagesPosted = can.PostMessages(mess, 0, i);
I modify it in order to be embedded in the inner loop.
int numberOfMessagesPosted = can.PostMessages(mess, i, 1);
Now all the messages are received but it still very slow.
I am using can monitor pro to check that in the first example some messages are not written while in the second all is ok.
In fact reading the file by chunk of 8 bytes is extremelly slow… (110s!!!)
the workload of bus is null (only emx send and lawicell)
Now that I know that filestream reads are responsible of 110s over 175, it sounds better but still!!! I know that given bitrate is different than usefull bitrate… but it 'smore than 100% of overhead!
@ leforban - I can’t help with CAN, but I have noticed that your DLC is always 8 even for the last message, which can be less than 8. Probably not a big deal, but I would refactor the code to something like this:
@ andre.m: when you talk about analyser to you mean a DSO?
@ GUS yep I think there’s hand tuning to do (I can not let the board wasting its time to read the file by chunk of 8 bytes (by chunk of 1024 will be really better I think)
@ architect. hex fil for EMX are multiple of 8bytes I think. Does anyone can confirm? But you’re right something more generic is better. ( next task is to send xml files…)
data = new byte[(bytesRemaining > 8) ? 8 : bytesRemaining];
will go through 700000 kb of memory. With my refactoring this is not an issue anymore.
But 87500 times mess[i] = new CAN.Message(); is an issue. With more than 20 bytes per CAN.Message object you are going through more than 1 750 000 more bytes. That taxes your loop with additional checks, garbage collection runs, etc.
I would pre-allocate and reuse a reasonable message array.
Just for comparison… Recently we’ve implemented a firmware update over CAN. With EMX, 1Mbps, 1MB firmware file. Our best result was ~40seconds without checks, and ~120seconds with an echo every 256 messages from the receiving side.
Nop, I am just sending raw data. CAN Open specification does not seem to be so open… I did not find any free documentation. Maybe I need to search more…