打印
[嵌入式linux]

开始学linux驱动,三个月熟悉,立帖为证!每日汇报进展

[复制链接]
楼主: tiger84
手机看帖
扫描二维码
随时随地手机跟帖
121
tiger84|  楼主 | 2010-1-19 12:33 | 只看该作者 回帖奖励 |倒序浏览
出差归来,继续

使用特权

评论回复
122
iotek2009| | 2010-1-19 15:05 | 只看该作者
支持,linux学习更快入门可以看看海同linux课程

使用特权

评论回复
123
icecut| | 2010-1-19 16:10 | 只看该作者
原来出差了

使用特权

评论回复
124
tiger84|  楼主 | 2010-1-19 21:46 | 只看该作者
今天帮同事整了个USB转串口的工装,USB转串口芯片用的是ft232,同事弄了好多天,都无法下手,然后俺这边直接在驱动里面选择上该芯片,写上测试应用程序就OK了,几个同事大呼linux真强大。

使用特权

评论回复
125
tiger84|  楼主 | 2010-1-19 22:01 | 只看该作者
出差时一直在思索sysfs文件系统。
好像/sys目录下只能查看属性,设置属性之类的,我刚开始一直想通过open来打开/sys目录下的某个设备,但是一直没有成功,貌似理解有问题。
写一个设备的驱动查看/sys目录下面,/device下面有该设备,/driver也有该设备驱动,这个时候我想通过open来打开这个设备,也不知道从何下手?iceut兄弟帮我解答下。
打算继续看这一块

使用特权

评论回复
126
tiger84|  楼主 | 2010-1-19 22:02 | 只看该作者
明天linux计划:争取搞定spi dataflash驱动

使用特权

评论回复
127
sdny7788| | 2010-1-19 22:03 | 只看该作者
支持一下

使用特权

评论回复
128
shenyunfeng| | 2010-1-19 23:58 | 只看该作者
路过!!!!!!!!

使用特权

评论回复
129
zhangxujun1981| | 2010-1-20 15:30 | 只看该作者
一起学习,加油:)

使用特权

评论回复
130
反质子| | 2010-1-20 17:32 | 只看该作者
过年了 买块ARM开发板来学习
好像挺带劲的   操作系统于我还是很神奇的未知世界!!

使用特权

评论回复
131
tiger84|  楼主 | 2010-1-20 20:39 | 只看该作者
今天试了下spi接口的data flash驱动,linux内核里面已经自带了芯片at45db161驱动,编译进去,启动系统,不能用。
提示检测不到flash。
然后看了下文件board-sam9260ek.c和板子的电路,发现at45db161使用的是片选0,而board-sam9260ek.c使用的是片选1,把sam9260ek.c里面的at45db161更改成片选0后,成功。

使用特权

评论回复
132
tiger84|  楼主 | 2010-1-20 20:54 | 只看该作者
手上的板子使用的SPI接口的SD卡,SPI0,片选1。也就是说用的和data flash芯片 at45db161同一路SPI,片选不一样而已。
在驱动里面选择 (*)MMC/SD card support
                              (*)MMC block device driver
                               <*> MMC/SD over SPI
然后在文件board-sam9260ek.c里面的ek_spi_devices做如下改动
static struct spi_board_info ek_spi_devices[] = {

#if !defined(CONFIG_MMC_AT91)
        {        // DataFlash chip
                .modalias        = "mtd_dataflash",
        //        .chip_select        = 1,
            .chip_select        = 0,     //zhh
                .max_speed_hz        = 15 * 1000 * 1000,
                .bus_num        = 0,
        },
#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
        {        // DataFlash card
                .modalias        = "mtd_dataflash",
                .chip_select        = 0,
                .max_speed_hz        = 15 * 1000 * 1000,
                .bus_num        = 0,
        },
#endif
#endif
#if defined(CONFIG_MMC_SPI)
        {        /* DataFlash card */
                .modalias        = "mmc_spi",
                .chip_select        = 1,
                .max_speed_hz        = 15 * 1000 * 1000,
                .bus_num        = 0,
        },
#endif


#if defined(CONFIG_SND_AT73C213) || defined(CONFIG_SND_AT73C213_MODULE)
        {        /* AT73C213 DAC */
                .modalias        = "at73c213",
                .chip_select        = 0,
                .max_speed_hz        = 10 * 1000 * 1000,
                .bus_num        = 1,
                .mode                = SPI_MODE_1,
                .platform_data        = &at73c213_data,
        },
#endif
};
     也就是增加了mmc_spi的初始化部分。
编译完毕,
启动系统,
提示
can't share SPI bus

为了简单,我直接把SPI其他部分屏蔽掉了,重新编译,启动,提示如下:
mmc0: error -84 whilst initialising SD card

一路跟踪
mmc_sd_init_card() ----->mmc_send_cid()----->mmc_send_cxd_data()----->
static int
mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,
                u32 opcode, void *buf, unsigned len)
{
        struct mmc_request mrq;
        struct mmc_command cmd;
        struct mmc_data data;
        struct scatterlist sg;
        void *data_buf;

        /* dma onto stack is unsafe/nonportable, but callers to this
         * routine normally provide temporary on-stack buffers ...
         */

        data_buf = kmalloc(len, GFP_KERNEL);
        if (data_buf == NULL)
                return -ENOMEM;

        memset(&mrq, 0, sizeof(struct mmc_request));
        memset(&cmd, 0, sizeof(struct mmc_command));
        memset(&data, 0, sizeof(struct mmc_data));

        mrq.cmd = &cmd;
        mrq.data = &data;

        cmd.opcode = opcode;
        cmd.arg = 0;

        /* NOTE HACK:  the MMC_RSP_SPI_R1 is always correct here, but we
         * rely on callers to never use this with "native" calls for reading
         * CSD or CID.  Native versions of those commands use the R2 type,
         * not R1 plus a data block.
         */
        cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;

        data.blksz = len;
        data.blocks = 1;
        data.flags = MMC_DATA_READ;
        data.sg = &sg;
        data.sg_len = 1;

        sg_init_one(&sg, data_buf, len);

        if (card)
                mmc_set_data_timeout(&data, card);

        mmc_wait_for_req(host, &mrq);

        memcpy(buf, data_buf, len);
        kfree(data_buf);

        if (cmd.error)
        {        
            return cmd.error;
        }               
        if (data.error)
        {
            printk("hello mmc_send_cxd_data data.error is %d\n",data.error);
            return data.error;
        }
               

        return 0;
}
就是上面的  (data.error),从这里跳出去的。

我估计我得把SD卡协议看看才能解决这个问题

使用特权

评论回复
133
yg2003618| | 2010-1-21 10:04 | 只看该作者
三个月?哎,spi这种三个星期足够了。

使用特权

评论回复
134
tiger84|  楼主 | 2010-1-21 20:29 | 只看该作者
把SPI模式的SD卡协议简单的看了下,知道SD卡的初始化过程,读写数据是怎么回事了。

然后跟踪SD卡的初始化,发现SD卡复位,进入IDLE模式都没问题,而问题是出在获取CID上,程序如下:
static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
        struct mmc_card *oldcard)
{
                省略
        ----------------

        err = mmc_send_if_cond(host, ocr);
        if (!err)
                ocr |= 1 << 30;

        err = mmc_send_app_op_cond(host, ocr, NULL);
        if (err)
                goto err;

        /*
         * For SPI, enable CRC as appropriate.
         */
        if (mmc_host_is_spi(host)) {
                //err = mmc_spi_set_crc(host, use_spi_crc);
                err = mmc_spi_set_crc(host, 0);  //zhh

                if (err)
                        goto err;
        }

        /*
         * Fetch CID from card.
         */
        if (mmc_host_is_spi(host))
    {      
        err = mmc_send_cid(host, cid);      
    }               
        else
                err = mmc_all_send_cid(host, cid);
        if (err)
                goto err;
-----------------------------
省略               
}
于是猜想会不会是spi加了ECC的原因,网上有位高手说SPI模式的SD卡加ECC是自讨苦吃,于是我把ECC去掉了,程序上面红色部分。

然后就成功了。

查看dev是179 0
然后mknod
试了下,OK。

使用特权

评论回复
135
tiger84|  楼主 | 2010-1-21 20:31 | 只看该作者
接下来打算解决data flash与SD卡共享SPI的问题

使用特权

评论回复
136
tiger84|  楼主 | 2010-1-21 21:32 | 只看该作者
理论上来说,data flash与SD卡共用一组SPI,CS不同应该是可以的,但是看了下SPI sd卡的源码,如下:
/* We can use the bus safely iff nobody else will interfere with us.
         * Most commands consist of one SPI message to issue a command, then
         * several more to collect its response, then possibly more for data
         * transfer.  Clocking access to other devices during that period will
         * corrupt the command execution.
         *
         * Until we have software primitives which guarantee non-interference,
         * we'll aim for a hardware-level guarantee.
         *
         * REVISIT we can't guarantee another device won't be added later...
         */
        if (spi->master->num_chipselect > 1) {
                struct count_children cc;

                cc.n = 0;               
                cc.bus = spi->dev.bus;
                status = device_for_each_child(spi->dev.parent, &cc,
                                maybe_count_child);
                if (status < 0) {
                        dev_err(&spi->dev, "can't share SPI bus\n");
                        return status;
                }

                dev_warn(&spi->dev, "ASSUMING SPI bus stays unshared!\n");
        }
觉得共享似乎不太可能了,用过的兄弟指点下吧。

使用特权

评论回复
137
tiger84|  楼主 | 2010-1-21 21:38 | 只看该作者
这段代码果然有些问题,如下
Subject: [PATCH 2/2] mmc_spi: lock the SPI bus when accessing the card - msg#06885
List: linux-kernel
Date: Prev Next Index Thread: Prev Next Index
From: Yi Li <yi.li@xxxxxxxxxx>

The MMC/SPI spec does not play well with typical SPI design -- it often
needs to send out a command in one message, read a response, then do some
other arbitrary step. Since we can't let another SPI client use the bus
during this time, use the new SPI lock/unlock functions to provide the
required exclusivity.

Signed-off-by: Yi Li <yi.li@xxxxxxxxxx>
Signed-off-by: Mike Frysinger <vapier@xxxxxxxxxx>
---
drivers/mmc/host/mmc_spi.c | 29 ++---------------------------
1 files changed, 2 insertions(+), 27 deletions(-)

diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index a461017..a96e058 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -1084,6 +1084,7 @@ static void mmc_spi_request(struct mmc_host *mmc, struct
mmc_request *mrq)
#endif

/* issue command; then optionally data and stop */
+ spi_lock_bus(host->spi);
status = mmc_spi_command_send(host, mrq, mrq->cmd, mrq->data != NULL);
if (status == 0 && mrq->data) {
mmc_spi_data_do(host, mrq->cmd, mrq->data, mrq->data->blksz);
@@ -1092,7 +1093,7 @@ static void mmc_spi_request(struct mmc_host *mmc, struct
mmc_request *mrq)
else
mmc_cs_off(host);
}
-
+ spi_unlock_bus(host->spi);
mmc_request_done(host->mmc, mrq);
}

@@ -1337,32 +1338,6 @@ static int mmc_spi_probe(struct spi_device *spi)
return status;
}

- /* We can use the bus safely iff nobody else will interfere with us.
- * Most commands consist of one SPI message to issue a command, then
- * several more to collect its response, then possibly more for data
- * transfer. Clocking access to other devices during that period will
- * corrupt the command execution.
- *
- * Until we have software primitives which guarantee non-interference,
- * we'll aim for a hardware-level guarantee.
- *
- * REVISIT we can't guarantee another device won't be added later...
- */
- if (spi->master->num_chipselect > 1) {
- struct count_children cc;
-
- cc.n = 0;
- cc.bus = spi->dev.bus;
- status = device_for_each_child(spi->dev.parent, &cc,
- maybe_count_child);
- if (status < 0) {
- dev_err(&spi->dev, "can't share SPI bus\n");
- return status;
- }
-
- dev_warn(&spi->dev, "ASSUMING SPI bus stays unshared!\n");
- }
-
/* We need a supply of ones to transmit. This is the only time
* the CPU touches these, so cache coherency isn't a concern.
*
--
1.6.5.rc1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

使用特权

评论回复
138
lxl_0598| | 2010-1-22 08:57 | 只看该作者
佩服楼主的**不懈,加油。

使用特权

评论回复
139
icecut| | 2010-1-23 12:28 | 只看该作者
不错。很入门了。

使用特权

评论回复
140
tiger84|  楼主 | 2010-1-24 11:48 | 只看该作者
谢谢icecut兄弟的鼓励。linux里面全部都有了,我好像什么都没做,至于入门,就真谈不上呢。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则