这个类似如串口键盘,不过只实现了一些键值,因为这个项目只用到这些。原理:首先开启一个服务循环读取串口的数据,然后将串口读到的数据,写给驱动,驱动在判断是什么键值,然后进行上报。
上层服务源码如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/ip.h>
#include <net/if.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <linux/rtc.h>
#include <time.h>
#include <errno.h>
#include <termios.h>
#include <string.h>
#include <pthread.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <math.h>
#include <linux/input.h>
#define LOG_TAG "SerialKey"
#include <syslog.h>
int main(int argc, char *argv[])
{
int fdosp=-1;
int fdc = -1;
struct termios option;
int status = 0;
fdosp=open("/dev/ttyS1",O_RDWR|O_NONBLOCK);
if (fdosp<0)
{
syslog(LOG_ERR,"%s:open devices failed\n",LOG_TAG);
return -1;
}
#if 1
fdc=open("/dev/gzsd-input",O_RDWR|O_NONBLOCK);
if (fdc<0)
{
syslog(LOG_ERR,"%s:open gzsd-input failed\n",LOG_TAG);
return -1;
}
#endif
memset(&option, 0, sizeof option);
option.c_iflag = IGNPAR;
option.c_cflag = B19200 | HUPCL | CS8 | CREAD | CLOCAL;
option.c_cc[VMIN] = 2;
status = tcsetattr(fdosp, TCSANOW, &option);
if (-1 == status)
{
syslog(LOG_ERR,"%s:set devices failed\n",LOG_TAG);
return -1;
}
fd_set readset;
struct timeval tv;
int MaxFd = 0;
int z;
FD_ZERO(&readset);
FD_SET(fdosp, &readset);
MaxFd = fdosp + 1;
tv.tv_sec = 1;
tv.tv_usec = 0;
z = select(MaxFd,&readset,0,0,&tv);
if(z == -1)
{
syslog(LOG_ERR,"%s:select failed\n",LOG_TAG);
return -1;
}
char databuf[10];
int i = 0;
int ret;
//printf("start to read......\n");
while(1)
{
i = read(fdosp,databuf,1);
if(i > 0)
{
databuf[i] = '\0';
//printf("read data is %s\n",databuf);
ret = write(fdosp,databuf,1);
if(ret < 0) {
syslog(LOG_ERR,"%s:write data failed\n",LOG_TAG);
}
#if 1
ret = write(fdc,databuf,sizeof(databuf));
#endif
}
}
syslog(LOG_ERR,"%s:exit\n",LOG_TAG);
return 0;
}
这个是amlogic下的,串口设备名为ttyS
驱动源码如下:
/*
* linux/drivers/char/gzsd_input.c
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
#include <asm/uaccess.h>
#define DEVICE_NAME "gzsd-input"
static struct input_dev * input;
static int s3c_Keycode[] = {KEY_A,KEY_B,KEY_C,KEY_D,KEY_E,KEY_F,KEY_G,KEY_H,KEY_I,KEY_J,KEY_K,KEY_L,
KEY_M,KEY_N,KEY_O,KEY_P,KEY_Q,KEY_R,KEY_S,KEY_T,KEY_U,KEY_V,KEY_W,KEY_X,
KEY_Y,KEY_Z,KEY_0,KEY_1,KEY_2,KEY_3,KEY_4,KEY_5,KEY_6,KEY_7,KEY_8,KEY_9,
KEY_BACK,KEY_HOME,KEY_MENU,KEY_VOLUMEUP,KEY_VOLUMEDOWN,KEY_UP,KEY_DOWN,
KEY_LEFT,KEY_RIGHT};
#define MAX_BUTTON_CNT (sizeof(s3c_Keycode)/sizeof(s3c_Keycode[0]))
static ssize_t gzsd_input_write(struct file *filp, char *buffer,int len)
{
int i = -1;
switch(buffer[0])
{
case 42:
i = 36;
break;
case 35:
i = 37;
break;
case 47:
i = 38;
break;
case 40:
i = 39;
break;
case 41:
i = 40;
break;
default:
break;
}
if((buffer[0] > 47) && (buffer[0] < 58))
i = (buffer[0] - 48) + 26;
else if((buffer[0] > 96) && (buffer[0] < 123))
i = buffer[0] - 97;
else if((buffer[0] > 59) && (buffer[0] < 64))
i = (buffer[0] - 60) + 41;
if(i < 0) return -1;
input_report_key(input, s3c_Keycode[i], 1);
input_sync(input);
msleep(10);
input_report_key(input, s3c_Keycode[i], 0);
input_sync(input);
return 0;
}
static int gzsd_input_open(struct inode *inode, struct file *filp)
{
return 0;
}
static int gzsd_input_release(struct inode *inode, struct file *filp)
{
return 0;
}
static struct file_operations gzsd_dev_fops = {
.owner =THIS_MODULE,
.open =gzsd_input_open,
.write =gzsd_input_write,
.release =gzsd_input_release,
};
static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = "gzsd-input",
.fops = &gzsd_dev_fops,
};
static int __init gzsd_input_init(void)
{
int ret;
int i;
input = input_allocate_device();
if(!input)
return -ENOMEM;
set_bit(EV_KEY, input->evbit);
for(i = 0; i < MAX_BUTTON_CNT; i++)
set_bit(s3c_Keycode[i], input->keybit);
input->name = "gzsd-input";
input->phys = "gzsd-input/input0";
input->id.bustype = BUS_HOST;
input->id.vendor = 0x0001;
input->id.product = 0x0001;
input->id.version = 0x0100;
input->keycode = s3c_Keycode;
if(input_register_device(input) != 0)
{
printk("gzsd-input input register device fail!!\n");
input_free_device(input);
return -ENODEV;
}
ret = misc_register(&misc);
printk(DEVICE_NAME"\tinitialized\n");
return ret;
}
static void __exit gzsd_input_exit(void)
{
input_unregister_device(input);
misc_deregister(&misc);
}
module_init(gzsd_input_init);
module_exit(gzsd_input_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("GZSD-TECH Inc.");
原理和源码其实很简单的,仅供初学者参考。
源码下载地址:点击打开链接