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子系统":
|
||||
|
||||
```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;
|
||||
}
|
||||
|
||||