Socketcan CAN-bus drivers added to OpenEmbedded

I just added a recipe to OpenEmbedded to build the Socketcan kernel modules from the socketcan SVN.  So if you are using the latest OpenEmbedded metadata, you can:

  • bitbake socketcan-modules
  • scp <oedir>/build/angstrom-2008.1/tmp/deploy/glibc/ipk/<machine>/socketcan-modules_0.0+svnr917-r0_cm-x270.ipk  root@<target IP address>:

and then on the target system:

  • opkg install socketcan-modules_0.0+svnr917-r0_cm-x270.ipk
  • opkg files socketcan-modules
Package socketcan-modules (0.0+svnr917-r0) is installed on root and has the following files:
/lib/modules/2.6.27/extra/net/can/can-bcm.ko
/lib/modules/2.6.27/extra/drivers/net/can/sja1000/ems_pci.ko
/lib/modules/2.6.27/extra/net/can/can-raw.ko
/lib/modules/2.6.27/extra/drivers/net/can/sja1000/sja1000.ko
/lib/modules/2.6.27/extra/drivers/net/can/softing/softing.ko
/lib/modules/2.6.27/extra/drivers/net/can/sja1000/ems_pcmcia.ko
/lib/modules/2.6.27/extra/drivers/net/can/sja1000/sja1000_platform.ko
/lib/modules/2.6.27/extra/drivers/net/can/can-dev.ko
/lib/modules/2.6.27/extra/drivers/net/can/softing/softing_cs.ko
/lib/modules/2.6.27/extra/drivers/net/can/sja1000/pipcan.ko
/lib/modules/2.6.27/extra/drivers/net/can/mcp251x.ko
/lib/modules/2.6.27/extra/net/can/can.ko
/lib/modules/2.6.27/extra/net/can/can-isotp.ko
/lib/modules/2.6.27/extra/drivers/net/can/vcan.ko

Then to use the modules:

  • depmod
  • modprobe mcp251x
  • modprobe can-bcm

What is CAN?  Can stands for Controller-area network and is popular in industrial and automotive applications.  A convenient way to add CAN to your Embedded Linux system is with the Microchip MCP2515.  This device connects to a SPI bus which means it can be interfaced with a number of popular SOC’s such as the PXA270, OMAP3, 91SAM9xxx, etc.

More on Socketcan later …

BTW, this recipe really illustrates how easy it is to compile kernel modules outside a kernel in OpenEmbedded:

DESCRIPTION = "Socketcan kernel modules"
HOMEPAGE = "http://developer.berlios.de/projects/socketcan/"
SECTION = "kernel/modules"
LICENSE = "GPL"
DEPENDS = "virtual/kernel"
PV = "0.0+svnr${SRCREV}"

SRC_URI = "svn://svn.berlios.de/socketcan/trunk;module=kernel;proto=svn"

S = "${WORKDIR}/kernel/2.6"

inherit module

This recipe tells OE to download the source, cross-compile it against your target kernel build dir, and then package it for easy install on the device.  This is the way things should work — no messing around figuring out make options, kernel source paths, compiler env variables, etc.

11 replies on “Socketcan CAN-bus drivers added to OpenEmbedded”

  1. What is the path to go to learn OE? The webpage or do you know any tutorial? I have a couple of ARM boards (2440 and IMX31), and I’m interested to add CAN.

    1. Hello,

      As to getting started, I would probably start with the OE wiki: http://wiki.openembedded.net/index.php/Main_Page

      Trying building for a machine/distro that is already in OE. Once you get a baseline build, then start modifying things for your target system. I’ll try to do some more writing along the lines of OE tutorial in the future.

      There is a good support on IRC, and maillist. Beyond that, there are several options for getting commercial support (including BEC Systems) for setting up a OE build system, training, etc.

      Good luck!

  2. A note about the AT91SAMxxx family and CAN … the AT91SAM9263 supports CAN natively, though a Linux kernel driver is not included in the vanilla release. There are some patches that can be applied to the kernel.

    Google is more authoritative on this, but here is one possibly helpful link:

    http://lists.berlios.de/pipermail/socketcan-core/2009-April/002410.html

    A search for the “at91_can.c” driver/patch might reveal more. Hopefully, it will be included in the Linux core soon.

  3. I’d like to use the MCP2515 CAN controller with the OMAP3 based Overo on SPI_1 port.
    Would you have any insight into configuring the mcp251x_platform_data and spi_board_info structures?

  4. To be able to use the mcp251x_platform on the overo would be great. Any success with this?

  5. This is what I used on a PXA270 system, something similiar should work on the overo:

    Below is what I used for a PXA270 system. You should be able to adapt
    for the Overo:

    /*
    * we must control the SPI CS manually as the PXA270 does
    * too much magic by sometimes deasserting it and sometimes
    * not
    */
    static void mcp251x_cs_control(u32 command)
    {
    if (command & PXA2XX_CS_ASSERT)
    gpio_set_value(XY_GPIO_SPI_CS_N, 0);
    else
    gpio_set_value(XY_GPIO_SPI_CS_N, 1);
    }

    static struct pxa2xx_spi_chip xy_mcp251x_chip_info = {
    .tx_threshold = 8, /* SSP hardward FIFO threshold */
    .rx_threshold = 8, /* SSP hardward FIFO threshold */
    .dma_burst_size = 8, /* Byte wide transfers used so 8 byte bursts */
    .timeout = 235, /* See Intel documentation */
    .cs_control = mcp251x_cs_control, /* Use external chip select */
    };

    static int xy_mcp251x_setup(struct spi_device *spi)
    {
    printk(“XY, reset CAN controller\n”);
    gpio_set_value(PP_GPIO_CAN_RST, 1);
    msleep(5);
    gpio_set_value(PP_GPIO_CAN_RST, 0);
    msleep(5);
    gpio_set_value(PP_GPIO_CAN_RST, 1);

    return 0;
    }

    static struct mcp251x_platform_data xy_mcp251x_info = {
    .oscillator_frequency = 16000000,
    .board_specific_setup = &xy_mcp251x_setup,
    .model = CAN_MCP251X_MCP2515,
    .power_enable = NULL,
    .transceiver_enable = NULL,
    };

    static struct spi_board_info spi_board_info[] = {
    {
    .modalias = “mcp251x”,
    .platform_data = &xy_mcp251x_info,
    .controller_data = &xy_mcp251x_chip_info,
    .irq = IRQ_GPIO(PP_GPIO_CAN_INT),
    // this can be increased to 10MHz with 15 part
    // SPI clock is divided down 13MHz, so granularity is not too good
    // 13MHz, 6.5MHz, 4.33MHz, 3.25MHz, 2.6MHz, 2.1666MHz etc.
    .max_speed_hz = 6500000,
    .bus_num = 1,
    .chip_select = 0,
    },
    };

Comments are closed.