skarlsson / NMEA2000_FeatherM4CAN

Adafruit Feather M4 CAN NMEA2000 driver
MIT License
1 stars 0 forks source link

Check is fastpacket properly handled on sending #1

Open ttlappalainen opened 2 years ago

ttlappalainen commented 2 years ago

I have not looked in to the Feather M4 CAN specs and do not know how it behaves. Some CAN controllers like on Teensy there are several mailboxes, which has different priorities. It is important to understand that logic to avoid problems with fastpackets. Original Teensy CAN library used 8 mailboxes for sending and simply wrote frame to next free mailbox. Lets define Mx as single frame message Fx-y as fastpacket message frame, where y is frame index. Now if library buffers data M1, M2, M3, M4, M5, F1-1,F1-2,F1-3, M6, F2-1, F2-2. With Teensy default FlexCAN driver that could be filled to mailboxes M1 -> mb1 M2 -> mb2 M3 -> mb3 M4 -> mb4 M5 -> mb5 F1-1 -> mb6 F1-2 -> mb7 F1-3 -> mb8 M6 -> mb1 F2-1 -> mb2 F2-2 -> mb1 This happens since mb1 is highest priority mailbox and will be sent first. So the result is that F2 frames comes to the bus in wrong order and devices can not handle them. So time to time there will be lost fastpackets.

This is why I have written own fixed drivers for FlexCAN, mcpcan. NMEA2000_esp32 and NMEA2000_Teensyx contains full controller code and are not dependent of other libraries. E.g., FlexCAN library versions has caused lot of hassle.

E.g., on Teensy driver I use only 3 mailboxes for sending and select mailbox according to message priority. In this way same fastpacket frames will be sent out from same mailbox and so always in order.

So now you should dive deep in to the Feather M4 CAN logic and check that does it do the same as default FlexCAN. Same problem is also with MBED and thy refuced to fix it, so it can not be reliably used.

Also I point to check buffering cababilities. E.g., with NMEA2000_Teensy there can be rather long buffers, which will be emptied by interrupts. It means that if one e.g., has 100 frame buffer, it can hold e.g., product information, configuration information, GNSS messages and then messages will be sent automatically by interrupt. Without interrupt buffer will be emptied by ParseMessages and delays on that will cause delays on messages sending. And same opposite on reciving. If you have 100 fram read buffer, but CAN controller (or library) holds only few frames, it is risk of loosing frames if there is any delay on ParseMessages. In case of message burst there can be up to 25 frames in 10 ms on the bus.

You can test your driver with my NMEA Simulator by making 2 devices one for sending all messages and one listening. Then you compare count of sent and received messages.

kelleyja commented 2 years ago

Thanks @ttlappalainen for the fantastic library, I am enjoying learning about N2k. I have successfully used this board to receive N2K messages, but have not yet investigated Tx messages. I modify NEMA2000_CAN.h to call the Adafruit CAN driver . It creates a single tx buffer, but can be modified to create another for fast packets. I think it would work then the same as what you do for mcp2515

ttlappalainen commented 2 years ago

I prefer not to modify NMEA2000_CAN.h, since you have to then replace it on every library update.

Also drivers did not look very good. Looks that they uses single mailbox for output, but they do not use interrupted transmission. This means that every time you send frame, it waits it has been really sent. This will cause 0.5-1 ms delay for every frame sending, while CPU could do some other things. In other drivers I write to buffer and interrups will take care of final sending.

Better would be to write own NMEA2000_SAME5x module and handle things properly. Looks like that CAN controller has two Tx mailboxes, so with proper driver both could be used for better performance.

So please do not make pull for library update with this solution.