自学朱有鹏嵌入式-高级IO总结
本周的几天自学朱有鹏嵌入式的高级IO篇。学习了阻塞式和非阻塞式。其中read、write,wait、pause、sleep为阻塞式。在阻塞式中做了三个实验,分别是单独写键盘、单独写鼠标以及同时写鼠标与键盘。
本人总结复习有点喜欢通过代码直接复习总结。因感觉复习linux应用无非是学会怎么用,通过代码回忆起老师上课的内容。
- 将阻塞式改为非阻塞式的方式:
第一:fd = open(“dev/input/mouse1”, O_NONBLOCK);
第二种:int flag; // 把0号文件描述符(stdin)变成非阻塞式的
flag = fcntl(0, F_GETFL); // 先获取原来的flag
flag |= O_NONBLOCK; // 添加非阻塞属性
fcntl(0, F_SETFL, flag);// 更新flag
// 这3步之后,0就变成了非阻塞式的了
然后通过循环不断读取,但是要加上read的返回值要大于0时才打印的条件。
while (1)
{
// 读鼠标
memset(buf, 0, sizeof(buf));
//printf("before 鼠标 read.\n");
ret = read(fd, buf, 50);
if (ret > 0)
{
printf("鼠标读出的内容是:[%s].\n", buf);
}
// 读键盘
memset(buf, 0, sizeof(buf));
//printf("before 键盘 read.\n");
ret = read(0, buf, 5);
if (ret > 0)
{
printf("键盘读出的内容是:[%s].\n", buf);
}
}
2.select、poll 函数的使用
这两个都是IO多路复用的方法。只是形参不一样。
poll:
struct pollfd myfds[2] = {0};
// 初始化我们的pollfd
myfds[0].fd = 0; // 键盘
myfds[0].events = POLLIN; // 等待读操作
myfds[1].fd = fd; // 鼠标
myfds[1].events = POLLIN; // 等待读操作
ret = poll(myfds, fd+1, 10000);
ret <0 时为错误。等于0时为超时,其他正确。
正确后通过myfds[0].events == myfds[0].revents是否一样进行,如果一样就是相应的IO到来。
else{
//正确
// 等到了一路IO,然后去监测到底是哪个IO到了,处理之
if (myfds[0].events == myfds[0].revents)
{
// 这里处理键盘
memset(buf, 0, sizeof(buf));
read(0, buf, 5);
printf("键盘读出的内容是:[%s].\n", buf);
}
if (myfds[1].events == myfds[1].revents)
{
// 这里处理鼠标
memset(buf, 0, sizeof(buf));
read(fd, buf, 50);
printf("鼠标读出的内容是:[%s].\n", buf);
}
}
select:
通过结构体申明时间。
struct timeval tm;
fd_set myset;
FD_ZERO(&myset);
FD_SET(fd, &myset);
FD_SET(0, &myset);
tm.tv_sec = 10;
tm.tv_usec = 0;
ret = select(fd+1, &myset, NULL, NULL, &tm);
/*
ret <0 时为错误。等于0时为超时,其他正确。 正确后通过myfds[0].events ==
myfds[0].revents是否一样进行,如果一样就是相应的IO到来
*/
通过FD_ISSET判断
// 等到了一路IO,然后去监测到底是哪个IO到了,处理之
if (FD_ISSET(0, &myset))
{
// 这里处理键盘
memset(buf, 0, sizeof(buf));
read(0, buf, 5);
printf("键盘读出的内容是:[%s].\n", buf);
}
if (FD_ISSET(fd, &myset))
{
// 这里处理鼠标
memset(buf, 0, sizeof(buf));
read(fd, buf, 50);
printf("鼠标读出的内容是:[%s].\n", buf);
}
}
4异步IO的做法;(相当于STM32中断函数)
flag = fcntl(mousefd, F_GETFL);
flag |= O_ASYNC;
fcntl(mousefd, F_SETFL, flag);// 把异步IO事件的接收进程设置为当前进程
fcntl(mousefd, F_SETOWN, getpid());
// 注册当前进程的SIGIO信号捕获函数
signal(SIGIO, func);//注意SIGIO,接受IO信号
当IO来时执行func
signal 函数收到了SIGIO会将其传给下面func1的形参,然后通过判断进行打印。
void func(int sig)
{
char buf[200] = {0};
if (sig != SIGIO)
return;
read(mousefd, buf, 50);
printf("鼠标读出的内容是:[%s].\n", buf);
}