<strike id="kiyse"></strike>
  • <tr id="kiyse"></tr>
  • <strike id="kiyse"></strike><samp id="kiyse"><tbody id="kiyse"></tbody></samp>
    <strike id="kiyse"><s id="kiyse"></s></strike>
    <tr id="kiyse"></tr>
    <noframes id="kiyse"><code id="kiyse"></code></noframes>
    <th id="kiyse"></th>
    <samp id="kiyse"></samp>
  • <th id="kiyse"><s id="kiyse"></s></th>
  • 精簡ISA總線Linux編程 – Part3

     2019-3-22     作者:Emtronix         

      精簡ISA總線接口是一種8-bit寬度的雙向并行擴展總線,其特點是地址數據分時復用8位總線,加上4條總線控制信號,即可實現對外部數據的快速讀寫。若再使能一條總線時鐘信號(共13條信號),就可實現高達10MB/s以上的數據傳輸。精簡ISA總線作為英創主板的特色功能之一,在ESM6802、ESM7000、ESM7100、ESM335x等多款型號中均有配置。


      關于對精簡ISA總線接口的應用編程的基本方法,請參考《精簡ISA總線編程– Part 1》;應用程序直接啟動DMA做定長數據的傳送方法,請參考《精簡ISA總線編程– Part 2》。本文介紹由外部硬件觸發DMA傳送,應用程序通過ISA驅動(/dev/em_isa)讀取采集數據的方法。


    硬件DMA的基本工作原理


      下圖是基于硬件DMA實現高速數據采集功能的系統框圖:


    精簡ISA總線編程– Part3-1.png


      ● 應用程序通過常規的異步ISA讀寫操作,對AD采集單元進行必要配置。

      ● 通過特殊的isa_write_buf(..)操作啟動硬件DMA。

      ● 當AD采集單元轉換數據準備好,發出DMA請求信號(DMAREQ置高,脈沖寬度400ns – 1000ns)。

      ● DMA控制器感受到DMAREQ信號,連續產生4個同步總線周期,讀取AD單元內已準備好的數據,每個同步周期讀取2個字節,共讀取8個字節。從DMAREQ請求開始,到DMA數據傳輸完畢,整個過程大約1840ns。之后DMA將等待一下一個DMAREQ脈沖信號。

      ● DMA讀取的數據將自動存入驅動程序內部的環形Buffer中,當DMA讀取的數據達到一定閾值(4KB)時,驅動將通過事件觸發應用程序讀取整塊數據。


      由于AD單元中的數據是通過DMA硬件存入系統緩沖區的,由此產生的CPU開銷就很低。應用程序可在數據采集的同時,完成必要的數據處理、顯示、通訊等功能塊。另一方面,由于AD采集單元不再需要保存轉換的數據,可有效降低硬件成本。


      實現基于硬件DMA的數據采集,需要以下信號:


    ESM7000信號管腳實際信號功能

    ISA_AD0

    ISA地址數據總線,LSB
    ISA_AD1ISA地址數據總線

    ISA_AD2

    ISA地址數據總線
    ISA_AD3ISA地址數據總線

    ISA_AD4

    ISA地址數據總線
    ISA_AD5ISA地址數據總線

    ISA_AD6

    ISA地址數據總線
    ISA_AD7ISA地址數據總線,MSB

    ISA_CSn

    ISA片選控制信號CS,低電平有效
    GPIO24ISA同步總線周期時鐘BCLK

    ISA_ADVn

    ISA地址鎖存控制信號ADV,低電平有效
    ISA_RDnISA數據讀控制信號RD,低電平有效

    ISA_WEn

    ISA數據寫控制信號WE,低電平有效
    GPIO12DMA請求信號DMAREQ,輸入,高電平有效


      注意:在使用硬件DMA數據傳輸時,將禁止使用掛角GPIO12和GPIO24的GPIO功能、禁止使用CAN2端口。


    DMA傳輸總線時序說明


      圖1是一次完整的DMA傳輸總體時序圖。


    dma-ext-read-bl4-sync-1.png


    精簡ISA總線編程– Part3.png

    圖1 硬件DMA傳輸總線時序


      從上面的時序可見,DMAREQ請求開始,到第一個總線周期,大約有640ns的延時。整個傳輸周期大約1840ns。按2000ns計算,采用硬件DMA傳輸,可實現每秒4MB字節的數據傳輸率。若假設4路模擬通道,每個樣點16-bit量化,這樣就對應每通道500ksps的采樣率。這樣的采樣率可滿足絕大部分的工控應用需求。展開圖1觀察,可見:


    dma-ext-read-bl4-sync-2.png

    圖2 硬件觸發DMA傳輸時序前半部分


    dma-ext-read-bl4-sync-3.png

    圖3 硬件觸發DMA傳輸時序后半部分


      從上面的時序圖可見,有DMA啟動的總線周期,每個周期只有6個BCLK脈沖,讀取2個數據字節。這與在《精簡ISA總線編程– Part 2》中介紹的CPU啟動的DMA操作不同。在使用時需特別注意。DMAREQ的脈沖寬度有一定要求:DMAREQ脈沖寬度應大于240ns,才能保證可靠觸發DMA,其次DMAREQ應在DMA傳輸周期結束前變低,否則可能誤觸發下一次DMA傳輸。


      每個總線周期詳細的時序關系如下:


    dma-ext-read-sync.png

    圖4 硬件觸發DMA總線周期時序


    精簡ISA總線編程– Part3-2.png

    圖5 硬件觸發DMA總線周期時序參數標注


      為了簡化AD采集單元的電路設計,硬件觸發DMA傳輸總線周期輸出的地址固定在0xE0。AD采集單元的其他寄存器應避免使用0xE0 – 0xE1這兩個地址。


    應用程序設計要點


      應用程序啟動DMA數據傳輸,需要使用數據結構struct isa_transfer的傳遞參數和數據,struct isa_transfer的結構定義如下:


    structisa_transfer
    {
           void              *rx_buf;                /* != NULL: buffer for bus read */
           void              *tx_buf;                /* != NULL: buffer for bus write */
           unsigned     len;                      /* buffer length in byte */
           unsigned     offset;                  /* offset,port address on isa bus */
           unsigned     inc;                      /* = 0: fixed offset, = 1: offset+1 after r/w */
    };


      啟動硬件觸發DMA傳輸,需要特殊的寫操作,代碼如下:


    structisa_transfer      t;
     
    // start ext-trigger dma
    memset(&t, 0, sizeof(structisa_transfer));
    t.offset = 0x50E0;
    t.len = 0xFFFFFFFF;           
    isa_write_buf(fd, &t);


      注意在上述代碼中t.rx_buf和t.tx_buf均必須為空。停止硬件觸發DMA傳輸的代碼為:


    structisa_transfer      t;
     
    // stopext-trigger dma
    memset(&t, 0, sizeof(structisa_transfer));
    t.offset = 0x50E0;
    t.len = 0;
    isa_write_buf(fd, &t);


      在啟動DMA后,應用程序的數據接收線程需調用poll等待數據ready的消息:


    structpollfdfds[1];
     
    fds[0].fd = fd;
    fds[0].events = POLLPRI;
     
    // wait data ready with timeout 2 seconds
    if(poll(fds, 1, 2) == -1) {
    perror("poll failed!\n");
    goto error;
        }
    // data is ready….


      讀取數據的代碼為:


    intrc, total_bytes;
    structisa_transfer      t;
    externunsignedchargbuf[64 * 1024];
     
    total_bytes = 0;
    memset(&t, 0, sizeof(structisa_transfer));
    // read data
    t.rx_buf = gbuf;
    t.offset = offset;
    t.len = sizeof(gbuf);
    rc = read(fd, &t, sizeof(structisa_transfer));
    if(rc< 0) {
           printf("%s dma data read failed %d\n", __func__, rc);
    }
    elseif(rc> 0) {
           total_bytes += rc;
           printf("%s dma data read %d\n", __func__, total_bytes);
    }


      有興趣的客戶可與英創公司技術聯系,索取完整的測試代碼源碼。技術支持郵箱:support@www.jsjflaw.com

    少妇人妻偷人精品无码视频新浪| 精品一区二区三区电影| 熟女人妻少妇精品视频| 国产精品美女午夜爽爽爽免费| 国产成人精品一区二区秒拍| 国产精品美女一区二区| 精品无码久久久久久午夜| 国产成人精品久久综合 | 竹菊影视国产精品| 国产偷伦精品视频| 国产精品99亚发布| 日韩精品专区AV无码| 久久国产精品一区| 国产精品免费_区二区三区观看 | 十八禁无遮挡99精品国产| 久久99精品久久| 久久噜噜久久久精品66| 国产精品线在线精品| 久久精品国产乱子伦| 麻豆精品久久精品色综合| 亚洲欧洲自拍拍偷精品 美利坚| 日韩精品成人无码专区免费| 久久精品无码专区免费青青 | 国产午夜精品一区二区三区极品| 99热精品国产麻豆| 秋霞久久国产精品电影院| 精品乱码久久久久久夜夜嗨| 国产精品亚洲综合一区在线观看| 好吊妞视频这里有精品| 中文精品久久久久国产网址| 久久精品94精品久久精品| 日韩精品无码视频一区二区蜜桃 | 1717国产精品久久| 日韩精品久久久久久免费| 成品人和精品人的区别在哪里| 国产亚洲蜜芽精品久久| 四虎精品在线视频| 国产人妻777人伦精品hd| 精品丝袜国产自在线拍亚洲| 久久亚洲私人国产精品vA | 精品日韩99亚洲的在线发布|