How to enable CAN peripheral

Hi I am working on Colibri iMX6ULL module and I want to use CAN peripheral. I used the below reference and edited the device tree source include file (.dtsi)

Reference: https://developer.toradex.com/linux-bsp/application-development/peripheral-access/can-linux#kernel-support-colibri-imx6ull

What should be my next step?

Hi, I’m the Toradex AI Assistant. I’m in early beta, and I would appreciate your feedback.
The Toradex Support team will follow up with you shortly!

Did you like my answer?

:+1: :-1:


Hello,

After editing the device tree source file to enable the CAN peripheral by setting the status of the &can1 and/or &can2 node to okay, your next steps should involve recompiling the device tree and deploying it to your Colibri iMX6ULL module. Here’s a concise guide on what to do next:

  1. Recompile the Device Tree: Use the appropriate commands to compile the device tree source files into a binary format (.dtb). This process typically involves using the dtc (Device Tree Compiler) tool or executing a build process through a build system like Yocto Project or Buildroot, depending on how you manage your software development.

  2. Deploy the Compiled Device Tree: Copy the compiled device tree binary to the boot partition of your module or use the U-Boot environment to tell the bootloader where to find the new device tree file. The exact method may vary depending on your setup and whether you’re using a carrier board’s specific configurations.

  3. Reboot the Module: After deploying the new device tree, reboot your Colibri iMX6ULL module to apply the changes. The system will use the updated device tree on boot, enabling the CAN peripheral as configured.

  4. Verify the CAN Interface: Once the system is up, verify that the CAN interface is recognized and correctly configured by the kernel. You can use the ip link show command to list all network interfaces, including CAN interfaces. If the CAN interface is correctly enabled, it should appear in the list.

  5. Configure the CAN Interface: Before using the CAN interface, you’ll need to configure it with the appropriate settings for your CAN network, such as bitrate. This can be done using the ip or ifconfig command-line tools.

  6. Test the CAN Interface: Finally, test the CAN interface to ensure it’s working as expected. You can use can-utils, a collection of utilities for Linux designed to work with CAN networks, to send and receive CAN frames.

Remember, any changes to the device tree or system configuration should be thoroughly tested to ensure they do not adversely affect your system’s stability or functionality.

Best regards,
Toradex AI Assistant

Please, also check if these links can help you solve your problem:

How to Use CAN on Torizon OS | Toradex Developer Center.

Hi @kp_2024,

To enable can, do device tree modification as per article and make sure pins assigned to can node is not used elsewhere.

Best regards
Ritesh Kumar

yes, I made the modifications as mentioned. But I am confused that what should be my next step- Do I regenerate the image directly using $bitbake core-image-minimal or is there a step I am missing in between?

Hi @kp_2024,

At this moment I will suggest if you can work with source code outside oe build specially for device tree. Please check below article:

Once you verified your device tree, then you can move to oe/yocto to generate final image.
Best regards
Ritesh Kumar

Thanks! This will definitely help me…

Hello Ritesh,

I build the device tree binary (dtb) with the applied changes as mentioned in the https://developer.toradex.com/linux-bsp/application-development/peripheral-access/can-linux#kernel-support-colibri-imx6ull

Once the dtb file is build, I copied it and pasted it into my core-image-minimal tezi file (unzipped) replacing the imx6ull-colibri-eval-v3.dtb file (old).

I rebooted the module with the new image (containing new dtb file), but sill I cannot see any device of CAN using command: $ip link show or $ifconfig

Could you guild me here little bit as the above steps that I mentioned are correct or not?

Thanks
Krutarth Purohit

hi @kp_2024 ,
You must have forgotten to check whether the CAN pins are used somewhere else or not and to disable them.
In your case, looking into the imx6ull-colibri.dtsi file, can0 and can1 pins (pinctrl_gpio3 pinctrl_gpio7) are used in &iomux.
Please delete/comment out these pins , recompile the device tree and test.

If you did something wrong with pinmuxing, like pins assigned to different modules, then something like dmesg | grep iomux should reveal such issues.
If you enable some node in DT, or do other changes in DT, inspecting /sys/firmware could help confirming got your changes successfully applied or not. For example checking for can status=“okay” could look like this

# find /sys/firmware -name "*can*"
/sys/firmware/devicetree/base/soc/bus@40000000/iomuxc@40048000/vf610-colibri/can0grp
/sys/firmware/devicetree/base/soc/bus@40000000/iomuxc@40048000/vf610-colibri/can_int
/sys/firmware/devicetree/base/soc/bus@40000000/iomuxc@40048000/vf610-colibri/can1grp
/sys/firmware/devicetree/base/soc/bus@40000000/spi@4002d000/can@0
/sys/firmware/devicetree/base/soc/bus@40000000/spi@4002d000/mcp2518fd@0/microchip,txcan-open-drain
/sys/firmware/devicetree/base/soc/bus@40000000/can@40020000
/sys/firmware/devicetree/base/soc/bus@40080000/can@400d4000
/sys/firmware/devicetree/base/aliases/can0
/sys/firmware/devicetree/base/aliases/can1

# ls /sys/firmware/devicetree/base/soc/bus@40000000/can@40020000
clock-names    compatible     name           pinctrl-names  status
clocks         interrupts     pinctrl-0      reg

# cat  /sys/firmware/devicetree/base/soc/bus@40000000/can@40020000/status
disabled


@Edward @sahil.tx

Hi thanks for replying, I have run the command and it seems like CAN-0 device is running.

root@localhost:~# find /sys/firmware/ -name "*can*"
/sys/firmware/devicetree/base/__symbols__/pinctrl_flexcan1
/sys/firmware/devicetree/base/__symbols__/can2
/sys/firmware/devicetree/base/__symbols__/pinctrl_flexcan2
/sys/firmware/devicetree/base/__symbols__/pinctrl_can_int
/sys/firmware/devicetree/base/__symbols__/can1
/sys/firmware/devicetree/base/soc/aips-bus@2000000/flexcan@2090000
/sys/firmware/devicetree/base/soc/aips-bus@2000000/spba-bus@2000000/spi@2008000/can@0
/sys/firmware/devicetree/base/soc/aips-bus@2000000/iomuxc@20e0000/imx6ull-colibri/flexcan2-grp
/sys/firmware/devicetree/base/soc/aips-bus@2000000/iomuxc@20e0000/imx6ull-colibri/flexcan1-grp
/sys/firmware/devicetree/base/soc/aips-bus@2000000/iomuxc@20e0000/imx6ull-colibri/canint-grp
/sys/firmware/devicetree/base/soc/aips-bus@2000000/flexcan@2094000
root@localhost:~#
root@localhost:~#
root@localhost:~# ls /sys/firmware/devicetree/base/soc/aips-bus@2000000/spba-bus@2000000/spi@2008000/can@0/
clocks             name               reg                xceiver-supply
compatible         phandle            spi-max-frequency
interrupt-parent   pinctrl-0          status
interrupts         pinctrl-names      vdd-supply
root@localhost:~# cat /sys/firmware/devicetree/base/soc/aips-bus@2000000/spba-bus@2000000/spi@2008000/can@0/status
okay

This is about MCP2515 SPI-CAN device on eval-v3 board, which is enabled by default in BSP. Your first message, at least the reference in it, was about SOC build-in FlexCAN devices, so you should check your DT flexcan instances:

cat /sys/firmware/devicetree/base/soc/aips-bus@2000000/flexcan@2090000/status
cat /sys/firmware/devicetree/base/soc/aips-bus@2000000/flexcan@2094000/status

hi,
I check the status of the flexcan, it was ‘disabled’ earlier, so I modified the device tree and change it’s status to ‘okay’.

**root@localhost:~#** cat /sys/firmware/devicetree/base/soc/aips-bus@2000000/flexcan@2090000/status
okay
**root@localhost:~#** cat /sys/firmware/devicetree/base/soc/aips-bus@2000000/flexcan@2094000/status
okay

Now, am I supposed to see any CAN device when I enter command: $ifconfig -a OR $ip link show? because I am not getting any CAN device.


root@localhost:~# ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop qlen 1000
    link/ether 00:14:2d:6a:45:4f brd ff:ff:ff:ff:ff:ff

root@localhost:~# ifconfig -a
eth0: flags=4098<BROADCAST,MULTICAST>  mtu 1500  metric 1
        ether 00:14:2d:6a:45:4f  txqueuelen 1000  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536  metric 1
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Kernel config should have FLEXCAN driver enabled. You may verify it with

# zcat /proc/config.gz | grep FLEXCAN
CONFIG_CAN_FLEXCAN=m

both =m and =y would be OK.

If flexcan is enabled, then dmesg should mention problems, which make driver probe fail. Try
dmesg | grep flexcan or dmesg | grep pinmux. If none finds something, then just try reading whole dmesg output. Some problems should be listed there

Hi I run the commands mentioned by you, here are the output:

root@localhost:~# zcat /proc/config.gz | grep FLEXCAN
CONFIG_CAN_FLEXCAN=m
root@localhost:~# dmesg | grep flexcan
root@localhost:~# dmesg | grep pinmux

The flexcan module is present but there is no mention of flexcan OR pinmux in the dmesg log.

Does lsmod list flexcan driver? Perhaps no loaded modules at all?

Hi @Edward @ritesh.tx

I noticed that there are no modules available for CAN when I checked using lsmod. However, I inserted CAN kernel modules - can.ko , can-dev.ko , can-raw.ko and flexcan.ko using insmod command.

Thank you both of you for your time and efforts.

Something is wrong on your side. Those modules should be autoloaded. Perhaps you have zImage from one compilation / config and modules from another one. You should compile both and populate both modules and kernel to target.

It seems that, minimal image do not auto-load the kernel module. I build the toradex the multimedia image and checked for the kernel modules that are present.

**root@colibri-imx6ull-06964559:~#** lsmod
Module                  Size  Used by
rfcomm                 69632  2
bnep                   24576  2
usb_f_rndis            32768  2
u_ether                24576  1 usb_f_rndis
mcp251x                20480  0
can_dev                28672  1 mcp251x
mwifiex_sdio           36864  0
btmrvl_sdio            32768  0
btmrvl                 24576  1 btmrvl_sdio
mwifiex               282624  1 mwifiex_sdio
bluetooth             491520  31 btmrvl_sdio,bnep,rfcomm,btmrvl
cfg80211              331776  1 mwifiex
imx_sdma               36864  2
virt_dma               16384  1 imx_sdma
secvio                 16384  0
libcomposite           61440  10 usb_f_rndis
configfs               45056  3 usb_f_rndis,libcomposite

I believe that multimedia image autoloades the kernel module.

Looks like you are using colibri-imx6ull-wifi . Did you modify DT files for colibri-imx6ull or colibri-imx6ull-wifi? You wrote previously that you saw status=okay in /sys/firmware for flexcan instances, so looks like you modified right files? Anyway, with status=okay, enabled driver in config, you should see flexcan module loaded automatically. Even if driver fails to probe, since it was okay, module should be loaded.

Yes, earlier I was editing colibri-imx6ull-eval-v3.dts but later I found out that my image was using colibri-imx6ull-wifi-eval-v3.dtb to load the device tree. Apologies, I should have clarified this earlier in our conservation.

I downloaded the the source code of the kernel (kernel version that is compatible with my BSP 5.x.y) and generated the kernel image [zImage] (colibri-imx6ull_defconfig) along with CAN-enabled device tree binary. Then I replaced both the image into my unzipped Toradex-Image-Tezi folder present in my USB stick.