add: 05_Input/app*
71
IMX6ULL/doc_pic/05_Input/02_先学习输入系统应用编程.md
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
## 先学习输入系统应用编程
|
||||||
|
|
||||||
|
### 1. 百问网Linux视频体系
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 2. 建议
|
||||||
|
|
||||||
|
在《Linux系列教程之快速入门》的《嵌入式Linux应用开发基础知识》的视频里,
|
||||||
|
我们讲解了9节的输入系统应用编程:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
1.输入系统框架及调试
|
||||||
|
2.现场编程读取获取输入设备信息
|
||||||
|
3.查询_休眠唤醒_方式读取输入数据
|
||||||
|
4.POLL_SELECT_方式读取输入数据
|
||||||
|
5.异步通知方式读取输入数据
|
||||||
|
6.电阻屏和电容屏
|
||||||
|
7.tslib框架分析
|
||||||
|
8.tslib交叉编译与测试
|
||||||
|
9.编写基于tslib的测试程序
|
||||||
|
```
|
||||||
|
|
||||||
|
强烈建议先学习这9个视频,至少必须学习其中这4个视频:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
1.输入系统框架及调试
|
||||||
|
2.现场编程读取获取输入设备信息
|
||||||
|
3.查询_休眠唤醒_方式读取输入数据
|
||||||
|
6.电阻屏和电容屏
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### 3. 视频在哪里
|
||||||
|
|
||||||
|
你当然可以去学习《嵌入式Linux应用开发基础知识》中的输入系统应用编程的视频,
|
||||||
|
为了方便大家学习,为了保持视频的完整性,我们把这些视频也放到了《驱动大全》里。
|
||||||
|
|
||||||
|
#### 3.1 在《嵌入式Linux应用开发基础》里
|
||||||
|
|
||||||
|
打开[官网](https://www.100ask.net/),根据下图找到视频
|
||||||
|

|
||||||
|
|
||||||
|
#### 3.2 在驱动大全里
|
||||||
|
|
||||||
|
为了保持视频的完整性,我们把这9个视频也放到了驱动大全里,如下:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 4. 文档、源码、图片在哪
|
||||||
|
|
||||||
|
输入系统应用编程对应的文档、源码、图片,可以从它的原始GIT仓库获得。
|
||||||
|
为了保持视频的完整性,我们把这些资料也放到的驱动大全的GIT仓库里。
|
||||||
|
|
||||||
|
* 在《Linux系列教程之快速入门》的GIT仓库里
|
||||||
|
|
||||||
|
```shell
|
||||||
|
git clone https://e.coding.net/weidongshan/01_all_series_quickstart.git
|
||||||
|
```
|
||||||
|
|
||||||
|
* 在《驱动大全》的GIT仓库里
|
||||||
|
|
||||||
|
```shell
|
||||||
|
git clone https://e.coding.net/weidongshan/linux/doc_and_source_for_drivers.git
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
它们的位置如下图所示(左边是原始仓库,右边是驱动大全仓库):
|
||||||
|
|
||||||
|

|
||||||
BIN
IMX6ULL/doc_pic/05_Input/03_输入系统应用编程.docx
Normal file
BIN
IMX6ULL/doc_pic/05_Input/03_输入系统应用编程.tif
Normal file
BIN
IMX6ULL/doc_pic/05_Input/pic/05_Input/04_videos_position1.png
Normal file
|
After Width: | Height: | Size: 207 KiB |
BIN
IMX6ULL/doc_pic/05_Input/pic/05_Input/05_videos_position2.png
Normal file
|
After Width: | Height: | Size: 355 KiB |
BIN
IMX6ULL/doc_pic/05_Input/pic/05_Input/06_doc_source_positons.png
Normal file
|
After Width: | Height: | Size: 269 KiB |
BIN
IMX6ULL/doc_pic/05_Input/pic/05_Input/07_video_tutorial.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
@@ -0,0 +1,88 @@
|
|||||||
|
|
||||||
|
#include <linux/input.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* ./01_get_input_info /dev/input/event0 */
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int err;
|
||||||
|
int len;
|
||||||
|
int i;
|
||||||
|
unsigned char byte;
|
||||||
|
int bit;
|
||||||
|
struct input_id id;
|
||||||
|
unsigned int evbit[2];
|
||||||
|
char *ev_names[] = {
|
||||||
|
"EV_SYN ",
|
||||||
|
"EV_KEY ",
|
||||||
|
"EV_REL ",
|
||||||
|
"EV_ABS ",
|
||||||
|
"EV_MSC ",
|
||||||
|
"EV_SW ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"EV_LED ",
|
||||||
|
"EV_SND ",
|
||||||
|
"NULL ",
|
||||||
|
"EV_REP ",
|
||||||
|
"EV_FF ",
|
||||||
|
"EV_PWR ",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
printf("Usage: %s <dev>\n", argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = open(argv[1], O_RDWR);
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
printf("open %s err\n", argv[1]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ioctl(fd, EVIOCGID, &id);
|
||||||
|
if (err == 0)
|
||||||
|
{
|
||||||
|
printf("bustype = 0x%x\n", id.bustype );
|
||||||
|
printf("vendor = 0x%x\n", id.vendor );
|
||||||
|
printf("product = 0x%x\n", id.product );
|
||||||
|
printf("version = 0x%x\n", id.version );
|
||||||
|
}
|
||||||
|
|
||||||
|
len = ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), &evbit);
|
||||||
|
if (len > 0 && len <= sizeof(evbit))
|
||||||
|
{
|
||||||
|
printf("support ev type: ");
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
byte = ((unsigned char *)evbit)[i];
|
||||||
|
for (bit = 0; bit < 8; bit++)
|
||||||
|
{
|
||||||
|
if (byte & (1<<bit)) {
|
||||||
|
printf("%s ", ev_names[i*8 + bit]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
112
IMX6ULL/source/05_Input/01_input_app/01_app_demo/02_input_read.c
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
|
||||||
|
#include <linux/input.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* ./01_get_input_info /dev/input/event0 noblock */
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int err;
|
||||||
|
int len;
|
||||||
|
int i;
|
||||||
|
unsigned char byte;
|
||||||
|
int bit;
|
||||||
|
struct input_id id;
|
||||||
|
unsigned int evbit[2];
|
||||||
|
struct input_event event;
|
||||||
|
|
||||||
|
char *ev_names[] = {
|
||||||
|
"EV_SYN ",
|
||||||
|
"EV_KEY ",
|
||||||
|
"EV_REL ",
|
||||||
|
"EV_ABS ",
|
||||||
|
"EV_MSC ",
|
||||||
|
"EV_SW ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"EV_LED ",
|
||||||
|
"EV_SND ",
|
||||||
|
"NULL ",
|
||||||
|
"EV_REP ",
|
||||||
|
"EV_FF ",
|
||||||
|
"EV_PWR ",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
printf("Usage: %s <dev> [noblock]\n", argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc == 3 && !strcmp(argv[2], "noblock"))
|
||||||
|
{
|
||||||
|
fd = open(argv[1], O_RDWR | O_NONBLOCK);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fd = open(argv[1], O_RDWR);
|
||||||
|
}
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
printf("open %s err\n", argv[1]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ioctl(fd, EVIOCGID, &id);
|
||||||
|
if (err == 0)
|
||||||
|
{
|
||||||
|
printf("bustype = 0x%x\n", id.bustype );
|
||||||
|
printf("vendor = 0x%x\n", id.vendor );
|
||||||
|
printf("product = 0x%x\n", id.product );
|
||||||
|
printf("version = 0x%x\n", id.version );
|
||||||
|
}
|
||||||
|
|
||||||
|
len = ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), &evbit);
|
||||||
|
if (len > 0 && len <= sizeof(evbit))
|
||||||
|
{
|
||||||
|
printf("support ev type: ");
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
byte = ((unsigned char *)evbit)[i];
|
||||||
|
for (bit = 0; bit < 8; bit++)
|
||||||
|
{
|
||||||
|
if (byte & (1<<bit)) {
|
||||||
|
printf("%s ", ev_names[i*8 + bit]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
len = read(fd, &event, sizeof(event));
|
||||||
|
if (len == sizeof(event))
|
||||||
|
{
|
||||||
|
printf("get event: type = 0x%x, code = 0x%x, value = 0x%x\n", event.type, event.code, event.value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("read err %d\n", len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
|
||||||
|
#include <linux/input.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <poll.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* ./01_get_input_info /dev/input/event0 */
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int err;
|
||||||
|
int len;
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
unsigned char byte;
|
||||||
|
int bit;
|
||||||
|
struct input_id id;
|
||||||
|
unsigned int evbit[2];
|
||||||
|
struct input_event event;
|
||||||
|
struct pollfd fds[1];
|
||||||
|
nfds_t nfds = 1;
|
||||||
|
|
||||||
|
char *ev_names[] = {
|
||||||
|
"EV_SYN ",
|
||||||
|
"EV_KEY ",
|
||||||
|
"EV_REL ",
|
||||||
|
"EV_ABS ",
|
||||||
|
"EV_MSC ",
|
||||||
|
"EV_SW ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"EV_LED ",
|
||||||
|
"EV_SND ",
|
||||||
|
"NULL ",
|
||||||
|
"EV_REP ",
|
||||||
|
"EV_FF ",
|
||||||
|
"EV_PWR ",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
printf("Usage: %s <dev>\n", argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = open(argv[1], O_RDWR | O_NONBLOCK);
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
printf("open %s err\n", argv[1]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ioctl(fd, EVIOCGID, &id);
|
||||||
|
if (err == 0)
|
||||||
|
{
|
||||||
|
printf("bustype = 0x%x\n", id.bustype );
|
||||||
|
printf("vendor = 0x%x\n", id.vendor );
|
||||||
|
printf("product = 0x%x\n", id.product );
|
||||||
|
printf("version = 0x%x\n", id.version );
|
||||||
|
}
|
||||||
|
|
||||||
|
len = ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), &evbit);
|
||||||
|
if (len > 0 && len <= sizeof(evbit))
|
||||||
|
{
|
||||||
|
printf("support ev type: ");
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
byte = ((unsigned char *)evbit)[i];
|
||||||
|
for (bit = 0; bit < 8; bit++)
|
||||||
|
{
|
||||||
|
if (byte & (1<<bit)) {
|
||||||
|
printf("%s ", ev_names[i*8 + bit]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
fds[0].fd = fd;
|
||||||
|
fds[0].events = POLLIN;
|
||||||
|
fds[0].revents = 0;
|
||||||
|
ret = poll(fds, nfds, 5000);
|
||||||
|
if (ret > 0)
|
||||||
|
{
|
||||||
|
if (fds[0].revents == POLLIN)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ret == 0)
|
||||||
|
{
|
||||||
|
printf("time out\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("poll err\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
|
||||||
|
#include <linux/input.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
|
||||||
|
/* According to earlier standards */
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* ./01_get_input_info /dev/input/event0 */
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int err;
|
||||||
|
int len;
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
unsigned char byte;
|
||||||
|
int bit;
|
||||||
|
struct input_id id;
|
||||||
|
unsigned int evbit[2];
|
||||||
|
struct input_event event;
|
||||||
|
int nfds;
|
||||||
|
struct timeval tv;
|
||||||
|
fd_set readfds;
|
||||||
|
|
||||||
|
char *ev_names[] = {
|
||||||
|
"EV_SYN ",
|
||||||
|
"EV_KEY ",
|
||||||
|
"EV_REL ",
|
||||||
|
"EV_ABS ",
|
||||||
|
"EV_MSC ",
|
||||||
|
"EV_SW ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"EV_LED ",
|
||||||
|
"EV_SND ",
|
||||||
|
"NULL ",
|
||||||
|
"EV_REP ",
|
||||||
|
"EV_FF ",
|
||||||
|
"EV_PWR ",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
printf("Usage: %s <dev>\n", argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = open(argv[1], O_RDWR | O_NONBLOCK);
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
printf("open %s err\n", argv[1]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ioctl(fd, EVIOCGID, &id);
|
||||||
|
if (err == 0)
|
||||||
|
{
|
||||||
|
printf("bustype = 0x%x\n", id.bustype );
|
||||||
|
printf("vendor = 0x%x\n", id.vendor );
|
||||||
|
printf("product = 0x%x\n", id.product );
|
||||||
|
printf("version = 0x%x\n", id.version );
|
||||||
|
}
|
||||||
|
|
||||||
|
len = ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), &evbit);
|
||||||
|
if (len > 0 && len <= sizeof(evbit))
|
||||||
|
{
|
||||||
|
printf("support ev type: ");
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
byte = ((unsigned char *)evbit)[i];
|
||||||
|
for (bit = 0; bit < 8; bit++)
|
||||||
|
{
|
||||||
|
if (byte & (1<<bit)) {
|
||||||
|
printf("%s ", ev_names[i*8 + bit]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
/* 设置超时时间 */
|
||||||
|
tv.tv_sec = 5;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
|
/* 想监测哪些文件? */
|
||||||
|
FD_ZERO(&readfds); /* 先全部清零 */
|
||||||
|
FD_SET(fd, &readfds); /* 想监测fd */
|
||||||
|
|
||||||
|
/* 函数原型为:
|
||||||
|
int select(int nfds, fd_set *readfds, fd_set *writefds,
|
||||||
|
fd_set *exceptfds, struct timeval *timeout);
|
||||||
|
* 我们为了"read"而监测, 所以只需要提供readfds
|
||||||
|
*/
|
||||||
|
nfds = fd + 1; /* nfds 是最大的文件句柄+1, 注意: 不是文件个数, 这与poll不一样 */
|
||||||
|
ret = select(nfds, &readfds, NULL, NULL, &tv);
|
||||||
|
if (ret > 0) /* 有文件可以提供数据了 */
|
||||||
|
{
|
||||||
|
/* 再次确认fd有数据 */
|
||||||
|
if (FD_ISSET(fd, &readfds))
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ret == 0) /* 超时 */
|
||||||
|
{
|
||||||
|
printf("time out\n");
|
||||||
|
}
|
||||||
|
else /* -1: error */
|
||||||
|
{
|
||||||
|
printf("select err\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
|
||||||
|
#include <linux/input.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ./05_input_read_fasync /dev/input/event0 */
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
int len;
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
unsigned char byte;
|
||||||
|
int bit;
|
||||||
|
struct input_id id;
|
||||||
|
unsigned int evbit[2];
|
||||||
|
unsigned int flags;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
char *ev_names[] = {
|
||||||
|
"EV_SYN ",
|
||||||
|
"EV_KEY ",
|
||||||
|
"EV_REL ",
|
||||||
|
"EV_ABS ",
|
||||||
|
"EV_MSC ",
|
||||||
|
"EV_SW ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"EV_LED ",
|
||||||
|
"EV_SND ",
|
||||||
|
"NULL ",
|
||||||
|
"EV_REP ",
|
||||||
|
"EV_FF ",
|
||||||
|
"EV_PWR ",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
printf("Usage: %s <dev>\n", argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 注册信号处理函数 */
|
||||||
|
signal(SIGIO, my_sig_handler);
|
||||||
|
|
||||||
|
/* 打开驱动程序 */
|
||||||
|
fd = open(argv[1], O_RDWR | O_NONBLOCK);
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
printf("open %s err\n", argv[1]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ioctl(fd, EVIOCGID, &id);
|
||||||
|
if (err == 0)
|
||||||
|
{
|
||||||
|
printf("bustype = 0x%x\n", id.bustype );
|
||||||
|
printf("vendor = 0x%x\n", id.vendor );
|
||||||
|
printf("product = 0x%x\n", id.product );
|
||||||
|
printf("version = 0x%x\n", id.version );
|
||||||
|
}
|
||||||
|
|
||||||
|
len = ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), &evbit);
|
||||||
|
if (len > 0 && len <= sizeof(evbit))
|
||||||
|
{
|
||||||
|
printf("support ev type: ");
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
byte = ((unsigned char *)evbit)[i];
|
||||||
|
for (bit = 0; bit < 8; bit++)
|
||||||
|
{
|
||||||
|
if (byte & (1<<bit)) {
|
||||||
|
printf("%s ", ev_names[i*8 + bit]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 把APP的进程号告诉驱动程序 */
|
||||||
|
fcntl(fd, F_SETOWN, getpid());
|
||||||
|
|
||||||
|
/* 使能"异步通知" */
|
||||||
|
flags = fcntl(fd, F_GETFL);
|
||||||
|
fcntl(fd, F_SETFL, flags | FASYNC);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
printf("main loop count = %d\n", count++);
|
||||||
|
sleep(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
115
IMX6ULL/source/05_Input/01_input_app/02_tslib/mt_cal_distance.c
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
|
#include <linux/input.h>
|
||||||
|
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
|
#include <tslib.h>
|
||||||
|
|
||||||
|
int distance(struct ts_sample_mt *point1, struct ts_sample_mt *point2)
|
||||||
|
{
|
||||||
|
int x = point1->x - point2->x;
|
||||||
|
int y = point1->y - point2->y;
|
||||||
|
|
||||||
|
return x*x + y*y;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct tsdev *ts;
|
||||||
|
int i;
|
||||||
|
int ret;
|
||||||
|
struct ts_sample_mt **samp_mt;
|
||||||
|
struct ts_sample_mt **pre_samp_mt;
|
||||||
|
int max_slots;
|
||||||
|
int point_pressed[20];
|
||||||
|
struct input_absinfo slot;
|
||||||
|
int touch_cnt = 0;
|
||||||
|
|
||||||
|
ts = ts_setup(NULL, 0);
|
||||||
|
if (!ts)
|
||||||
|
{
|
||||||
|
printf("ts_setup err\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ioctl(ts_fd(ts), EVIOCGABS(ABS_MT_SLOT), &slot) < 0) {
|
||||||
|
perror("ioctl EVIOGABS");
|
||||||
|
ts_close(ts);
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
max_slots = slot.maximum + 1 - slot.minimum;
|
||||||
|
|
||||||
|
samp_mt = malloc(sizeof(struct ts_sample_mt *));
|
||||||
|
if (!samp_mt) {
|
||||||
|
ts_close(ts);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
samp_mt[0] = calloc(max_slots, sizeof(struct ts_sample_mt));
|
||||||
|
if (!samp_mt[0]) {
|
||||||
|
free(samp_mt);
|
||||||
|
ts_close(ts);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre_samp_mt = malloc(sizeof(struct ts_sample_mt *));
|
||||||
|
if (!pre_samp_mt) {
|
||||||
|
ts_close(ts);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
pre_samp_mt[0] = calloc(max_slots, sizeof(struct ts_sample_mt));
|
||||||
|
if (!pre_samp_mt[0]) {
|
||||||
|
free(pre_samp_mt);
|
||||||
|
ts_close(ts);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for ( i = 0; i < max_slots; i++)
|
||||||
|
pre_samp_mt[0][i].valid = 0;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
ret = ts_read_mt(ts, samp_mt, max_slots, 1);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
printf("ts_read_mt err\n");
|
||||||
|
ts_close(ts);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < max_slots; i++)
|
||||||
|
{
|
||||||
|
if (samp_mt[0][i].valid)
|
||||||
|
{
|
||||||
|
memcpy(&pre_samp_mt[0][i], &samp_mt[0][i], sizeof(struct ts_sample_mt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
touch_cnt = 0;
|
||||||
|
for (i = 0; i < max_slots; i++)
|
||||||
|
{
|
||||||
|
if (pre_samp_mt[0][i].valid && pre_samp_mt[0][i].tracking_id != -1)
|
||||||
|
point_pressed[touch_cnt++] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (touch_cnt == 2)
|
||||||
|
{
|
||||||
|
printf("distance: %08d\n", distance(&pre_samp_mt[0][point_pressed[0]], &pre_samp_mt[0][point_pressed[1]]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
BIN
IMX6ULL/source/05_Input/01_input_app/02_tslib/tslib-1.21.tar.xz
Normal file
17
README.md
@@ -134,6 +134,23 @@ git clone https://e.coding.net/weidongshan/doc_and_source_for_drivers.git
|
|||||||
|
|
||||||
* 2021.03.23 发布"Input子系统":01_Input子系统视频介绍
|
* 2021.03.23 发布"Input子系统":01_Input子系统视频介绍
|
||||||
|
|
||||||
|
* 2021.03.23 发布"Input子系统":
|
||||||
|
|
||||||
|
```shell
|
||||||
|
02_先学习输入系统应用编程
|
||||||
|
APP_01.输入系统框架及调试
|
||||||
|
APP_02.现场编程读取获取输入设备信息
|
||||||
|
APP_03.查询_休眠唤醒_方式读取输入数据
|
||||||
|
APP_04.POLL_SELECT_方式读取输入数据
|
||||||
|
APP_05.异步通知方式读取输入数据
|
||||||
|
APP_06.电阻屏和电容屏
|
||||||
|
APP_07.tslib框架分析
|
||||||
|
APP_08.tslib交叉编译与测试
|
||||||
|
APP_09.编写基于tslib的测试程序
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
71
STM32MP157/doc_pic/05_Input/02_先学习输入系统应用编程.md
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
## 先学习输入系统应用编程
|
||||||
|
|
||||||
|
### 1. 百问网Linux视频体系
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 2. 建议
|
||||||
|
|
||||||
|
在《Linux系列教程之快速入门》的《嵌入式Linux应用开发基础知识》的视频里,
|
||||||
|
我们讲解了9节的输入系统应用编程:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
1.输入系统框架及调试
|
||||||
|
2.现场编程读取获取输入设备信息
|
||||||
|
3.查询_休眠唤醒_方式读取输入数据
|
||||||
|
4.POLL_SELECT_方式读取输入数据
|
||||||
|
5.异步通知方式读取输入数据
|
||||||
|
6.电阻屏和电容屏
|
||||||
|
7.tslib框架分析
|
||||||
|
8.tslib交叉编译与测试
|
||||||
|
9.编写基于tslib的测试程序
|
||||||
|
```
|
||||||
|
|
||||||
|
强烈建议先学习这9个视频,至少必须学习其中这4个视频:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
1.输入系统框架及调试
|
||||||
|
2.现场编程读取获取输入设备信息
|
||||||
|
3.查询_休眠唤醒_方式读取输入数据
|
||||||
|
6.电阻屏和电容屏
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### 3. 视频在哪里
|
||||||
|
|
||||||
|
你当然可以去学习《嵌入式Linux应用开发基础知识》中的输入系统应用编程的视频,
|
||||||
|
为了方便大家学习,为了保持视频的完整性,我们把这些视频也放到了《驱动大全》里。
|
||||||
|
|
||||||
|
#### 3.1 在《嵌入式Linux应用开发基础》里
|
||||||
|
|
||||||
|
打开[官网](https://www.100ask.net/),根据下图找到视频
|
||||||
|

|
||||||
|
|
||||||
|
#### 3.2 在驱动大全里
|
||||||
|
|
||||||
|
为了保持视频的完整性,我们把这9个视频也放到了驱动大全里,如下:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 4. 文档、源码、图片在哪
|
||||||
|
|
||||||
|
输入系统应用编程对应的文档、源码、图片,可以从它的原始GIT仓库获得。
|
||||||
|
为了保持视频的完整性,我们把这些资料也放到的驱动大全的GIT仓库里。
|
||||||
|
|
||||||
|
* 在《Linux系列教程之快速入门》的GIT仓库里
|
||||||
|
|
||||||
|
```shell
|
||||||
|
git clone https://e.coding.net/weidongshan/01_all_series_quickstart.git
|
||||||
|
```
|
||||||
|
|
||||||
|
* 在《驱动大全》的GIT仓库里
|
||||||
|
|
||||||
|
```shell
|
||||||
|
git clone https://e.coding.net/weidongshan/linux/doc_and_source_for_drivers.git
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
它们的位置如下图所示(左边是原始仓库,右边是驱动大全仓库):
|
||||||
|
|
||||||
|

|
||||||
BIN
STM32MP157/doc_pic/05_Input/03_输入系统应用编程.docx
Normal file
BIN
STM32MP157/doc_pic/05_Input/03_输入系统应用编程.tif
Normal file
31
STM32MP157/doc_pic/05_Input/04_Input子系统框架.md
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
## Input子系统框架
|
||||||
|
|
||||||
|
参考资料:
|
||||||
|
|
||||||
|
* Linux 5.x内核文档
|
||||||
|
* Documentation\input\input-programming.rst
|
||||||
|
* Documentation\input\event-codes.rst
|
||||||
|
* Linux 4.x内核文档
|
||||||
|
* Documentation\input\input-programming.txt
|
||||||
|
* Documentation\input\event-codes.txt
|
||||||
|
|
||||||
|
### 1. 回顾字符设备驱动程序
|
||||||
|
|
||||||
|

|
||||||
|
怎么编写字符设备驱动程序?
|
||||||
|
|
||||||
|
* 确定主设备号
|
||||||
|
* 创建file_operations结构体
|
||||||
|
* 在里面填充drv_open/drv_read/drv_ioctl等函数
|
||||||
|
* 注册file_operations结构体
|
||||||
|
* register_chrdev(major, &fops, name)
|
||||||
|
* 谁调用register_chrdev?在入口函数调用
|
||||||
|
* 有入口自然就有出口
|
||||||
|
* 在出口函数unregister_chrdev
|
||||||
|
* 辅助函数(帮助系统自动创建设备节点)
|
||||||
|
* class_create
|
||||||
|
* device_create
|
||||||
|
|
||||||
|
### 2. 驱动程序分离的套路
|
||||||
|
|
||||||
|

|
||||||
BIN
STM32MP157/doc_pic/05_Input/04_Input子系统框架.tif
Normal file
BIN
STM32MP157/doc_pic/05_Input/pic/05_Input/04_videos_position1.png
Normal file
|
After Width: | Height: | Size: 207 KiB |
BIN
STM32MP157/doc_pic/05_Input/pic/05_Input/05_videos_position2.png
Normal file
|
After Width: | Height: | Size: 355 KiB |
|
After Width: | Height: | Size: 269 KiB |
BIN
STM32MP157/doc_pic/05_Input/pic/05_Input/07_video_tutorial.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
@@ -0,0 +1,88 @@
|
|||||||
|
|
||||||
|
#include <linux/input.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* ./01_get_input_info /dev/input/event0 */
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int err;
|
||||||
|
int len;
|
||||||
|
int i;
|
||||||
|
unsigned char byte;
|
||||||
|
int bit;
|
||||||
|
struct input_id id;
|
||||||
|
unsigned int evbit[2];
|
||||||
|
char *ev_names[] = {
|
||||||
|
"EV_SYN ",
|
||||||
|
"EV_KEY ",
|
||||||
|
"EV_REL ",
|
||||||
|
"EV_ABS ",
|
||||||
|
"EV_MSC ",
|
||||||
|
"EV_SW ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"EV_LED ",
|
||||||
|
"EV_SND ",
|
||||||
|
"NULL ",
|
||||||
|
"EV_REP ",
|
||||||
|
"EV_FF ",
|
||||||
|
"EV_PWR ",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
printf("Usage: %s <dev>\n", argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = open(argv[1], O_RDWR);
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
printf("open %s err\n", argv[1]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ioctl(fd, EVIOCGID, &id);
|
||||||
|
if (err == 0)
|
||||||
|
{
|
||||||
|
printf("bustype = 0x%x\n", id.bustype );
|
||||||
|
printf("vendor = 0x%x\n", id.vendor );
|
||||||
|
printf("product = 0x%x\n", id.product );
|
||||||
|
printf("version = 0x%x\n", id.version );
|
||||||
|
}
|
||||||
|
|
||||||
|
len = ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), &evbit);
|
||||||
|
if (len > 0 && len <= sizeof(evbit))
|
||||||
|
{
|
||||||
|
printf("support ev type: ");
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
byte = ((unsigned char *)evbit)[i];
|
||||||
|
for (bit = 0; bit < 8; bit++)
|
||||||
|
{
|
||||||
|
if (byte & (1<<bit)) {
|
||||||
|
printf("%s ", ev_names[i*8 + bit]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
|
||||||
|
#include <linux/input.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* ./01_get_input_info /dev/input/event0 noblock */
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int err;
|
||||||
|
int len;
|
||||||
|
int i;
|
||||||
|
unsigned char byte;
|
||||||
|
int bit;
|
||||||
|
struct input_id id;
|
||||||
|
unsigned int evbit[2];
|
||||||
|
struct input_event event;
|
||||||
|
|
||||||
|
char *ev_names[] = {
|
||||||
|
"EV_SYN ",
|
||||||
|
"EV_KEY ",
|
||||||
|
"EV_REL ",
|
||||||
|
"EV_ABS ",
|
||||||
|
"EV_MSC ",
|
||||||
|
"EV_SW ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"EV_LED ",
|
||||||
|
"EV_SND ",
|
||||||
|
"NULL ",
|
||||||
|
"EV_REP ",
|
||||||
|
"EV_FF ",
|
||||||
|
"EV_PWR ",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
{
|
||||||
|
printf("Usage: %s <dev> [noblock]\n", argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc == 3 && !strcmp(argv[2], "noblock"))
|
||||||
|
{
|
||||||
|
fd = open(argv[1], O_RDWR | O_NONBLOCK);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fd = open(argv[1], O_RDWR);
|
||||||
|
}
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
printf("open %s err\n", argv[1]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ioctl(fd, EVIOCGID, &id);
|
||||||
|
if (err == 0)
|
||||||
|
{
|
||||||
|
printf("bustype = 0x%x\n", id.bustype );
|
||||||
|
printf("vendor = 0x%x\n", id.vendor );
|
||||||
|
printf("product = 0x%x\n", id.product );
|
||||||
|
printf("version = 0x%x\n", id.version );
|
||||||
|
}
|
||||||
|
|
||||||
|
len = ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), &evbit);
|
||||||
|
if (len > 0 && len <= sizeof(evbit))
|
||||||
|
{
|
||||||
|
printf("support ev type: ");
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
byte = ((unsigned char *)evbit)[i];
|
||||||
|
for (bit = 0; bit < 8; bit++)
|
||||||
|
{
|
||||||
|
if (byte & (1<<bit)) {
|
||||||
|
printf("%s ", ev_names[i*8 + bit]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
len = read(fd, &event, sizeof(event));
|
||||||
|
if (len == sizeof(event))
|
||||||
|
{
|
||||||
|
printf("get event: type = 0x%x, code = 0x%x, value = 0x%x\n", event.type, event.code, event.value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("read err %d\n", len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
|
||||||
|
#include <linux/input.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <poll.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* ./01_get_input_info /dev/input/event0 */
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int err;
|
||||||
|
int len;
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
unsigned char byte;
|
||||||
|
int bit;
|
||||||
|
struct input_id id;
|
||||||
|
unsigned int evbit[2];
|
||||||
|
struct input_event event;
|
||||||
|
struct pollfd fds[1];
|
||||||
|
nfds_t nfds = 1;
|
||||||
|
|
||||||
|
char *ev_names[] = {
|
||||||
|
"EV_SYN ",
|
||||||
|
"EV_KEY ",
|
||||||
|
"EV_REL ",
|
||||||
|
"EV_ABS ",
|
||||||
|
"EV_MSC ",
|
||||||
|
"EV_SW ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"EV_LED ",
|
||||||
|
"EV_SND ",
|
||||||
|
"NULL ",
|
||||||
|
"EV_REP ",
|
||||||
|
"EV_FF ",
|
||||||
|
"EV_PWR ",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
printf("Usage: %s <dev>\n", argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = open(argv[1], O_RDWR | O_NONBLOCK);
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
printf("open %s err\n", argv[1]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ioctl(fd, EVIOCGID, &id);
|
||||||
|
if (err == 0)
|
||||||
|
{
|
||||||
|
printf("bustype = 0x%x\n", id.bustype );
|
||||||
|
printf("vendor = 0x%x\n", id.vendor );
|
||||||
|
printf("product = 0x%x\n", id.product );
|
||||||
|
printf("version = 0x%x\n", id.version );
|
||||||
|
}
|
||||||
|
|
||||||
|
len = ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), &evbit);
|
||||||
|
if (len > 0 && len <= sizeof(evbit))
|
||||||
|
{
|
||||||
|
printf("support ev type: ");
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
byte = ((unsigned char *)evbit)[i];
|
||||||
|
for (bit = 0; bit < 8; bit++)
|
||||||
|
{
|
||||||
|
if (byte & (1<<bit)) {
|
||||||
|
printf("%s ", ev_names[i*8 + bit]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
fds[0].fd = fd;
|
||||||
|
fds[0].events = POLLIN;
|
||||||
|
fds[0].revents = 0;
|
||||||
|
ret = poll(fds, nfds, 5000);
|
||||||
|
if (ret > 0)
|
||||||
|
{
|
||||||
|
if (fds[0].revents == POLLIN)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ret == 0)
|
||||||
|
{
|
||||||
|
printf("time out\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("poll err\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,138 @@
|
|||||||
|
|
||||||
|
#include <linux/input.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
|
||||||
|
/* According to earlier standards */
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* ./01_get_input_info /dev/input/event0 */
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int err;
|
||||||
|
int len;
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
unsigned char byte;
|
||||||
|
int bit;
|
||||||
|
struct input_id id;
|
||||||
|
unsigned int evbit[2];
|
||||||
|
struct input_event event;
|
||||||
|
int nfds;
|
||||||
|
struct timeval tv;
|
||||||
|
fd_set readfds;
|
||||||
|
|
||||||
|
char *ev_names[] = {
|
||||||
|
"EV_SYN ",
|
||||||
|
"EV_KEY ",
|
||||||
|
"EV_REL ",
|
||||||
|
"EV_ABS ",
|
||||||
|
"EV_MSC ",
|
||||||
|
"EV_SW ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"EV_LED ",
|
||||||
|
"EV_SND ",
|
||||||
|
"NULL ",
|
||||||
|
"EV_REP ",
|
||||||
|
"EV_FF ",
|
||||||
|
"EV_PWR ",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
printf("Usage: %s <dev>\n", argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = open(argv[1], O_RDWR | O_NONBLOCK);
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
printf("open %s err\n", argv[1]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ioctl(fd, EVIOCGID, &id);
|
||||||
|
if (err == 0)
|
||||||
|
{
|
||||||
|
printf("bustype = 0x%x\n", id.bustype );
|
||||||
|
printf("vendor = 0x%x\n", id.vendor );
|
||||||
|
printf("product = 0x%x\n", id.product );
|
||||||
|
printf("version = 0x%x\n", id.version );
|
||||||
|
}
|
||||||
|
|
||||||
|
len = ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), &evbit);
|
||||||
|
if (len > 0 && len <= sizeof(evbit))
|
||||||
|
{
|
||||||
|
printf("support ev type: ");
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
byte = ((unsigned char *)evbit)[i];
|
||||||
|
for (bit = 0; bit < 8; bit++)
|
||||||
|
{
|
||||||
|
if (byte & (1<<bit)) {
|
||||||
|
printf("%s ", ev_names[i*8 + bit]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
/* 设置超时时间 */
|
||||||
|
tv.tv_sec = 5;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
|
/* 想监测哪些文件? */
|
||||||
|
FD_ZERO(&readfds); /* 先全部清零 */
|
||||||
|
FD_SET(fd, &readfds); /* 想监测fd */
|
||||||
|
|
||||||
|
/* 函数原型为:
|
||||||
|
int select(int nfds, fd_set *readfds, fd_set *writefds,
|
||||||
|
fd_set *exceptfds, struct timeval *timeout);
|
||||||
|
* 我们为了"read"而监测, 所以只需要提供readfds
|
||||||
|
*/
|
||||||
|
nfds = fd + 1; /* nfds 是最大的文件句柄+1, 注意: 不是文件个数, 这与poll不一样 */
|
||||||
|
ret = select(nfds, &readfds, NULL, NULL, &tv);
|
||||||
|
if (ret > 0) /* 有文件可以提供数据了 */
|
||||||
|
{
|
||||||
|
/* 再次确认fd有数据 */
|
||||||
|
if (FD_ISSET(fd, &readfds))
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (ret == 0) /* 超时 */
|
||||||
|
{
|
||||||
|
printf("time out\n");
|
||||||
|
}
|
||||||
|
else /* -1: error */
|
||||||
|
{
|
||||||
|
printf("select err\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
|
||||||
|
#include <linux/input.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ./05_input_read_fasync /dev/input/event0 */
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
int len;
|
||||||
|
int ret;
|
||||||
|
int i;
|
||||||
|
unsigned char byte;
|
||||||
|
int bit;
|
||||||
|
struct input_id id;
|
||||||
|
unsigned int evbit[2];
|
||||||
|
unsigned int flags;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
char *ev_names[] = {
|
||||||
|
"EV_SYN ",
|
||||||
|
"EV_KEY ",
|
||||||
|
"EV_REL ",
|
||||||
|
"EV_ABS ",
|
||||||
|
"EV_MSC ",
|
||||||
|
"EV_SW ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"NULL ",
|
||||||
|
"EV_LED ",
|
||||||
|
"EV_SND ",
|
||||||
|
"NULL ",
|
||||||
|
"EV_REP ",
|
||||||
|
"EV_FF ",
|
||||||
|
"EV_PWR ",
|
||||||
|
};
|
||||||
|
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
printf("Usage: %s <dev>\n", argv[0]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 注册信号处理函数 */
|
||||||
|
signal(SIGIO, my_sig_handler);
|
||||||
|
|
||||||
|
/* 打开驱动程序 */
|
||||||
|
fd = open(argv[1], O_RDWR | O_NONBLOCK);
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
printf("open %s err\n", argv[1]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ioctl(fd, EVIOCGID, &id);
|
||||||
|
if (err == 0)
|
||||||
|
{
|
||||||
|
printf("bustype = 0x%x\n", id.bustype );
|
||||||
|
printf("vendor = 0x%x\n", id.vendor );
|
||||||
|
printf("product = 0x%x\n", id.product );
|
||||||
|
printf("version = 0x%x\n", id.version );
|
||||||
|
}
|
||||||
|
|
||||||
|
len = ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), &evbit);
|
||||||
|
if (len > 0 && len <= sizeof(evbit))
|
||||||
|
{
|
||||||
|
printf("support ev type: ");
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
byte = ((unsigned char *)evbit)[i];
|
||||||
|
for (bit = 0; bit < 8; bit++)
|
||||||
|
{
|
||||||
|
if (byte & (1<<bit)) {
|
||||||
|
printf("%s ", ev_names[i*8 + bit]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 把APP的进程号告诉驱动程序 */
|
||||||
|
fcntl(fd, F_SETOWN, getpid());
|
||||||
|
|
||||||
|
/* 使能"异步通知" */
|
||||||
|
flags = fcntl(fd, F_GETFL);
|
||||||
|
fcntl(fd, F_SETFL, flags | FASYNC);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
printf("main loop count = %d\n", count++);
|
||||||
|
sleep(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
|
#include <linux/input.h>
|
||||||
|
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
|
#include <tslib.h>
|
||||||
|
|
||||||
|
int distance(struct ts_sample_mt *point1, struct ts_sample_mt *point2)
|
||||||
|
{
|
||||||
|
int x = point1->x - point2->x;
|
||||||
|
int y = point1->y - point2->y;
|
||||||
|
|
||||||
|
return x*x + y*y;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
struct tsdev *ts;
|
||||||
|
int i;
|
||||||
|
int ret;
|
||||||
|
struct ts_sample_mt **samp_mt;
|
||||||
|
struct ts_sample_mt **pre_samp_mt;
|
||||||
|
int max_slots;
|
||||||
|
int point_pressed[20];
|
||||||
|
struct input_absinfo slot;
|
||||||
|
int touch_cnt = 0;
|
||||||
|
|
||||||
|
ts = ts_setup(NULL, 0);
|
||||||
|
if (!ts)
|
||||||
|
{
|
||||||
|
printf("ts_setup err\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ioctl(ts_fd(ts), EVIOCGABS(ABS_MT_SLOT), &slot) < 0) {
|
||||||
|
perror("ioctl EVIOGABS");
|
||||||
|
ts_close(ts);
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
max_slots = slot.maximum + 1 - slot.minimum;
|
||||||
|
|
||||||
|
samp_mt = malloc(sizeof(struct ts_sample_mt *));
|
||||||
|
if (!samp_mt) {
|
||||||
|
ts_close(ts);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
samp_mt[0] = calloc(max_slots, sizeof(struct ts_sample_mt));
|
||||||
|
if (!samp_mt[0]) {
|
||||||
|
free(samp_mt);
|
||||||
|
ts_close(ts);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre_samp_mt = malloc(sizeof(struct ts_sample_mt *));
|
||||||
|
if (!pre_samp_mt) {
|
||||||
|
ts_close(ts);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
pre_samp_mt[0] = calloc(max_slots, sizeof(struct ts_sample_mt));
|
||||||
|
if (!pre_samp_mt[0]) {
|
||||||
|
free(pre_samp_mt);
|
||||||
|
ts_close(ts);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for ( i = 0; i < max_slots; i++)
|
||||||
|
pre_samp_mt[0][i].valid = 0;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
ret = ts_read_mt(ts, samp_mt, max_slots, 1);
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
printf("ts_read_mt err\n");
|
||||||
|
ts_close(ts);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < max_slots; i++)
|
||||||
|
{
|
||||||
|
if (samp_mt[0][i].valid)
|
||||||
|
{
|
||||||
|
memcpy(&pre_samp_mt[0][i], &samp_mt[0][i], sizeof(struct ts_sample_mt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
touch_cnt = 0;
|
||||||
|
for (i = 0; i < max_slots; i++)
|
||||||
|
{
|
||||||
|
if (pre_samp_mt[0][i].valid && pre_samp_mt[0][i].tracking_id != -1)
|
||||||
|
point_pressed[touch_cnt++] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (touch_cnt == 2)
|
||||||
|
{
|
||||||
|
printf("distance: %08d\n", distance(&pre_samp_mt[0][point_pressed[0]], &pre_samp_mt[0][point_pressed[1]]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||