- 論壇徽章:
- 0
|
兩種方式
一 驅(qū)動(dòng)程序執(zhí)行方式
1.申請(qǐng)I/O端口
A 直接端口方式
check_region
request_region
B內(nèi)存映射方式
check_mem_region
request_mem_retion
然后隊(duì)端口地址映射
ioremap
2.注冊(cè)驅(qū)動(dòng)
register_chrdev 申請(qǐng)主設(shè)備號(hào),注冊(cè)驅(qū)動(dòng)名,相關(guān)的操作.
3.探測(cè)中斷
A 內(nèi)核探測(cè)
B 定制探測(cè)
C 直接根據(jù)I/O地址,分配相應(yīng)的IRQ號(hào)
4.安裝中斷相應(yīng)處理函數(shù)
request_irq(irq,(*)Handler()...)
A 共享中斷的處理函數(shù)
端口有中斷到,則判斷時(shí)不時(shí)本端口的中斷.若是.則填充緩沖區(qū).同時(shí)wake_up_interruptible,喚起等待序列.
在read操作中的隊(duì)列由signal_pending喚醒,拷貝數(shù)據(jù)到用戶空間.
B 下半部中斷的處理函數(shù)
通過(guò)queue_task,執(zhí)行隊(duì)列處理函數(shù)喚起中斷.
C 小任務(wù)中斷處理函數(shù)
通過(guò)tasklet_schedule執(zhí)行小任務(wù)處理函數(shù)喚起中斷.
二 應(yīng)用程序執(zhí)行方式.
- 通過(guò) ioperm 命令,例如,ioperm ( BASE, range , 1),調(diào)用內(nèi)核,得到 I/O 地址空間的使用權(quán);
- 通過(guò)一個(gè)發(fā)送請(qǐng)求指令,例如, outb(1, BASE ) ,
- 等待足夠的時(shí)間讓咖啡煮好,讓時(shí)間參數(shù)在命令行中被讀取是一件很好的事情
- 然后發(fā)送 out(0, BASE) 指令關(guān)掉咖啡機(jī)
- 在結(jié)束之前還應(yīng)歸還并口 I/O 地址的使用權(quán), ioperm(BASE,range,0) .
程序:/* coffee.c */
#include /* linux-specific */
#ifdef __GLIBC__
# include
#endif
int main(int argc, char **argv)
{
setuid(0); /* if we're setuid, force it on */
if(ioperm(0x378,1,1))
printf("error,we can't ioperm our ox378 port
");
outb(0xff,0x378);
sleep(5);
outb(0,0x378);
if(ioperm(0x378,1,0))
printf("error,we can't ioperm our ox378 port
");
exit(1);
}
三 在驅(qū)動(dòng)程序中如何取得被其它驅(qū)動(dòng)程序使用的并口
首先 cat /proc/ioports 看端口地址是分配給誰(shuí)了.
然后看該名字的 ls -l /dev/port_name
找到主設(shè)備號(hào)和次設(shè)備號(hào)
然后 cat /proc/devices 看主設(shè)備好對(duì)應(yīng)的驅(qū)動(dòng)
然后rmmod 該驅(qū)動(dòng).
如果是編譯到了內(nèi)核的驅(qū)動(dòng)則只需在/lib/module/`uname -r`/kernel/drivers/ 刪除該名字的驅(qū)動(dòng),
則重起后,該驅(qū)動(dòng)就不會(huì)暫用該端口了,但這個(gè)驅(qū)動(dòng)的名字不一定在/proc/devices 中出現(xiàn)
本文來(lái)自ChinaUnix博客,如果查看原文請(qǐng)點(diǎn):http://blog.chinaunix.net/u/4591/showart_36101.html |
|