输入系统
#
1.数据结构抽象对于量产工具测试,输入两个来源:
- 网络输入
- 屏幕点击
将输入数据抽象成一个输入事件,Input_Event。
再定义一个输入设备结构体,用来描述不同设备操作:
#
2.触摸屏输入#
2.1 编程编写input/touchscreen.c
先定义一个输入设备结构体-触摸屏设备:
参考"01_all_series_quickstart\04_嵌入式Linux应用开发基础知识\source\11_input\02_tslib\mt_cal_distance.c"
,
实现结构体中的三个函数,使用tslib中的函数:
- 初始化函数:ts_setup
- 结束函数:ts_close
- 获取输入事件:ts_read。读取输入事件到samp,给传入的ptInputEvent赋值。
#
2.2 测试#
main直接在input/touchscreen.c文件下写一个主函数用于测试:
#
修改makefile(1)在input目录下添加一个Makefile
(2)修改顶层目录makefile:
- 链接tslib库
前提是交叉编译过tslib,并安装:参考《01_嵌入式Linux应用开发完全手册V5.1_IMX6ULL_Pro开发板》7.5.2 交叉编译、测试 tslib
- 添加input目录
问题:
注意在input_manager.h中包含
但我发现在#include <tslib.h>
的情况下,不包含time.h,也通过了编译。说明tslib.h中也包含了time.h,但是这样不规范。
#
3.网络输入#
3.1 编程#
3.2 测试编译成功后,仅剩下touchscreen的警告,因为关闭了其测试程序:
拷贝01all_series_quickstart\04嵌入式Linux应用开发基础知识\source\12_socket\udp2\client.c到
6th_project_practice_source\09_input_netinput_unittest\unittest,然后编译一下
#
4.输入管理为了支持同时从多个输入设备得到数据,不丢失数据,引入输入管理架构。
#
4.1 总体结构要想支持多个输入设备,只能使用线程: 为每个InputDevice都创建一个“读取线程”
#
4.2 如何避免数据丢失?比如触摸屏,它会一下子上报很多数据
对于网络输入,也有可能同时又多个client发来数据、
所以,不能使用单一的变量来保存数据,而是使用一个数组来保存数据 — 使用“环形缓冲区”
#
4.3 编程#
输入管理的框架代码void RegisterInputDevice(PInputDevice ptInputDev)
:下层调用,注册输入设备到输入管理的设备链表void IntputRegisterInit(void)
:上层调用,注册所有输入设备static void *input_recv_tread_func(void *data)
:内部调用,输入设备事件的接收线程函数void IntputDeviceInit(void)
:上层调用,输入设备初始化,调用下层函数进行初始化。具体地,从输入管理的设备链表中找出设备,调用其初始化函数ptInputDevtmp->DeviceInit()
,然后为其创建一个线程。 为何需要使用线程?因为有两个输入设备,如果在同一个程序里面轮询,读取触摸屏时,可能会休眠,那么网络输入就会丢失;读取网络数据时,也可能会休眠,那么触摸屏数据就会丢失。所有需要为每个输入设备都创建一个线程,并且要使用锁,实现互斥地访问环形缓冲区。int GetInputEvent(PInputEvent PT_InputEvent)
:上层调用,获取输入事件
#
实现环形缓冲区- 注意NEXT_POS(x)需要取余数计算
- 注意空条件与满条件的区别,以放弃一个存储位置来做区分:读写位置相同时为空,下一个写的位置等于读的位置时为满。
#
线程函数与获取输入事件函数完善线程函数input_recv_tread_func
与获取输入事件函数GetInputEvent
:
- GetInputEvent:上层调用此函数获取输入数据,为实现多线程对环形缓冲区资源的临界访问,需要使用互斥锁。参考
"01_all_series_quickstart\04_嵌入式Linux应用开发基础知识\source\13_thread\02_视频配套源码\pthread5.c"
代码。
- input_recv_tread_func:多个输入设备共用这个函数来创建不同的线程,通过传入的data转换为PInputDevice来区分;调用下层的设备提供的函数获取输入事件,成功就保存数据 - 保存数据前需要获取互斥锁,保存数据后唤醒等待数据的线程(在我们的任务中就是调用上面函数GetInputEvent的线程),然后再释放互斥锁。
#
补充input_manager.h
声明函数
struct timeval需要包含time.h
#
总结#
4.4 测试#
main在unittest
目录下创建input_test.c
#
上机(1)修改Makefile
unittest/Makefile
input/Makefile
顶层目录的Makefile
(2)错误:
链接错误:/home/book/nfs_rootfs/12_intput_manager_unittest/input/input_manager.c:108: undefined reference to pthread_create
需要在makefile中加入pthread库
不能把临时变量的地址赋给返回值,应该进行值拷贝:
测试通过:
请点击左侧菜单(移动端为右下角)选择要查看的所有笔记吧。