Linux驱动开发之异步通知实验

异步通知基础:
  信号:是一种类似中断的机制,当驱动程序可以访问的时候主动告诉应用程序
  异步通知的核心就是信号,在arch/xtensa/include/uapi/asm/signal.h文件中,就有Linux所支持的所有信号,例如我们常用的kill -9、CTRL+C

#define SIGHUP 1 /* 终端挂起或控制进程终止 */
#define SIGINT 2 /* 终端中断(Ctrl+C 组合键) */
#define SIGQUIT 3 /* 终端退出(Ctrl+\组合键) */
#define SIGILL 4 /* 非法指令 */
#define SIGTRAP 5 /* debug 使用,有断点指令产生 */
#define SIGABRT 6 /* 由 abort(3)发出的退出指令 */
#define SIGIOT 6 /* IOT 指令 */
#define SIGBUS 7 /* 总线错误 */
#define SIGFPE 8 /* 浮点运算错误 */
#define SIGKILL 9 /* 杀死、终止进程 */
#define SIGUSR1 10 /* 用户自定义信号 1 */
#define SIGSEGV 11 /* 段违例(无效的内存段) */
#define SIGUSR2 12 /* 用户自定义信号 2 */
#define SIGPIPE 13 /* 向非读管道写入数据 */
#define SIGALRM 14 /* 闹钟 */
#define SIGTERM 15 /* 软件终止 */
#define SIGSTKFLT 16 /* 栈异常 */
#define SIGCHLD 17 /* 子进程结束 */
#define SIGCONT 18 /* 进程继续 */
#define SIGSTOP 19 /* 停止进程的执行,只是暂停 */

  使用中断的时候需要设置中断处理函数,同样的,应用程序中使用信号,也要设置信号处理函数。
信号处理函数:sighandler_t signal(int signum, sighandler_t handler)
signum:要设置处理函数的信号
handler:信号的处理函数名称
成功的话,返回前一个函数,失败的话返回SIG_ERR

驱动中的信号处理

  fasynv_struct结构体位于/include/linux/fs.h文件中,该结构体是使用异步通知必须的

struct fasync_struct {
   
	spinlock_t fa_lock;
	int magic;
	int fa_fd;
	struct fasync_struct *fa_next;
	struct file *fa_file;
	struct rcu_head fa_rcu;
};

1.kill_fasync函数void kill_fasync(struct fasync_struct **fp, int sig, int band)
fp:要操作的 fasync_struct。
sig: 要发送的信号。
band: 可读时设置为 POLL_IN,可写时设置为 POLL_OUT。
返回值: 无。

应用程序中的信号处理

第一步:注册信号处理函数
第二步:将本应用程序的进程号告诉给内核
第三步:开启异步通知

      
  
  

-----------------------------------------驱动实验编写开始 ----------------------------------

1.添加需要用到的头文件

#include <linux/poll.h>
#include <linux/fcntl.h>

2.在设备结构体中添加fasynv_struct结构体

/* imx6uirq设备结构体 */
struct imx6uirq_dev{
   
	dev_t devid;			/* 设备号 	 */
	struct cdev cdev;		/* cdev 	*/
	struct class *class;	/* 类 		*/
	struct device *device;	/* 设备 	 */
	int major;				/* 主设备号	  */
	int minor;				/* 次设备号   */
	struct device_node	*nd; /* 设备节点 */
	atomic_t keyvalue;		/* 有效的按键键值 */
	atomic_t releasekey;	/* 标记是否完成一次完成的按键,包括按下和释放 */
	struct timer_list timer;/* 定义一个定时器*/
	struct irq_keydesc irqkeydesc[KEY_NUM];	/* 按键描述数组 */
	unsigned char curkeynum;				/* 当前的按键号 */

	struct fasync_struct *fasync_queue;
};

3.在设备操作函数中添加fasync和release

/* 设备操作函数 */
static struct file_operations imx6uirq_fops = {
   
	.owner = THIS_MODULE,
	.open = imx6uirq_open,
	.read = imx6uirq_read,
	.fasync = imx6uirq_fasync,
	.release = imx6uirq_release,
};

4,添加imx6uirq_fasync和imx6uirq_release函数,因为在上一步我们已经添加了这2个操作集函数。至此驱动函数方面的便添加完了。

static int imx6uirq_fasync(int fd, struct file *filp, int on)
{
   
	struct imx6uirq_dev *dev = filp->private_data;

	return fasync_helper(fd, filp, on, &dev->fasync_queue);
}

int imx6uirq_release(struct inode *inode, struct file *filp)
{
   
	return imx6uirq_fasync(-1, filp, 0);
}

6.应用程序修改:添加sigio_signal_func函数

static void sigio_signal_func(int num)
{
   
	int err;
	unsigned int keyvalue =0;
	err = read(fd, &keyvalue, sizeof(keyvalue)
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拼个世界给自己

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值