在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

linux系統(tǒng)和驅(qū)動中按鍵驅(qū)動的編寫詳解

454398 ? 來源:AI加速 ? 作者:AI加速 ? 2020-11-21 11:03 ? 次閱讀

引言

隨著深度學(xué)習(xí)5G的應(yīng)用,對FPGA的功能要求越來越多。因此近幾年FPGA大廠紛紛將自己的器件集成了更多的內(nèi)核,比如賽靈思的zynq系列就集成了armGPU,PCIE,射頻處理模塊等等,用于滿足各種各樣的需求。出身FPGA的工程師們也必須擁抱這些變化,不僅僅要精通FPGA開發(fā),還需要了解其他方面的知識。比如基于zynq的開發(fā)者,就需要了解arm,linux驅(qū)動以及l(fā)inux系統(tǒng)。做深度學(xué)習(xí)加速的還需要了解深度學(xué)習(xí)網(wǎng)絡(luò)以及網(wǎng)絡(luò)壓縮等知識。學(xué)習(xí)這些知識會讓你的眼界更加開闊,會站得高看得遠,在開始一項任務(wù)的時候不再是盲人摸象,而是高瞻遠矚,把握全局。

這是我介紹linux系統(tǒng)和驅(qū)動的第4篇文章,如有不恰當(dāng)?shù)牡胤綒g迎指正,因為本人也是處于學(xué)習(xí)入門階段。三人行,必有我?guī)熝伞S懻摰亩嗔耍瑔栴}也就清晰了。這一篇主要介紹按鍵驅(qū)動的編寫,了解中斷的處理過程,以及設(shè)備樹的修改。

1. vivado工程搭建

工程搭建很簡單,就是配置完zynq核的外設(shè)后,增加一個axi_gpio模塊,作為外部按鍵的接口。雖然按鍵并不是直接連接到arm的IO上,但是axi_gpio也被映射到zynq系統(tǒng)的內(nèi)存空間中,linux驅(qū)動通過讀寫key對應(yīng)的映射內(nèi)存來控制和檢測。要檢測到key被按下我們必須開啟中斷,因此axi_gpio模塊設(shè)置如下圖。Address editor是gpio的對應(yīng)的內(nèi)存空間。Zynq已經(jīng)為不同外設(shè)類型分配了可選的內(nèi)存映射,通常工程建立完后,由軟件工具自行分配就好了。如果一些外設(shè)內(nèi)存有沖突,是無法生成hdf的。




配置完成后,進行管腳約束,然后綜合實現(xiàn),生成bit文件。再導(dǎo)出hdf文件,打開SDK來生成fsbl,u-boot還使用前幾篇介紹驅(qū)動中的u-boot。U-boot通常不會因為驅(qū)動的新增而修改。但是由于增加了key按鍵,我們需要去設(shè)備樹中修改對應(yīng)的配置。

具體如何修改設(shè)備樹,可以到linux驅(qū)動文件夾Documentation/devicetree中去尋找對應(yīng)的外設(shè)文件,其中有設(shè)備樹修改的介紹。Gpio的修改可以到gpio文件夾下的gpio-zynq.txt查看。其基本形式為:

         gpio@e000a000 { #gpio-cells = <2>;
                   compatible = "xlnx,zynq-gpio-1.0";
                   clocks = <&clkc 42>;
                   gpio-controller;
                   interrupt-parent = <&intc>;
                   interrupts = <0 20 4>;
                   interrupt-controller;
                   #interrupt-cells = <2>;
                   reg = <0xe000a000 0x1000>; };

其中compatible主要是用于linux驅(qū)動去匹配設(shè)備樹中相應(yīng)的節(jié)點,后面我們會介紹,這個名字和那一塊程序有關(guān)。主要是配置中斷,其中interrupts-cell指定了interrupts有多少個屬性。Interrupts的第一個屬性是中斷類型,第二個是中斷號,最后一個表示觸發(fā)類型:高電平觸發(fā)、低電平觸發(fā)、上升沿觸發(fā)和下降沿觸發(fā)四種類型。Interrupt-parent是中斷所屬的中斷控制器。我們在SDK中產(chǎn)生了設(shè)備樹,我們看到按鍵的相應(yīng)節(jié)點位于amba_pl節(jié)點下,其中amba_pl是PL端的總線節(jié)點,而amba是PS端的總線節(jié)點,修改pl.dtsi中的gpio內(nèi)容:

我們改了compitable的內(nèi)容,同時要關(guān)注inerrupts,xlnx,all-inputs,xlnx,gpio-width這些屬性。Gpio-width是寬度,all-inputs是表示為輸入。

設(shè)備樹修改完后就可以編譯設(shè)備樹文件,然后用fsbl,u-boot,設(shè)備樹來制作boot.bin了。放到SD卡,啟動linux系統(tǒng)。接下來進入關(guān)鍵環(huán)節(jié),key驅(qū)動的編寫。

2. 按鍵驅(qū)動代碼剖析

對于一個剛剛?cè)腴T的人來說,其實了解了驅(qū)動的基本框架就好了。每個驅(qū)動都按照它的框架進行編寫和修改。能理解驅(qū)動的各個模塊功能,在驅(qū)動調(diào)試或者編寫中就能有的放矢。一個簡單的驅(qū)動的構(gòu)成也很復(fù)雜,代碼也很多,篇幅有限,我只介紹主要部分。

1)platform框架

Platform是一種虛擬的平臺,提供了驅(qū)動和具體硬件交互的接口。Platform_device類似于虛擬的總線,IIC,LCD,GPIO等外設(shè)都可以看做platform_device,通過它可以遍歷所有的總線設(shè)備,而對應(yīng)的驅(qū)動就是platform_driver。基本流程是:先注冊platform_device,再注冊platform_driver,然后匹配設(shè)備和驅(qū)動,最后注冊整個驅(qū)動。

在linux3以前的版本,需要定義platform_device結(jié)構(gòu)體,然后通過platform_device_register函數(shù)來注冊設(shè)備。但是linux3.0以后出現(xiàn)了設(shè)備樹,內(nèi)核函數(shù)of_platform_default_populate_init會在內(nèi)核啟動后遍歷設(shè)備樹,自動注冊每個節(jié)點對應(yīng)的設(shè)備。因此只需要修改設(shè)備樹參數(shù)就行了。首先看這個結(jié)構(gòu)體:

static const struct of_device_id key_of_match[] __devinitdata={
         {.compatible="xlnx,gpio-keys",},
         {/*end of list*/},
};

這實際上定義了設(shè)備的匹配號,compatible就是在設(shè)備樹節(jié)點axi-gpio中對應(yīng)的節(jié)點匹配名稱。我們只要讓compitable和設(shè)備樹中對應(yīng)節(jié)點的值匹配上就可以將節(jié)點對應(yīng)的設(shè)備注冊到總線上了。

platform_driver用于對設(shè)備的搜索和配置,主要就是去解析設(shè)備樹,根據(jù)設(shè)備樹中節(jié)點信息來填充設(shè)備結(jié)構(gòu)體對應(yīng)信息或者直接對設(shè)備完成配置。

static struct platform_driver key_driver={
         .driver={
                   .name=DRIVER_NAME,
                   .owner=THIS_MODULE,
                   .of_match_table=key_of_match,
         },
         .probe=key_probe,
         .remove=key_remove,
};

我們主要關(guān)注其三個變量,of_match_table就是of_device_id結(jié)構(gòu)體定義的,用來匹配節(jié)點。Probe函數(shù)用來解析節(jié)點,配置設(shè)備。Remove主要是釋放在probe中使用的資源等。

編寫key驅(qū)動主要就是去填充probe和remove兩個函數(shù)。

來看probe函數(shù)是如何查找到設(shè)備的一些屬性的,比如我們要確定key鍵的數(shù)量,那么我們可以這樣來做:

         if(of_property_read_u32(node, "xlnx,gpio-width", &width)){
                   printk(KERN_ERR "get the gpio-width/n");
         }

通過匹配“xlnx,gpio-width”來獲得key的位寬,這個屬性就在設(shè)備中定義的。

如果我們要操作key,需要獲得key設(shè)備的內(nèi)存映射空間,這個可以通過函數(shù)platform_get_resource函數(shù)來完成。

mem=platform_get_resource(pdev, IORESOURCE_MEM, 0);
         if(!mem){
                   printk(KERN_ERR "get memory resource/n");
                   return -ENODEV;
         }

第一個參數(shù)pdev是platform_device結(jié)構(gòu)體,在進入probe函數(shù)之前就已經(jīng)被注冊了,其指向的就是key對應(yīng)的設(shè)備。第二個參數(shù)是類型,主要有IORESOURCE_MEM, IORESOURCE_IRQ等。最后一個參數(shù)是號碼,指示platform_device結(jié)構(gòu)體中不同的資源類型,即IORESOURCE類型。

以上獲得的mem就是在設(shè)備樹中由reg指定的內(nèi)存映射:

reg = <0x41210000 0x10000>;

中斷的獲得可以通過函數(shù):

         r_irq=irq_of_parse_and_map(node, 0);
         if(!r_irq){
                   printk(KERN_ERR "get interrupt/n");
         }

其中device_node就是設(shè)備節(jié)點,在platform_device注冊的時候,含有該節(jié)點,所以可以通過該結(jié)構(gòu)體獲得。第二個參數(shù)表示一個設(shè)備樹節(jié)點有多個中斷時的索引

通過設(shè)備樹獲得了硬件信息后,我們將其填充到key_device中,key_device定義如下:

struct key_dev{
         struct cdev dev;
         struct work_struct work;                 
         int irq;
         int major;
         unsigned long start_addr;
         unsigned long size;
         void __iomem *baseaddr;
         int width;
         int inout;
         int key_prs;
};

其中irq為中斷號,cdev是字符設(shè)備結(jié)構(gòu)體,因為key等屬于字符設(shè)備。填充如下:

        lp->start_addr=mem->start;
         lp->size=mem->end-mem->start;
         lp->irq=r_irq;
         lp->width=width;

2)中斷處理

在platform中我們談到了對中斷號的獲取,那么取得了中斷號之后如何來檢測中斷事件呢?中斷處理過程可以被分成兩部分:頂半部和底半步。頂半部主要處理硬件上比較緊急的事物,比如檢測中斷,底半部用于處理中斷產(chǎn)生之后需要進行的事務(wù)處理。在底半部處理過程中不會耽誤檢測下一個中斷。這兩個部分不是絕對的,也可以只有一個部分。

驅(qū)動中首先需要定義一個中斷函數(shù),用于中斷產(chǎn)生后進行的操作。然后申請中斷,實現(xiàn)函數(shù):

err=request_irq(k_dev->irq,key_interrupt, IRQF_SHARED|IRQF_TRIGGER_RISING, DRIVER_NAME, k_dev);

第一個是中斷號,第二個為中斷處理函數(shù),第三個參數(shù)為中斷產(chǎn)生類型,上升沿下降沿一類,第四個為名字,可以命名中斷,最后一個是設(shè)備結(jié)構(gòu)體。

釋放中斷就通過free_irq(unsigned int irq, void *dev_id)來完成。

實現(xiàn)中斷底半部處理機制主要有tasklet,工作隊列,軟中斷和線程化irq。中斷機制較為復(fù)雜,任何一種機制都可以讓你竭盡腦汁。入門者還是循序漸進,所以我也只用了一種簡單的方法。類似鎖機制,我們定義一個事件:

static DECLARE_WAIT_QUEUE_HEAD(press_queue);

然后在中斷函數(shù)中喚醒這個事件,在其他函數(shù)中可以通過等待這個事件來進行中斷處理。我們的中斷函數(shù)為:

static irqreturn_t key_interrupt(int irq, void *dev_id)
{
         struct key_dev *dev=dev_id;
         dev->key_prs++;
         printk(KERN_INFO "interruptted/n");
         wake_up_interruptible(&press_queue);
         return IRQ_HANDLED;
}

而等待該事件放在key_read函數(shù)中:

ssize_t key_read(struct file *filp, char __user *buf, size_t count, loff_t *fops)
{
         int err;     
         struct key_dev *dev=filp->private_data;        
         wait_event_interruptible(press_queue, event_press);
         event_press=0;
         err=copy_to_user(buf, &dev->key_prs, count);
         return err ? -EFAULT : 0;
}

3)文件結(jié)構(gòu)

Linux一切皆文件,任何驅(qū)動最終都被封裝為一個文件,用戶空間通過讀寫文件來操作驅(qū)動。文件操作包括打開,關(guān)閉,讀和寫等。我們不做具體介紹,簡單列出文件結(jié)構(gòu)體為:

struct file_operations key_fops={
         .owner=THIS_MODULE,
         .open=key_open,
         .read=key_read,
         .release=key_close,
};

總結(jié)

對以上進行總結(jié)就是:
1) 首先進行設(shè)備樹節(jié)點屬性修改;
2) 填充platform框架下的probe,remove等函數(shù),并定義of_device_id和platform_driver結(jié)構(gòu)體;
3) 申請中斷,釋放中斷,編寫中斷函數(shù)等;
4) 填充文件結(jié)構(gòu),編寫open,close,read等函數(shù);

編輯:hfy


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • FPGA
    +關(guān)注

    關(guān)注

    1629

    文章

    21742

    瀏覽量

    603544
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11306

    瀏覽量

    209576
  • 5G
    5G
    +關(guān)注

    關(guān)注

    1354

    文章

    48456

    瀏覽量

    564343
  • 深度學(xué)習(xí)
    +關(guān)注

    關(guān)注

    73

    文章

    5503

    瀏覽量

    121182
收藏 人收藏

    評論

    相關(guān)推薦

    Linux系統(tǒng)驅(qū)動格式基本編寫方法

    今天主要和大家聊一聊,編寫Linux驅(qū)動格式與方法。
    發(fā)表于 12-02 09:34 ?576次閱讀

    Linux模塊相關(guān)命令 Linux驅(qū)動模塊的編寫與掛載

    Linux模塊相關(guān)命令 Linux驅(qū)動模塊的編寫與掛載
    發(fā)表于 10-01 12:20 ?482次閱讀
    <b class='flag-5'>Linux</b>模塊相關(guān)命令 <b class='flag-5'>Linux</b><b class='flag-5'>驅(qū)動</b>模塊的<b class='flag-5'>編寫</b>與掛載

    實時系統(tǒng)VxWorks下設(shè)備驅(qū)動程序的編寫詳解

    實時系統(tǒng)VxWorks下設(shè)備驅(qū)動程序的編寫詳解
    發(fā)表于 03-29 12:26 ?15次下載

    Linux設(shè)備驅(qū)動開發(fā)詳解》第17章、Linux音頻設(shè)備驅(qū)動

    Linux設(shè)備驅(qū)動開發(fā)詳解》第17章、Linux音頻設(shè)備驅(qū)動
    發(fā)表于 10-27 11:14 ?17次下載
    《<b class='flag-5'>Linux</b>設(shè)備<b class='flag-5'>驅(qū)動</b>開發(fā)<b class='flag-5'>詳解</b>》第17章、<b class='flag-5'>Linux</b>音頻設(shè)備<b class='flag-5'>驅(qū)動</b>

    Linux設(shè)備驅(qū)動開發(fā)詳解》第16章、Linux網(wǎng)絡(luò)設(shè)備驅(qū)動

    Linux設(shè)備驅(qū)動開發(fā)詳解》第16章、Linux網(wǎng)絡(luò)設(shè)備驅(qū)動
    發(fā)表于 10-27 11:17 ?5次下載
    《<b class='flag-5'>Linux</b>設(shè)備<b class='flag-5'>驅(qū)動</b>開發(fā)<b class='flag-5'>詳解</b>》第16章、<b class='flag-5'>Linux</b>網(wǎng)絡(luò)設(shè)備<b class='flag-5'>驅(qū)動</b>

    Linux設(shè)備驅(qū)動開發(fā)詳解》第14章、Linux終端設(shè)備驅(qū)動

    Linux設(shè)備驅(qū)動開發(fā)詳解》第14章、Linux終端設(shè)備驅(qū)動
    發(fā)表于 10-27 11:22 ?8次下載
    《<b class='flag-5'>Linux</b>設(shè)備<b class='flag-5'>驅(qū)動</b>開發(fā)<b class='flag-5'>詳解</b>》第14章、<b class='flag-5'>Linux</b>終端設(shè)備<b class='flag-5'>驅(qū)動</b>

    Linux設(shè)備驅(qū)動開發(fā)詳解》第13章、Linux塊設(shè)備驅(qū)動

    Linux設(shè)備驅(qū)動開發(fā)詳解》第13章、Linux塊設(shè)備驅(qū)動
    發(fā)表于 10-27 11:24 ?18次下載
    《<b class='flag-5'>Linux</b>設(shè)備<b class='flag-5'>驅(qū)動</b>開發(fā)<b class='flag-5'>詳解</b>》第13章、<b class='flag-5'>Linux</b>塊設(shè)備<b class='flag-5'>驅(qū)動</b>

    Linux設(shè)備驅(qū)動開發(fā)詳解》第9章、Linux設(shè)備驅(qū)動的異步通知與異步IO

    Linux設(shè)備驅(qū)動開發(fā)詳解》第9章、Linux設(shè)備驅(qū)動的異步通知與異步IO
    發(fā)表于 10-27 11:33 ?0次下載
    《<b class='flag-5'>Linux</b>設(shè)備<b class='flag-5'>驅(qū)動</b>開發(fā)<b class='flag-5'>詳解</b>》第9章、<b class='flag-5'>Linux</b>設(shè)備<b class='flag-5'>驅(qū)動</b><b class='flag-5'>中</b>的異步通知與異步IO

    Linux設(shè)備驅(qū)動開發(fā)詳解》第8章、Linux設(shè)備驅(qū)動的阻塞與非阻塞IO

    Linux設(shè)備驅(qū)動開發(fā)詳解》第8章、Linux設(shè)備驅(qū)動的阻塞與非阻塞IO
    發(fā)表于 10-27 11:35 ?9次下載
    《<b class='flag-5'>Linux</b>設(shè)備<b class='flag-5'>驅(qū)動</b>開發(fā)<b class='flag-5'>詳解</b>》第8章、<b class='flag-5'>Linux</b>設(shè)備<b class='flag-5'>驅(qū)動</b><b class='flag-5'>中</b>的阻塞與非阻塞IO

    Linux設(shè)備驅(qū)動開發(fā)詳解》第7章、Linux設(shè)備驅(qū)動的并發(fā)控制

    Linux設(shè)備驅(qū)動開發(fā)詳解》第7章、Linux設(shè)備驅(qū)動的并發(fā)控制
    發(fā)表于 10-27 11:37 ?10次下載
    《<b class='flag-5'>Linux</b>設(shè)備<b class='flag-5'>驅(qū)動</b>開發(fā)<b class='flag-5'>詳解</b>》第7章、<b class='flag-5'>Linux</b>設(shè)備<b class='flag-5'>驅(qū)動</b><b class='flag-5'>中</b>的并發(fā)控制

    Linux設(shè)備驅(qū)動開發(fā)詳解》第5章、Linux文件系統(tǒng)與設(shè)備文件系統(tǒng)

    Linux設(shè)備驅(qū)動開發(fā)詳解》第5章、Linux文件系統(tǒng)與設(shè)備文件系統(tǒng)
    發(fā)表于 10-27 14:13 ?0次下載
    《<b class='flag-5'>Linux</b>設(shè)備<b class='flag-5'>驅(qū)動</b>開發(fā)<b class='flag-5'>詳解</b>》第5章、<b class='flag-5'>Linux</b>文件<b class='flag-5'>系統(tǒng)</b>與設(shè)備文件<b class='flag-5'>系統(tǒng)</b>

    如何編寫Linux 下Nand Flash驅(qū)動

    如何編寫Linux 下Nand Flash驅(qū)動
    發(fā)表于 10-30 08:36 ?15次下載
    如何<b class='flag-5'>編寫</b><b class='flag-5'>Linux</b> 下Nand Flash<b class='flag-5'>驅(qū)動</b>

    Linux系統(tǒng)網(wǎng)絡(luò)驅(qū)動程序的編寫

    驅(qū)動程序編寫 一.Linux系統(tǒng)設(shè)備驅(qū)動程序概述 1.1 Linux設(shè)備
    發(fā)表于 11-07 10:40 ?0次下載

    Linux驅(qū)動開發(fā)-編寫按鍵驅(qū)動

    這篇文章介紹,如何使用雜項設(shè)備框架編寫一個簡單的按鍵驅(qū)動,完成編寫、編譯、安裝、測試等流程,了解一個雜項字符設(shè)備驅(qū)動的開發(fā)流程。
    的頭像 發(fā)表于 09-17 15:08 ?1658次閱讀
    <b class='flag-5'>Linux</b><b class='flag-5'>驅(qū)動</b>開發(fā)-<b class='flag-5'>編寫</b><b class='flag-5'>按鍵</b><b class='flag-5'>驅(qū)動</b>

    Linux設(shè)備驅(qū)動開發(fā)詳解

    Linux設(shè)備驅(qū)動開發(fā)詳解
    發(fā)表于 10-28 11:03 ?50次下載
    主站蜘蛛池模板: 天堂8资源在线官网资源| 欧美成人福利| 午夜爽视频| 精品久草| 天天射天| 97av在线播放| 狠狠色丁香六月色| 欧美在线视| 性欧美高清| 女bbbbxxxx视频| 在线播放国产不卡免费视频| 黄色性生活毛片| 欧美激欧美啪啪片免费看| 男人的天堂在线精品视频| 色多多视频在线观看| 新版天堂中文网| 黄网站免费视频| 天天躁狠狠躁夜躁2021| 老师下面很湿很爽很紧| 日本视频不卡| 亚洲一区二区福利视频| 欧美激情αv一区二区三区| 国产午夜免费一区二区三区| 日本jlzz| 欧美超级碰碰| 亚洲毛片儿| 啪啪91视频| 日韩亚洲人成在线综合日本| 亚洲一区不卡视频| 亚洲综合情| 亚洲五月激情综合图片区| 亚洲最大的黄色网址| 四虎永久地址4hu紧急入口| 天天久久影视色香综合网| 亚洲精品成人久久久影院| 午夜宅男在线视频| 男女爱爱视频免费看| 爱爱网站免费| 午夜影视在线观看| 天天操天天看| 狠狠操夜夜爱|