微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARM的嵌入式Linux移植体验之设备驱动

ARM的嵌入式Linux移植体验之设备驱动

时间:11-13 来源:互联网 点击:

_blkdev(unsigned int major, const char *name, struct block_device_operations *bdops);
int unregister_blkdev(unsigned int major, const char *name);

  但是,register_chrdev使用一个向 file_operations 结构的指针,而register_blkdev 则使用 block_device_operations 结构的指针,其中定义的open、release 和 ioctl 方法和字符设备的对应方法相同,但未定义 read 或者 write 操作。这是因为,所有涉及到块设备的 I/O 通常由系统进行缓冲处理。

  块驱动程序最终必须提供完成实际块 I/O 操作的机制,在 Linux 当中,用于这些 I/O 操作的方法称为"request(请求)"。在块设备的注册过程中,需要初始化request队列,这一动作通过blk_init_queue来完成,blk_init_queue函数建立队列,并将该驱动程序的 request 函数关联到队列。在模块的清除阶段,应调用 blk_cleanup_queue 函数。

  本例中相关的代码为:

BLK_INIT_QUEUE(BLK_DEFAULT_QUEUE(MAJOR_NR), mtdblock_request, mtdblock_lock);
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));

  每个设备有一个默认使用的请求队列,必要时,可使用 BLK_DEFAULT_QUEUE(major) 宏得到该默认队列。这个宏在 blk_dev_struct 结构形成的全局数组(该数组名为 blk_dev)中搜索得到对应的默认队列。blk_dev 数组由内核维护,并可通过主设备号索引。blk_dev_struct 接口定义如下:

struct blk_dev_struct {
 /*
 * queue_proc has to be atomic
 */
 request_queue_t request_queue;
 queue_proc *queue;
 void *data;
};

  request_queue 成员包含了初始化之后的 I/O 请求队列,data 成员可由驱动程序使用,以便保存一些私有数据。

  request_queue定义为:

struct request_queue
{
 /*
 * the queue request freelist, one for reads and one for writes
 */
 struct request_list rq[2];

 /*
 * Together with queue_head for cacheline sharing
 */
 struct list_head queue_head;
 elevator_t elevator;

 request_fn_proc * request_fn;
 merge_request_fn * back_merge_fn;
 merge_request_fn * front_merge_fn;
 merge_requests_fn * merge_requests_fn;
 make_request_fn * make_request_fn;
 plug_device_fn * plug_device_fn;
 /*
 * The queue owner gets to use this for whatever they like.
 * ll_rw_blk doesn't touch it.
 */
 void * queuedata;

 /*
 * This is used to remove the plug when tq_disk runs.
 */
 struct tq_struct plug_tq;

 /*
 * Boolean that indicates whether this queue is plugged or not.
 */
 char plugged;

 /*
 * Boolean that indicates whether current_request is active or
 * not.
 */
 char head_active;

 /*
 * Is meant to protect the queue in the future instead of
 * io_request_lock
 */
 spinlock_t queue_lock;

 /*
 * Tasks wait here for free request
 */
 wait_queue_head_t wait_for_request;
};

  下图表征了blk_dev、blk_dev_struct和request_queue的关系:

  下图则表征了块设备的注册和释放过程:

  5.小结

  本章讲述了Linux设备驱动程序的入口函数及驱动程序中的内存申请、中断等,并分别以实例讲述了字符设备及块设备的驱动开发方法。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top