Enabling SJA1000 support on iMX6 for custom carrier board

We are exploring the possibility of migrating our applications, which currently run on top of WinCE7 on a T20 Colibri, to run on top of TorizonCore on a iMX6 Colibri.

We make custom carriers board which are mostly compatible with TorizonCore on a iMX6 Colibri, but our applications rely heavily on CAN communication and our custom board currently uses the SJA1000 CAN controller which we know is not supported out the box.

We know the iMX6 has an internal CAN controller which is supported on TorizonCore and it should be preferably used over an external CAN controller. We are working on a new custom board which will make use on the internal CAN controller, but in the meantime and also for backwards compatibility with our current board we wanted to know if it would be possible to use the SJA1000 CAN controller with the iMX6 Colibri and TorizonCore.

We expect that we’ll need to modify and build a custom device tree/overlay, but also on the CAN documentation we read that to enable SJA1000 support for the T20 Colibri the linux kernel needs to be recompiled with certain options and we were wondering if this was possible/necessary to enable it on the iMX6.

We found bindings and a driver in the linux kernel source. Could we instead use these to build and load the driver as external kernel module using TorizonCore Builder?

We read about the SocketCAN layer and it is our brief understanding that if we write software that uses this API (and maybe also the SAE J1939 protocol) and later down the line we change the CAN controller, the software will keep working independently of the hardware and the driver, is this correct?

Colibri iMX6DL 512MB V1.1A
Custom carrier board
TorizonCore Upstream 5.5.0+build.11 (dunfell)

Greetings @mmarcos.sensor,

Before I go in-depth into your question here I have a couple of question just to make sure I understand your situation.

So you’re looking to enable Linux kernel support for this “SJA1000” CAN controller on TorizonCore. However, you eventually plan to make use of the internal CAN controller on the i.MX6 going forward. But for compatibility reasons you’d like the option to have both of these if possible. Did I understand that all correct?

OS-wise do you plan to have 2 variations of your TorizonCore image? One that is configured for the SJA1000 and another that is configured for the internal CAN controller?

Or, are you going to have just one OS image that has both configured at the same time?

Best Regards,
Jeremias

@jeremias.tx thank you for replying so shortly.

So you’re looking to enable Linux kernel support for this “SJA1000” CAN controller on TorizonCore. However, you eventually plan to make use of the internal CAN controller on the i.MX6 going forward. But for compatibility reasons you’d like the option to have both of these if possible. Did I understand that all correct?

Your first assumption is correct, this was exactly our reasoning.

OS-wise do you plan to have 2 variations of your TorizonCore image? One that is configured for the SJA1000 and another that is configured for the internal CAN controller?

Or, are you going to have just one OS image that has both configured at the same time?

Regarding your questions: whether we plan to have 1 or 2 images, we are still contemplating the advantages or disadvantages of each case.

Our experience is that having 1 image is easier to maintain, but it adds an extra configuration step to production. Having 2 images is simpler for production but adds a maintenance burden. We could solve it with our CI server, having it automatically build both images from the same application source. There are lots of ways to go about it.

Why exactly do you ask? How does the answer vary in one case or the other?

Best regards,
Martin.

Hi @mmarcos.sensor,

Why exactly do you ask? How does the answer vary in one case or the other?

This doesn’t matter too much, it’s just good to know ahead of time in case the conversation goes deeper. Though let me begin answering your initial questions first of all.

we were wondering if this was possible/necessary to enable it on the iMX6.

Yes, it is possible to use SJA1000 CAN controller with the Colibri iMX6, but the kernel needs to be recompiled with additional configurations enabled. And as you said, the device tree has to be modified accordingly. Just to confirm do you know which exact kernel configs need to enabled for this controller? Looking at the driver source I can assume, but I just want to make sure we enable the correct things for you.

We know the iMX6 has an internal CAN controller which is supported on TorizonCore and it should be preferably used over an external CAN controller.

You also have to tinker with the device tree if you use the internal CAN controller, as its pins are not set by default in our Colibri modules. The CAN developer page you linked has additional information on how to do it.

Could we instead use these to build and load the driver as external kernel module using TorizonCore Builder?

The current TorizonCore upstream kernel already has the SJA1000 driver in it’s source (sja1000 « can « net « drivers - linux-toradex.git - Linux kernel for Apalis and Colibri modules), so you don’t need to load it as a separate module. I can make the request to enable this as a kernel module by default once we confirm what configuration options you would need enabled.

later down the line we change the CAN controller, the software will keep working independently of the hardware and the driver, is this correct?

About the SocketCAN layer, you’re pretty much correct about it.

With all that said if you could confirm the exact kernel configurations you want enabled for the SJA1000, then I can proceed with the request to our team.

Best Regards,
Jeremias

@jeremias.tx

Actually we don’t know exactly what kernel options need to be enabled, we are pretty new to kernel configuration and compilation. How can we figure out what options are available and which ones need to be enabled for a desired functionality? Is there any documentation we can consult? Is there a command we can execute on the kernel source to get all available kernel options?

We only guessed that we would need to enable certain kernel options and recompile because we read it on the CAN documentation for the Colibri T20/T30. It says that kernel needs to be recompiled with the following options enabled:

CONFIG_CAN
CONFIG_CAN_RAW
CONFIG_CAN_BCM
CONFIG_CAN_DEV (depending on kernel version)

And, for de SJA1000 CAN controller which comes on the Evaluation Board revision 2.x, the following options as well:

CONFIG_CAN_SJA1000
CONFIG_CAN_SJA1000_PLATFORM

How can we be sure these are the same options that need to be enabled for the Colibri iMX6?

Yes, we saw it. We had some experience recently modifying the device tree and we think we can manage it when the time comes to switch to the iMX6’s internal CAN controller. At least this step doesn’t require reconfiguring and recompiling the kernel.

About the SocketCAN layer, you’re pretty much correct about it.

Great, that means we can start developing the application and it will still work when we switch the controller and driver.

Best regards,
Martin.

Actually we don’t know exactly what kernel options need to be enabled, we are pretty new to kernel configuration and compilation. How can we figure out what options are available and which ones need to be enabled for a desired functionality? Is there any documentation we can consult? Is there a command we can execute on the kernel source to get all available kernel options?

Looking at the list of options related to the SJA1000 here: Kconfig « sja1000 « can « net « drivers - linux-toradex.git - Linux kernel for Apalis and Colibri modules

It looks like it only needs these options:

CONFIG_CAN_SJA1000
CONFIG_CAN_SJA1000_PLATFORM

I’ll see if this is something we can check before we add these to make sure.

With that said let me do this. I’ll make the request to our team to add the kernel config options for the above options related to the SJA1000. If there are no issues with adding these then the team should be able to add them relatively easy.

It will probably take the team roughly a week or so to add these. Once they’re added you should be able to then see these options enabled in a future nightly build of TorizonCore.

Does this sound all good to you? If yes, then I can go ahead with the request on my side.

Best Regards,
Jeremias

@jeremias.tx

It sound good to us.

Thank you for all your support.

Best regards,
Martin.

Alright then, the request for these configs has been made to the team. I’ll let you know when there is an update.

Best Regards,
Jeremias

Hi @mmarcos.sensor,

I was just informed that these configuration options should now be enabled by default in our kernel. This change should start showing up in our nightly builds in the next day or so.

Keep an eye out for this and let me know if you still don’t see this configuration enabled by default.

Best Regards,
Jeremias