I develop a project using the imx8mm chip running Linux 4.19. The chip has no CAN controller so we use a SPI to CAN converter Microchip MCP2518FD. It is connected via SPI and one interrupt GPIO. The interaction between imx8 and mcp2518 is driven by that GPIO interrupt (for example, the GPIO pin is asserted when there's new data in Rx buffer).
I have a strange issue. The kernel log often says that mcp2518 Rx buffer gets overlowed and ifconfig shows a significant number of rx errors on can0 interface. While investigating the issue, I noticed that the number of errors highly depends on the load of imx8 core 0.
- When core 0 load is low, the rx error rate goes up to 6%.
- When core 0 load is 100%, there are no rx errors. For testing purposes, I used a script that creates a dummy load on core0 (continious archiving of a file or continios reading of /dev/random).
It looks very strange, that loading the main core fixes the issue. I suppose that some interrupts are missed or processed with delay due to wait or sleep mode of the CPU. And creating a dummy load prevents the CPU from entering such modes.
Could you suggest any ideas on how to make SPI or interrupt GPIO work reliable at low CPU load?
I have no idea why you get better results with higher CPU load. I haven't read the MCP2518FD data sheet, but if the RX FIFO is small and you have only a small budget for the IRQ-to-SPI latency, I would try either...
For getting an idea about custom SDMA scripts, you can read this:
We are using an MPX2518FD on an imx8mm for the same reason ( no can in imx8mm) ..
Can I ask you how you managed to get MCP2518fd running on an older IMX-kernel ( for example 4.14.98)
Ive been trying to backport (the current 'linux-next' drivers for mcp251xfd, but ran into to many troubles)
Hi @Noel_V ,
I also found it difficult to backport the mcp25xxfd driver from the latest kernel. A year ago, we successfully ported the driver from the kernel version 5.10 (if I remember it right). That required minor changes (changing fields in one struct, modifying Makefile, etc.). Unfortunately, I cannot answer exactly because I moved my project to kernel 5.40 and abandoned all work with older versions.
While investigating the ways to resolve CAN issues, I found out that Variscite puts much efforts on supporting MCP25. I'd suggest checking their fork of linux-imx on github , that helped me a lot.
It seems that the GPIO interrupt priority might not be handled correctly by the processor. Have you tried to use the spidev utility?
I hope this helps!
Thank you for response. The MCP2518 uses the kernel space driver linux-imx/drivers/net/can/spi/mcp251x.c and is available as "can0" network interface. I haven't tried to implement custom driver but I feel that user space driver might be a bad choice. We also tried to backport the driver from the latest mainline kernel but the rx overlow is still there.