NuttX CAN drivers on STM32H7x3

Hello, everyone!
I am trying to connect to the CAN port on a board with a STM32H7 chip. I set CONFIG_CAN=y in the defconfig file and get the error

/src/can.c:26:10: fatal error: stm32_can.h: No such file or directory
   26 | #include "stm32_can.h"
      |          ^~~~~~~~~~~~~
compilation terminated.

After a little understanding I realized that STM32H7 chips do not support NuttX CAN because

In
PX4-Autopilot/platforms/nuttx/NuttX/nuttx/arch/arm/src/stm32h7
does not exist files stm32_can.h stm32_can.c
and
PX4-Autopilot/platforms/nuttx/NuttX/nuttx/arch/arm/src/stm32h7/hardware
does not exist file stm32_can.h

In this connection I have a question:
How does UAVCAN work without CAN bus libraries on a board with STM32H7 chip? @PavelKirienko
Are there plans to implement CAN support on STM32H7 chips in NuttX and when? @nuttx

There is CAN-FD support coming on H7 with the next NuttX update, check these PRs:

I’m not sure if it’s in NuttX 10.3 or 10.4 but some PRs are coming soon here.

That being said, I tried to get a CAN device (not UAVCAN) working on top of 10.4 but I could not see my device using candump in the console. Maybe I’m missing something, or maybe it’s not that trivial to use a CAN device using CAN-FD although I thought it was backwards compatible.

Hi!
Thank you so much for your reply. I just saw that 5 hours ago the NuttX platform was upgraded to version 10.3+
I too am now trying to add a CAN 2.0A device, it is a microwave radio altimeter based on the Nanoradar NRA24. I hope I succeed and share this driver with everyone, maybe you can do it now too.
Thanks a lot to you and the dev team!

Unfortunately with the NuttX update the CAN port does not start this is also due to missing files in

PX4-Autopilot/platforms/nuttx/NuttX/nuttx/arch/arm/src/stm32h7
does not exist files stm32_can.h stm32_can.c
and
PX4-Autopilot/platforms/nuttx/NuttX/nuttx/arch/arm/src/stm32h7/hardware
does not exist file stm32_can.h

Sorry, I should have specified. This now uses the socketcan interface.

I am now immersed in studying the AUVCAN driver software code for the STM32H7. Since Pavel Kirienko answered that UAVCAN can share the same bus with other protocols based on CAN 2.0A (11-bit identifiers).
I am planning to either write a new function in the existing UAVCAN driver which will pass the standard CAN frames I need or use the existing ones, similar to what was already described, like this:

	/* Copy SocketCAN frame to CanardFrame */

	if (_can_fd) {
		struct canfd_frame *recv_frame = (struct canfd_frame *)&_recv_frame;
		out_frame.id = recv_frame->can_id;
		out_frame.dlc = recv_frame->len;
		memcpy(out_frame.data, &recv_frame->data, recv_frame->len);

	} else {
		struct can_frame *recv_frame = (struct can_frame *)&_recv_frame;
		out_frame.id = recv_frame->can_id;
		out_frame.dlc = recv_frame->can_dlc;
		memcpy(out_frame.data, &recv_frame->data, recv_frame->can_dlc);
	}

If it works, then we do not have to disable UAVCAN to receive messages from CAN 2A devices and receive and process them on the same wires as the UAVCAN devices

I guess that would as well.

I now have writing working inspired by cansend.c and I’m just trying to get reading to work like in candump.c.

The driver I meant is here:

Hi Julian
I am planning on using the socketCAN driver for Pixhawk6C. I am running into NuttX compile errors using the defconfig defines you have above in the fmu-v6c defconfig file. It is because NET_SOCK_TYPE isn’t defined. It appears CONFIG_NET_IPv4 is somehow defined. That causes NET_SOCK_FAMILY to be AF_INET, and NET_SOCK_TYPE to not be defined in netconfig.h. Have you come across this before?

Enabling CONFIG_NET_UDP fixed this issue. Not clear why CONFIG_NET_IPv4 is enabled…and KCONFIG doesn’t show this dependancy…

1 Like

One more thing that I just found.

I’m running my custom CAN driver on CAN2, and I have UAVCAN configured for only one interface, so CAN1.

Now, as soon as I do uavcan start (or set UAVCAN_ENABLE to > 0) my custom CAN driver locks up. I couldn’t yet figure out why.

These are my UAVCAN settings:

CONFIG_BOARD_UAVCAN_INTERFACES=1

Hi Julian
Have you achieved reading and writing classic can messages busing stm32_fdcan_sock.c ? Can you please give a brief introduction about how to use this. I am confronting the problem of reading/writing can messages via v6x(which uses stm32h753)

Let me try to summarize the steps I did to get a driver working on CAN2:

Add this to boards/px4/fmu-v6x/init/rc.board_defaults:

ifup can1

Update NuttX submodule to this hack:

Add to boards/px4/fmu-v6x/default.px4board:

CONFIG_BOARD_UAVCAN_INTERFACES=1

Add to boards/px4/fmu-v6x/nuttx-config/nsh/defconfig:

CONFIG_NETDEV_CAN_BITRATE_IOCTL=y
CONFIG_NETDEV_IFINDEX=y
CONFIG_NET_CAN=y
CONFIG_NET_CAN_RAW_TX_DEADLINE=y
CONFIG_NET_CAN_SOCK_OPTS=y
CONFIG_NET_CAN_NOTIFIER=y
CONFIG_NET_TIMESTAMP=y
CONFIG_STM32H7_FDCAN1=y
CONFIG_STM32H7_FDCAN2=y
CONFIG_CANUTILS_CANDUMP=y
CONFIG_CANUTILS_CANSEND=y

And then basically try out cansend and candump and adapt those to what I needed.

And I think I still have to set ENABLE_UAVCAN to 0 to actually get it to work, even though that shouldn’t be required.

Thanks for your reply!
Do you mean by conducting these settings, I can directly call the methods in cansend.c and candump.c in platforms\nuttx\NuttX\apps\canutils to receive/transmit messages? Are there any other settings need to be done such as modifing the original methods in cansend.c ?

You will have to adapt cansend and candump to what you actually need to do on CAN. Or rather you copy the parts of cansend and candump that you need. But for a first test, cansend/candump can help you debug whether it works.

got it. I will try it on my v6x hardware,hope it works. Thanks very much!

1 Like

Hi Julian, I did the configuarations as you described above, but when I type “cansend can0 1122334455667788” or “candump can0” in the nsh console, nothing happens and i can’t receive or send any can messages through my USB-CAN device.
Are there any mistake in my working procedure? I just don’t know how to make it work…

It actually worked out as described by @JulianOes .
However it turns that i cannot change the configuration “CONFIG_FDCAN1_DATA_BITRATE=500000” and “CONFIG_FDCAN2_DATA_BITRATE=500000” ,I still have to use baudrate of 1000k to establish commonication.
Does anyone know how can I change the baudrate to 500k? Thanks in advance.

Hi,Julian. I found the following issue when using v6x CAN communication: when using standard frames, only some ID data can be received, and many IDs seem to be filtered. This issue does not occur when using extended frame packets. May I ask if there is a problem with my configuration?I configured it according to what you provided above.

Did you see my hack?

And my question here?
https://community.st.com/s/question/0D53W00001xRGuQSAW/how-is-can-message-ram-initializedzeroed-on-stm32h7

thank you Julian!!! It’s work.

1 Like