大体上可分为以下几个部分:

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 函数,该方法会让需要延迟的任务睡眠到指定的延时时间后在重新运行。

SPI Flash(W25Q16DV) 驱动的更多相关文章

  1. SPI Flash(W25Q16DV) 基本操作

    读取厂家\设备 ID 发送 90H 指令,再发送 00h 的地址,然后接收即可. 代码如下: void SPIFlashReadID(int *pMID, int *pDID) { SPIFlash_ ...

  2. RTThread DFS文件系统使用: 基于使用SFUD驱动的SPI FLASH之上的ELM FATFS文件系统

    参考博文: 博文很长,但是实际要操作的步骤没几下. http://m.elecfans.com/article/730878.html  为了防止几年后文章链接找不到,我把文章复制过来了 /***** ...

  3. Nand Flash,Nor Flash,CFI Flash,SPI Flash 之间的关系

    前言:    在嵌入式开发中,如uboot的移植,kernel的移植都需要对Flash 有基本的了解.下面细说一下标题中的中Flash中的关系 一,Flash的内存存储结构    flash按照内部存 ...

  4. OpenRisc-32-ORPSoC烧写外部spi flash

    引言 经过前面的分析和介绍,我们对ORPSoC的启动过程(http://blog.csdn.net/rill_zhen/article/details/8855743)和 ORpSoC的debug子系 ...

  5. [转]uboot中SPI Flash Booting配置

    转自:https://e2echina.ti.com/question_answer/dsp_arm/sitara_arm/f/25/t/124834 最近和人一起调试SPI FLASH的配置问题,做 ...

  6. SPI设备的驱动

    主要包括两个SPI设备步骤:register_chrdevspi_register_driver关键点1:spi_board_info可以去已经运行的板子下面找例子:/sys/bus/spi/driv ...

  7. 【转】SPI FLASH与NOR FLASH的区别 详解SPI FLASH与NOR FLASH的不一样

    转自:http://m.elecfans.com/article/778203.html 本文主要是关于SPI FLASH与NOR FLASH的相关介绍,并着重对SPI FLASH与NOR FLASH ...

  8. spi子系统之驱动SSD1306 OLED

    spi子系统之驱动SSD1306 OLED 接触Linux之前,曾以为读源码可以更快的学习软件,于是前几个博客都是一边读源码一边添加注释,甚至精读到每一行代码,实际上效果并不理想,看过之后就忘记了.主 ...

  9. 【iCore、iCore2 双核心板】EPCS 实验(SPI Flash)(基于Verilog语言)

    _____________________________________ 深入交流QQ群: A: 204255896(1000人超级群,可加入) B: 165201798(500人超级群,满员) C ...

随机推荐

  1. Innodb IO优化-配置优化

    作者:吴炳锡 来源:http://www.mysqlsupport.cn/ 联系方式: wubingxi#gmail.com 转载请注明作/译者和出处,并且不能用于商业用途,违者必究. 对于数据库来讲 ...

  2. selenium实现淘宝的商品爬取

    一.问题 本次利用selenium自动化测试,完成对淘宝的爬取,这样可以避免一些反爬的措施,也是一种爬虫常用的手段.本次实战的难点: 1.如何利用selenium绕过淘宝的登录界面 2.获取淘宝的页面 ...

  3. <fieldset>标签

    <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Conten ...

  4. PHP幸运大转盘源码,支持ThinkPHP

    原理 先看图 可以看到1-6等奖都只有1个 ,7等奖有6个.指针默认指向上图位置,记为0°. 每个奖项对应不同的角度,圆的角度为360°,分成12块,所以每块为30°. 为了防止指针指着相邻两个将向之 ...

  5. 基于OpenCV的图书扫描识别程序开发

    1.AndroidStudio环境配置 https://www.cnblogs.com/little-monkey/p/7162340.html

  6. 桌面应用开发之WPF页面导航

    先看效果图 Get Start   为了项目解耦,使用mvvmlight框架.MVVM设计模式请自行了解. 1 新建项目   新建一个MvvmLight(WPF)项目,删除其中无关文件夹:Design ...

  7. FreeRTOS移植到STM32上的移植过程

    所有的单片机都是顺序执行的,而对于多任务而言就显得力不从心了,虽然在一些小项目中可以通过定时器来实现,但这种实现方式没有实时性,一旦任务需要在规定时间内做出响应,那只能通过实时操作系统来完成了.在很多 ...

  8. RSA 算法

    RSA 算法  from http://www.matrix67.com/blog/archives/5100 所有工作都准备就绪,下面我们可以开始描述 RSA 算法了. 首先,找两个质数,比如说 1 ...

  9. ubuntu16.04安装最新版docker、docker-compose、docker-machine

    安装前说明: 本文将介绍在ubuntu16.04系统下安装和升级docker.docker-compose.docker-machine. docker:有两个版本:docker-ce(社区版)和do ...

  10. Spring AOP的实现及源码解析

    在介绍AOP之前,想必很多人都听说AOP是基于动态代理和反射来实现的,那么在看AOP之前,你需要弄懂什么是动态代理和反射及它们又是如何实现的. 想了解JDK的动态代理及反射的实现和源码分析,请参见下面 ...