对于mcp2515的移植相关知识课先参考这里http://blog.csdn.net/sno_guo/article/details/17029295
下面是针对s5p4418官方提供的内核为基础做的相关修改。
对于2515的驱动我们不用关心,直接使用内核自带的即可。首先我们需要对内核的配置做添加,具体如下面的图所示:
务必确保内核的配置中上面图片的选择是被打开的,免得做其他工作时造成未知的问题。
下面是修改板级目录下device.c的文件,找到下面的代码,并修改成如下所示:
/*------------------------------------------------------------------------------ * SSP/SPI */ #if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE) #include <linux/spi/spi.h> #include <linux/can/platform/mcp251x.h> static void spi0_cs(u32 chipselect) { //printk("ERTER:%s ......\n",__func__); #if (CFG_SPI0_CS_GPIO_MODE) if(nxp_soc_gpio_get_io_func( CFG_SPI0_CS )!= nxp_soc_gpio_get_altnum( CFG_SPI0_CS)) nxp_soc_gpio_set_io_func( CFG_SPI0_CS, nxp_soc_gpio_get_altnum( CFG_SPI0_CS)); nxp_soc_gpio_set_io_dir( CFG_SPI0_CS,1); nxp_soc_gpio_set_out_value( CFG_SPI0_CS , chipselect); #else ; #endif } struct pl022_config_chip spi0_info = { /* available POLLING_TRANSFER, INTERRUPT_TRANSFER, DMA_TRANSFER */ .com_mode = CFG_SPI0_COM_MODE, .iface = SSP_INTERFACE_MOTOROLA_SPI, /* We can only act as master but SSP_SLAVE is possible in theory */ .hierarchy = SSP_MASTER, /* 0 = drive TX even as slave, 1 = do not drive TX as slave */ .slave_tx_disable = 1, .rx_lev_trig = SSP_RX_4_OR_MORE_ELEM, .tx_lev_trig = SSP_TX_4_OR_MORE_EMPTY_LOC, .ctrl_len = SSP_BITS_8, .wait_state = SSP_MWIRE_WAIT_ZERO, .duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX, /* * This is where you insert a call to a function to enable CS * (usually GPIO) for a certain chip. */ #if (CFG_SPI0_CS_GPIO_MODE) .cs_control = spi0_cs, #endif .clkdelay = SSP_FEEDBACK_CLK_DELAY_1T, }; void s5p4418_mcp2515_init(void) { printk("ERTER:%s ......\n",__func__); nxp_soc_gpio_set_io_func(PAD_GPIO_C+ 30, 0); nxp_soc_gpio_set_io_func(PAD_GPIO_C+ 29, 1); nxp_soc_gpio_set_io_func(PAD_GPIO_D+ 0, 1); nxp_soc_gpio_set_io_func(PAD_GPIO_C+ 31, 1); nxp_soc_gpio_set_io_func(PAD_GPIO_B+ 6, 0); } static struct mcp251x_platform_data mcp251x_info = { .oscillator_frequency = 20 * 1000 * 1000, .board_specific_setup = &s5p4418_mcp2515_init, .power_enable = NULL, .transceiver_enable = NULL, }; static struct spi_board_info spi_plat_board[] __initdata = { #ifdef CONFIG_CAN_MCP251X [0] = { .modalias = "mcp2515", /* fixup */ .max_speed_hz = 1 * 1000 * 1000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, /* Note> set bus num, must be smaller than ARRAY_SIZE(spi_plat_device) */ .chip_select = 0, /* Note> set chip select num, must be smaller than spi cs_num */ .controller_data = &spi0_info, .mode = SPI_MODE_0, .platform_data = &mcp251x_info, .irq = PB_PIO_IRQ(CFG_IO_CAN_DETECT), }, #else [0] = { .modalias = "spidev", /* fixup */ .max_speed_hz = 3125000, /* max spi clock (SCK) speed in HZ */ .bus_num = 0, /* Note> set bus num, must be smaller than ARRAY_SIZE(spi_plat_device) */ .chip_select = 0, /* Note> set chip select num, must be smaller than spi cs_num */ .controller_data = &spi0_info, .mode = SPI_MODE_3 | SPI_CPOL | SPI_CPHA, }, #endif }; #endif
1.spi_plat_board结构体增加了对mcp2515的定义
2.添加mcp251x_info结构定义
3.添加void s5p4418_mcp2515_init(void)函数
这里说明一下void s5p4418_mcp2515_init(void)函数的意义,该函数是对SPI0的GPIO做了配置,在默认的情况下SPI0的GPIO不一定为SPI的功能,所以这里务必需要重新配置一下(由于开始没注意,导致了无法初始化的问题),当然这个配置工作也可以在其他的地方做。
CFG_IO_CAN_DETECT这个定义是在板级目录的include目录下cfg_main.h文件中,这里定义的是GPIOB6引脚。
做了上面的配置之后初始化就应该没有问题了。
使用ifconfig can0 up进行检测,如果不报错那么与mcp2515的通信是没有问题了。
剩下的就可以使用ip、candump等命令进行 can操作了。
希望对移植can遇到问题的朋友有所帮助。