linux系统改造成复合鼠键设备(平台-rockip-rv1126)

需求:

将rv1126改造成复合鼠键设备,1126通过usb插到主机或者电脑上,能识别成鼠标和键盘,通过对结点的写入,完成鼠标和键盘的事件输入给主机或电脑。


附注

QQ:614187086

此方法对在linux系统上都是通用,并无特别要求。

要想设备成为鼠标键盘复合设备,需要对hid设备的设备描述符有深入的了解,
建议看这文章前先去搜索相关信息,有初步的认知。

修改方法:

我将整理好的设备描述符贴出来,有需要的自行使用

设备描述符:

键盘:

echo -ne \\x05\\x01\\x09\\x06\\xa1\\x01\\x05\\x07\\x19\\xe0\\x29\\xe7\\x15\\x00\\x25\\x01\\x75\\x01\\x95\\x08\\x81\\x02\\x95\\x01\\x75\\x08\\x81\\x03\\x95\\x05\\x75\\x01\\x05\\x08\\x19\\x01\\x29\\x05\\x91\\x02\\x95\\x01\\x75\\x03\\x91\\x03\\x95\\x06\\x75\\x08\\x15\\x00\\x25\\x65\\x05\\x07\\x19\\x00\\x29\\x65\\x81\\x00\\xc0 > /sys/kernel/config/usb_gadget/rockchip/functions/hid.usb1/report_desc

鼠标:

echo -ne \\x05\\x01\\x09\\x02\\xa1\\x01\\x09\\x01\\xa1\\x00\\x05\\x09\\x19\\x01\\x29\\x03\\x15\\x00\\x25\\x01\\x95\\x03\\x75\\x01\\x81\\x02\\x95\\x01\\x75\\x05\\x81\\x03\\x05\\x01\\x09\\x30\\x09\\x31\\x09\\x38\\x15\\x81\\x25\\x7F\\x75\\x08\\x95\\x03\\x81\\x06\\xc0\\xc0 > /sys/kernel/config/usb_gadget/rockchip/functions/hid.usb0/report_desc

hid设备输入和输出:

配置成鼠标和键盘设备后,dev下面会有/dev/hidg0 和/dev/hidg1产生
设备的输入通过dev/结点的输入完成

我将实现的代码贴出来,网上只有键盘的实现,我在此基础上,完成了对鼠标的兼容

代码如下

package main
 




#include <pthread.h>
#include <string.h> 
#include <stdio.h> 
#include <ctype.h> 
#include <fcntl.h> 
#include <errno.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h>
 
#define BUF_LEN 512

struct options { 
	const char    *opt;
	unsigned char val; 
};
 
static struct options kmod[] = { 
	{.opt = "--left-ctrl",		.val = 0x01},
	{.opt = "--right-ctrl",		.val = 0x10},
	{.opt = "--left-shift",		.val = 0x02},
	{.opt = "--right-shift",	.val = 0x20},
	{.opt = "--left-alt",		.val = 0x04},
	{.opt = "--right-alt",		.val = 0x40},
	{.opt = "--left-meta",		.val = 0x08},
	{.opt = "--right-meta",		.val = 0x80},
	{.opt = NULL} 
};
 
static struct options kval[] = { 
	{.opt = "--return",	.val = 0x28},
	{.opt = "--esc",	.val = 0x29},
	{.opt = "--bckspc",	.val = 0x2a},
	{.opt = "--tab",	.val = 0x2b},
	{.opt = "--spacebar",	.val = 0x2c},
	{.opt = "--caps-lock",	.val = 0x39},
	{.opt = "--f1",		.val = 0x3a},
	{.opt = "--f2",		.val = 0x3b},
	{.opt = "--f3",		.val = 0x3c},
	{.opt = "--f4",		.val = 0x3d},
	{.opt = "--f5",		.val = 0x3e},
	{.opt = "--f6",		.val = 0x3f},
	{.opt = "--f7",		.val = 0x40},
	{.opt = "--f8",		.val = 0x41},
	{.opt = "--f9",		.val = 0x42},
	{.opt = "--f10",	.val = 0x43},
	{.opt = "--f11",	.val = 0x44},
	{.opt = "--f12",	.val = 0x45},
	{.opt = "--insert",	.val = 0x49},
	{.opt = "--home",	.val = 0x4a},
	{.opt = "--pageup",	.val = 0x4b},
	{.opt = "--del",	.val = 0x4c},
	{.opt = "--end",	.val = 0x4d},
	{.opt = "--pagedown",	.val = 0x4e},
	{.opt = "--right",	.val = 0x4f},
	{.opt = "--left",	.val = 0x50},
	{.opt = "--down",	.val = 0x51},
	{.opt = "--kp-enter",	.val = 0x58},
	{.opt = "--up",		.val = 0x52},
	{.opt = "--num-lock",	.val = 0x53},
	{.opt = NULL} 
};
 

    char *replacestr(char *strbuf, char *sstr, char *dstr)
    {       char *p,*p1;
            int len;
            if ((strbuf == NULL)||(sstr == NULL)||(dstr == NULL))
                    return NULL;
            p = strstr(strbuf, sstr);       //返回字符串第一次出现的地址,否则返回NULL
            if (p == NULL)  
                    return NULL;
            len = strlen(strbuf) + strlen(dstr) - strlen(sstr);
            p1 = malloc(len);
            bzero(p1, len);
            strncpy(p1, strbuf, p-strbuf);
            strcat(p1, dstr);
            p += strlen(sstr);
            strcat(p1, p);
            return p1;
    }


int keyboard_fill_report(char report[8], char buf[BUF_LEN], int *hold)
{ 
//		fprintf(stderr, "report: %s\n", report); 
//		fprintf(stderr, "buf: %s\n", buf); 
//		fprintf(stderr, "hold: %d\n", *hold); 
	char *tok = strtok(buf, " ");
	int key = 0;
	int i = 0;
	for (; tok != NULL; tok = strtok(NULL, " ")) {
		if (strcmp(tok, "--quit") == 0) 
			return -1;
		
		if (strcmp(tok, "--hold") == 0) {
			*hold = 1;
			continue; 
		}
		
		if (key < 6) { 
			for (i = 0; kval[i].opt != NULL; i++) 
				if (strcmp(tok, kval[i].opt) == 0) { 
					report[2 + key++] = kval[i].val;
					break; 
				} 
			if (kval[i].opt != NULL) 
				continue;
		}
		
		if (key < 6) if (islower(tok[0])) { 
			report[2 + key++] = (tok[0] - ('a' - 0x04));
			continue; 
		}
		
		for (i = 0; kmod[i].opt != NULL; i++) 
			if (strcmp(tok, kmod[i].opt) == 0) { 
				report[0] = report[0] | kmod[i].val;
				break; 
			} 
			
		if (kmod[i].opt != NULL) 
			continue;
		
		if (key < 6) 
			fprintf(stderr, "unknown option: %s\n", tok); 
	}
 
	return 8; 
}
 
static struct options mmod[] = { 
	{.opt = "--b1", .val = 0x01},
	{.opt = "--b2", .val = 0x02},
	{.opt = "--b3", .val = 0x04},
	{.opt = NULL} 
};
 
int mouse_fill_report(char report[8], char buf[BUF_LEN], int *hold)
{ 
	//	fprintf(stderr, "report: %s\n", report); 
	//	fprintf(stderr, "buf: %s\n", buf); 
	//	fprintf(stderr, "hold: %d\n", *hold); 
	char *tok = strtok(buf, " ");
	int mvt = 0;
	int i = 0;
	
	for (; tok != NULL; tok = strtok(NULL, " ")) 
	{
		if (strcmp(tok, "--quit") == 0) 
			return -1;
		
		if (strcmp(tok, "--hold") == 0) {
			*hold = 1;
			continue; 
		}
		
		for (i = 0; mmod[i].opt != NULL; i++) 
			if (strcmp(tok, mmod[i].opt) == 0) { 
				report[0] = report[0] | mmod[i].val;
				break; 
			}
			
		if (mmod[i].opt != NULL) 
			continue;
		
		if (!(tok[0] == '-' && tok[1] == '-') && mvt < 2) { 
			errno = 0;
			report[1 + mvt++] = (char)strtol(tok, NULL, 0);
			if (errno != 0) { 
				fprintf(stderr, "Bad value:'%s'\n", tok);
				report[1 + mvt--] = 0; 
			}
			continue; 
		}
		
		fprintf(stderr, "unknown option: %s\n", tok); 
	}
 
	return 3; 
}
 
static struct options jmod[] = { 
	{.opt = "--b1",		.val = 0x10},
	{.opt = "--b2",		.val = 0x20},
	{.opt = "--b3",		.val = 0x40},
	{.opt = "--b4",		.val = 0x80},
	{.opt = "--hat1",	.val = 0x00},
	{.opt = "--hat2",	.val = 0x01},
	{.opt = "--hat3",	.val = 0x02},
	{.opt = "--hat4",	.val = 0x03},
	{.opt = "--hatneutral",	.val = 0x04},
	{.opt = NULL} 
};
 
int joystick_fill_report(char report[8], char buf[BUF_LEN], int *hold) 
{ 
	char *tok = strtok(buf, " ");
	int mvt = 0;
	int i = 0;
	*hold = 1;

	report[3] = 0x04;
	
	for (; tok != NULL; tok = strtok(NULL, " ")) {
		if (strcmp(tok, "--quit") == 0) 
			return -1;
		
		for (i = 0; jmod[i].opt != NULL; i++) 
			if (strcmp(tok, jmod[i].opt) == 0) { 
				report[3] = (report[3] & 0xF0) | jmod[i].val;
				break; 
			}
			
		if (jmod[i].opt != NULL) 
			continue;
		
		if (!(tok[0] == '-' && tok[1] == '-') && mvt < 3) { 
			errno = 0;
			report[mvt++] = (char)strtol(tok, NULL, 0);
			
			if (errno != 0) { 
				fprintf(stderr, "Bad value:'%s'\n", tok);
				report[mvt--] = 0; 
			}
			continue; 
		}
		
		fprintf(stderr, "unknown option: %s\n", tok); 
	}
 
	return 4; 
}
 
void print_options(char c) 
{ 	
	int i = 0;
	if (c == 'k') { 
		printf("	keyboard options:\n" "		--hold\n"); 
		for (i = 0; kmod[i].opt != NULL; i++) 
			printf("\t\t%s\n", kmod[i].opt); 
		printf("\n	keyboard values:\n" "		[a-z] or\n"); 
		for (i = 0; kval[i].opt != NULL; i++) 
			printf("\t\t%-8s%s", kval[i].opt, i % 2 ? "\n" : ""); 
		printf("\n"); 
	} else if (c == 'm') { 
		printf("	mouse options:\n" "		--hold\n"); 
		for (i = 0; mmod[i].opt != NULL; i++) 
			printf("\t\t%s\n", mmod[i].opt); 
		printf("\n	mouse values:\n" "		Two signed numbers\n"
		       "--quit to close\n"); 
	} else { 
		printf("	joystick options:\n");
		for (i = 0; jmod[i].opt != NULL; i++) 
			printf("\t\t%s\n", jmod[i].opt); 
		printf("\n	joystick values:\n" "		three signed numbers\n"
		       "--quit to close\n"); 
	} 
}
 
int mainin(int argc, const char *argv0,char *argv1,char *argv2) 
{ 	
	const char *filename = "hid.txt";
	int fd = 0;
	char buf[BUF_LEN];
	int cmd_len;
	char report[8];
	int to_send = 8;
	int hold = 0;
	fd_set rfds;
	int retval, i;
	
	if (argc < 2) { 
		fprintf(stderr, "Usage: %s devname mouse|keyboard|joystick\n", argv0); 
		return 1; 
	}
	
	if (argv1[0] != 'k' && argv1[0] != 'm' && argv1[0] != 'j') 
		return 2;
	
	filename = argv0;
	if ((fd = open(filename, O_RDWR, 0666)) == -1) { 
		perror(filename);
		return 3; 
	}
	
//	print_options(argv1[0]);




		
		//	buf=argv2;
			
			hold = 0;
	
			if (argv1[0] == 'k') 
				to_send = keyboard_fill_report(report,argv2 , &hold); 
			else if (argv1[0] == 'm') 

				to_send = mouse_fill_report(report, replacestr(argv2,","," " ), &hold); 
			else 
				to_send = joystick_fill_report(report, argv2, &hold);
			if (to_send == -1) 
				return 0; 
			if (write(fd, report, to_send) != to_send) { 
				perror(filename);
				return 5; 
			}
			if (!hold) { 
				memset(report, 0x0, sizeof(report));
				if (write(fd, report, to_send) != to_send) { 
					perror(filename);
					return 6; 
				} 
			}
		

	close(fd);
	return 0; 
} 




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RK方案开发者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值