国产精品久久久久影院,成人午夜福利视频,国产精品久久久久高潮,国产精品 欧美 亚洲 制服,国产精品白浆无码流出

基于ok6410的韋東山驅(qū)動(dòng)視頻簡(jiǎn)要分析--USB驅(qū)動(dòng)

發(fā)布者:溫柔的愛(ài)情最新更新時(shí)間:2024-11-06 來(lái)源: cnblogs關(guān)鍵字:ok6410  USB驅(qū)動(dòng) 手機(jī)看文章 掃描二維碼
隨時(shí)隨地手機(jī)看文章

注意:本篇講的鼠標(biāo)驅(qū)動(dòng)僅能實(shí)現(xiàn)鼠標(biāo)左右鍵跟滑輪這三個(gè)按鍵類(lèi)似button的功能,按下左鍵則打出'l',右鍵打出“s”,滑輪打出“enter”。如果要實(shí)現(xiàn)正常的鼠標(biāo)驅(qū)動(dòng),參考內(nèi)核的鼠標(biāo)驅(qū)動(dòng),修改input的一些參數(shù)即可。


 


一、寫(xiě)驅(qū)動(dòng)的步驟(新手稍微看下即可,內(nèi)容有點(diǎn)搞)


1、復(fù)制頭文件;


2、寫(xiě)入口函數(shù),出口函數(shù),再加上協(xié)議;


3、分配注冊(cè)u(píng)sb_driver結(jié)構(gòu)體(拷別人的),


static struct usb_driver usb_mk_driver = {};


在init中注冊(cè)該結(jié)構(gòu)體:usb_register(&usb_mk_driver);


在exit中注銷(xiāo)該結(jié)構(gòu)體:usb_deregister(&usb_mk_driver);


4、寫(xiě)id_table函數(shù),static struct usb_device_id usb_mk_id_table [] = {},只有滿(mǎn)足id_table中的各種類(lèi)別,子類(lèi)號(hào),協(xié)議,才能調(diào)用;


5、寫(xiě)probe函數(shù):static int usb_mk_probe(struct usb_interface *intf, const struct usb_device_id *id);


6、寫(xiě)disconnect函數(shù):static void usb_mk_disconnect(struct usb_interface *intf)


7、如果想在開(kāi)發(fā)板插入usb設(shè)備的時(shí)候打印設(shè)備信息(可以不用),可以在probe中加入:


printk('VID = 0x%x, PID = 0x%xn', dev->descriptor.idVendor, dev->descriptor.idProduct);


printk('USB VERS = 0x%x, PID = 0x%xn', dev->descriptor.bcdUSB);


8、probe之后要進(jìn)一步判斷你這個(gè)是不是鼠標(biāo):


1、分配一個(gè)input_dev結(jié)構(gòu)體:在頭文件下定義;static struct input_dev       *mk_dev;  在probe內(nèi):mk_dev = input_allocate_device();


2、設(shè)置:


1、能產(chǎn)生哪類(lèi)事件


set_bit(EV_KEY, mk_dev->evbit);


set_bit(EV_REP, mk_dev->evbit);


2、能產(chǎn)生哪些事件


set_bit(KEY_L, mk_dev->keybit);


set_bit(KEY_S, mk_dev->keybit);


set_bit(KEY_ENTER, mk_dev->keybit);


3、注冊(cè):input_register_device(mk_dev);


4、設(shè)置:數(shù)據(jù)傳輸3要素: 源, 目的, 長(zhǎng)度


先從usbmouse.c中拷入幾行代碼


struct usb_device *dev = interface_to_usbdev(intf);


struct usb_host_interface *interface;


struct usb_endpoint_descriptor *endpoint;


int pipe;


endpoint = &interface->endpoint[0].desc;


源:usb設(shè)備的某個(gè)端點(diǎn)


pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);


目的:需要設(shè)置緩沖區(qū)buffer:


buf = usb_alloc_coherent(dev, len, GFP_ATOMIC, &buf_phys);


在頭文件下定義一個(gè)緩沖區(qū):


static char *buf; 


static dma_addr_t buf_phys;


長(zhǎng)度:static  int len(作為全局變量,等會(huì)有用)


len = endpoint->wMaxPacketSize;


5、怎么用那三要素呢?


在probe中;


1、分配一個(gè)urb,mk_urb = usb_alloc_urb(0, GFP_KERNEL);


在頭文件下定義urb:static struct urb *mk_urb;


2、使用三要素填充urb:


usb_fill_int_urb(mk_urb, dev, pipe, buf,


 len,


 uk_callback, NULL, endpoint->bInterval);


mk_urb->transfer_dma = buf_phys;


mk_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;


 


3、使用URB:usb_submit_urb(mk_urb, GFP_KERNEL);


6、要寫(xiě)一個(gè)中斷函數(shù),原因是usb控制器收到從usb傳來(lái)的數(shù)據(jù)后,需要一個(gè)中斷來(lái)通知cpu有信號(hào)啦!static void uk_callback(struct urb *urb)


在中斷函數(shù)中定義一些唧唧歪歪的東西后看,重新提交urb:


usb_submit_urb(mk_urb, GFP_KERNEL);


7,提交urb后當(dāng)然還要做殺掉urb,在disconnect中殺掉它!usb_kill_urb(mk_urb);


順便再disconnect中注銷(xiāo)或卸載其他的函數(shù);


8、在中斷函數(shù)里上報(bào)事件。


 


**************************************************************************************************************


 


二、驅(qū)動(dòng)程序


#include <linux/kernel.h>

#include

#include

#include

#include

#include

#include


/* 參考drivershidusbhidusbmouse.c

 */


static struct input_dev *mk_dev;

static int len;

static char *buf;  //定義一個(gè)緩沖區(qū)

static dma_addr_t buf_phys; //dma_addr實(shí)際上是一個(gè)物理地址

static struct urb *mk_urb;


static struct usb_device_id usb_mk_id_table [] = {

{ USB_INTERFACE_INFO(USB_INTERFACE_CLASS_HID, USB_INTERFACE_SUBCLASS_BOOT,

USB_INTERFACE_PROTOCOL_MOUSE) },

/*只要它的類(lèi)是class_hid,子類(lèi)是boot,協(xié)議是mouse,那么就可以匹配*/

 *{USB_DEVICE(0x46d, 0xc52f)或者直接指定自己的usb設(shè)備只支持這種廠家的設(shè)備。*/

{ } /* Terminating entry */

};


/* 當(dāng)USB主機(jī)控制器獲得鼠標(biāo)數(shù)據(jù)后,

 * 會(huì)調(diào)用這個(gè)函數(shù)

 */

static void uk_callback(struct urb *urb)//這是一個(gè)中斷函數(shù)!

{

int i;

static char pre_val;

#if 0 //這一段都用不到了,因?yàn)閕f = 0 ;這一段的作用就是用來(lái)看鼠標(biāo)按下之后都顯示什么數(shù)值,最后通過(guò)這些數(shù)值來(lái)設(shè)置上報(bào)事件。

printk('Get datas:n');

for (i = 0; i < len; i++)

{

printk('%02x ', buf[i]);

}

printk('n');

#endif

/* 鼠標(biāo)數(shù)據(jù)含義:

* buf[0]: bit0-左鍵, 0-松開(kāi), 1-按下

*         bit1-右鍵, 0-松開(kāi), 1-按下

*         bit2-中鍵, 0-松開(kāi), 1-按下

* buf[1],buf[2]構(gòu)成一個(gè)整數(shù), 表示X方向的相對(duì)位移

*         >0 : 右移

*         <0 : 左移

* buf[3],buf[4]構(gòu)成一個(gè)整數(shù), 表示Y方向的相對(duì)位移

*         >0 : 下移

*         <0 : 上移

* buf[6]: 滾輪

*/

 

/* 確定按鍵值 */

/* 上報(bào)數(shù)據(jù) */

if ((pre_val & (1<<0)) != (buf[0] & (1<<0))) //如果上次數(shù)據(jù)的bit0不等于這次數(shù)據(jù)的bit0,那么就是左鍵發(fā)生變化

{

/* 左鍵按下或松開(kāi) */

input_event(mk_dev, EV_KEY, KEY_L, (buf[0] & (1<<0)) ? 1 : 0);//如果buf0=1的話(huà)那就是按下,既是1,否則為0;

input_sync(mk_dev);

}


if ((pre_val & (1<<1)) != (buf[0] & (1<<1)))

{

/* 右鍵按下或松開(kāi) */

input_event(mk_dev, EV_KEY, KEY_S, (buf[0] & (1<<1)) ? 1 : 0);

input_sync(mk_dev);

}


if ((pre_val & (1<<2)) != (buf[0] & (1<<2)))

{

/* 中鍵按下或松開(kāi) */

input_event(mk_dev, EV_KEY, KEY_ENTER, (buf[0] & (1<<2)) ? 1 : 0);

input_sync(mk_dev);

}


pre_val = buf[0];


/* 重新提交URB */

usb_submit_urb(mk_urb, GFP_KERNEL);

}


/*interface是指接口,一個(gè)usb設(shè)備可能有多個(gè)邏輯接口,這個(gè)邏輯接口就是用下面的usb_interface來(lái)表示的*/

static int usb_mk_probe(struct usb_interface *intf, const struct usb_device_id *id)

{

struct usb_device *dev = interface_to_usbdev(intf);

struct usb_host_interface *interface;

struct usb_endpoint_descriptor *endpoint;

int pipe;

static int first = 1;


if (!first)

return -EIO;

first = 0;


/* 每一個(gè)設(shè)備都有端點(diǎn)0

* interface->endpoint[]數(shù)組里放'除了端點(diǎn)0外的其他端點(diǎn)'

* interface->endpoint[0]表示'除端點(diǎn)0外的第1個(gè)端點(diǎn)'

* interface->endpoint[1]表示'除端點(diǎn)0外的第2個(gè)端點(diǎn)'

*/

interface = intf->cur_altsetting;

endpoint = &interface->endpoint[0].desc;


/* 1. 分配inputd_dev */

mk_dev = input_allocate_device();

/* 2. 設(shè)置 */

/* 2.1 能產(chǎn)生哪類(lèi)事件 */

set_bit(EV_KEY, mk_dev->evbit);  //按鍵類(lèi)事件

set_bit(EV_REP, mk_dev->evbit);  //重復(fù)類(lèi)事件,例如一直按著L,則會(huì)顯示LLLLLLL。。。

/* 2.2 能產(chǎn)生這類(lèi)事件里的哪些事件 */

set_bit(KEY_L, mk_dev->keybit);

set_bit(KEY_S, mk_dev->keybit);

set_bit(KEY_ENTER, mk_dev->keybit);

/* 3. 注冊(cè) */

input_register_device(mk_dev);


/* 4. 硬件相關(guān)的操作: 

*    對(duì)于GPIO按鍵, 是request_irq, 在中斷處理函數(shù)里上報(bào)按鍵

*    對(duì)于USB設(shè)備, 是使用'USB主機(jī)驅(qū)動(dòng)程序提供的函數(shù)'發(fā)起USB傳輸獲得數(shù)據(jù)

*/

/* 數(shù)據(jù)傳輸3要素: 源, 目的, 長(zhǎng)度 */

/* A. 源: USB設(shè)備的某個(gè)端點(diǎn) */

/* ((PIPE_INTERRUPT << 30) | (dev->devnum << 8) | (endpoint << 15) | USB_DIR_IN) */

pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress);//pipe是源,源是一個(gè)整數(shù),這個(gè)整數(shù)里有端點(diǎn)的類(lèi)型,端點(diǎn)的方向

/* C. 長(zhǎng)度: 這個(gè)端點(diǎn)描述符的wMaxPacketSize */

len = endpoint->wMaxPacketSize;


/* B. 目的: 分配buffer */

buf = usb_alloc_coherent(dev, len, GFP_ATOMIC, &buf_phys);//從usb_buffer_alloc換成usb_alloc_coherent


/* D. 怎么使用這3要素 ? */

/* 分配URB: USB Reqeust Block ,usb請(qǐng)求塊*/

mk_urb = usb_alloc_urb(0, GFP_KERNEL);

/* 用3要素填充URB 

*實(shí)際上usb設(shè)備沒(méi)有中斷cpu的能力,但是電腦的usb主機(jī)有中斷cpu的能力,所以u(píng)sb主機(jī)不斷查詢(xún),有信號(hào)便中斷cpu。

*/

usb_fill_int_urb(mk_urb, dev, pipe, buf,

len,

uk_callback, NULL, endpoint->bInterval);//bInterval:查詢(xún)頻率,uk_callback是一個(gè)中斷函數(shù);

mk_urb->transfer_dma = buf_phys; //得到數(shù)據(jù)后要往某個(gè)內(nèi)存里寫(xiě),它沒(méi)那么聰明,需要一個(gè)物理地址

mk_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;//還有設(shè)置某些標(biāo)記,這標(biāo)記什么意思偉哥也不懂

/* 使用URB ,看看別人怎么做*/

usb_submit_urb(mk_urb, GFP_KERNEL);//提交urb


return 0;

}


static void usb_mk_disconnect(struct usb_interface *intf)

{

struct usb_device *dev = interface_to_usbdev(intf);

printk('disconnect usb mouse!!!!!n');

usb_kill_urb(mk_urb);

usb_free_urb(mk_urb);

usb_free_coherent(dev,len, buf, buf_phys);//應(yīng)該是usb_free_coherent

input_unregister_device(mk_dev);

input_free_device(mk_dev);

}


/* 1. 分配usb_driver */

/* 2. 設(shè)置 */

static struct usb_driver usb_mk_driver = {

.name = 'usbmk',

.probe = usb_mk_probe,

.disconnect = usb_mk_disconnect,

.id_table = usb_mk_id_table,

};


static int usb_mk_init(void)

{

/* 3. 注冊(cè) */

usb_register(&usb_mk_driver);

return 0;

}


static void usb_mk_exit(void)

{

usb_deregister(&usb_mk_driver);

}


module_init(usb_mk_init);

module_exit(usb_mk_exit);


MODULE_LICENSE('GPL');


關(guān)鍵字:ok6410  USB驅(qū)動(dòng) 引用地址:基于ok6410的韋東山驅(qū)動(dòng)視頻簡(jiǎn)要分析--USB驅(qū)動(dòng)

上一篇:u-boot2010.03 移植篇(一) 建立編譯目標(biāo)
下一篇:基于ok6410的韋東山驅(qū)動(dòng)視頻簡(jiǎn)要分析--ts驅(qū)動(dòng)

推薦閱讀最新更新時(shí)間:2025-06-17 01:51

OK6410啟動(dòng)配置過(guò)程(詳細(xì)信息)
硬件平臺(tái):OK6410開(kāi)發(fā)板 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 KK U-Boot 1.1.6 (Sep 19 2014 - 10:00:03) for SMDK6410 **************************************** ** u-boot 1.1.6
[單片機(jī)]
OK6410裸機(jī)學(xué)習(xí)第二天:2th_leds
start.S文件: .globl _start _start: 1、硬件相關(guān)的設(shè)置:把外設(shè)的基地址告訴CPU 0 ~ 0x6fff ffff為內(nèi)存的地址空間,0x7000 0000 ~ 0x7fff ffff為外設(shè)寄存器的地址空間 ldr r0, =0x70000000 orr r0, r0, #0x13 mcr p15,0,r0,c15,c2,4 @ 256M(0x70000000-0x7fffffff) 2、關(guān)看門(mén)狗 ,往WTCON(0x7E004000)寫(xiě)0 ldr r0, =0x7E004000 mov r1, #0 str r1, 3、設(shè)置GPMCON讓GPM0/1/2/
[單片機(jī)]
OK6410裸機(jī)程序之開(kāi)始模板(Linux環(huán)境)
一、 裸機(jī)程序的構(gòu)成 1. 基本的裸機(jī)程序由啟動(dòng)代碼和C函數(shù)文件構(gòu)成。而啟動(dòng)代碼包括:硬件設(shè)備初始化、調(diào)用C函數(shù)。 本次分析中代碼文件有: start.S 啟動(dòng)代碼,都是匯編寫(xiě)的 commom.h 一些通用的函數(shù),比如設(shè)置某寄存器的某位為1或0 irq.c 中斷初始化,中斷處理等 regs.h 6410的寄存器地址,需要哪些寄存器可以在本文件中聲明和定義 sdram.c 有關(guān)sdram的一些操作,如sdram初始化等 time.c 系統(tǒng)時(shí)鐘的有關(guān)設(shè)置,如PLLclock等 led.c 這個(gè)就是主函數(shù)了,主程序就在這里編寫(xiě),本次只是演示,控制開(kāi)發(fā)板的led
[單片機(jī)]
<font color='red'>OK6410</font>裸機(jī)程序之開(kāi)始模板(Linux環(huán)境)
小廣播
設(shè)計(jì)資源 培訓(xùn) 開(kāi)發(fā)板 精華推薦

最新單片機(jī)文章

 
EEWorld訂閱號(hào)

 
EEWorld服務(wù)號(hào)

 
汽車(chē)開(kāi)發(fā)圈

 
機(jī)器人開(kāi)發(fā)圈

電子工程世界版權(quán)所有 京ICP證060456號(hào) 京ICP備10001474號(hào)-1 電信業(yè)務(wù)審批[2006]字第258號(hào)函 京公網(wǎng)安備 11010802033920號(hào) Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved