标签:内核源码 开发者 原型 时钟 stop 参考 logs 进程状态 trap
本章内容为驱动基石之一。
驱动只提供功能,不提供策略。
阻塞与非阻塞是 APP 询问 驱动设备。
异步通知是 驱动设备 主动通知 APP。
原文:https://www.cnblogs.com/lizhuming/p/14918049.html
异步通知:一旦设备就绪,则主动通知APP,这样APP就不用轮询查询设备状态了。
异步IO:APP 发起 IO 请求后,立即返回。然后再查询 IO 完成情况,或者 IO 完成后被调回。这个过程叫做 异步IO。
可以使用 信号 来进行进程间通信(IPC)。
Linux信号表:
信号 | 值 | 说明 |
---|---|---|
SIGHUP | 1 | 挂起 |
SIGINT | 2 | 中断中断 |
SIGQUIT | 3 | 终端退出 |
SIGILL | 4 | 无效命令 |
SIGTRAP | 5 | 跟踪陷阱 |
SIGABRT | 6 | 异常终止信号,和 SIGIOT 同义 |
SIGIOT | 6 | IOT陷阱,和 SIGABRT 同义 |
SIGBUS | 7 | BUS错误 |
SIGFPE | 8 | 浮点异常 |
SIGKILL | 9 | 强制终止 |
SIGUSR1 | 10 | 用户自定义信号1 |
SIGSEGV | 11 | 无效的内存段处理 |
SIGUSR2 | 12 | 用户自定义信号2 |
SIGPIPE | 13 | 半关闭管道的写操作 |
SIGALRM | 14 | 计时器到期 |
SIGTERM | 15 | 终止 |
SIGSTKFLT | 16 | 堆栈错误 |
SIGCHLD | 17 | 子进程已经停止或退出 |
SIGCONT | 18 | 如果停止了,继续执行 |
SIGSTOP | 19 | 停止执行 |
SIGTSTP | 20 | 终端停止信号 |
SIGTTIN | 21 | 后台进程需要从终端读取输入 |
SIGTTOU | 22 | 后台进程需要从终端写出 |
SIGURG | 23 | 紧急的套接字事件 |
SIGXCPU | 24 | 超额使用CPU分配的时间 |
SIGXFSZ | 25 | 文件尺寸超额 |
SIGVTALRM | 26 | 虚拟时钟信号 |
SIGPROF | 27 | 时钟信号描述 |
SIGWINCH | 28 | 出口尺寸变化 |
SIGIO | 29 | I/O |
SIGPOLL | SIGIO | I/O |
除了 SIGSTOP 和 SIGKILL 两个信号外,进程能够忽略或捕获其它所有信号。
一个信号被捕获的意思是当一个信号到达时有相应代码处理它。
如果一个信号没有被这进程所捕获,内核将采取默认行为处理。
流程图参考韦东山:
分析中的细节部分会在后本节后面说明
分析:
②:绑定信号与回调函数。使用sighandler_t signal(int signum, sighandler_t handler)
。
③:把 APP PID 告诉内核。同时,该 PID 会保存到该驱动的内核文件 file 结构体中。
④:读取该驱动程序文件的 Flag。
⑤:设置 Flag 里面的 FASYNC 位为 1。当 FASYNC 位发生变化时,该驱动会调用驱动操作 drv_fasync
函数。
⑥:驱动开发者实现的函数。主要是调用 fasync_helper 函数。
⑦:调用 fasync_helper() 函数,主要是把 驱动程序内核文件 file 结构体绑定到 button_async->fa_file 中。而 file 包含了 APP 的 PID。所以发送信号时,只需要使用 button_async 作为参数即可。
⑩:发送信号给对应的 APP。参数为 button_async。
注:button_async 结构体由驱动开发者创建,维护。
APP 信号编程步骤:
KERNEL 信号编程步骤:
APP 模型 截段:
......
/* 设置信号 SIGIO 的处理函数 */
signal(SIGIO, sigio_signal_func);
fcntl(fd, F_SETOWN, getpid()); /* 将当前进程的进程号告诉给内核 */
flags = fcntl(fd, F_GETFD); /* 获取当前的进程状态 */
fcntl(fd, F_SETFL, flags | FASYNC); /* 设置进程启用异步通知功能。会调用驱动中的 drv_fasync 函数 */
......
fasync_struct:
struct fasync_struct {
rwlock_t fa_lock;
int magic;
int fa_fd;
struct fasync_struct *fa_next; /* singly linked list */
struct file *fa_file;
struct rcu_head fa_rcu;
};
APP 使用。
函数原型:sighandler_t signal(int signum, sighandler_t handler)
:
typedef void (*sighandler_t)(int);
。KERNEL 使用。
函数原型:void kill_fasync(struct fasync_struct **fp, int sig, int band)
:
标签:内核源码 开发者 原型 时钟 stop 参考 logs 进程状态 trap
原文地址:https://www.cnblogs.com/lizhuming/p/14918049.html