国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

高級(jí)驅(qū)動(dòng)——(驅(qū)動(dòng)所有按鍵)

JessYanCoding / 3597人閱讀

摘要:我們用一種更為高級(jí)的方法去驅(qū)動(dòng)所有的按鍵理論上按鍵最多可以驅(qū)動(dòng)個(gè),但是我的板子只有三個(gè)按鍵所以現(xiàn)在只能驅(qū)動(dòng)三個(gè),但是驅(qū)動(dòng)三個(gè)和驅(qū)動(dòng)個(gè)都是一樣的。

我們用一種更為高級(jí)的方法去驅(qū)動(dòng)所有的按鍵————理論上按鍵最多可以驅(qū)動(dòng)768個(gè),但是我的板子只有三個(gè)按鍵
所以現(xiàn)在只能驅(qū)動(dòng)三個(gè),但是驅(qū)動(dòng)三個(gè)和驅(qū)動(dòng)768個(gè)都是一樣的。
首先我們要利用起設(shè)備樹文件了,如果不用設(shè)備樹的話,你就得一個(gè)一個(gè)的去驅(qū)動(dòng),雖然你可以在一個(gè)模塊上完成所有的按鍵驅(qū)動(dòng),但是要是真的驅(qū)動(dòng)768個(gè)按鍵,那么你估計(jì)能寫上萬行代碼。你要跟以前的方法一樣,每一個(gè)按鍵都要去實(shí)例化設(shè)備,然后獲取中斷,地址,…這些信息,然后再處理這些信息。
但是如果你用了設(shè)備樹,我直接在設(shè)備樹上寫好這些信息,到時(shí)候你拿的去用就可以了。
并且你直接整一個(gè)for循環(huán),它就自動(dòng)把768個(gè)設(shè)備信息給你全部拿過來了,豈不爽哉!!
那就讓我們來領(lǐng)略一下設(shè)備樹的魅力:
————————————————————————————————————————————————
驅(qū)動(dòng)所有按鍵第一步:
編寫設(shè)備樹:
我們之前也編寫過,這里我們?cè)敿?xì)的講一下:(設(shè)備樹就是用來存儲(chǔ)設(shè)備信息的)
首先是在根節(jié)點(diǎn)下創(chuàng)建了一個(gè)屬于我們的設(shè)備叫:key_int_node.
我們要驅(qū)動(dòng)三個(gè)按鍵,所以在這個(gè)我們的設(shè)備下面創(chuàng)建了三個(gè)子設(shè)備,代表我這設(shè)備由這三個(gè)設(shè)備共同組成。
要是你有一千個(gè)設(shè)備那么你也可以吧一千個(gè)設(shè)備寫里面組成你的設(shè)備。
好讓我們看一下每一個(gè)子設(shè)備下存儲(chǔ)了上面信息

```c在設(shè)備樹文件中設(shè)置這幾個(gè)元素:  key_int_node{            compatible = "test_key";            #address-cells = <1>;            #size-cells = <1>;            key_int@0 {                    key_name = "key2_power_eint";     //表示我這個(gè)子設(shè)備名字叫....自定義                    key_code = <116>;	              //設(shè)置這個(gè)子設(shè)備的鍵值,就是代表這個(gè)鍵是用來干嘛的,                    									//你可以隨便設(shè)你想讓它有上面功能都可以                    gpio = <&gpx1 1 0>;				//代表這個(gè)引腳在電路圖上是屬于gpx1_1引腳,后面可以讀這個(gè)引腳的值來獲                    								//取按鍵有沒有按下,就很方便                    reg = <0x11000C20 0x18>;			//物理地址                    interrupt-parent = <&gpx1>;			//表示中斷繼承了gpx1                    interrupts = <1 0>;					//代表是gpx1_1的中斷,后面根據(jù)節(jié)點(diǎn)獲取中斷號(hào)就是            };            key_int@1 {                    key_name = "key3_vup_eint";                    key_code = <115>;                    gpio = <&gpx1 2 0>;                    reg = <0x11000C20 0x18>;                    interrupt-parent = <&gpx1>;                    interrupts = <2 0>;            };            key_int@2 {                    key_name = "key4_vdown_eint";                    key_code = <114>;                    gpio = <&gpx3 2 0>;                    reg = <0x11000C60 0x18>;                    interrupt-parent = <&gpx3>;                    interrupts = <2 0>;            };	};		好了第一步完成,你可以根據(jù)芯片手冊(cè),把所有的按鍵信息寫進(jìn)去

——————————————————————————————————————
驅(qū)動(dòng)所有按鍵第二步:
接下來我們就要編寫設(shè)備模塊代碼了
1)首先就是日常搭框架
2)然后就是想辦法從設(shè)備樹上把這些我們寫的文件信息拿過來。

我們采用了我通用的設(shè)備信息結(jié)構(gòu)體,
然后我用一個(gè)數(shù)組去實(shí)例化它,那么我只要一個(gè)數(shù)組的名字我就可以存儲(chǔ)并且找到所有的設(shè)備信息了。

struct  key_desc{	char *name;	int key_code;	int irqno;	int gpio_num;	void *regbase;	struct device_node *cnp;	};struct key_desc *all_dev[KEY_NOM];

那我們有這樣一個(gè)結(jié)構(gòu)體數(shù)組了,那我還是沒有從設(shè)備樹上獲取到信息啊。
別急——我們寫一個(gè)函數(shù),直接對(duì)著設(shè)備樹就是 —拿來吧你
我們需要一個(gè)中介去連接我們的設(shè)備樹,和用來存儲(chǔ)信息的結(jié)構(gòu)體:這個(gè)中介就是: struct device_node *cnp; 這是一個(gè)設(shè)備節(jié)點(diǎn)在結(jié)構(gòu)體中已經(jīng)定義了
首先我們像獲取中斷號(hào)一樣,從設(shè)備樹上獲取到節(jié)點(diǎn),但是這個(gè)節(jié)點(diǎn),不是我們要的兒子節(jié)點(diǎn)。所有我們得獲取到子節(jié)點(diǎn)點(diǎn),并且,
要一個(gè)設(shè)備結(jié)構(gòu)體數(shù)組對(duì)應(yīng)一個(gè)子節(jié)點(diǎn)信息:

void get_allirqno(void){	//從設(shè)備樹上獲取設(shè)備節(jié)點(diǎn)	struct device_node *np = of_find_node_by_path("/key_int_node");	if(np == NULL){		printk("find_node error/n");		return 0;	}	struct  device_node*lcnp;   //用來記錄節(jié)點(diǎn)的,到時(shí)候再賦給每一個(gè)的all_dev的cnp		//要獲取的節(jié)點(diǎn)的上一個(gè)節(jié)點(diǎn),這樣就可以通過上一個(gè)節(jié)點(diǎn)的位置獲取到我要獲取的節(jié)點(diǎn)的位置	 struct device_node *prev = NULL;	int i=0;		do{					if(lcnp != NULL){				all_dev[i++].cnp = lcnp;//將當(dāng)前的節(jié)點(diǎn)記錄下來			}			prev = lcnp; //把當(dāng)前的設(shè)置位prev		}while(of_get_next_child(np, prev) != NULL);								}

這樣我們就可以通過設(shè)備結(jié)構(gòu)體數(shù)組中的子節(jié)點(diǎn)與設(shè)備樹建立了連接。

——————————————————————————————————————————————————
接下來是驅(qū)動(dòng)第三步:
完成模塊裝載入口
我們之前在模塊裝載路口做了三件事:
1,分配一個(gè)input device對(duì)象
2, 初始化input device對(duì)象
3,注冊(cè)input device對(duì)象
我們現(xiàn)在也是做這三件事;
1)實(shí)例化一個(gè)輸入設(shè)備對(duì)象,并發(fā)分配空間,和部分初始化
struct input_dev *inputdev; //實(shí)例化一個(gè)輸入設(shè)備對(duì)象
inputdev = input_allocate_device(void);
2)可以添加設(shè)備信息
3)調(diào)用我們的獲取信息的函數(shù)————因?yàn)槲覀兘酉聛硪玫竭@些在設(shè)備樹上的信息

4)初始化input device對(duì)象
這里需要初始化倆個(gè):
一個(gè)是按鍵類型
//初始化inputdevice對(duì)象—設(shè)為按鍵類型信息
_set_bit(EV_KEY, inputdev->evbit);
還有就是按鍵的具體信息:
但是不要忘了,我們有很多很多的按鍵,所以我們要利用我們之前的設(shè)備結(jié)構(gòu)體數(shù)組中的子節(jié)點(diǎn)
然后利用for循環(huán),把設(shè)備樹上的其它對(duì)應(yīng)信息讀到對(duì)應(yīng)的設(shè)備結(jié)構(gòu)體數(shù)組中去
我們還要
1)設(shè)置鍵值具體信息:所以要拿到對(duì)應(yīng)的鍵值
of_property_read_u32(cnp,“key_code”, &code
2)申請(qǐng)對(duì)應(yīng)中斷:所以要拿到中斷號(hào)
irqno = irq_of_parse_and_map(cnp, 0)
3)我們還可以打印設(shè)備名字用來區(qū)分設(shè)備
of_property_read_string(cnp, “key_name”, &key_name);

這樣我們就完成了,設(shè)備的初始化以及中斷申請(qǐng)
4)注冊(cè)設(shè)備:
我們申請(qǐng)了設(shè)備(由很多子設(shè)備組成的大設(shè)備)就要注冊(cè)進(jìn)去,讓內(nèi)核幫我們匹配
input_register_device(inputdev);
——————————————————————————————
接下來是驅(qū)動(dòng)第三步:
那我們拿到數(shù)據(jù)了,怎么把按鍵的值傳出去呢?
,我們寫在中斷處理函數(shù)里面,但是我有幾百個(gè)設(shè)備,我只用了一個(gè)中斷處理函數(shù)我怎么區(qū)分你按的是什么中斷?
首先我們?cè)谏暾?qǐng)中斷的時(shí)候就會(huì)把,設(shè)備信息結(jié)構(gòu)體指針傳個(gè)中斷處理函數(shù)。
我們直接可以區(qū)分不同的鍵值。
并且我們還可以直接根據(jù)設(shè)備樹上的gpionum直接去讀引腳的數(shù)據(jù)判斷,是否被按下————nice
int gpionum = of_get_named_gpio(pdesc->cnp, “gpio”, 0);
//直接通過gpio獲取按鍵狀態(tài)
int value = gpio_get_value(gpionum);
——————————————————總的代碼————————————————————

#include #include #include #include #include #include #include #include #define KEY_NUMS 3#define KEY_NOM 3#define IRQFLAGS IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISINGstruct input_dev *inputdev;  //實(shí)例化一個(gè)輸入設(shè)備對(duì)象struct  key_desc{	char *name;	int key_code;	int irqno;	int gpio_num;	void *regbase;	struct device_node *cnp;	};struct key_desc all_dev[KEY_NOM];irqreturn_t  input_key_irq_handler(int irqno, void *devid){		//區(qū)分不同的按鍵	struct key_desc *pdesc = (struct key_desc *)devid;	int gpionum = of_get_named_gpio(pdesc->cnp, "gpio", 0);	//直接通過gpio獲取按鍵狀態(tài)	int value = gpio_get_value(gpionum);	if(value){//抬起				input_report_key(inputdev, pdesc->key_code, 0);		input_sync(inputdev);//上報(bào)數(shù)據(jù)結(jié)束				}else{		input_report_key(inputdev, pdesc->key_code, 1);		input_sync(inputdev);//上報(bào)數(shù)據(jù)結(jié)束}return IRQ_HANDLED;}void get_allirqno(void){	//從設(shè)備樹上獲取設(shè)備節(jié)點(diǎn)	struct device_node *np = of_find_node_by_path("/key_int_node");	if(np == NULL){		printk("find_node error/n");		return 0;	}	struct  device_node*lcnp;   //用來記錄節(jié)點(diǎn)的,到時(shí)候再賦給每一個(gè)的all_dev的cnp		//要獲取的節(jié)點(diǎn)的上一個(gè)節(jié)點(diǎn),這樣就可以通過上一個(gè)節(jié)點(diǎn)的位置獲取到我要獲取的節(jié)點(diǎn)的位置	 struct device_node *prev = NULL;	int i=0;		do{					if(lcnp != NULL){				all_dev[i++].cnp = lcnp;//將當(dāng)前的節(jié)點(diǎn)記錄下來			}			prev = lcnp; //把當(dāng)前的設(shè)置位prev		}while(of_get_next_child(np, prev) != NULL);								}static int __init akey_dev_init(void){	//編寫輸入子系統(tǒng)代碼	/*		1,分配一個(gè)input device對(duì)象		2, 初始化input  device對(duì)象		3,注冊(cè)input device對(duì)象	*/	//1、給實(shí)例化的輸入設(shè)備對(duì)象分配空間并部分初始化	inputdev = input_allocate_device(void)if(inputdev == NULL)	{		printk(KERN_ERR "input_allocate_device error/n");		return -ENOMEM;	}	//添加設(shè)備信息/sys/class/input/eventx/device/	//自定義	inputdev->name = "input key";	inputdev->phys = "key/input/input0";	inputdev->uniq = "simple key0 for 4412";	inputdev->id.bustype = BUS_HOST;	inputdev->id.vendor =0x1234 ;	inputdev->id.product = 0x8888;	inputdev->id.version = 0x0001;	get_allirqno();		//初始化inputdevice對(duì)象---設(shè)為按鍵類型信息	_set_bit(EV_KEY, inputdev->evbit);	//利用設(shè)備樹多個(gè)獲取信息	int i;	for(i=0;i<KEY_NOM;++i){			struct device_node *cnp = all_dev[i].cnp;   //這個(gè)cnp記錄了每個(gè)設(shè)備的節(jié)點(diǎn)	//獲取鍵值	int code;	of_property_read_u32(cnp,"key_code", &code);	_set_bit(code, inputdev->keybit); //將從設(shè)備樹上獲取的鍵值設(shè)置位鍵值數(shù)據(jù)code	 all_dev[i].key_code = code; //把code信息記錄到每個(gè)子設(shè)備的結(jié)構(gòu)體中	//獲取中斷號(hào)	int irqno;	irqno = irq_of_parse_and_map(cnp, 0);	all_dev->irqno = irqno;	//獲取按鍵name	char *key_name ;	of_property_read_string(cnp, "key_name",  &key_name);	all_dev[i].name = key_name;	//申請(qǐng)中斷		ret = request_irq(irqno, input_key_irq_handler, irqflags, 					key_name, &all_dev[i]);		if(ret != 0)		{			printk("request_irq error/n");			goto err_1;			}		}	//注冊(cè)設(shè)備	ret = input_register_device(inputdev);	if(ret != 0)	{		printk(KERN_ERR "input_register_device error/n");		goto err_0;	}	return 0;err_1:	input_unregister_device(inputdev);err_0:	input_free_device(inputdev);}static int __exit akey_dev_exit(void){	int i;	for(i=0; i<KEY_NOM; i++)		free_irq(all_dev[i].irqno, &all_dev[i]);			input_unregister_device(inputdev);	input_free_device(inputdev);}module_init(akey_dev_init);module_exit(akey_dev_exit);MODULE_LICENSE("GPL");

—————————————————————應(yīng)用程序代碼———————————————————————

#include #include #include #include #include #include #include #include int main(void){	int fd;	int ret;	struct input_event event;		fd = open("/dev/input/event1", O_RDWR);	if(fd < 0)	{		perror("open");		exit(1);	}	while(1)	{		ret = read(fd, &event, sizeof(struct input_event));		if(ret < 0)		{			perror("read");			exit(1);		}		if(event.type == EV_KEY){					switch(event.code){				case KEY_POWER:					if(event.value){ //按下						printf("__APP_USER__ :  power pressed/n");					}else{						printf("__APP_USER__ :  power up/n");					}					break;				case KEY_VOLUMEDOWN:					if(event.value){ //按下						printf("__APP_USER__ :  vollum dowm  pressed/n");					}else{						printf("__APP_USER__ :  vollum dowm up/n");					}					break;				case KEY_VOLUMEUP:					if(event.value){ //按下						printf("__APP_USER__ :  vollum up  pressed/n");					}else{						printf("__APP_USER__ :  vollum up up/n");					}					break;				default:					printf("error");			}		}			}	close(fd);	return 0;}

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/121073.html

相關(guān)文章

  • ??爬蟲+自動(dòng)化利器 selenium 之自學(xué)成才篇(一)??

    文章目錄 selenium 簡(jiǎn)介selenium安裝安裝瀏覽器驅(qū)動(dòng)確定瀏覽器版本下載驅(qū)動(dòng) 定位頁面元素打開指定頁面id 定位name 定位class 定位tag 定位xpath 定位css 定位link 定位partial_link 定位 瀏覽器控制修改瀏覽器窗口大小瀏覽器前進(jìn)&后退瀏覽器刷新瀏覽器窗口切換常見操作 鼠標(biāo)控制單擊左鍵單擊右鍵雙擊拖動(dòng)鼠標(biāo)懸停 鍵盤控制 seleni...

    james 評(píng)論0 收藏0
  • YOOGA 40藍(lán)牙雙模焊接PCB簡(jiǎn)要說明

    摘要:鍵盤使用說明索引均為出廠默認(rèn)值升級(jí)固件軟件支持一些常見問題解答電池開關(guān)電池插座轉(zhuǎn)接小板連接首次使用測(cè)試步驟藍(lán)牙和切換鍵盤默認(rèn)層默認(rèn)觸發(fā)層的鍵配置的功能默認(rèn)功能層配置的功能默認(rèn)的快捷鍵藍(lán)牙配對(duì)藍(lán)牙參數(shù)藍(lán)牙地址管理升級(jí)固件 ...

    不知名網(wǎng)友 評(píng)論0 收藏0
  • 事件驅(qū)動(dòng)模型

    摘要:應(yīng)用程序的模型是基于一個(gè)事件驅(qū)動(dòng)的協(xié)作式多任務(wù)模型。兩個(gè)數(shù)據(jù)字段均不包含數(shù)據(jù)的事件有和。僅在短數(shù)據(jù)字段中包含數(shù)據(jù)的典型事件有,僅在長(zhǎng)數(shù)據(jù)字段中包含數(shù)據(jù)的典型事件有和。 BREW應(yīng)用程序的模型是基于一個(gè)事件驅(qū)動(dòng)的協(xié)作式多任務(wù)模型。事件處理機(jī)制的核心問題是程序應(yīng)該只處理需要的事件,對(duì)于不...

    MiracleWong 評(píng)論0 收藏0
  • 【Python爬蟲】4萬字,詳解selenium從入門到實(shí)戰(zhàn)【錯(cuò)過再無】

    摘要:難在哪里根據(jù)上面的標(biāo)簽需要定位最后一行標(biāo)簽,以下列出了四種方式,定位的方式多樣并不唯一,使用時(shí)根據(jù)情況進(jìn)行解析即可。加入每日一練我們使用并指明標(biāo)簽內(nèi)全部文本即可定位。 ...

    shiyang6017 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<