您的位置:首页 > 其它

字符设备驱动之笔记-异步通知(fasync)

2011-09-14 17:49 369 查看
发信号:

1. 谁发

2. 发给谁

3. 发什么

4. 怎么发

5. 收到信号后做什么

16th_signal_app

发信号:

1. 谁发 a

2. 发给谁 b

3. 发什么 SIGIO

4. 怎么发 int kill(pid_t pid, int sig);

5. 收到信号后做什么: sighandler_t signal(int signum, sighandler_t handler);

驱动和应用

发信号:

1. 谁发 按键中断服务程序

2. 发给谁 使用按键的应用程序

3. 发什么 SIGIO

4. 怎么发 kill_fasync(谁, SIGIO)

5. 收到信号后做什么: sighandler_t signal(int signum, sighandler_t handler);

怎么写驱动?

1. 定义一个fasync_struct指针:

struct fasync_struct *buttons_async;

2. 设置它:

static int buttons_fasync(int fd, struct file *filp, int on)

{

int retval;

retval = fasync_helper(fd, filp, on, &buttons_async);

if (retval < 0)

return retval;

return 0;

}

static const struct file_operations buttons_fops = {

......

.fasync = buttons_fasync,

};

3. 使用它:

kill_fasync(&buttons_async, SIGIO, POLL_IN);

怎么写应用?

1. 注册信号处理函数

signal(SIGNO, signal_function);

2. 执行某些函数, 使得驱动里的fasync被调用

flag = fcntl(fd, F_GETFL);

flag |= FASYNC;

fcntl(fd, F_SETFL, flag);

3. 把应用程序的PID告诉驱动:

fcntl(fd, F_SETOWN, getpid());

应用调用到驱动里的fasync:

1.

app: flag = fcntl(fd, F_GETFL);

--------------------------------------------------------

kernel: sys_fcntl

do_fcntl

err = filp->f_flags;

return err;

2.

app: fcntl(fd, F_SETFL, flag);

--------------------------------------------------------

kernel: sys_fcntl

do_fcntl

err = setfl(fd, filp, arg);

// 要改变file->f_flasgs的FASYNC时

// 调用驱动的fasync

if ((arg ^ filp->f_flags) & FASYNC) {

if (filp->f_op && filp->f_op->fasync) {

error = filp->f_op->fasync(fd, filp, (arg & FASYNC) != 0);

if (error < 0)

goto out;

}

3.

app: fcntl(fd, F_SETOWN, getpid());

-----------------------------------------------------

kernel: sys_fcntl

do_fcntl

err = f_setown(filp, arg, 1);

result = __f_setown(filp, pid, type, force);

4.

kill_fasync(&buttons_async, SIGIO, POLL_IN);

__kill_fasync(*fp, sig, band);

fown = &fa->fa_file->f_owner;

send_sigio(fown, fa->fa_fd, band);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: