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

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

最新文章

  1. <<< java异常The import java.util cannot be resolved
  2. MySQL(无GUI) Windows安装和启动
  3. Swift高级语法学习总结(转)
  4. How do I remove javascript validation from my eclipse project?
  5. mybatis执行批量更新update
  6. 如何恢复低版本的FlashPlayer
  7. 通过beego快速创建一个Restful风格API项目及API文档自动化
  8. javascript第三方组件
  9. Xcode中为代码添加特殊标记
  10. BFS 模板
  11. vs2010突然变慢解决方法
  12. java+mysql对于表情的处理
  13. JavaScript 语言中的 this
  14. 学JAVA的第二天,静态网站制作,脑阔一点疼
  15. Linux内存管理 (2)页表的映射过程
  16. Linux 下装逼技巧
  17. LZW算法PHP实现方法 lzw_decompress php
  18. node 文件操作
  19. 软件调用QML的两种方式
  20. 20165326 java第八周学习笔记

热门文章

  1. 返回头部js
  2. (PMP)第10章-----项目沟通管理
  3. (21)The history of human emotions
  4. python模块:json
  5. Oracle 异常 中文乱码
  6. SELECT版FTP
  7. ssh整合详解
  8. Delphi - 子窗体继承父窗体后如何显示父窗体上的控件
  9. Javascript百学不厌 - 模块模式
  10. php cli模式和浏览器访问下加载php.ini文件的注意事项[架构篇]