<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 基于Linux操作系統(tǒng)的視頻采集卡驅(qū)動(dòng)程序設(shè)計(jì)

          基于Linux操作系統(tǒng)的視頻采集卡驅(qū)動(dòng)程序設(shè)計(jì)

          作者: 時(shí)間:2012-05-21 來源:網(wǎng)絡(luò) 收藏

          4.2 的實(shí)現(xiàn)

          下面討論的具體實(shí)現(xiàn)。

          4.2.1 PCI

          本文采用的卡是基于PCI總線的,因此在這里首先討論P(yáng)CI驅(qū)動(dòng)程序的結(jié)構(gòu)。

          PCI設(shè)備是無跳線設(shè)備,可在引導(dǎo)階段自動(dòng)配置。這樣設(shè)備驅(qū)動(dòng)程序必須能夠訪問設(shè)備中的配置信息以便完成初始化。對(duì)于PCI設(shè)備來說,這些工作無需探測就可以完成[1][5]。

          所有的PCI設(shè)備都有至少256字節(jié)的地址空間,前64字節(jié)是標(biāo)準(zhǔn)化的,其余的是設(shè)備相關(guān)的。這個(gè)空間也叫做PCI配置空間,它包含廠商標(biāo)識(shí),設(shè)備標(biāo)識(shí),設(shè)備類別,基地址寄存器,中斷引腳等等,編寫PCI的驅(qū)動(dòng)程序就是利用這些域與設(shè)備進(jìn)行“溝通”。

          盡管PCI設(shè)備千差萬別,但是控制他們的結(jié)構(gòu)基本是類似的。

          1)為了正確注冊(cè)到內(nèi)核,所有的PCI驅(qū)動(dòng)程序需要?jiǎng)?chuàng)建pci_driver結(jié)構(gòu)體,該結(jié)構(gòu)體由許多回調(diào)函數(shù)和變量組成。初始化該結(jié)構(gòu)體如下:

          struct pci_driver saa7146__driver = {

          name: "saa7146 ",

          id_table: saa7146__pci_tbl,

          probe: saa7146_v4l2_init_one,

          remove: saa7146_v4l2_remove_one,

          suspend: saa7146_v4l2_suspend,

          resume: saa7146_v4l2_resume,

          };

          為了把struct pci_driver注冊(cè)到PCI核心,需要調(diào)用以其為參數(shù)的pci_module_init函數(shù):

          pci_module_init(saa7146_v4l2_driver);

          2)如果上述函數(shù)返回為0,表示初始化成功,此時(shí)在驅(qū)動(dòng)程序可以訪問PCI設(shè)備的任何設(shè)備資源之前(I/O區(qū)域或中斷),驅(qū)動(dòng)程序必須調(diào)用pci_enable_device函數(shù):

          int pci_enable_device(struct pci_dev *dev);

          3)上述函數(shù)將激活設(shè)備,此時(shí)驅(qū)動(dòng)程序就需要讀取或?qū)懭肴齻€(gè)地址空間:內(nèi)存,I/O端口,配置空間。把I/O空間和內(nèi)存空間都看作是系統(tǒng)的資源,使用前必須申請(qǐng),即在系統(tǒng)中進(jìn)行登記,避免資源使用的混亂。簡述如下:

          首先調(diào)用pci_resource_start()和pci_resource_len()函數(shù)獲取資源信息,然后調(diào)用 request_mem_region()函數(shù)分配I/O內(nèi)存區(qū)域,為了確保該內(nèi)存對(duì)內(nèi)核而言是可訪問的,必須還要建立映射,映射的建立由 ioremap()函數(shù)完成,這樣設(shè)備驅(qū)動(dòng)程序就可以訪問任意的I/O內(nèi)存地址。

          4)與設(shè)備通信,即通過訪問I/O內(nèi)存的函數(shù),諸如writel(),readl()等;以及進(jìn)行I2C操作的函數(shù)對(duì)SAA7111a進(jìn)行初始化。

          4.2.2 驅(qū)動(dòng)模塊的設(shè)計(jì)與實(shí)現(xiàn)

          采集卡驅(qū)動(dòng)程序主要由saa7146_v4l2,v4l2_extension,saa7111a三個(gè)模塊構(gòu)成,這三個(gè)模塊都要調(diào)用i2c- core模塊(Kernel提供)中的函數(shù),即它們依賴于i2c-core模塊;saa7111a模塊具體負(fù)責(zé)通過I2C控制SAA7111a芯片,v4l2_extension模塊依賴于saa7146_v4l2模塊,它把自己注冊(cè)到saa7146核心模塊中。

          重要數(shù)據(jù)結(jié)構(gòu)聲明

          采集設(shè)備的擴(kuò)展部分結(jié)構(gòu):

          struct saa7146_v4l2_extension{

          char name[64]; /* 設(shè)備名 */

          struct saa7146_v4l2_extension_ioctls* ioctls;

          u32 irq_mask; /* 擴(kuò)展部分處理的IRQ */

          void (*irq_func)(struct capture_device*, u32* irq_mask);

          /* 擴(kuò)展部分的函數(shù)主要就是ioctl()用于實(shí)現(xiàn)各種類型硬件控制 */

          int (*ioctl)(void *id, unsigned int cmd, void *arg);

          };

          采集設(shè)備核心結(jié)構(gòu):

          struct capture_device{

          struct v4l2_device v4l2;

          struct v4l2_capability capability;

          struct pci_dev *pci_device;

          ……

          }

          linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)

          linux相關(guān)文章:linux教程




          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();