5.1 使用轮询方法

input_manager.h

#ifndef _INPUT_MANAGER_H
#define _INPUT_MANAGER_H
#include <sys/time.h>


#define INPUT_TYPE_STDIN        0
#define INPUT_TYPE_TOUCHSCREEN  1

#define INPUT_VALUE_UP          0   
#define INPUT_VALUE_DOWN        1
#define INPUT_VALUE_EXIT        2
#define INPUT_VALUE_UNKNOWN     -1


typedef struct InputEvent {
    struct timeval tTime;
    int iType;  /* stdin, touchsceen */
    int iVal;   /*  */
}T_InputEvent, *PT_InputEvent;


typedef struct InputOpr {
    char *name;
    int (*DeviceInit)(void);
    int (*DeviceExit)(void);
    int (*GetInputEvent)(PT_InputEvent ptInputEvent);
    struct InputOpr *ptNext;
}T_InputOpr, *PT_InputOpr;


int InputInit(void);
int RegisterInputOpr(PT_InputOpr ptInputOpr);
void ShowInputOpr(void);
int AllInputDevicesInit(void);
int GetInputEvent(PT_InputEvent ptInputEvent);

#endif /* _INPUT_MANAGER_H */

input_manager.c

#include <config.h>
#include <input_manager.h>
#include <stdlib.h>

#include <tslib.h>

/* 参考tslib里的ts_print.c */

static struct tsdev *g_tTSDev;
static int giXres;
static int giYres;

/* 注意: 由于要用到LCD的分辨率, 此函数要在SelectAndInitDisplay之后调用 */
static int TouchScreenDevInit(void)
{
    char *pcTSName = NULL;

    if ((pcTSName = getenv("TSLIB_TSDEVICE")) != NULL ) 
    {
        g_tTSDev = ts_open(pcTSName, 1);
    }
    else
    {
        g_tTSDev = ts_open("/dev/event0", 1);
    }

    if (!g_tTSDev) {
        DBG_PRINTF("ts_open error!
");
        return -1;
    }

    if (ts_config(g_tTSDev)) {
        DBG_PRINTF("ts_config error!
");
        return -1;
    }

    if (GetDispResolution(&giXres, &giYres))
    {
        return -1;
    }

    return 0;
}

static int TouchScreenDevExit(void)
{
    return 0;
}


static int isOutOf500ms(struct timeval *ptPreTime, struct timeval *ptNowTime)
{
    int iPreMs;
    int iNowMs;
    
    iPreMs = ptPreTime->tv_sec * 1000 + ptPreTime->tv_usec / 1000;
    iNowMs = ptNowTime->tv_sec * 1000 + ptNowTime->tv_usec / 1000;

    return (iNowMs > iPreMs + 500);
}

static int TouchScreenGetInputEvent(PT_InputEvent ptInputEvent)
{
    struct ts_sample tSamp;
    int iRet;

    static struct timeval tPreTime;
    
    iRet = ts_read(g_tTSDev, &tSamp, 1);
    
    if (iRet < 0) {
        return -1;
    }

    /* 处理数据 */
    if (isOutOf500ms(&tPreTime, &tSamp.tv))
    {
        /* 如果此次触摸事件发生的时间, 距上次事件超过了500ms */
        tPreTime = tSamp.tv;
        ptInputEvent->tTime = tSamp.tv;
        ptInputEvent->iType = INPUT_TYPE_TOUCHSCREEN;

        if (tSamp.y < giYres/3)
        {
            ptInputEvent->iVal = INPUT_VALUE_UP;
        }
        else if (tSamp.y > 2*giYres/3)
        {
            ptInputEvent->iVal = INPUT_VALUE_DOWN;
        }
        else
        {
            ptInputEvent->iVal = INPUT_VALUE_UNKNOWN;
        }
        return 0;
        
    }
    else
    {
        return -1;
    }
    

    return 0;
}


static T_InputOpr g_tTouchScreenOpr = {
    .name          = "touchscreen",
    .DeviceInit    = TouchScreenDevInit,
    .DeviceExit    = TouchScreenDevExit,
    .GetInputEvent = TouchScreenGetInputEvent,
};

int TouchScreenInit(void)
{
    return RegisterInputOpr(&g_tTouchScreenOpr);
}

stdin.c

#include <input_manager.h>
#include <termios.h>
#include <unistd.h>
#include <stdio.h>


static int StdinDevInit(void)
{
    struct termios tTTYState;
 
    //get the terminal state
    tcgetattr(STDIN_FILENO, &tTTYState);
 
    //turn off canonical mode
    tTTYState.c_lflag &= ~ICANON;
    //minimum of number input read.
    tTTYState.c_cc[VMIN] = 1;   /* 有一个数据时就立刻返回 */

    //set the terminal attributes.
    tcsetattr(STDIN_FILENO, TCSANOW, &tTTYState);

    return 0;
}

static int StdinDevExit(void)
{

    struct termios tTTYState;
 
    //get the terminal state
    tcgetattr(STDIN_FILENO, &tTTYState);
 
    //turn on canonical mode
    tTTYState.c_lflag |= ICANON;
    
    //set the terminal attributes.
    tcsetattr(STDIN_FILENO, TCSANOW, &tTTYState);    
    return 0;
}

static int StdinGetInputEvent(PT_InputEvent ptInputEvent)
{
    /* 如果有数据就读取、处理、返回
     * 如果没有数据, 立刻返回, 不等待
     */

    /* select, poll 可以参数 UNIX环境高级编程 */

    struct timeval tTV;
    fd_set tFDs;
    char c;
    
    tTV.tv_sec = 0;
    tTV.tv_usec = 0;
    FD_ZERO(&tFDs);
    
    FD_SET(STDIN_FILENO, &tFDs); //STDIN_FILENO is 0
    select(STDIN_FILENO+1, &tFDs, NULL, NULL, &tTV);
    
    if (FD_ISSET(STDIN_FILENO, &tFDs))
    {
        /* 处理数据 */
        ptInputEvent->iType = INPUT_TYPE_STDIN;
        gettimeofday(&ptInputEvent->tTime, NULL);
        
        c = fgetc(stdin);
        if (c == 'u')
        {
            ptInputEvent->iVal = INPUT_VALUE_UP;
        }
        else if (c == 'n')
        {
            ptInputEvent->iVal = INPUT_VALUE_DOWN;
        }
        else if (c == 'q')
        {
            ptInputEvent->iVal = INPUT_VALUE_EXIT;
        }
        else
        {
            ptInputEvent->iVal = INPUT_VALUE_UNKNOWN;
        }        
        return 0;
    }
    else
    {
        return -1;
    }
}

static T_InputOpr g_tStdinOpr = {
    .name          = "stdin",
    .DeviceInit    = StdinDevInit,
    .DeviceExit    = StdinDevExit,
    .GetInputEvent = StdinGetInputEvent,
};


int StdinInit(void)
{
    return RegisterInputOpr(&g_tStdinOpr);
}

touchscreen.c

#include <config.h>
#include <input_manager.h>
#include <stdlib.h>

#include <tslib.h>

/* 参考tslib里的ts_print.c */

static struct tsdev *g_tTSDev;
static int giXres;
static int giYres;

/* 注意: 由于要用到LCD的分辨率, 此函数要在SelectAndInitDisplay之后调用 */
static int TouchScreenDevInit(void)
{
    char *pcTSName = NULL;

    if ((pcTSName = getenv("TSLIB_TSDEVICE")) != NULL ) 
    {
        g_tTSDev = ts_open(pcTSName, 1);
    }
    else
    {
        g_tTSDev = ts_open("/dev/event0", 1);
    }

    if (!g_tTSDev) {
        DBG_PRINTF("ts_open error!
");
        return -1;
    }

    if (ts_config(g_tTSDev)) {
        DBG_PRINTF("ts_config error!
");
        return -1;
    }

    if (GetDispResolution(&giXres, &giYres))
    {
        return -1;
    }

    return 0;
}

static int TouchScreenDevExit(void)
{
    return 0;
}


static int isOutOf500ms(struct timeval *ptPreTime, struct timeval *ptNowTime)
{
    int iPreMs;
    int iNowMs;
    
    iPreMs = ptPreTime->tv_sec * 1000 + ptPreTime->tv_usec / 1000;
    iNowMs = ptNowTime->tv_sec * 1000 + ptNowTime->tv_usec / 1000;

    return (iNowMs > iPreMs + 500);
}

static int TouchScreenGetInputEvent(PT_InputEvent ptInputEvent)
{
    struct ts_sample tSamp;
    int iRet;

    static struct timeval tPreTime;
    
    iRet = ts_read(g_tTSDev, &tSamp, 1);
    
    if (iRet < 0) {
        return -1;
    }

    /* 处理数据 */
    if (isOutOf500ms(&tPreTime, &tSamp.tv))
    {
        /* 如果此次触摸事件发生的时间, 距上次事件超过了500ms */
        tPreTime = tSamp.tv;
        ptInputEvent->tTime = tSamp.tv;
        ptInputEvent->iType = INPUT_TYPE_TOUCHSCREEN;

        if (tSamp.y < giYres/3)
        {
            ptInputEvent->iVal = INPUT_VALUE_UP;
        }
        else if (tSamp.y > 2*giYres/3)
        {
            ptInputEvent->iVal = INPUT_VALUE_DOWN;
        }
        else
        {
            ptInputEvent->iVal = INPUT_VALUE_UNKNOWN;
        }
        return 0;
        
    }
    else
    {
        return -1;
    }
    

    return 0;
}


static T_InputOpr g_tTouchScreenOpr = {
    .name          = "touchscreen",
    .DeviceInit    = TouchScreenDevInit,
    .DeviceExit    = TouchScreenDevExit,
    .GetInputEvent = TouchScreenGetInputEvent,
};

int TouchScreenInit(void)
{
    return RegisterInputOpr(&g_tTouchScreenOpr);
}

5.1 使用轮询方法  // CPU占用率高
实验方法:
a. insmod  s3c_ts.ko
   确定是哪个设备节点对应触摸屏
b.
export TSLIB_TSDEVICE=/dev/event0
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_PLUGINDIR=/lib/ts
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0

c. 较准
ts_calibrate  

d. telnetd -l /bin/sh  //启动telnet服务,为了登录进去观察CPU占用率

e. ./show_file -s 24 -d fb -f ./MSYH.TTF ./utf8_novel.txt

f. telnet上开发板执行top命令观察

原文地址:https://www.cnblogs.com/CZM-/p/5349670.html