這幾天把外圍簡單的輸入驅動給寫了下,... - 程序員聯_第1頁
這幾天把外圍簡單的輸入驅動給寫了下,... - 程序員聯_第2頁
這幾天把外圍簡單的輸入驅動給寫了下,... - 程序員聯_第3頁
這幾天把外圍簡單的輸入驅動給寫了下,... - 程序員聯_第4頁
這幾天把外圍簡單的輸入驅動給寫了下,... - 程序員聯_第5頁
已閱讀5頁,還剩12頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、這段時間都在忙驅動了,幾個有代表性的簡單的外圍接口,寫寫,讓我知道什么是所謂的驅動!完全原創,若有轉載,請標記出處,若有什么疑問,請聯系我:85469843.三峽大學感謝網上朋友的熱心幫助,解決了幾個硬件方面的疑問!這幾天把外圍簡單的輸入驅動給寫了下,盡管簡單,但還是花了我不少心思呀!/*eint.c*/*實現功能很簡單,就是按下接中斷的按鍵后,LED就亮,中間涉及到中斷的注冊,中斷驅動程序的實現.但還沒有加入防抖動的功能,實在太懶了!*/#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*/*測試程序,什么都不做,打開設備后就是等著你去按按鍵了*/#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鍵盤的驅動,已經加入了防抖動的功能,參考了光盤上的中斷處理程序,感謝同學呂貴蓉一起研究了那段惱人的代碼!這里面主要是鍵盤完全沒有使用硬件中斷,所以只有在open()后不停的輪詢,這樣就使用了系統內核定時器,而定時器每add_timer()一次,就完了,不能實現每10ms就調用一次掃描操作,所以不得已之下,在中斷處理程序里面做了點手腳,你可以看!我想本來應該還要加入原子操作才對的!然后呢,由于是要讀外部設備,自然涉及到了阻塞和非阻塞了,這關系到喚醒與睡眠的問題了.這里說的幾個問題相信經常編寫驅動的高手一定很熟悉了!

15、感謝涂志波師兄借給我的書設備驅動程序,嵌入式系統接口設計與linux驅動程序設計說心底話,真想買一本,但實在太貴了!以后有的話,要考慮收藏一本了!難道真的是書非借不可讀也?*/#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*/*已經沒有什么新意了,測試程序都是這樣的了!*/#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轉換的驅動,終于感受了一把轉化!太受不了自己了,一個研究生了,居然一直都沒有用轉換做過東

36、西!哎,人水了,沒有辦法!原來轉換可以用兩種機制來實現的,一種是讀轉換結束標志位,一種是才用轉換結束中斷,我這個才用的讀轉換結束標志位,比較簡單的一種。我看網上的一個的驅動,兩個都用了,我想應該是他錯了吧!希望有網友能批評我的觀點!*/#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. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論