Zubax / kocherga

Robust platform-agnostic Cyphal/DroneCAN bootloader for deeply embedded systems
https://zubax.com
MIT License
45 stars 10 forks source link

libcanard polling too slow #5

Closed chemicstry closed 5 years ago

chemicstry commented 5 years ago

I'm not sure whether this issue belongs to this repository but at least I will share the problem I encountered.

I'm using this bootloader on a STM32F103 @ 72 MHz and the main bootloader loop is too slow to poll libcanard stm32 driver receive function hence losing packets during file transfer. The internal receive buffer is only 2 frames and it seems that it cannot keep up with 1mbps CAN bitrate. The way I solved this is by making libcanard driver interrupt driven and feeding frames to an intermediate RX queue (ChibiOS FIFO).

This is highly platform specific, but I think someone will definitely encounter this issue. I'm not sure if this should be fixed by making libcanard driver buffered or by other means.

pavel-kirienko commented 5 years ago

Normally, you should fix this at the platform level. You could add an RX FIFO queue between your CAN driver and the library.

Here you can find an STM32F105-based bootloader (CM3 72 MHz, execution from flash) with ChibiOS which works without issues at 1 Mbps: https://github.com/Zubax/zubax_gnss/blob/3ed2388a7dbe0eae226293846b327309d414521e/bootloader/src/board/can.hpp

I am not familiar with your application, but I suppose the culprit might be right here:

/**
 * Hardware FIFO is 3 frames deep; the shortest (worst case) frame duration with acceptance filters allowing only
 * extended frames is:
 *  (1+11+1+1+18+1+2+4+0+15+1+1+1+7) = 64 bits = 64 microseconds @ 1 Mbps
 *
 * Multiply by the depth of the FIFO:
 *  64 * 3 = 192 microseconds
 *
 * Therefore, we must read the driver not less frequently than every 192 microseconds, otherwise we might be
 * losing frames due to RX overrun. Therefore we enforce that the system tick interval is less than that.
 */
static_assert((1000000 / CH_CFG_ST_FREQUENCY) < 180,
            "Minimal delay must be lower in order for the libcanard STM32 driver to work properly");
chemicstry commented 5 years ago

Thank you for the link with an example implementation, I think you should add that to the readme.

And yes, that indeed might have been the culprit. I will report if it has fixed the issue if I find time to revert my modifications and try again.

pavel-kirienko commented 5 years ago

I think it's well-covered in the README for the driver already: https://github.com/UAVCAN/libcanard/tree/master/drivers/stm32

Writing anything more specific would not be sufficiently generic, so I would rather not do that.

chemicstry commented 5 years ago

I mean adding the https://github.com/Zubax/zubax_gnss/ link to this repository as an example implementation of a kocherga bootloader. Sorry for the confusion :)

EDIT: oh my bad, I thought it was based on this bootloader framework, but it's not. Nervermind.

chemicstry commented 5 years ago

Just a quick update if anyone encounters this problem. Increasing ChibiOS system tick frequency, as suggested by Pavel, fixed the issue and I'm no longer losing frames.