激情综合丁香-激情综合六月-激情综合婷婷亚洲图片-激情综合图区-激情综合网五月

精簡ISA總線Linux編程 – Part2

 2019-3-20     作者:Emtronix         

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


  關于對精簡ISA總線接口的應用編程的基本方法,請參考《精簡ISA總線編程 – Part 1》。本文介紹由應用程序啟動基于DMA的數據塊讀寫,即MemCpy方式的DMA。采用DMA進行ISA總線數據傳送的目的,是為了降低高速傳送大量數據時的CPU開銷。MemCpy方式的DMA是指軟件線程啟動DMA,然后該線程掛起等待DMA操作完成。在多線程環境中,其他線程即可在DMA執行過程中得以并行運行。


  ISA總線信號定義如下:


信號及說明PIN#信號及說明
RESET_B,硬件復位12ISA_ADVn,地址鎖存控制信號
ISA_AD0,地址數據總線,LSB34ISA_AD4,地址數據總線
ISA_AD1,地址數據總線56ISA_AD5,地址數據總線
ISA_AD2,地址數據總線78ISA_AD6,地址數據總線
ISA_AD3,地址數據總線910ISA_AD7,地址數據總線,MSB
MSLn,支持多模塊掛接總線1112ISA_WEn,數據寫控制信號
GPIO9,可選作為IRQ1314ISA_RDn,數據讀控制信號
GPIO8,可選作為IRQ1516ISA_CSn,片選控制信號
GPIO25,可選作為IRQ1718VDD_5V0,+5V供電
GPIO24 / ISA_BCLK,同步時鐘ISA_BCLK1920GND,電源信號地


  本文以下部分,將以ESM7000 Linux平臺為例,介紹具體的編程方法。


DMA總線訪問API


  應用啟動DMA數據傳輸,需要使用數據結構struct isa_transfer的傳遞參數和數據,structisa_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 */
};


  每一個總線周期的操作只能是讀或寫,因此在isa_transfer結構中只能有一個buffer指針不為NULL。以下是執行32字節數據塊寫的代碼,寫入地址為0x4040。順序的數據可方便時序的觀察。


unsignedchargbuf[64 * 1024];
unsignedint i, value;
structisa_transfer      t;
unsignedchar   *pBuf8;
 
// write data block
memset(&t, 0, sizeof(structisa_transfer));
t.offset = 0x4040;
t.len = 32;            // max len<= 16KB = 16 * 1024
t.tx_buf = gbuf;
// fill data
value = 0x55;             // initialvalue
pBuf8 = (unsignedchar*)t.tx_buf;
for(i = 0; i<t.len; i++){
       *pBuf8 = (unsignedchar)(value + i);
       pBuf8++;
}
isa_write_buf(fd, &t);


  注意offset必須是0x4000 – 0x40FF,驅動程序才會啟動MemCpy方式的DMA傳輸。若從0x4040讀入32字節數據,實現代碼則為:


unsignedchargbuf[64 * 1024];
structisa_transfer      t;
 
// read data block
memset(&t, 0, sizeof(structisa_transfer));
t.offset = 0x4040;
t.len = 32;                   // max len<= 16KB = 16 * 1024
t.rx_buf = gbuf;
isa_read_buf(fd, &t);


DMA傳輸總線時序說明


  圖1、圖2分別為MemCpy方式DMA讀總線時序概要、寫總線時序概要。


isa_read_buf-dma-1.png

圖1 DMA讀總線時序


isa_write_buf-dma-1.png

圖2 DMA寫總線時序


  從上面的時序可見,DMA也是16字節一組,連續4個總線周期組成,每組之間有一定間隔。DMA讀操作的總線速率大約為11.8MB/s,DMA寫操作的總線速率大約為11.2MB/s。


  展開DMA寫的總線時序可看到:


isa_write_buf-dma-2.png

圖3 DMA寫總線時序—第1組起始部分


 isa_write_buf-dma-3.png

圖4 DMA寫總線時序—第1組結束部分


 isa_write_buf-dma-4.png

圖5 DMA寫總線時序—第2組起始部分


isa_write_buf-dma-5.png

圖6 DMA寫總線時序—第2組結束部分


  在每個總線周期中,地址遞增4。這樣當傳輸長度超過256字節時,ISA地址及會循環。這意味著當采用MemCpy方式DMA進行數據傳輸時,數據端口譯碼不能采用普通的組合電路地址譯碼方式,而必須采用BCLK+ ADV#的同步電路譯碼方式。具體方式就是每個周期的第一個BCLK下降沿鎖存到有效ADV#,標志同步周期的開始,之后經過連續7個BCLK下降沿后同步周期結束。


DMA傳輸時的CPU負載率


  與純軟件的同步總線周期傳輸相比,DMA傳輸最大的優點是有效降低了總線傳輸的CPU開銷,使應用程序的其它線程能同步運行。基本的測試代碼如下:


#define MAX_DMA_LEN         (16*1024)
unsignedchar gbuf[64 * 1024];
 
unsignedint i, count = 1;
struct isa_transfer     t;
unsignedchar   *pBuf8;
longdouble a[4], b[4], loadavg;    //for CPU utilization calculation
FILE *fp;
constchar *bus_type_name[] = {"async-cpu","async-dma-mem","async-dma-ext", "sync-cpu","sync-dma-mem","sync-dma-ext"};
 
// fill data
pBuf8 = (unsignedchar*)gbuf;
for(i = 0; i < MAX_DMA_LEN; i++){
       *pBuf8 = (unsignedchar)(value + i);
       pBuf8++;
}
memset(&t, 0, sizeof(struct isa_transfer));
 
// get initial values for calculating CPU usage in %
fp = fopen("/proc/stat","r");
fscanf(fp,"%*s %Lf %Lf %Lf %Lf",&a[0],&a[1],&a[2],&a[3]);
fclose(fp);
 
// write data block loop
while(count) {
       i = (count < MAX_DMA_LEN)? count : MAX_DMA_LEN;
       t.offset = offset;
       t.len = i;
       t.tx_buf = gbuf;
       isa_write_buf(fd, &t);
       count -= i;
}
 
// get end values for calculating CPU usage in %
fp = fopen("/proc/stat","r");
fscanf(fp,"%*s %Lf %Lf %Lf %Lf",&b[0],&b[1],&b[2],&b[3]);
fclose(fp);
 
// calculate CPU usage in %
loadavg = ((b[0]+b[1]+b[2]) - (a[0]+a[1]+a[2])) / ((b[0]+b[1]+b[2]+b[3]) - (a[0]+a[1]+a[2]+a[3]));
loadavg *= 100;
i = (offset >> 12) & 0xf;
printf("%s bus write, CPU utilization is : %Lf%%\n",bus_type_name[i], loadavg);


  使用100M數據長度來測試總的CPU負載率的情況如下:


模式MemCpy DMA純軟件操作
同步總線讀6.01%50.3%
同步總線寫5.71%50.0%


  ESM7000使用的是具有雙核CPU的iMX7D,總CPU負載率50%,表示某個CPU核的負載已經100%。DMA的使用對提高系統整體的性能是非常顯著的。


  進一步可測試應用層實際的傳輸速率如下:


模式傳輸速率CPU負載
MemCpy DMA同步總線讀8.67MB/s6.01%
MemCpy DMA同步總線寫7.93MB/s5.71%


  若把每個周期傳輸的字節數從4個提升到8個,傳輸率則可有50%的提升。


  以上是對精簡ISA總線基本讀寫的介紹,有興趣的客戶可與英創公司技術聯系,索取完整的測試代碼源碼。技術支持郵箱:support@emtronix.com

主站蜘蛛池模板: 高清毛片aaaaaaaaa片| 国产99久久精品| 丁香六月婷婷| 欧美日韩在线视频| 污黄视频在线观看| 国产免费一级高清淫曰本片| jizz国产精品免费麻豆| 久久亚洲天堂| 五月天六月婷婷开心激情| 91网站免费看| 亚洲精品日本一区二区在线| 草草影视在线观看| 91在线 | 欧美| 国产免费大片| 妞干网手机免费视频| 一级特黄aaa大片在线观看| 手机看片1024久久| 在线观看视频黄| 国产成人精品亚洲| 经典香港一级a毛片免费看| 88福利视频| 岛国精品在线| 国产日韩一区二区三区在线播放 | 国产尤物在线观看| 和日本免费不卡在线v| 精品中文字幕制服中文| 国产成人精品男人的天堂网站| 精品精品久久宅男的天堂| 欧美另类69xxxxx免费| 1024国产基地永久免费| 一级做a爱过程免费视频时看| 日本久久黄色| 日韩一区二区三区在线| 午夜精品在线| 亚洲成a人片在线网站| 在线成人天天鲁夜啪视频| 成年女人色费视频免费| 免费a级毛片无码| 男女在线观看啪网站| 欧美一级高清在线观看| 欧美在线乱妇一级毛片|