欢迎光临MCUWAY! 本站网名:单片机之路  永久域名:www.mcuway.com

设为首页

加入收藏

电子基础 初学MCU 单片机类型 MCU程序 MCU应用 设计软件 测控电路 技术论坛
 您现在的位置: 单片机之路 >> 单片机类型 >> ARM系列 >> 文章正文

移植嵌入式Linux到ARM处理器S3C2410:设备驱动 2

4.块设备驱动

  块设备驱动程序的编写是一个浩繁的工程,其难度远超过字符设备,上千行的代码往往只能搞定一个简单的块设备,而数十行代码就可能搞定一个字符设备。因此,非得有相当的基本功才能完成此项工作。下面先给出一个实例,即mtdblock块设备的驱动。我们通过分析此实例中的代码来说明块设备驱动程序的写法(由于篇幅的关系,大量的代码被省略,只保留了必要的主干):

#include <linux/config.h>
#include <linux/devfs_fs_kernel.h>
static void mtd_notify_add(struct mtd_info* mtd);
static void mtd_notify_remove(struct mtd_info* mtd);
static struct mtd_notifier notifier = {
 mtd_notify_add,
 mtd_notify_remove,
 NULL
};
static devfs_handle_t devfs_dir_handle = NULL;
static devfs_handle_t devfs_rw_handle[MAX_MTD_DEVICES];

static struct mtdblk_dev {
 struct mtd_info *mtd; /* Locked */
 int count;
 struct semaphore cache_sem;
 unsigned char *cache_data;
 unsigned long cache_offset;
 unsigned int cache_size;
 enum { STATE_EMPTY, STATE_CLEAN, STATE_DIRTY } cache_state;
} *mtdblks[MAX_MTD_DEVICES];

static spinlock_t mtdblks_lock;
/* this lock is used just in kernels >= 2.5.x */
static spinlock_t mtdblock_lock;

static int mtd_sizes[MAX_MTD_DEVICES];
static int mtd_blksizes[MAX_MTD_DEVICES];

static void erase_callback(struct erase_info *done)
{
 wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv;
 wake_up(wait_q);
}

static int erase_write (struct mtd_info *mtd, unsigned long pos,
int len, const char *buf)
{
 struct erase_info erase;
 DECLARE_WAITQUEUE(wait, current);
 wait_queue_head_t wait_q;
 size_t retlen;
 int ret;

 /*
 * First, let's erase the flash block.
 */

 init_waitqueue_head(&wait_q);
 erase.mtd = mtd;
 erase.callback = erase_callback;
 erase.addr = pos;
 erase.len = len;
 erase.priv = (u_long)&wait_q;

 set_current_state(TASK_INTERRUPTIBLE);
 add_wait_queue(&wait_q, &wait);

 ret = MTD_ERASE(mtd, &erase);
 if (ret) {
  set_current_state(TASK_RUNNING);
  remove_wait_queue(&wait_q, &wait);
  printk (KERN_WARNING "mtdblock: erase of region [0x%lx, 0x%x] " "on \"%s\" failed\n",
pos, len, mtd->name);
  return ret;
 }

 schedule(); /* Wait for erase to finish. */
 remove_wait_queue(&wait_q, &wait);

 /*
 * Next, writhe data to flash.
 */

 ret = MTD_WRITE (mtd, pos, len, &retlen, buf);
 if (ret)
  return ret;
 if (retlen != len)
  return -EIO;
 return 0;
}

[1] [2] [3] [4] 下一页

“单片机之路”的网址:www.mcuway.com

普通文章SST89C54/58系列单片机的IAP应用技术
普通文章AT89C51单片机的介绍——最常用的51芯
普通文章如何进行反汇编
普通文章将目标文件写入单片机
普通文章keil软件的使用
普通文章跟我来编一个最简单的单片机程序
普通文章单片机的管脚
普通文章指针类型和存储区的关系详解
普通文章单片机MCS-51系列指令快速记忆法
普通文章MCS51和8051是否相同?
普通文章什么是单片机
普通文章与电源管理有关的技术问答
普通文章关于复位源和其他C8051F单片机的技术
普通文章关于开发工具及调试的技术问答
普通文章JTAG与ISP的区别
普通文章单片机振荡器技术问答
普通文章有关IDE(集成开发环境)的技术问答
普通文章uPSD系列8 位单片机概述
普通文章电子工程师的心声
普通文章一个嵌入式工程师的忠告
普通文章单片机的发展之路
普通文章一位电子前辈的心得体会
普通文章单片机应“做中学”
普通文章给年轻IC解密和芯片解密工程师的十大
普通文章MC-S51单片机简介

  • 上一篇文章:
  • 下一篇文章:
  • 更多精彩内容>>>

    普通文章电容器的基础知识及检测方…
    普通文章可控硅的特性于检测
    普通文章电阻的使用
    普通文章芯片封装

    学习单片机的必经之路——单片机之路,永久域名:www.mcuway.com