Chinaunix首页 | 论坛 | 博客
  • 博客访问: 976795
  • 博文数量: 109
  • 博客积分: 554
  • 博客等级: 中士
  • 技术积分: 2577
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-04 12:49
文章分类

全部博文(109)

文章存档

2019年(5)

2016年(7)

2015年(9)

2014年(1)

2013年(71)

2012年(16)

分类: 嵌入式

2013-05-19 10:24:56

1. 开发环境

主机操作系统: Debian 6.0

开发板内核: 2.6.38

主机交叉编译器: arm-none-linux-gnueabi-gcc version 4.5.1 (Sourcery G++ Lite 2010.09-50)

2. 给内核打补丁

1.  首先从

2.  内核与代码目录 /home/enzo/H9200F/linux-2.6.38,将补丁文件拷贝到/home/enzo/H9200F目录

3.  给内核打上at91rm9200补丁,切换工作目录到/home/enzo/H9200F/linux-2.6.38/执行一下命令:

zcat ../2.6.38-at91.patch.gz |patch p1

 

3   修改内核代码支持SD

以下内容为自己修改支持SD卡补丁

diff --git a/arch/arm/mach-at91/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c

index c1f9feb..e3405cf 100644

--- a/arch/arm/mach-at91/at91rm9200_devices.c

+++ b/arch/arm/mach-at91/at91rm9200_devices.c

@@ -563,9 +563,9 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)

    for (i = 0; i < nr_devices; i++) {

       if (devices[i].controller_data)

           cs_pin = (unsigned long) devices[i].controller_data;

-      else

+      else                    /*使用PA4标准片选*/

           cs_pin = spi_standard_cs[devices[i].chip_select];

-

+        /* 设置片选线为输出 */

       if (devices[i].chip_select == 0)   /* for CS0 errata */

           at91_set_A_periph(cs_pin, 0);

       else

@@ -583,6 +583,7 @@ void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)

    }

 

    spi_register_board_info(devices, nr_devices);

+    /* 注册spi设备 */

    platform_device_register(&at91rm9200_spi_device);

 }

 #else

diff --git a/arch/arm/mach-at91/board-rm9200dk.c b/arch/arm/mach-at91/board-rm9200dk.c

index 5b0611e..cc716cd 100644

--- a/arch/arm/mach-at91/board-rm9200dk.c

+++ b/arch/arm/mach-at91/board-rm9200dk.c

@@ -29,6 +29,7 @@

 #include

 #include

 #include

+#include //struct mcp251x_platf

 

 #include

 #include

@@ -278,8 +279,43 @@ static struct at91_mmc_data __initdata dk_mmc_data = {

    .wire4     = 1,

     .wire4       = 0, //9200 4 wire mode has some problem,but 1 wire mode work well.

 };

+static void __init mcp251x_init(void)

+{

+//    at91_set_gpio_output(AT91_PIN_PB17, 0); /* power on */

+//    at91_set_gpio_output(AT91_PIN_PB16, 1); /* can reset */

+   

+     at91_set_gpio_input(AT91_PIN_PC0, 1);

+     at91_set_deglitch(AT91_PIN_PC0, 1);

+}

+

+static int mcp251x_power_enable(int enable)

+{

+   printk(KERN_INFO "mcp251x_power_enable\n");

+   return 0;

+}

+

+

+static struct mcp251x_platform_data mcp251x_info = {

+        .oscillator_frequency = 16000000,

+        //.board_specific_setup = myboard_mcp251x_initfunc,

+        //.device_reset = myboard_mcp251x_reset,

+        .power_enable = NULL,

+        .transceiver_enable = NULL,

+};

 

 static struct spi_board_info dk_spi_devices[] = {

+    {

+        .modalias       = "mcp2515", //与实际芯片名字一致,不能为mcp251x,参见mcp251x.c注释

+        .platform_data  = &mcp251x_info,  //上面的结构体

+        .irq              = AT91_PIN_PC0,           // 中断端口号

+        .max_speed_hz  = 8000000,            //spi最大的速度

+//        .bus_num        = 0,            //spi控制器编号

+        .chip_select      = 1,            //片选编号

+        .controller_data = (void *) AT91_PIN_PA4,   /* CS pin */

+

+    },

+

+#if 0   

    {   /* DataFlash chip */

       .modalias  = "mtd_dataflash",

       .chip_select  = 0,

@@ -302,8 +338,10 @@ static struct spi_board_info dk_spi_devices[] = {

       .max_speed_hz = 15 * 1000 * 1000,

    }

 #endif

+#endif

 };

 

+

 static struct i2c_board_info __initdata dk_i2c_devices[] = {

    {

       I2C_BOARD_INFO("ics1523", 0x26),

@@ -383,11 +421,13 @@ static void __init dk_board_init(void)

 // at91_add_device_udc(&dk_udc_data);

 // at91_set_multi_drive(dk_udc_data.pullup_pin, 1); /* pullup_pin is connected to reset */

    /* Compact Flash */

-   at91_add_device_cf(&dk_cf_data);

+// at91_add_device_cf(&dk_cf_data);

    /* I2C */

-   at91_add_device_i2c(dk_i2c_devices, ARRAY_SIZE(dk_i2c_devices));

+// at91_add_device_i2c(dk_i2c_devices, ARRAY_SIZE(dk_i2c_devices));

    /* SPI */

+    mcp251x_init();

    at91_add_device_spi(dk_spi_devices, ARRAY_SIZE(dk_spi_devices));

+

 #ifdef CONFIG_MTD_AT91_DATAFLASH_CARD

    /* DataFlash card */

    at91_set_gpio_output(AT91_PIN_PB7, 0);

@@ -397,17 +437,17 @@ static void __init dk_board_init(void)

    at91_add_device_mmc(0, &dk_mmc_data);

 #endif

    /* NAND */

-   at91_add_device_nand(&dk_nand_data);

+// at91_add_device_nand(&dk_nand_data);

    /* NOR Flash */

    platform_device_register(&dk_flash);

    /* LEDs */

-   at91_gpio_leds(dk_leds, ARRAY_SIZE(dk_leds));

+// at91_gpio_leds(dk_leds, ARRAY_SIZE(dk_leds));

    /* SSC (to LM4549 audio codec) */

-   at91_add_device_ssc(AT91RM9200_ID_SSC1, ATMEL_SSC_TD | ATMEL_SSC_RX);

+// at91_add_device_ssc(AT91RM9200_ID_SSC1, ATMEL_SSC_TD | ATMEL_SSC_RX);

    /* SSC (to SI3021 line interface) */

-   at91_add_device_ssc(AT91RM9200_ID_SSC2, ATMEL_SSC_TD | ATMEL_SSC_TK | ATMEL_SSC_RD | ATMEL_SSC_RF);

+// at91_add_device_ssc(AT91RM9200_ID_SSC2, ATMEL_SSC_TD | ATMEL_SSC_TK | ATMEL_SSC_RD | ATMEL_SSC_RF);

    /* VGA */

-   dk_add_device_video();

+// dk_add_device_video();

 }

 

 MACHINE_START(AT91RM9200, "Atmel AT91RM9200-DK")

diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c

index 7513c45..90e1f3f 100644

--- a/drivers/net/can/mcp251x.c

+++ b/drivers/net/can/mcp251x.c

@@ -915,6 +915,11 @@ static int mcp251x_open(struct net_device *net)

    struct spi_device *spi = priv->spi;

    struct mcp251x_platform_data *pdata = spi->dev.platform_data;

    int ret;

+    unsigned long irq_flags;

+/*   

+    dev_dbg(&spi->dev, "%s: irq_flags: %d oscillator_frequency: %d\n", \

+                __FUNCTION__, pdata->irq_flags,pdata->oscillator_frequency);

+*/

 

    ret = open_candev(net);

    if (ret) {

@@ -929,9 +934,12 @@ static int mcp251x_open(struct net_device *net)

    priv->force_quit = 0;

    priv->tx_skb = NULL;

    priv->tx_len = 0;

-

+    /* atmel 必须使用上升沿+下降沿,不能只用上升沿,或下降沿, at91 GPIO是电平变化中断 */

+    irq_flags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING;

+// irq_flags |= IRQF_ONESHOT;

+    dev_dbg(&spi->dev, "%s: irq_flags: %d oscillator_frequency: %d\n",__FUNCTION__, irq_flags,pdata->oscillator_frequency);

    ret = request_threaded_irq(spi->irq, NULL, mcp251x_can_ist,

-            IRQF_TRIGGER_FALLING, DEVICE_NAME, priv);

+            irq_flags, DEVICE_NAME, priv);

    if (ret) {

       dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq);

       if (pdata->transceiver_enable)

@@ -978,7 +986,7 @@ static int __devinit mcp251x_can_probe(struct spi_device *spi)

    struct mcp251x_priv *priv;

    struct mcp251x_platform_data *pdata = spi->dev.platform_data;

    int ret = -ENODEV;

-

+    dev_dbg(&spi->dev, "%s: start\n",  __FUNCTION__);

    if (!pdata)

       /* Platform data is required for osc freq */

       goto error_out;

diff --git a/kernel/printk.c b/kernel/printk.c

index 3623152..39f9878 100644

--- a/kernel/printk.c

+++ b/kernel/printk.c

@@ -57,7 +57,7 @@ void asmlinkage __attribute__((weak)) early_printk(const char *fmt, ...)

 

 /* We show everything that is MORE important than this.. */

 #define MINIMUM_CONSOLE_LOGLEVEL 1 /* Minimum loglevel we let people use */

-#define DEFAULT_CONSOLE_LOGLEVEL 7 /* anything MORE serious than KERN_DEBUG */

+#define DEFAULT_CONSOLE_LOGLEVEL 8 /* anything MORE serious than KERN_DEBUG */

 

 DECLARE_WAIT_QUEUE_HEAD(log_wait);

 

 

配置内核

Device Drivers -à

    <*>MMC/SD/SDIO card support -à

       <*> MMC block device driver

       (8) Number of minors per block device

       [*] Use bounce buffer for simple hosts

       <*> Atmel SD/MMC Driver(AT91 SD/MMC Card Interface support

           (X)AT91 SD/MMC Card Interface support

重新编译内核,生成内核镜像

make uImage


阅读(2293) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~