diff --git a/IMX6ULL/doc_pic/05_Input/02_先学习输入系统应用编程.md b/IMX6ULL/doc_pic/05_Input/02_先学习输入系统应用编程.md new file mode 100644 index 0000000..701004b --- /dev/null +++ b/IMX6ULL/doc_pic/05_Input/02_先学习输入系统应用编程.md @@ -0,0 +1,71 @@ +## 先学习输入系统应用编程 + +### 1. 百问网Linux视频体系 + +![image-20210324102014845](pic/05_Input/07_video_tutorial.png) + +### 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/),根据下图找到视频 +![image-20210324110234596](pic/05_Input/04_videos_position1.png) + +#### 3.2 在驱动大全里 + +为了保持视频的完整性,我们把这9个视频也放到了驱动大全里,如下: + +![image-20210324110006388](pic/05_Input/05_videos_position2.png) + +### 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 + ``` + + +它们的位置如下图所示(左边是原始仓库,右边是驱动大全仓库): + +![image-20210324094623077](pic/05_Input/06_doc_source_positons.png) \ No newline at end of file diff --git a/IMX6ULL/doc_pic/05_Input/03_输入系统应用编程.docx b/IMX6ULL/doc_pic/05_Input/03_输入系统应用编程.docx new file mode 100644 index 0000000..41b0986 Binary files /dev/null and b/IMX6ULL/doc_pic/05_Input/03_输入系统应用编程.docx differ diff --git a/IMX6ULL/doc_pic/05_Input/03_输入系统应用编程.tif b/IMX6ULL/doc_pic/05_Input/03_输入系统应用编程.tif new file mode 100644 index 0000000..fb8fd59 Binary files /dev/null and b/IMX6ULL/doc_pic/05_Input/03_输入系统应用编程.tif differ diff --git a/IMX6ULL/doc_pic/05_Input/02_Input子系统框架.md b/IMX6ULL/doc_pic/05_Input/04_Input子系统框架.md similarity index 100% rename from IMX6ULL/doc_pic/05_Input/02_Input子系统框架.md rename to IMX6ULL/doc_pic/05_Input/04_Input子系统框架.md diff --git a/IMX6ULL/doc_pic/05_Input/02_Input子系统框架.tif b/IMX6ULL/doc_pic/05_Input/04_Input子系统框架.tif similarity index 100% rename from IMX6ULL/doc_pic/05_Input/02_Input子系统框架.tif rename to IMX6ULL/doc_pic/05_Input/04_Input子系统框架.tif diff --git a/IMX6ULL/doc_pic/05_Input/pic/05_Input/04_videos_position1.png b/IMX6ULL/doc_pic/05_Input/pic/05_Input/04_videos_position1.png new file mode 100644 index 0000000..1360e66 Binary files /dev/null and b/IMX6ULL/doc_pic/05_Input/pic/05_Input/04_videos_position1.png differ diff --git a/IMX6ULL/doc_pic/05_Input/pic/05_Input/05_videos_position2.png b/IMX6ULL/doc_pic/05_Input/pic/05_Input/05_videos_position2.png new file mode 100644 index 0000000..0b98959 Binary files /dev/null and b/IMX6ULL/doc_pic/05_Input/pic/05_Input/05_videos_position2.png differ diff --git a/IMX6ULL/doc_pic/05_Input/pic/05_Input/06_doc_source_positons.png b/IMX6ULL/doc_pic/05_Input/pic/05_Input/06_doc_source_positons.png new file mode 100644 index 0000000..7a277fe Binary files /dev/null and b/IMX6ULL/doc_pic/05_Input/pic/05_Input/06_doc_source_positons.png differ diff --git a/IMX6ULL/doc_pic/05_Input/pic/05_Input/07_video_tutorial.png b/IMX6ULL/doc_pic/05_Input/pic/05_Input/07_video_tutorial.png new file mode 100644 index 0000000..94a6f78 Binary files /dev/null and b/IMX6ULL/doc_pic/05_Input/pic/05_Input/07_video_tutorial.png differ diff --git a/IMX6ULL/source/05_Input/01_input_app/01_app_demo/01_get_input_info.c b/IMX6ULL/source/05_Input/01_input_app/01_app_demo/01_get_input_info.c new file mode 100644 index 0000000..31deaf7 --- /dev/null +++ b/IMX6ULL/source/05_Input/01_input_app/01_app_demo/01_get_input_info.c @@ -0,0 +1,88 @@ + +#include +#include +#include +#include +#include +#include + + +/* ./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 \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< +#include +#include +#include +#include +#include +#include +#include + + +/* ./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 [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< +#include +#include +#include +#include +#include +#include +#include +#include + + +/* ./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 \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< 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; +} + diff --git a/IMX6ULL/source/05_Input/01_input_app/01_app_demo/04_input_read_select.c b/IMX6ULL/source/05_Input/01_input_app/01_app_demo/04_input_read_select.c new file mode 100644 index 0000000..9d694c1 --- /dev/null +++ b/IMX6ULL/source/05_Input/01_input_app/01_app_demo/04_input_read_select.c @@ -0,0 +1,138 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* According to earlier standards */ +#include + + +/* ./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 \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< 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; +} + diff --git a/IMX6ULL/source/05_Input/01_input_app/01_app_demo/05_input_read_fasync.c b/IMX6ULL/source/05_Input/01_input_app/01_app_demo/05_input_read_fasync.c new file mode 100644 index 0000000..d816198 --- /dev/null +++ b/IMX6ULL/source/05_Input/01_input_app/01_app_demo/05_input_read_fasync.c @@ -0,0 +1,123 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 \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< +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +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; +} + diff --git a/IMX6ULL/source/05_Input/01_input_app/02_tslib/tslib-1.21.tar.xz b/IMX6ULL/source/05_Input/01_input_app/02_tslib/tslib-1.21.tar.xz new file mode 100644 index 0000000..30f1450 Binary files /dev/null and b/IMX6ULL/source/05_Input/01_input_app/02_tslib/tslib-1.21.tar.xz differ diff --git a/README.md b/README.md index a2e7b70..6ba83f2 100644 --- a/README.md +++ b/README.md @@ -134,8 +134,25 @@ 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的测试程序 + ``` + + + + + ## 6. 联系方式 diff --git a/STM32MP157/doc_pic/05_Input/02_先学习输入系统应用编程.md b/STM32MP157/doc_pic/05_Input/02_先学习输入系统应用编程.md new file mode 100644 index 0000000..701004b --- /dev/null +++ b/STM32MP157/doc_pic/05_Input/02_先学习输入系统应用编程.md @@ -0,0 +1,71 @@ +## 先学习输入系统应用编程 + +### 1. 百问网Linux视频体系 + +![image-20210324102014845](pic/05_Input/07_video_tutorial.png) + +### 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/),根据下图找到视频 +![image-20210324110234596](pic/05_Input/04_videos_position1.png) + +#### 3.2 在驱动大全里 + +为了保持视频的完整性,我们把这9个视频也放到了驱动大全里,如下: + +![image-20210324110006388](pic/05_Input/05_videos_position2.png) + +### 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 + ``` + + +它们的位置如下图所示(左边是原始仓库,右边是驱动大全仓库): + +![image-20210324094623077](pic/05_Input/06_doc_source_positons.png) \ No newline at end of file diff --git a/STM32MP157/doc_pic/05_Input/03_输入系统应用编程.docx b/STM32MP157/doc_pic/05_Input/03_输入系统应用编程.docx new file mode 100644 index 0000000..41b0986 Binary files /dev/null and b/STM32MP157/doc_pic/05_Input/03_输入系统应用编程.docx differ diff --git a/STM32MP157/doc_pic/05_Input/03_输入系统应用编程.tif b/STM32MP157/doc_pic/05_Input/03_输入系统应用编程.tif new file mode 100644 index 0000000..fb8fd59 Binary files /dev/null and b/STM32MP157/doc_pic/05_Input/03_输入系统应用编程.tif differ diff --git a/STM32MP157/doc_pic/05_Input/04_Input子系统框架.md b/STM32MP157/doc_pic/05_Input/04_Input子系统框架.md new file mode 100644 index 0000000..04064ca --- /dev/null +++ b/STM32MP157/doc_pic/05_Input/04_Input子系统框架.md @@ -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. 回顾字符设备驱动程序 + +![](pic/05_Input/02_char_driver.png) +怎么编写字符设备驱动程序? + +* 确定主设备号 +* 创建file_operations结构体 + * 在里面填充drv_open/drv_read/drv_ioctl等函数 +* 注册file_operations结构体 + * register_chrdev(major, &fops, name) +* 谁调用register_chrdev?在入口函数调用 +* 有入口自然就有出口 + * 在出口函数unregister_chrdev +* 辅助函数(帮助系统自动创建设备节点) + * class_create + * device_create + +### 2. 驱动程序分离的套路 + +![](pic/05_Input/03_input_driver_module.png) diff --git a/STM32MP157/doc_pic/05_Input/04_Input子系统框架.tif b/STM32MP157/doc_pic/05_Input/04_Input子系统框架.tif new file mode 100644 index 0000000..f0da0e7 Binary files /dev/null and b/STM32MP157/doc_pic/05_Input/04_Input子系统框架.tif differ diff --git a/STM32MP157/doc_pic/05_Input/pic/05_Input/04_videos_position1.png b/STM32MP157/doc_pic/05_Input/pic/05_Input/04_videos_position1.png new file mode 100644 index 0000000..1360e66 Binary files /dev/null and b/STM32MP157/doc_pic/05_Input/pic/05_Input/04_videos_position1.png differ diff --git a/STM32MP157/doc_pic/05_Input/pic/05_Input/05_videos_position2.png b/STM32MP157/doc_pic/05_Input/pic/05_Input/05_videos_position2.png new file mode 100644 index 0000000..0b98959 Binary files /dev/null and b/STM32MP157/doc_pic/05_Input/pic/05_Input/05_videos_position2.png differ diff --git a/STM32MP157/doc_pic/05_Input/pic/05_Input/06_doc_source_positons.png b/STM32MP157/doc_pic/05_Input/pic/05_Input/06_doc_source_positons.png new file mode 100644 index 0000000..7a277fe Binary files /dev/null and b/STM32MP157/doc_pic/05_Input/pic/05_Input/06_doc_source_positons.png differ diff --git a/STM32MP157/doc_pic/05_Input/pic/05_Input/07_video_tutorial.png b/STM32MP157/doc_pic/05_Input/pic/05_Input/07_video_tutorial.png new file mode 100644 index 0000000..94a6f78 Binary files /dev/null and b/STM32MP157/doc_pic/05_Input/pic/05_Input/07_video_tutorial.png differ diff --git a/STM32MP157/source/A7/05_Input/01_input_app/01_app_demo/01_get_input_info.c b/STM32MP157/source/A7/05_Input/01_input_app/01_app_demo/01_get_input_info.c new file mode 100644 index 0000000..31deaf7 --- /dev/null +++ b/STM32MP157/source/A7/05_Input/01_input_app/01_app_demo/01_get_input_info.c @@ -0,0 +1,88 @@ + +#include +#include +#include +#include +#include +#include + + +/* ./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 \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< +#include +#include +#include +#include +#include +#include +#include + + +/* ./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 [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< +#include +#include +#include +#include +#include +#include +#include +#include + + +/* ./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 \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< 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; +} + diff --git a/STM32MP157/source/A7/05_Input/01_input_app/01_app_demo/04_input_read_select.c b/STM32MP157/source/A7/05_Input/01_input_app/01_app_demo/04_input_read_select.c new file mode 100644 index 0000000..9d694c1 --- /dev/null +++ b/STM32MP157/source/A7/05_Input/01_input_app/01_app_demo/04_input_read_select.c @@ -0,0 +1,138 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* According to earlier standards */ +#include + + +/* ./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 \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< 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; +} + diff --git a/STM32MP157/source/A7/05_Input/01_input_app/01_app_demo/05_input_read_fasync.c b/STM32MP157/source/A7/05_Input/01_input_app/01_app_demo/05_input_read_fasync.c new file mode 100644 index 0000000..d816198 --- /dev/null +++ b/STM32MP157/source/A7/05_Input/01_input_app/01_app_demo/05_input_read_fasync.c @@ -0,0 +1,123 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 \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< +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +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; +} + diff --git a/STM32MP157/source/A7/05_Input/01_input_app/02_tslib/tslib-1.21.tar.xz b/STM32MP157/source/A7/05_Input/01_input_app/02_tslib/tslib-1.21.tar.xz new file mode 100644 index 0000000..30f1450 Binary files /dev/null and b/STM32MP157/source/A7/05_Input/01_input_app/02_tslib/tslib-1.21.tar.xz differ