驱动通知应用层

驱动部分

驱动想要给应用层发送信号,需要用到kill_fasync()函数和xxx_fasync()函数

例如:

kill_fasync(&pled->async_queue, SIGRTMIN, POLL_OUT)
    //第一个参数为特定的结构体
    //第二个参数为信号的类型
    //第三个参数为信号值
    //作用:驱动通过此函数; 发信号给应用程序,应用程序就调用自己安装的响应函数去处理。
static int kernaldemo_fasync (int fd, struct file *filp, int mode) 
{
   
   
	printk(KERN_EMERG "kernaldemo_fasync\n"); 
	pled = filp->private_data;
	return fasync_helper (fd, filp, mode, &pled->async_queue); 
}
	//fasync_helper作用就是初始化fasync这个东西,包括分配内存和设置属性,
	//dev->async_queue可用来区分向谁发	
	//最后在驱动的release里把fasync_helper初始化的东西free掉。
  • 补充1:

​ 在早期的UNIX中信号是不可靠的,不可靠在这里指的是:信号可能丢失,一个信号发生了,但进程却可能一直不知道这一点。现在Linux 在SIGRTMIN实时信号之前的都叫不可靠信号,这里的不可靠主要是不支持信号队列,就是当多个信号发生在进程中的时候(收到信号的速度超过进程处理的速度的时候),这些没来的及处理的信号就会被丢掉,仅仅留下一个信号。可靠信号是多个信号发送到进程的时候(收到信号的速度超过进程处理信号的速度的时候),这些没来的及处理的信号就会排入进程的队列。等进程有机会来处理的时候,依次再处理,信号不丢失。

执行kill -l命令,输出如下:(全部的命令)

1) SIGHUP			2) SIGINT       		3) SIGQUIT		4) SIGILL
 5) SIGTRAP     	6) SIGABRT      	7) SIGBUS       	8) SIGFPE
 9) SIGKILL     	10) SIGUSR1     	11) SIGSEGV     	12) SIGUSR2
13) SIGPIPE     	14) SIGALRM     	15) SIGTERM     	16) SIGSTKFLT
17) SIGCHLD     	18) SIGCONT     	19) SIGSTOP     	20) SIGTSTP
21) SIGTTIN     	22) SIGTTOU     	23) SIGURG      	24) SIGXCPU
25) SIGXFSZ     	26) SIGVTALRM   	27) SIGPROF     	28) SIGWINCH
29) SIGIO       	30) SIGPWR      	31) SIGSYS      	34) SIGRTMIN
35) SIGRTMIN+1  	36) SIGRTMIN+2 		37) SIGRTMIN+3  	38) SIGRTMIN+4
39) SIGRTMIN+5  	40) SIGRTMIN+6  	41) SIGRTMIN+7  	42) SIGRTMIN+8
43) SIGRTMIN+9  	44) SIGRTMIN+10 	45) SIGRTMIN+11 	46) SIGRTMIN+12
47) SIGRTMIN+13 	48) SIGRTMIN+14 	49) SIGRTMIN+15 	50) SIGRTMAX-14
51) SIGRTMAX-13 	52) SIGRTMAX-12  	53) SIGRTMAX-11 	54) SIGRTMAX-10
55) SIGRTMAX-9  	56) SIGRTMAX-8  	57) SIGRTMAX-7  	58) SIGRTMAX-6
59) SIGRTMAX-5  	60) SIGRTMAX-4  	61) SIGRTMAX-3  	62) SIGRTMAX-2
63) SIGRTMAX-1  	64) SIGRTMAX  
  • 补充2:

针对SIGRTMIN,一般发送的信号为POLL_IN和POLL_OUT,其他信号可在siginfo.h中的枚举中查到

  POLL_IN = 1,		/* Data input available.  */
# define POLL_IN	POLL_IN
  POLL_OUT,			/* Output buffers available.  */
# define POLL_OUT	POLL_OUT
  POLL_MSG,			/* Input message available.   */
# define POLL_MSG	POLL_MSG
  POLL_ERR,			/* I/O error.  */
# define POLL_ERR	POLL_ERR
  POLL_PRI,			/* High priority input available.  */
# define POLL_PRI	POLL_PRI
  POLL_HUP			/* Device disconnected.  */
# define POLL_HUP	POLL_HUP

应用层部分

应用层部分想要接收到驱动发出的信号,需要用到信号注册函数,信号回调(处理)函数,绑定函数

  • 信号注册函数
	//第一类
	struct sigaction act;			//定义信号结构体
	memset(&act, 0, sizeof(act));	//清空
	sigemptyset(&act.sa_mask);		//将参数set信号集初始化并清空。
	act.sa_flags = SA_SIGINFO;		//设置可用信号结构体携带附加信息
	act.sa_sigaction = new_op;		//信号处理函数
	if(sigaction(SIGRTMIN, &act, NULL) != 0)	//信号注册函数
	{
   
   
      	perror("sigaction is error");
	}
	//第二类,不如第一类效果好,一般选用第一类
	//SIGIO: 接受的信号
	//catch_sigio:信号处理函数
	if (SIG_ERR == signal(SIGIO, catch_sigio))	
	{
   
   
		perror("signal failed\n");
	}
  • 绑定函数
	fcntl(fd, F_SETSIG, SIGRTMIN); //设置异步通知的信号为SIGRTMIN
	fcntl(fd, F_SETOWN, getpid());	
	fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | FASYNC);	

补充:

  • 函数原型:

    int fcntl(int fd, int cmd);

    int fcntl(int fd, int cmd, long arg);

    int fcntl(int fd, int cmd, struct flock *lock);

  • 描述:

    fcntl()针对(文件)描述符提供控制.参数fd是被参数cmd操作(如下面的描述)的描述符.

    针对cmd的值,fcntl能够接受第三个参数(arg)

  • fcntl函数有5种功能:

    ​ 1.复制一个现有的描述符(cmd=F_DUPFD).

    ​ 2.获得/设置文件描述符标记(cmd=F_GETFD或F_SETFD).

    ​ 3.获得/设置文件状态标记(cmd=F_GETFL或F_SETFL).

    ​ 4.获得/设置异步I/O所有权(cmd=F_GETOWN或F_SETOWN).

    ​ 5.获得/设置记录锁(cmd=F_GETLK,F_SETLK或F_SETLKW).

  • cmd 选项:

F_DUPFD 返回一个如下描述的(文件)描述符:
(1)最小的大于或等于arg的一个可用的描述符
(2)与原始操作符一样的某对象的引用
(3)如果对象是文件(file)的话,返回一个新的描述符,这个描述符与arg共享相同的偏移量(offset)
(4)相同的访问模式(读,写或读/写)
(5)相同的文件状态标志(如:两个文件描述符共享相同的状态标志)
(6)与新的文件描述符结合在一起的close-on-exec标志被设置成交叉式访问execve(2)的系统调用
F_GETFD 取得与文件描述符fd联合close-on-exec标志,类似FD_CLOEXEC.如果返回值和FD_CLOEXEC进行与运算结果是0的话,文件保持交叉式访问exec(),       否则如果通过exec运行的话,文件将被关闭(arg被忽略)
F_SETFD 设置close-on-exec旗标。该旗标以参数arg的FD_CLOEXEC位决定。
F_GETFL 取得fd的文件状态标志,如同下面的描述一样(arg被忽略)
F_SETFL 设置给arg描述符状态标志,可以更改的几个标志是:O_APPEND, O_NONBLOCK,O_SYNC和O_ASYNC。 F_GETOWN 取得当前正在接收SIGIO或者SIGURG信号的进程id或进程组id,进程组id返回成负值(arg被忽略)
F_SETOWN 设置将接收SIGIO和SIGURG信号的进程id或进程组id,进程组id通过提供负值的arg来说明,否则,arg将被认为是进程id
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值