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

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. for循环的实例

    1.大马驮2石粮食,中马驮1石粮食,两头小马驮一石粮食,要用100匹马,驮100石粮食,该如//首先我们要知道一百石粮食需要这些马分别几匹 //第一个是大马,需要五十匹马for(var x=0;x&l ...

  2. 《Linux就该这么学》第五天课程

    今天我很迷茫! 一下是一些命令的整合 原创地址:https://www.linuxprobe.com/chapter-04.html 下面是Linux系统中最重要的10个环境变量 变量名称 作用 HO ...

  3. springboot 使用maven 打包 报 (请使用 -source 7 或更高版本以启用 diamond 运算符) 错误解决办法

    在使用springboot maven 打包时 报如下错误 (请使用 -source 7 或更高版本以启用 diamond 运算符) pom.xml编译插件 配置如下: <plugin> ...

  4. 简单好用的时间选择插件My97datepicker

    我们经常会需要验证字符串的格式,比如密码长度范围.电子邮件格式.固定电话号码和手机号码格式等,这个时候我们经常会需要用到正则表达式.但是正则表达式用起来性能会低一点,所以在需要验证的时候能不使用正则表 ...

  5. Codeforces828 D. High Load

    D. High Load time limit per test 2 seconds memory limit per test 512 megabytes input standard input ...

  6. 调用opencv相关函数,从视频流中提取出图片序列&&&&jpg图片序列,转化成avi格式视频

    /************************ @HJ 2017/3/30 参考http://blog.sina.com.cn/s/blog_4b0020f301010qcz.html修改的代码 ...

  7. HTTPS抓包之Charles

    这里对HTTP请求的抓包操作不做讲解了,只讲解HTTPS的抓包要进行的操作. [说明]:下面以MAC电脑示例,Windows版本可参考:http://weibo.com/ttarticle/p/sho ...

  8. 三菱蓝瑟CK4A

    日本JDM蓝瑟,而且还是MR的性能版,避震行程也是这么长的.证明这个车子就是这样设计的. 90年代拉力血统的车就这样? 东南厂国产的蓝瑟,原装避震是厦门开发生产,来自于台湾开发工业集团的全资子公司,而 ...

  9. react中使用阿里Viser图表

    参考demo的codesandbox:https://codesandbox.io/s/kxxxx3w5kv 使用步骤:   1. 安装依赖  viser-react和@antv/data-set 2 ...

  10. js内存空间的那点事

    由于js具有自动垃圾回收机制,导致接触js后一直没去关注js的内存分配及变量回收等原理,只是懵懂的了解用变量标记法(null)可以手动的去清除或是回收:是时候弥补这个大坑了... 垃圾回收两种方法 一 ...