你的位置:首页 > 操作系统

[操作系统]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   -1typedef 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!\n");    return -1;  }  if (ts_config(g_tTSDev)) {    DBG_PRINTF("ts_config error!\n");    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!\n");    return -1;  }  if (ts_config(g_tTSDev)) {    DBG_PRINTF("ts_config error!\n");    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命令观察