




版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、這段時(shí)間都在忙驅(qū)動(dòng)了,幾個(gè)有代表性的簡(jiǎn)單的外圍接口,寫(xiě)寫(xiě),讓我知道什么是所謂的驅(qū)動(dòng)!完全原創(chuàng),若有轉(zhuǎn)載,請(qǐng)標(biāo)記出處,若有什么疑問(wèn),請(qǐng)聯(lián)系我:85469843.三峽大學(xué)感謝網(wǎng)上朋友的熱心幫助,解決了幾個(gè)硬件方面的疑問(wèn)!這幾天把外圍簡(jiǎn)單的輸入驅(qū)動(dòng)給寫(xiě)了下,盡管簡(jiǎn)單,但還是花了我不少心思呀!/*eint.c*/*實(shí)現(xiàn)功能很簡(jiǎn)單,就是按下接中斷的按鍵后,LED就亮,中間涉及到中斷的注冊(cè),中斷驅(qū)動(dòng)程序的實(shí)現(xiàn).但還沒(méi)有加入防抖動(dòng)的功能,實(shí)在太懶了!*/#ifndef _KERNEL_#define _KERNEL_#endif#ifndef MODULE#define MODULE#endif#inclu
2、de #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define DEVICE_MAJOR 253#define DEV_NAME eintstatic int eint_open(struct inode *inode,struct file *filp); static int eint_release(struct inode *inode, struct file *filp);
3、static ssize_t eint_read(struct file *filp,char *buffer,size_t count,loff_t* ppos); static int _init eint_init(void); static void _exit eint_cleanup(void); /static void (*kbdEvent)(void);/void kbdEvent_dummy(void)/#define KBD_TIMER_DELAY (HZ/10)/#define KBD_TIMER_DELAY1 (HZ/100)/#define MAX_KBD_BUF1
4、6/typedef unsigned char KBD_RET;/*typedef structunsigned int kbdStatus;KBD_RET bufMAX_KBD_BUF;unsigned int head,tail;wait_queue_head_t wq;KBD_DEV;static KBD_DEV kbddev;#define BUF_HEAD (kbddev.bufkbddev.head)#define BUF_TAIL (kbddev.bufkbddev.tail)#define INCBUF(x,mod) (+(x)&(mod)-1)static struct ti
5、mer_list kbd_timer;*/ static struct file_operations eint_fops= owner:THIS_MODULE, open:eint_open, release:eint_release, read:eint_read, ; static void isr_kbd(int irq,void *dev_id,struct pt_regs *reg)printk(Occured key board Interrupt,irq=%dn,irq);/*if(kbddev.kbdStatus=KEYSTATUS_UP )KBD_CLOSE_INT();i
6、f(ISKBD_DOWN()kbddev.kbdStatus=KEYSTATUS_DOWNX;kbd_timer.expires=jiffies+KBD_TIMER_DELAY1;add_timer(&kbd_timer);elseKBD_OPEN_INT();*/*(unsigned char*)0xd1000000)=0x00; static int _init eint_init(void) int ret; set_external_irq(IRQ_EINT2,EXT_LOWLEVEL,GPIO_PULLUP_EN);set_external_irq(IRQ_EINT3,EXT_LOW
7、LEVEL,GPIO_PULLUP_EN);/kbdEvent=kbdEvent_dummy; ret=register_chrdev(DEVICE_MAJOR,DEV_NAME,&eint_fops); if (ret0) printk(DEV_NAME cannot get major number!n); return ret; if( check_region( GPIO_F2,1 ) &check_region(GPIO_F3,1) & check_region(0x10000000,1)printk(the port is used by another modulen);retu
8、rn -1; request_region(GPIO_F2,1,DEV_NAME);request_region(GPIO_F3,1,DEV_NAME);request_region(0x10000000,1,DEV_NAME);ret=request_irq(IRQ_EINT2,isr_kbd,SA_INTERRUPT,DEV_NAME,isr_kbd);if(ret) return ret;ret=request_irq(IRQ_EINT3,isr_kbd,SA_INTERRUPT,DEV_NAME,isr_kbd);if(ret) return ret;/*kbddev.head=kbd
9、dev.tail=0;kbddev.kbdStatus=KEYSTATUS_UP;init_waitqueue_head(&(kbddev.wq);init_timer(&kbd_timer);kbd_timer.function=kbd_timer_handler;*/return 0; static void _exit eint_cleanup(void) *(unsigned char*)0xd1000000)=0xff; release_region(GPIO_F2,1); release_region(GPIO_F3,1);release_region(0x10000000,1);
10、free_irq(IRQ_EINT2,DEV_NAME);free_irq(IRQ_EINT3,DEV_NAME);unregister_chrdev(DEVICE_MAJOR,DEV_NAME); static int eint_open(struct inode *inode,struct file *filp) MOD_INC_USE_COUNT; return 0; static int eint_release(struct inode *inode, struct file *filp) MOD_DEC_USE_COUNT;/del_timer(&kbd_timer); print
11、k(release successn); return 0; static ssize_t eint_read(struct file *filp,char *buffer,size_t count,loff_t* ppos) /*retry:if(ascii_key!=z)printk(prepare to copy to user);copy_to_user(buffer,&ascii_key,sizeof(char);return sizeof(char);else/printk(prepare to sleepn);interruptible_sleep_on(&wq);/printk
12、(sleeping!n);if(signal_pending(current)return -ERESTARTSYS;/printk(retry? n);goto retry ;*/return sizeof(char); module_init(eint_init); module_exit(eint_cleanup); /*eint.c*/*測(cè)試程序,什么都不做,打開(kāi)設(shè)備后就是等著你去按按鍵了*/#include #include #include #include /#include static void delay()int i,j,k;for(i=100;i0;i-)for(j=1
13、00;j0;j-)for(k=100;k0;k-)int main(int argc ,char* argv)int fd;char a=0;printf(prepare to open /dev/keybutton n);fd=open(/dev/eint,O_RDONLY);printf(WYQ fd is %dn,fd);if(fd0)printf(keybutton was opened n);while(1)/read(fd,&a,sizeof(a);/printf(%c was read from keyboardn,a);/delay();close(fd);printf(fd
14、was closedn);return 0;/*keybutton.c*/*4X4鍵盤(pán)的驅(qū)動(dòng),已經(jīng)加入了防抖動(dòng)的功能,參考了光盤(pán)上的中斷處理程序,感謝同學(xué)呂貴蓉一起研究了那段惱人的代碼!這里面主要是鍵盤(pán)完全沒(méi)有使用硬件中斷,所以只有在open()后不停的輪詢(xún),這樣就使用了系統(tǒng)內(nèi)核定時(shí)器,而定時(shí)器每add_timer()一次,就完了,不能實(shí)現(xiàn)每10ms就調(diào)用一次掃描操作,所以不得已之下,在中斷處理程序里面做了點(diǎn)手腳,你可以看!我想本來(lái)應(yīng)該還要加入原子操作才對(duì)的!然后呢,由于是要讀外部設(shè)備,自然涉及到了阻塞和非阻塞了,這關(guān)系到喚醒與睡眠的問(wèn)題了.這里說(shuō)的幾個(gè)問(wèn)題相信經(jīng)常編寫(xiě)驅(qū)動(dòng)的高手一定很熟悉了!
15、感謝涂志波師兄借給我的書(shū)設(shè)備驅(qū)動(dòng)程序,嵌入式系統(tǒng)接口設(shè)計(jì)與linux驅(qū)動(dòng)程序設(shè)計(jì)說(shuō)心底話(huà),真想買(mǎi)一本,但實(shí)在太貴了!以后有的話(huà),要考慮收藏一本了!難道真的是書(shū)非借不可讀也?*/#ifndef _KERNEL_#define _KERNEL_#endif#ifndef MODULE#define MODULE#endif#include #include #include #include #include #include #include #include #include #include #include #include #include #define DEVICE_MAJOR 25
16、1#define DEV_NAME keybuttonstatic int keybutton_open(struct inode *inode,struct file *filp); static int keybutton_release(struct inode *inode, struct file *filp); static ssize_t keybutton_read(struct file *filp,char *buffer,size_t count,loff_t* ppos); static int _init keybutton_init(void); static vo
17、id _exit keybutton_cleanup(void); static char key_get_char(int row,int col);/*#define MAX_KBD_BUF 16typedef unsigned char KBD_RET;typedef struct/unsigned int kbdStatus;KBD_RET bufMAX_KBD_BUF;unsigned int head,tail;wait_queue_head_t wq;static KBD_DEV kbddev;#define BUF_HEAD(kbddev.bufkbddev.head)#def
18、ine BUF_TAIL(kbddev.bufkbddev.tail)#define INCBUF(x,mod)(+(x) & (mod)-1)*/static wait_queue_head_t wq;enum KEYBOARD_SCAN_STATUSKEYBOARD_SCAN_FIRST,KEYBOARD_SCAN_SECOND,KEYBOARD_SCAN_THIRD,KEYBOARD_SCAN_FOURTH;int row = 0;/extern unsigned char output_0x10000000;static unsigned char ascii_key=z, input
19、_key4, input_key14, key_mask = 0x0F;static unsigned char*keyboard_port_scan = (unsigned char*)0xd1000000;static unsigned char*keyboard_port_value = (unsigned char*)0xd1000002;static int keyboard_scan_status4 = KEYBOARD_SCAN_FIRST, KEYBOARD_SCAN_FIRST, KEYBOARD_SCAN_FIRST, KEYBOARD_SCAN_FIRST;static
20、struct timer_list kbd_timer;static char key_get_char(int row, int col)char key = 0;printk(key_get_charn);switch( row )case 0:if(col & 0x01) = 0) key = 0; else if(col & 0x02) = 0) key =A; else if(col & 0x04) = 0) key = B; else if(col & 0x08) = 0) key = F; break;case 1:if(col & 0x01) = 0) key = 7; els
21、e if(col & 0x02) = 0) key = 8; else if(col & 0x04) = 0) key = 9;else if(col & 0x08) = 0) key = E;break;case 2:if(col & 0x01) = 0) key = 4; else if(col & 0x02) = 0) key = 5; else if(col & 0x04) = 0) key = 6; else if(col & 0x08) = 0) key = D; break;case 3:if(col & 0x01) = 0) key = 1; else if(col & 0x0
22、2) = 0) key = 2; else if(col & 0x04) = 0) key = 3; else if(col & 0x08) = 0) key = C; break;default:break;return key;static void recv_key(unsigned char c)unsigned char cc;cc=c;/printk(recv_key recevied char %c,cc);static void Kbd_Scan(unsigned long data)int loopcnt = row, bexit = 0;int temp;/printk(1
23、0ms was past! begin to scan n);del_timer(&kbd_timer);for( loopcnt = row; loopcnt = 4)temp = loopcnt - 4;elsetemp = loopcnt;/printk(temp is %dn,temp);switch(keyboard_scan_statustemp)case KEYBOARD_SCAN_FIRST:/printk(status is %dn,keyboard_scan_statustemp);*keyboard_port_scan = (0x00000001temp); keyboa
24、rd_scan_statustemp = KEYBOARD_SCAN_SECOND;bexit = 1;break;case KEYBOARD_SCAN_SECOND:/ printk(status is %dn,keyboard_scan_statustemp);input_keytemp = (*keyboard_port_value) & key_mask;if(input_keytemp = key_mask)keyboard_scan_statustemp = KEYBOARD_SCAN_FIRST;elsekeyboard_scan_statustemp=KEYBOARD_SCAN
25、_THIRD;printk(some key was down mainly!n);bexit = 1;break;case KEYBOARD_SCAN_THIRD:/ printk(status is %dn,keyboard_scan_statustemp);if (*keyboard_port_value) & key_mask) != input_keytemp) keyboard_scan_statustemp = KEYBOARD_SCAN_FIRST;elseascii_key = key_get_char(temp, input_keytemp);printk(prepare
26、to wake upn);wake_up_interruptible(&wq);/ascii_key=z;printk(has waken up n);printk(ooooooooooooooooothe char is %cn,ascii_key);keyboard_scan_statustemp = KEYBOARD_SCAN_FOURTH;printk(some key was really down);*keyboard_port_scan = (0x00000001temp); bexit = 1;break;case KEYBOARD_SCAN_FOURTH:/ printk(s
27、tatus is %dn,keyboard_scan_statustemp);input_key1temp = (*keyboard_port_value) & key_mask;if(input_key1temp = key_mask)/ get a keyrecv_key(ascii_key);printk(key was up now!n);keyboard_scan_statustemp = KEYBOARD_SCAN_FIRST;else*keyboard_port_scan = (0x00000001temp); bexit = 1;break;if(bexit)break;row
28、 = temp;kbd_timer.expires=jiffies+HZ/100; add_timer(&kbd_timer); static struct file_operations keybutton_fops= owner:THIS_MODULE, open:keybutton_open, release:keybutton_release, read:keybutton_read, ; /*keybutton_init*/ static int _init keybutton_init(void) int ret; ret=register_chrdev(DEVICE_MAJOR,
29、DEV_NAME,&keybutton_fops); if (ret0) printk(DEV_NAME cannot get major number!n); return ret; if( check_region( 0x10000000,1 ) &check_region(0x10000002,1)printk(the port is used by another modulen);return -1; request_region(0x10000000,1,DEV_NAME);request_region(0x10000002,1,DEV_NAME);/*kbddev.head=kb
30、ddev.tail=0;*/init_waitqueue_head(&wq);printk(success to request_regionn);return 0; /*keybutton_cleanup*/static void _exit keybutton_cleanup(void) release_region(0x10000000,1); release_region(0x10000002,1);unregister_chrdev(DEVICE_MAJOR,DEV_NAME); static int keybutton_open(struct inode *inode,struct
31、 file *filp) init_timer(&kbd_timer);kbd_timer.function=Kbd_Scan; kbd_timer.expires=jiffies+HZ/100; add_timer(&kbd_timer); MOD_INC_USE_COUNT; printk(open device keybuttonn);printk(timer has added into systemn);return 0; static int keybutton_release(struct inode *inode, struct file *filp) MOD_DEC_USE_
32、COUNT;/del_timer(&kbd_timer); printk(release successn); return 0; /* static KBD_RET kbdRead(void)KBD_RET kbd_ret;kbd_ret=BUF_TAIL;kbddev.tail=INCBUF(kbddev.tail,MAX_KBD_BUF);return kbd_ret; */static ssize_t keybutton_read(struct file *filp,char *buffer,size_t count,loff_t* ppos) /add_timer(&kbd_time
33、r);/printk(timer has added into systemn);retry:if(ascii_key!=z)printk(prepare to copy to user);copy_to_user(buffer,&ascii_key,sizeof(char);return sizeof(char);else/printk(prepare to sleepn);interruptible_sleep_on(&wq);/printk(sleeping!n);if(signal_pending(current)return -ERESTARTSYS;/printk(retry? n
34、);goto retry ;return sizeof(char); module_init(keybutton_init); module_exit(keybutton_cleanup); keytest.c*/*已經(jīng)沒(méi)有什么新意了,測(cè)試程序都是這樣的了!*/#include #include #include #include /#include static void delay()int i,j,k;for(i=100;i0;i-)for(j=100;j0;j-)for(k=100;k0;k-)int main(int argc ,char* argv)int fd;char a=0;
35、printf(prepare to open /dev/keybutton n);fd=open(/dev/keybutton,O_RDONLY);printf(WYQ fd is %dn,fd);if(fd0)printf(keybutton was opened n);read(fd,&a,sizeof(a);printf(%c was read from keyboardn,a);delay();close(fd);printf(fd was closedn);return 0;adv.c*/*A/D轉(zhuǎn)換的驅(qū)動(dòng),終于感受了一把轉(zhuǎn)化!太受不了自己了,一個(gè)研究生了,居然一直都沒(méi)有用轉(zhuǎn)換做過(guò)東
36、西!哎,人水了,沒(méi)有辦法!原來(lái)轉(zhuǎn)換可以用兩種機(jī)制來(lái)實(shí)現(xiàn)的,一種是讀轉(zhuǎn)換結(jié)束標(biāo)志位,一種是才用轉(zhuǎn)換結(jié)束中斷,我這個(gè)才用的讀轉(zhuǎn)換結(jié)束標(biāo)志位,比較簡(jiǎn)單的一種。我看網(wǎng)上的一個(gè)的驅(qū)動(dòng),兩個(gè)都用了,我想應(yīng)該是他錯(cuò)了吧!希望有網(wǎng)友能批評(píng)我的觀點(diǎn)!*/#ifndef _KERNEL_#define _KERNEL_#endif#ifndef MODULE#define MODULE#endif#include #include #include #include #include #include #include #include #include #include #include #include #i
37、nclude #define DEVICE_MAJOR 252#define DEV_NAME ADVstatic int ADV_open(struct inode *inode,struct file *filp); static int ADV_release(struct inode *inode, struct file *filp); static ssize_t ADV_read(struct file *filp,char *buffer,size_t count,loff_t* ppos); static int _init ADV_init(void); static void _exit ADV_cleanup(void); /static wait_queue_head_t wq;/static struct timer_list kbd_timer; static struct file_o
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 配電安規(guī)習(xí)題+參考答案
- 河南省上蔡一高2025年高三3月份模擬考試英語(yǔ)試題含解析
- 機(jī)修鉗工(設(shè)備鉗工)復(fù)習(xí)題及答案
- 浙江省寧波四中2025屆高三下學(xué)期第五次調(diào)研考試英語(yǔ)試題含解析
- 2025年福建省廈門(mén)二中高考考前模擬英語(yǔ)試題含答案
- 江蘇省連云港市海州區(qū)2024-2025學(xué)年高一下學(xué)期4月期中學(xué)業(yè)水平質(zhì)量監(jiān)測(cè)化學(xué)試題(原卷版+解析版)
- 紙容器食品安全包裝要求與檢測(cè)考核試卷
- 管道工程綠色施工技術(shù)創(chuàng)新動(dòng)態(tài)與發(fā)展趨勢(shì)考核試卷
- 美容儀器電路設(shè)計(jì)與優(yōu)化案例分析考核試卷
- 航空物流企業(yè)的供應(yīng)鏈金融創(chuàng)新考核試卷
- 危險(xiǎn)性較大的分部分項(xiàng)工程清單(表格版)
- 國(guó)開(kāi)2024春《人文英語(yǔ)3》第1-4單元作文練習(xí)參考答案
- 【電石乙炔法制備氯乙烯的生產(chǎn)工藝設(shè)計(jì)9600字(論文)】
- 2024年廣東省梅州市中考一模歷史試題(無(wú)答案)
- 2024年北京鐵路局集團(tuán)招聘筆試參考題庫(kù)含答案解析
- 500字作文標(biāo)準(zhǔn)稿紙A4打印模板-直接打印
- 發(fā)電機(jī)安全運(yùn)行常識(shí)
- 整理收納師課件
- 火災(zāi)安全教育培訓(xùn)主題
- 如何寫(xiě)好校園新聞稿
- 護(hù)士溝通技巧與人文關(guān)懷護(hù)理課件
評(píng)論
0/150
提交評(píng)論