LDD3读书笔记(第11章 高级字符驱动程序操作)

本章的目的是让读者知道:
1.内核与用户空间同步
2.如何使进程休眠(并唤醒)
3.如何实现非阻塞I/O
4.设备可读取或写入时如何通知用户空间

#include <linux/ioctl.h>
    这个头文件声明了用于定义ioctl命令的所有的宏。它现在包含在<linux/fs.h>中。
_IOC_NRBITS
_IOC_TYPEBITS
_IOC_SIZEBITS
_IOC_DIRBITS
    ioctl命令的不同位字段的可用位数。还有四个宏定义了不同的MASK(掩码),另外四个宏定义了不同的SHIFT(偏移),但它们基本上仅在内部使用。由于_IOC_SIZEBITS在不同体系架构上的值不同,因此需要重点关注。
_IOC_NONE
_IOC_READ
_IOC_WRITE
    “方向”位字段的可能值。“读”和“写”是不同的位,可以“OR”在一起来指定读/写。这些值都是基于0的。
_IOC(dir,type,nr,size)
_IO(type,nr)
_IOC(type,nr,size)
_IOW(type,nr,size)
_IOWR(type,nr,size)
    用于生成ioctl命令的宏。
_IOC_DIR(nr)
_IOC_TYPE(nr)
_IOC_NR(nr)
_IOC_SIZE(nr)
    用于解码ioctl命令的宏。特别地,_IOC_TYPE(nr)是_IOC_READ和_IOC_WRITE进行“OR”的结果。
#include <asm/uaccess.h>
int access_ok(int type,const void *addr,unsigned long size);
    这个函数验证指向用户空间的指针是否可用。如果允许访问,access_ok返回非零值。
VERIFY_READ
VERIFY_WRITE
    在access_ok中type参数可取的值。VERIFY_WRITE是VERIFY_READ的超集。
#include <asm/uaccess.h>
int put_user(datum,ptr);
int get_user(local,ptr);
int __put_user(datum,ptr);
int __get_user(local,ptr);
    用于向(或从)用户空间保存(或获取)单个数据项的宏。传递的字节数目由sizeof(*ptr)决定。前两个要先调用access_ok,后两个(__put_user和__get_user)则假设access_ok已经被调用过了。
#include <linux/capability.h>
    定义有各种CAP_符号,用于描述用户空间进程可能拥有的权能操作。
int capable(int capability);
    如果进程具有指定的权能,返回非零值。
#include <linux/wait.h>
typedef struct {/* ... */} wait_queue_head_t;
void init_waitqueue_head(wait_queue_head_t *queue);
DECLARE_WAIT_QUEUE_HEAD(queue);
    预先定义的Linux等待队列类型。wait_queue_head_t类型必须显式地初始化,初始化方法可在运行时用init_waitqueue_head,或在编译时用DECLARE_WAIT_QUEUE_HEAD。
void wait_event(wait_queue_head_t q,int condition);
int wait_event_interruptible(wait_queue_head_t q,int condition);
int wait_event_timeout(wait_queue_head_t q,int condition,int time);
int wait_event_interruptible_timeout(wait_queue_head_t q,int condition,int time);
    使进程在指定的队列上休眠,直到给定的condition值为真。
void wake_up(struct wait_queue **q);
void wakr_up_interruptible(struct wait_queue **q);
void wake_up_nr(struct wait_queue **q,int nr);
void wake_up_interruptible_nr(struct wait_queue **q,int nr);
void wake_up_all(struct wait_queue **q);
void wake_up_interruptible_all(struct wait_queue **q);
void wake_up_interruptible_sync(struct wait_queue **q);
    这些函数唤醒休眠在队列q上的进程。_interruptible形式的函数只能唤醒可中断的进程。通常,只会唤醒一个独占等待进程,但其行为通过_nr或_all形式改变。_sync版本的唤醒函数在返回前不会重新调度CPU。
#include <linux/sched.h>
set_current_state(int state);
    设置当前进程的执行状态。TASK_RUNNING表示准备运行,而休眠状态是TASK_INTERRUPTIBLE和TASK_UNINTERRUPTIBLE。
void schedule(void);
    从运行队列中选择一个可运行进程,选定的进程可以是current或另一个不同的进程。
typedef struct {/* ... */} wait_queue_t;
init_waitqueue_entry(wait_queue_t *entry,struct task_strcut *task);
    wait_queue_t类型用来将某个进程放置到一个等待队列上。
void prepare_to_wait(wait_queue_head_t *queue,wait_queue_t *wait,int state);
void prepare_to_wait_exclisive(wait_queue_head_t *queue,wait_queue_t *wait,int state);
void finish_wait(wait_queue_head_t *queue,wait_queue_t *wait);
    可用于手工休眠代码的辅助函数。
void sleep_on(wait_queue_head_t *queue);
void interruptible_sleep_on(wait_queue_head_t *queue);
    已废弃的两个函数,它们将当前进程无条件地置于休眠状态。
#include <linux/poll.h>
void poll_wait(struct file *filp,wait_queue_head_t *q,pool_table *p);
    将当前进程置于某个等待队列但并不立即调度。该函数主要用于设备驱动程序的poll方法。
int fasync_helper(struct inode *inode,struct file *filp,int mode,struct fasync_struct **fa);
    用来实现fasync设备方法的辅助函数。mode参数取传入该方法的同一值,而fa指向设备专有的fasync_struct *。
void kill_fasync(struct fasync_struct *fa,int sig,int band);
    如果驱动程序支持异步通知,则这个函数可以用来发送一个信号给注册在fa中的进程。
int nonseekable_open(struct inode *inode,struct file *filp);
loff_t no_llseek(struct file *file,loff_t offset,int whence);
    任何不支持定位的设备都应该在其open方法中调用nonseekable_open。这类设备还应该在其llseek方法中使用no_llseek。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值