dronecan / libcanard

MIT License
50 stars 56 forks source link

Support for Zephyr #51

Open waseemR02 opened 1 year ago

waseemR02 commented 1 year ago

I am working on programming blackpill_f401cc (WeAct) as a daughter board for Pixhawk. I was using mcp2515 for can interface and Zephyr as the RTOS. How do I go about implementing libcanard there?

adolfogc commented 1 year ago

Hi,

How did you connect the controller to the blackpill? It seems like SPI1 is the only available device for this board [1].

Some steps you probably need to accomplish:

Pointers:

  1. https://docs.zephyrproject.org/latest/boards/arm/blackpill_f401cc/doc/index.html
  2. https://docs.zephyrproject.org/latest/hardware/porting/shields.html
  3. https://github.com/zephyrproject-rtos/zephyr/tree/main/boards/shields/mcp2515
  4. https://docs.zephyrproject.org/latest/kernel/drivers/index.html
  5. https://github.com/zephyrproject-rtos/zephyr/blob/main/drivers/can
  6. https://github.com/dronecan/libcanard/blob/22102c717db29cc2a2c2869ff80f3e4389704d89/examples/ESCNode/esc_node.c#L591

Hope this helps.

waseemR02 commented 1 year ago

I defined the mcp2515 under spi1 in device tree and used the existing shield example to write a c program for loopback. At this point, I didn't really test whether it works because i shifted my focus to dronecan as that's what I intend to use at the end to interact with pixhawk. This is where I don't know how to move forward. I have asked in the zephyr community and someone suggested to just write a driver for it. Keeping in mind i have never written any driver, though I m not against writing if I can write it. But then for this I would need to adapt the mcp2515 driver and write it for libcanard.

waseemR02 commented 1 year ago

As far as i understand I would need to read some can frame using the existing driver for mcp2515 and push it to the rx queue of libcanard and then pop a tx frame from tx queue and send it to the device. All this would still need the library.

adolfogc commented 1 year ago

Roughly, yes. Note that as per libcanard's internal documentation [1]:

... Libcanard does not interact with the underlying platform drivers directly, but does so via the application. Therefore, there is no need in a dedicated porting guide. ...

So you don't need a driver specifically coded for libcanard. Instead, in your application you use both the CAN driver's interface and libcanard's interface. Also, it isn't required to implement it as a TxRx function, you should code it as it best fits your own design. For example, you could implement the transmit and receive logic in separate functions.

I suggest that you first try to run the sample provided by Zephyr [2], and confirm that your current setup works. Also read Zephyr's CAN documentation, which provides some examples [3].

Finally, I can also point you to an example I had written a while ago, and that uses libcanard and the STM32 driver bundled with libcanard, in hopes that it may give you further ideas [4][5][6]. The code is designed to work with a different kernel+framework (qpc), however.

--

  1. https://github.com/dronecan/libcanard/tree/master/drivers
  2. https://github.com/zephyrproject-rtos/zephyr/blob/main/samples/drivers/can/counter/src/main.c
  3. https://docs.zephyrproject.org/latest/hardware/peripherals/canbus/controller.html
  4. https://github.com/adolfogc/stg-8nn-scaffold/blob/main/bsp/stg/src/bsp_can.c
  5. https://github.com/adolfogc/stg-8nn-scaffold-example/blob/master/blinky/uavcan_override.c
  6. https://github.com/adolfogc/stg-8nn-scaffold/blob/main/app/uavcan_node/uavcan_node_helpers.c