【嵌入式应用开发项目之输入系统】

软件整体框架

输入系统框架
主要考虑触摸屏输入与网络输入,主要由一个头文件、三个源文件与一个包含main函数的可执行文件组成,以下是一些主要功能介绍。

input_manager.h

typedef struct InputDevice{
    char *name;
    int (*GetInputEvent)(PInputEvent ptInputEvent);
    int (*DeviceInit)(void);
    int (*DeviceExit)(void);
    struct InputDevice *ptNext;
}InputDevice,*PInputDevice;

typedef struct InputEvent{
    struct timeval tTime;
    int iType;
    int iXPos;
    int iYPos;
    int iPre;
    char str[1024];
}InputEvent,*PInputEvent;

将输入设备与输入事件抽象为具有共性的两个结构体,对于InputDevice结构体使用了函数指针,定义了指向什么类型的函数,这样写对于不同的输入设备的.c文件,可以实现不同的底层功能,与C++中的类相似。InputEvent是存储输入事件信息的结构体,使两种输入设备可以共用一种统一的结构体。

touchscreen.c

//定义并初始化触摸屏结构体
static InputDevice g_tTouchscreenDev = {
    .name = "touchscreen",
    .GetInputEvent   = TouchscreenGetInputEvent,
    .DeviceInit      = TouchscreenDeviceInit,
    .DeviceExit      = TouchscreenDeviceExit,
};
//定义获取触摸屏事件信息的函数,并将信息保存在ptInputEvent结构体中
static int TouchscreenGetInputEvent(PInputEvent ptInputEvent)
//定义初始化函数
static int TouchscreenDeviceInit(void)
//定义退出函数
static int TouchscreenDeviceExit(void)

该文件主要通过tslib工具实现对触摸屏事件信息的获取过程:初始化->获取event->保存(返回)信息->关闭。

netinput.c

static InputDevice g_tNetinputDev = {
    .name = "netinput",
    .GetInputEvent   = NetinputGetInputEvent,
    .DeviceInit      = NetinputDeviceInit,
    .DeviceExit      = NetinputDeviceExit,
};

同touchscreen.c文件一样,实现设备结构体及内部函数。

input_manager.c

输入管理器
采用多线程是为了能够同时监测触摸屏与网络设备的输入,采用环形buffer是为了不丢失数据

/* 注册各个输入设备 */
void InputInit(void)

/* 初始化输入设备,并为每个输入设备创建线程 同时获得多个输入设备的信息*/
void InputDeviceInit(void)

/* 在APP中调用这个函数,如果buffer为空,则睡眠,等待唤醒 */
int GetInputEvent(PInputEvent pInputEvent)

/* 线程函数->每个硬件对应一个线程,检测到event,就把event保存到buffer中,并唤醒等待数据的线程(告诉这些线程,来数据了) */
static void *input_recv_thread_func(void *data)

//环形buffer
/* start 实现环形缓冲区 */
#define BUFFER_LEN 20
static int g_iRead  = 0;
static int g_iWrite = 0;
static InputEvent g_atInputEvents[BUFFER_LEN];

static int isInputBufferFull(void)
{
    return (g_iWrite == ((g_iRead + 1) % BUFFER_LEN));   //下一个写的位置等于读的位置,表示为满
}

static int isInputBufferEmpty(void)
{
    if (g_iWrite == g_iRead)
    {
        return 1;
    }else
    {
        return 0;
    }
    
}

static void PutInputEventToBuffer(PInputEvent ptInputEvent)
{
    if (!isInputBufferFull())
    {
        g_atInputEvents[g_iWrite] = *ptInputEvent;
        g_iWrite = (g_iWrite + 1) % BUFFER_LEN;
    }
}

static int GetInputEventFromBuffer(PInputEvent ptInputEvent)
{
    if (!isInputBufferEmpty())
    {
        *ptInputEvent = g_atInputEvents[g_iRead];
        g_iRead = (g_iRead + 1) % BUFFER_LEN;
        return 1;
    }else
    {
        return 0;
    }
    
}

/* end 实现环形缓冲区 */

用数组实现环形buffer

测试过程遇到的问题

ps命令的使用

  • 开发板与虚拟机ps命令不一样
    可能是软件版本不同,开发板不支持ps -T查看线程,用top可以,相关链接:link1link2
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值