APP访问硬件的四种方式

  1. 查询方式
  2. 休眠-唤醒
  3. poll/select方式
  4. 异步通知

查询

不断访问查询是否 有数据

  • app调用open函数时,传入"O_NONBLOCK" 表示 非阻塞
  • app调用read函数读取数据时,如果驱动程序中有数据,那么app的read函数会返回数据,否则也会立刻返回错误
fd = open(argv[1], O_RDWR | O_NONBLOCK);

休眠-唤醒

一直等待驱动中返回数据

  • app调用open函数时,不要传入"O_NONBLOCK"
  • app调用read函数读取数据时,如果驱动程序中有数据,那么app的read函数会返回数据;否则app就会在内核态休眠,当有数据时驱动程序会把app唤醒,read函数恢复执行并返回数据给app
fd = open(argv[1], O_RDWR);

poll/select

在调用poll,select函数时可以传入 超时时间。在这段时间内,条件合适就会立刻返回,否则等到超时时返回错误

  • app先调用open
  • app不直接调用read函数,而是先调用poll或select函数,这2个函数中可以传入超时时间。
  • app根据poll或select的返回值有判断之后,就调用read函数读取数据时,这时就会立刻获得数据
  • app根据poll或select的返回值判断有数据之后,在调用read函数读取
  • poll/select 函数可以监听多个文件,可以监测多种事件

在调用poll函数时,要指明:

  • 要检测那个文件 那个fd
  • 要检测文件的那种事件,是POLLIN、还是POLLOUT
// 导包
#include <poll.h>

// 定义pollfd 结构体
struct pollfd fds[1];

fd = open(argv[1], O_RDWR | O_NONBLOCK);
// 指定检测的文件
fds[0].fd = fd;
// 指定检测使劲啊
fds[0].events  = POLLIN;
fds[0].revents = 0;
ret = poll(fds, nfds, 5000);

异步通知

所谓异步通知,就是app可以忙自己的事情,当驱动程序用数据时它会主动app发信号,这会导致app执行信号处理函数

关于发信号的 几个问题点

  • 谁发信号:驱动程序来发
  • 发什么:信号
  • 发什么信号:SIGIO
  • 怎么发:内核提供的函数
  • 发给谁:app,app要把自己告诉驱动
  • app收到后做什么:执行信号处理函数
  • 信号处理函数和信号,之间怎么挂钩:app注册信号处理函数
// 编写信号处理函数
void my_sig_handler(int sig)
{
	struct input_event event;
	while (read(fd, &event, sizeof(event)) == sizeof(event))
	{
		printf("get event: type = 0x%x, code = 0x%x, value = 0x%x\n", event.type, event.code, event.value);		
	}
}

/* 注册信号处理函数 */
signal(SIGIO, my_sig_handler);

/* 打开驱动程序 */
fd = open(argv[1], O_RDWR | O_NONBLOCK);

/* 把APP的进程号告诉驱动程序 */
fcntl(fd, F_SETOWN, getpid());


/* 使能"异步通知" */
flags = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, flags | FASYNC);

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值