ISA總線簡介
英創(chuàng)精簡ISA總線接口是一種8-bit寬度的雙向并行擴(kuò)展總線,其特點(diǎn)是地址數(shù)據(jù)分時復(fù)用8-bit總線。英創(chuàng)精簡ISA總線支持異步和同步訪問模式,異步訪問模式下ISA總線使用8條數(shù)據(jù)線加上4條總線控制信號,即可實(shí)現(xiàn)對外部數(shù)據(jù)的快速讀寫,異步訪問的最高速率在5MB/s左右。同步訪問需要再使能一條總線時鐘信號(共13條信號),可實(shí)現(xiàn)高達(dá)12MB/s的數(shù)據(jù)傳輸。精簡ISA總線作為英創(chuàng)主板的特色功能之一,在ESM6802、ESM7000、ESM335x等多款型號中均有配置。英創(chuàng)精簡ISA總線的信號定義如下:
| 主板引腳 | 信號及說明 |
| E2 | ISA_D0,地址數(shù)據(jù)總線,LSB |
| E3 | ISA_D1,地址數(shù)據(jù)總線 |
| E4 | ISA_D2,地址數(shù)據(jù)總線 |
| E5 | ISA_D3,地址數(shù)據(jù)總線 |
| E6 | ISA_D4,地址數(shù)據(jù)總線 |
| E7 | ISA_D5,地址數(shù)據(jù)總線 |
| E8 | ISA_D6,地址數(shù)據(jù)總線 |
| E9 | ISA_D7,地址數(shù)據(jù)總線 |
| E10 | ISA_RDn,數(shù)據(jù)讀控制信號 |
| E11 | ISA_WEn,數(shù)據(jù)寫控制信號 |
| E12 | ISA_ADVn,地址鎖存控制信號 |
| E13 | ISA_CSn,片選信號 |
| F9 | GPIO24 / ISA_BCLK,同步時鐘ISA_BCLK |
ISA總線數(shù)據(jù)結(jié)構(gòu)
ISA總線的數(shù)據(jù)傳輸由ISA_BLOCK_INFO數(shù)據(jù)結(jié)構(gòu)定義,其說明如下:
|
typedef struct { PBYTE pReadBuf; PBYTE pWriteBuf; DWORD dwDataLength; DWORD dwDataPortOfs; DWORD dwInc; } ISA_BLOCK_INFO, *PISA_BLOCK_INFO; |
成員說明
pReadBuf
ISA總線讀數(shù)據(jù)緩存,!=NULL表示為ISA總線讀操作,pReadBuf與pWriteBuf指針不能同時有效
pWriteBuf
ISA總線寫數(shù)據(jù)緩存, !=NULL表示為ISA總線寫操作,pReadBuf與pWriteBuf指針不能同時有效
dwDataLength
讀/寫訪問的字節(jié)長度
dwDataPortOfs
ISA端口地址。ISA總線驅(qū)動程序支持應(yīng)用程序使用不同的地址范圍來區(qū)別不同的操作模式,根據(jù)ISA端口地址可實(shí)現(xiàn)以下幾種總線訪問模式。
| Value | ISA總線訪問模式 |
| 0x0000...0x00FF | 異步總線周期,CPU操作 |
| 0x1000...0x10FF | 異步總線周期,DMA方式傳輸,dwInc需要同時設(shè)置為0 |
| 0x4000...0x40FF | 同步總線周期,DMA方式傳輸,dwInc需要同時設(shè)置為0 |
由于精簡ISA總線的寬度只有8-bit,因此它實(shí)際的物理尋址范圍也只有8-bit,即0x00-0xFF。
dwInc
每次ISA讀寫后地址是否增加
| Value | Meaning |
| 0 | 固定地址 |
| 1 | 讀/寫后地址自動加1 |
備注:
ISA總線的CPU操作方式主要用于小量數(shù)據(jù)的傳輸,比如控制命令、配置數(shù)據(jù)讀寫等。
DMA方式傳輸可在較低CPU開銷的情況下實(shí)現(xiàn)大批量數(shù)據(jù)的高速傳輸,DMA方式傳輸要求傳輸?shù)臄?shù)據(jù)長度dwDataLength為32的整倍數(shù)、同時需要將dwInc設(shè)置為0,否則驅(qū)動程序會使用CPU方式進(jìn)行數(shù)據(jù)傳輸。DMA傳輸方式需要連接在ISA總線的上CPLD/FPGA使用固定的數(shù)據(jù)端口地址,在CPLD/FPGA內(nèi)部自己管理地址偏移。
ESM335x工控主板只支持異步訪問模式,在異步DMA方式傳輸時,需要將dwInc設(shè)置為0來固定數(shù)據(jù)端口地址。
ESM6802/ESM7000支持異步和同步DMA訪問模式,但由于SDMA(NXP Smart DMA)的原因,即使將dwInc設(shè)置為0,在進(jìn)行DMA數(shù)據(jù)傳輸時也無法固定端口地址,因此CPLD/FPGA需要通過額外的方法來識別當(dāng)前為DMA傳輸。ESM6802/ESM7000在進(jìn)行異步DMA訪問時,可通過1位GPIO來向外表明當(dāng)前為異步DMA訪問模式,也可通過CPU操作方式向指定地址寫入特定命令,讓CPLD/FPGA切換到異步DMA傳輸模式。在進(jìn)行同步DMA訪問時,可結(jié)合ISA_BCLK信號來識別當(dāng)前的傳輸模式。為了避免混淆,在實(shí)際應(yīng)用時建議僅使用一種DMA(同步或異步)訪問模式,推薦使用同步DMA訪問模式以獲得最高的ISA總線速度。
ISA總線速度測試
在ISA_BLOCK_INFO結(jié)構(gòu)體中定義了異步CPU訪問,異步DMA和同步DMA三種ISA總線訪問方式,而異步CPU訪問又可通過驅(qū)動API函數(shù)和內(nèi)存映射兩種方式來實(shí)現(xiàn)。
驅(qū)動API訪問是指應(yīng)用程序直接調(diào)用設(shè)備驅(qū)動API函數(shù)WriteFil/ReadFile進(jìn)行字/字節(jié)的總線讀寫。ISA總線周期通常在200ns左右,而應(yīng)用程序調(diào)用一次設(shè)備驅(qū)動程序API花費(fèi)的時間卻需要數(shù)微秒的時間,這顯然大大降低了總線單字(或單字節(jié))的訪問效率。為了解決這一問題,我們利用了WinCE的虛擬地址映射技術(shù),在ISA驅(qū)動程序中實(shí)現(xiàn)了,在使用ISA總線的應(yīng)用進(jìn)程地址空間內(nèi)分配一段虛擬地址空間,并將其與ISA接口的物理地址空間進(jìn)行綁定。簡單來講就是實(shí)現(xiàn)了在WinCE應(yīng)用程序中可以直接訪問ISA總線的外設(shè)地址空間,即內(nèi)存映射訪問方式。
下圖是ESM3354、ESM7000和ESM6802,ISA總線在各種訪問模式下的總線速度。

圖1ESM335x / ESM7000 / ESM6802 ISA總線速度
下圖是ESM7000 ISA總線在不同訪問模式下,總線速度與CPU使用情況的對比??梢钥吹絻?nèi)存映射方式訪問(異步CPU操作)與異步DMA訪問在總線速度上很接近,但使用DMA傳輸可大大降低對CPU的開銷。因此對于頻繁的字或字節(jié)訪問可以使用內(nèi)存映射方式訪問,而對于成批量數(shù)據(jù)的讀寫應(yīng)該使用DMA方式進(jìn)行傳輸。

圖2ESM7000 ISA總線在不同訪問方式下總線速度與CPU占用率
ISA總線訪問API
對ISA總線的所有訪問方法都包含在isa_api_v3.cpp文件中,如下所示:
|
#include "StdAfx.h" #include "bsp_drivers.h" #include #include "isa_api_v3.h" DWORD g_dwISABase = 0; HANDLE ISA_Open( LPCWSTR lpDevName ) { HANDLE hISA; hISA = CreateFile(lpDevName, // name of device GENERIC_READ|GENERIC_WRITE, // desired access FILE_SHARE_READ|FILE_SHARE_WRITE, // sharing mode NULL, // security attributes (ignored) OPEN_EXISTING, // creation disposition FILE_FLAG_RANDOM_ACCESS, // flags/attributes NULL); if(hISA != INVALID_HANDLE_VALUE) { if(DeviceIoControl(hISA, //打開“ISA1:”返回的Handler IOCTL_VIRTUAL_COPY_EX, // IOCTL命令碼 NULL,0, // 不使用輸入?yún)?shù) &g_dwISABase, sizeof(DWORD), // 得到ISA基地址 NULL, NULL)) return hISA; CloseHandle(hISA); hISA = INVALID_HANDLE_VALUE; } return hISA; } BOOL ISA_Close( HANDLE hISA) { g_dwISABase = 0; return CloseHandle( hISA ); } // Function: read a byte from a port on ISA bus // Input: hISA: the HANDLE returned from ISA_Open function // dwPortOffset = 0, 1, .. 255, address of port on ISA // Return: the byte data read BYTE ISARead8(HANDLE hISA, DWORD dwPortOffset) { WORD *pPortAddr; WORD wValue; BYTE ucValue; DWORD dwNbBytesRead = 0; if(g_dwISABase != 0) { dwPortOffset &= 0xff; dwPortOffset <<= 1;?????????????? // D[0..7] <=> A[1..8] in AD-muxed mode pPortAddr = (WORD*)(g_dwISABase + dwPortOffset); wValue = *pPortAddr; return (BYTE)wValue; } ucValue = (BYTE)(dwPortOffset & 0xFF); ReadFile(hISA, &ucValue, sizeof(ucValue), &dwNbBytesRead, NULL); return ucValue; } // Function: write a byte to a port on ISA bus // Input: hISA: the HANDLE returned from ISA_Open function // dwPortOffset = 0, 1, .. 255, address of port on ISA // ucValue = the byte data to be written void ISAWrite8(HANDLE hISA, DWORD dwPortOffset, BYTE ucValue) { WORD *pPortAddr; WORD wValue; DWORD dwNbBytesWritten = 0; if(g_dwISABase != 0) { dwPortOffset &= 0xff; dwPortOffset <<= 1;?????????????? // D[0..7] <=> A[1..8] in AD-muxed mode pPortAddr = (WORD*)(g_dwISABase + dwPortOffset); *pPortAddr = (WORD)ucValue; return; } wValue = (WORD)(dwPortOffset & 0xFF); wValue = (wValue << 8) | ucValue; WriteFile(hISA, &wValue, sizeof(wValue), &dwNbBytesWritten, NULL); } // Function: read a word from a port on ISA bus // Input: hISA: the HANDLE returned from ISA_Open function // dwPortOffset = 0, 2, 4, .. 254, address of port on ISA // Return: the word data read WORD ISARead16(HANDLE hISA, DWORD dwPortOffset) { DWORD *pPortAddr; DWORD dwValue; WORD wValue; DWORD dwNbBytesRead = 0; if(g_dwISABase != 0) { dwPortOffset &= 0xFE; // 2-byte alignment dwPortOffset <<= 1;?????????????? // D[0..7] <=> A[1..8] in AD-muxed mode pPortAddr = (DWORD*)(g_dwISABase + dwPortOffset); dwValue = *pPortAddr; // the high-byte of data is at value[23..16] return (WORD)(((dwValue >> 8) & 0xFF00) | (dwValue & 0xFF)); } wValue = (WORD)(dwPortOffset & 0xFE); ReadFile(hISA, &wValue, sizeof(wValue), &dwNbBytesRead, NULL); return wValue; } // Function: write a word to a port on ISA bus // Input: hISA: the HANDLE returned from ISA_Open function // dwPortOffset = 0, 2, 4, .. 254, address of port on ISA // wValue = the word data to be written void ISAWrite16(HANDLE hISA, DWORD dwPortOffset, WORD wValue) { DWORD *pPortAddr; DWORD dwValue; DWORD dwNbBytesWritten = 0; if(g_dwISABase != 0) { dwPortOffset &= 0xFE; // 2-byte alignment dwPortOffset <<= 1;?????????????? // D[0..7] <=> A[1..8] in AD-muxed mode pPortAddr = (DWORD*)(g_dwISABase + dwPortOffset); dwValue = wValue; // dispatch high-byte of data to value[23..16] *pPortAddr = ((dwValue << 8) & 0x00ff0000) | (dwValue & 0x000000ff); return; } dwValue = (dwPortOffset << 16) | wValue; WriteFile(hISA, &dwValue, sizeof(dwValue), &dwNbBytesWritten, NULL); } // Function: read a bulk data from a port on ISA bus // Input: hISA: the HANDLE returned from ISA_Open function // *tp: a pointer to the ISA_BLOCK_INFO structure // Return: number of bytes read DWORD ISAReadBuf(HANDLE hISA, PISA_BLOCK_INFO tp) { DWORD dwNbBytesRead = 0; if(ReadFile(hISA, tp, sizeof(ISA_BLOCK_INFO), &dwNbBytesRead, NULL)) return dwNbBytesRead; return 0; } // Function: read a bulk data from a port on ISA bus // Input: hISA: the HANDLE returned from ISA_Open function // *tp: a pointer to the ISA_BLOCK_INFO structure // Return: the number of bytes written DWORD ISAWriteBuf(HANDLE hISA, PISA_BLOCK_INFO tp) { DWORD dwNbBytesWritten = 0; if(WriteFile(hISA, tp, sizeof(ISA_BLOCK_INFO), &dwNbBytesWritten, NULL)) return dwNbBytesWritten; return 0; } |
注意,當(dāng)采用內(nèi)存映射方式訪問時,若在多個線程中均有調(diào)用字或字節(jié)讀寫函數(shù)(ISAWrite8, ISAWrite16, ISARead8, ISARead126),需要加互斥鎖,以保證對硬件資源操作的完整性。通過驅(qū)動API調(diào)用的讀寫函數(shù),在驅(qū)動內(nèi)部已經(jīng)增加了互斥操作,應(yīng)用程序不需要再次添加。
ISA異步總線周期讀時序

ISA異步總線周期寫時序

ISA同步總線周期讀時序

ISA擴(kuò)展單元可根據(jù)上述時序來支持高速的同步總線周期讀邏輯電路,其要點(diǎn)包括:
●每個同步周期共12個BCLK時鐘,第1個BCLK下降沿ADVn有效,標(biāo)志同步周期的開始,之后連續(xù)11個BCLK下降沿后同步周期結(jié)束。
●每個同步周期傳輸8個字節(jié)有效數(shù)據(jù),ISA總線從BCLK第5個上升沿開始鎖存數(shù)據(jù),連續(xù)讀8個字節(jié)。
●ISA總線雖然輸出了ADDR地址數(shù)據(jù),但這個地址是不固定的,ISA擴(kuò)展單元應(yīng)該忽略此地址數(shù)據(jù)。
ISA同步總線周期寫時序

ISA擴(kuò)展單元可根據(jù)上述時序來支持高速的同步總線周期寫邏輯電路,其要點(diǎn)包括:
●每個同步周期共12個BCLK時鐘,第1個BCLK下降沿ADVn有效,標(biāo)志同步周期的開始,之后連續(xù)11個BCLK下降沿后同步周期結(jié)束。
●每個同步周期傳輸8個字節(jié)有效數(shù)據(jù),ISA擴(kuò)展單元應(yīng)從BCLK第5個上升沿開始鎖存數(shù)據(jù),連續(xù)8個字節(jié)。
●ISA總線雖然輸出了ADDR地址數(shù)據(jù),但這個地址是不固定的,ISA擴(kuò)展單元應(yīng)該忽略此地址數(shù)據(jù)。
-
嵌入式主板
+關(guān)注
關(guān)注
7文章
6107瀏覽量
36920
發(fā)布評論請先 登錄
龍芯中科助力2025教育信息技術(shù)應(yīng)用創(chuàng)新大賽成功舉辦
誠邁科技信創(chuàng)電腦助力2025第二屆教育信息技術(shù)應(yīng)用創(chuàng)新大賽圓滿收官
寶馬南京信息技術(shù)有限公司開業(yè)
易華錄入選國家級信息技術(shù)應(yīng)用創(chuàng)新典型解決方案
“信息技術(shù)應(yīng)用產(chǎn)學(xué)協(xié)同人才培養(yǎng)行動計(jì)劃”正式發(fā)布,誠邁科技入選首批參與單位
佛瑞亞如何通過信息技術(shù)推動業(yè)務(wù)增長
飛騰主板為信創(chuàng)產(chǎn)業(yè)發(fā)展提高硬實(shí)力
DEKRA德凱成為沙特通信和信息技術(shù)設(shè)備技術(shù)法規(guī)認(rèn)證機(jī)構(gòu)
科普|信創(chuàng)是什么?一文讀懂“信息技術(shù)應(yīng)用創(chuàng)新”戰(zhàn)略

英創(chuàng)信息技術(shù)精簡ISA總線WinCE編程簡介
評論