Flash基础入门之SPI Flash(W25Q16DV) 驱动
小标 2018-08-24 来源 : 阅读 5346 评论 0

摘要:本文主要向大家介绍了Flash基础入门之SPI Flash(W25Q16DV) 驱动,通过具体的内容向大家展现,希望对大家学习Flash基础入门有所帮助。

本文主要向大家介绍了Flash基础入门之SPI Flash(W25Q16DV) 驱动,通过具体的内容向大家展现,希望对大家学习Flash基础入门有所帮助。

大体上可分为以下几个部分:
1.注册设备驱动 spi_register_driver
2.分配 mtd_info 结构体
3.配置 mtd_info 结构体
4.注册 mtd_info 结构体
构建 spi_driver 并注册
static struct spi_driver spi_flash_drv = {
    .driver = {
        .name   = "spi_flash",
        .owner  = THIS_MODULE,
    },
    .probe      = spi_flash_probe,
    .remove     = __devexit_p(spi_flash_remove),
};

static int spi_flash_init(void)
{
    return spi_register_driver(&spi_flash_drv);
}
当内核中注册了同名的设备,会调用该驱动的 probe 程序
/* 分配 mtd_info 结构体 */
static struct mtd_info spi_flash_dev;

static int __devinit spi_flash_probe(struct spi_device *spi)
{
    int mid, did;
    
    spi_flash = spi;

    s3c2410_gpio_cfgpin(spi->chip_select, S3C2410_GPIO_OUTPUT);
    SPIFlashInit();
    SPIFlashReadID(&mid, &did);
    printk("SPI Flash ID: %02x %02x\n", mid, did);
    memset(&spi_flash_dev, 0, sizeof(spi_flash_dev));
        
    /* 构造并注册这个 mtd_info
     * mtd_device_register(master, parts, nr_parts)
     */

    /* Setup the MTD structure */
    spi_flash_dev.name = "spi_flash";
    spi_flash_dev.type = MTD_NORFLASH;
    spi_flash_dev.flags = MTD_CAP_NORFLASH;
    spi_flash_dev.size = 0x200000;  /* 2M */
    spi_flash_dev.writesize = 1;
    spi_flash_dev.writebufsize = 4096; /* 没有用到 */
    spi_flash_dev.erasesize = 4096;  /* 擦除的最小单位 */

    spi_flash_dev.owner = THIS_MODULE;
    spi_flash_dev._erase = spi_flash_erase;
    spi_flash_dev._read  = spi_flash_read;
    spi_flash_dev._write = spi_flash_write;

    mtd_device_register(&spi_flash_dev, NULL, 0);
     
    return 0;
}

spi_flash_dev._erase = spi_flash_erase;
spi_flash_dev._read  = spi_flash_read;
spi_flash_dev._write = spi_flash_write;
这三个函数与前面一篇文章所调用的函数基本相同,只是 SPI 的发送我们需要调用内核中的函数来完成,程序如下(linux/spi.h):
static inline int
spi_write(struct spi_device *spi, const void *buf, size_t len)
{
    struct spi_transfer t = {
            .tx_buf     = buf,
            .len        = len,
        };
    struct spi_message  m;

    spi_message_init(&m);
    spi_message_add_tail(&t, &m);
    return spi_sync(spi, &m);
}
忙等待函数我们也要加以修改,避免浪费 CPU 资源,程序如下:
static void SPIFlashWaitWhenBusy(void)
{
    while (SPIFlashReadStatusReg1() & 1)
    {
        /* 休眠一段时间 */
        set_current_state(TASK_INTERRUPTIBLE);
        schedule_timeout(HZ/100);  /* 休眠10MS后再次判断 */
    }
}
将进程设置为可中断的等待状态 TASK_INTERRUPTIBLE 。
状态解释:进程被挂起(睡眠),直到某个条件变为真。产生一个硬件中断,释放进程正在等待的系统资源,或传递一个信号都是可以唤醒进程的条件 (把进程的状态放回到 TASK_RUNNING)。
使用 schedule_timeout 函数,该方法会让需要延迟的任务睡眠到指定的延时时间后在重新运行。    

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标常用软件Flash频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 7 不喜欢 | 0
看完这篇文章有何感觉?已经有7人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved