<dfn id="is4kg"></dfn>
  • <ul id="is4kg"></ul>
  • <abbr id="is4kg"></abbr>
  • <ul id="is4kg"></ul>
    <bdo id="is4kg"></bdo>
    以文本方式查看主題

    -  曙海教育集團論壇  (http://www.hufushizhe.com/bbs/index.asp)
    --  WinCE應(yīng)用開發(fā)  (http://www.hufushizhe.com/bbs/list.asp?boardid=35)
    ----  WINCE驅(qū)動開發(fā)之DMA的使用  (http://www.hufushizhe.com/bbs/dispbbs.asp?boardid=35&id=1799)

    --  作者:wangxinxin
    --  發(fā)布時間:2010-11-26 9:22:53
    --  WINCE驅(qū)動開發(fā)之DMA的使用

    以下是MSDN中的說法:

    The Windows CE NDIS implementation does not support direct memory access (DMA). Do not use the NdisSetupDmaTransfer, NdisCompleteDmaTransfer, NdisMRegisterDmaChannel, NdisMDeregisterDmaChannel, NdisMAllocateMapRegisters, NdisMFreeMapRegisters, NdisMReadDmaCounter, and NdisGetSharedDataAlignment functions. 

    Use the NdisMAllocateSharedMemory and NdisMFreeSharedMemory functions for PCI bus master DMA transfers. 


    具體如何實現(xiàn)DMA呢?

    在microsoft windows CE device driver kit中有一節(jié)是:Implementing DMA for NDIS Miniport Drivers 
    專門提到了這個問題,當前ce還沒有自己的DMA機制,然而開發(fā)人員可以在他們自己的小端口卡驅(qū)動程序中實現(xiàn)相同的功能,但是寫的太簡單了

    Implementing DMA for NDIS Miniport Drivers
    DMA is important for efficient networking because it enables the layers in 
    the networking architecture to share data without first copying that data

    two categories of DMA: slave DMA and busmaster DMAB
     
    Slave DMA
    Slave DMA is appropriate for OEMs because it requires a block of memory that 
    is pre-allocated in the device memory map of the Windows CE–based platform. 
    Miniport drivers can map that block of physical memory to the driver’virtual
    memory space, and then use the VirtualAlloc and VirtualCopy functions to move 
    data in and out of that space
     
    busmaster DMA 
    To receive data, the driver allocates a shared memory block, transfers the 
    data to buffers within that block, and uses NDIS functions to indicate that a 
    packet has arrived. To send data, the driver uses the LockPages and 
    UnlockPages functions to map the virtual memory to device memory, informs the 
    NIC of the addresses of the data, and instructs the NIC to send the data. 
    This method can be faster for larger data block sizes.

    后來發(fā)MAIL給一位曾經(jīng)遇到此問題的朋友,回復(fù)如下:

    事實上在使用DMA是的關(guān)鍵是得到一個連續(xù)的物理地址空間,然后將該空間的物理地址放入DMA控制器的源地址或者目的地址寄存器中(根據(jù)你使用DMA的方向決定);
    然后等待DMA中斷;
    由于DMA使用的是物理地址但是在wince中只能使用虛擬地址,所以在DMA中斷產(chǎn)生之后如需分析數(shù)據(jù)請使用虛擬地址;
    特別提示參考一下的文章:
     DMA的使用
    1、 芯片DMA的使用要點:
    AK3224芯片的DMA使用中,RAM的地址作為DMA傳輸?shù)哪繕说刂贰⒃吹刂,必須?字節(jié)對齊。而且DMA的操作長度以內(nèi)的RAM地址,必須連續(xù)。
    不過在使用中發(fā)現(xiàn):Nandflash驅(qū)動中RAM地址作為目標地址時,只需要2字節(jié)對齊。RAM地址作為源地址可不需對齊。(其他情況需要逐一驗證)
    2、 wince中的DMA使用:
    根據(jù)DMA一次操作的RAM地址必須連續(xù)的特性,在驅(qū)動DMA使用時,我們需要確保虛擬地址映射的物理地址是連續(xù)的。有3個途徑:
    1:數(shù)據(jù)區(qū)地址是由應(yīng)用層或者其他進程、線程傳入的,驅(qū)動并不知道其虛擬地址對應(yīng)的物理地址是否一直連續(xù)。
    由于wince的內(nèi)存申請,是以4K字節(jié)為一個頁,一段數(shù)據(jù)的內(nèi)存申請可能跨越多個頁。因此,只要數(shù)據(jù)區(qū)長度大于1字節(jié),就有可能其物理地址是跨越的、不連續(xù)的。為了確保DMA操作,我們必須查詢這段數(shù)據(jù)區(qū)在RAM上的物理分布。
    首先,得到數(shù)據(jù)區(qū)所在的虛擬頁: VirPageStart = (ULONG)pSourceBuffer & 0xFFFFF000;
    其次,得到數(shù)據(jù)區(qū)在頁內(nèi)的偏移地址 :offset = (ULONG)pSourceBuffer & 0x0FFF;
    計算數(shù)據(jù)區(qū)是否跨越頁段
    if(offset + NumberOfBytes > 4096)
    PageSize = WCE_UNIFORM_SIZE - offset;       //整個數(shù)據(jù)跨越此頁,則DMA傳輸需要分多個部分,一次一個頁段的傳
    else
    PageSize = NumberOfBytes;                //數(shù)據(jù)區(qū)沒有跨越頁
    由得到的頁地址,查詢映射的物理地址。
    if(!LockPages((LPVOID)VirPageStart, 4096, &TransAddr, LOCKFLAG_READ))
    {
            //異常處理
    }
    UnlockPages((LPVOID)VirPageStart, 4096);
    得到了映射的物理地址TransAddr后,根據(jù)RAM是目標地址還是源地址,做進一步的處理。
    假設(shè)一個數(shù)據(jù)區(qū)作為DMA源地址,大小為9K。在虛擬地址首頁的偏移為4K。那么它必然跨越3個頁段。
    首先查詢第一頁的物理地址發(fā)送,第一個頁的2K數(shù)據(jù)。然后查詢第二頁的物理地址,發(fā)送4K數(shù)據(jù)。最后查詢第三頁的物理地址,發(fā)送3K數(shù)據(jù)。

    2:數(shù)據(jù)區(qū)的申請可以使用AllocPhysMem函數(shù)申請。
    LPVOID AllocPhysMem(
    DWORD cbSize,                 參數(shù)1:數(shù)據(jù)區(qū)大小
    DWORD fdwProtect,             參數(shù)2:保護標記
    DWORD dwAlignmentMask,         參數(shù)3:0(default system)
    DWORD dwFlags,                參數(shù)4:0(Reserved for future use)
    PULONG pPhysicalAddress         參數(shù)5:得到數(shù)據(jù)區(qū)對應(yīng)的物理地址
    );
    AllocPhysMem函數(shù)返回值為指向申請后的虛擬地址指針。
    如:pSerialHead->RxBufferInfo.RxCharBuffer =            //alloc physical memory
    AllocPhysMem(pSerialHead->RxBufferInfo.Length + 16, PAGE_READWRITE, 0, 0, &RX_PhyAddr);
    由于此函數(shù)必定申請到一片連續(xù)的物理地址,因此pSerialHead->RxBufferInfo.RxCharBuffer的使用不再需要查詢是否跨越多個頁段。
    但是,AllocPhysMem函數(shù)申請的物理地址可能會跨越多個RAM CHIP。因此,在使用1片以上RAM芯片的系統(tǒng)中,依然需要查詢是否跨越CHIP。
           AllocPhysMem函數(shù)使用后,需要使用FreePhysMem函數(shù)進行釋放。
    3:數(shù)據(jù)區(qū)可以在系統(tǒng)config.bib文件中,預(yù)先定義好一片連續(xù)、不跨越CHIP的RAM空間。
    如下,系統(tǒng)保留了虛擬地址0x80024000開始,大小為0x3000的一段RAM。
    SER_DMA                80024000 00003000 RESERVED
    那么驅(qū)動DMA使用中,不再需要對這段內(nèi)存,進行任何的查詢動作。我們只需要在進程空間中做映射即可。
    pSerialHead->RxBufferInfo.RxCharBuffer = VirtualAlloc(0, RX_PhySize, MEM_RESERVE, PAGE_NOACCESS);
        if (pSerialHead->RxBufferInfo.RxCharBuffer == NULL)
        {
            DEBUGMSG(ZONE_ERROR, (TEXT("COM_Init:: VirtualAlloc failed!\\r\\n")));
            return(NULL);
        }
        else
        {
            if (!VirtualCopy((PVOID)pSerialHead->RxBufferInfo.RxCharBuffer, (PVOID)(RX_PhyAddr),
                RX_PhySize, (PAGE_READWRITE | PAGE_NOCACHE)))
            {
               DEBUGMSG(ZONE_ERROR, (TEXT("COM_Init:: VirtualCopy failed!\\r\\n")));
               return(NULL);
            }
        }
    上面這段程序中,先使用函數(shù)VirtualAlloc,在進程空間中申請一段保留的虛擬地址空間。然后使用VirtualCopy,把需要使用的物理地址空間,映射到已經(jīng)申請好的虛擬地址上。使用完畢,必須使用函數(shù)VirtualFree進行釋放。
    LPVOID VirtualAlloc(
    LPVOID lpAddress,                  
    DWORD dwSize,
    DWORD flAllocationType,
    DWORD flProtect
    );
    BOOL VirtualCopy(
    LPVOID lpvDest,
    LPVOID lpvSrc,
    DWORD cbSize,
    DWORD fdwProtect
    );
    BOOL VirtualFree(
    LPVOID lpAddress,
    DWORD dwSize,
    DWORD dwFreeType
    );


    主站蜘蛛池模板: 黄色毛片免费看| 国产麻豆欧美亚洲综合久久| 伊人久久大香线蕉精品| 91亚洲精品视频| 小蝌蚪视频在线观看www| 亚洲a级在线观看| 永久看一二三四线| 国产成人无码av在线播放不卡 | 中文字幕亚洲日韩无线码| 村上凉子丰满禁断五十路| 国产AV一区二区三区无码野战 | 亚洲午夜国产精品无码老牛影视| 美妇岳的疯狂迎合| 国外bbw免费视频| 中文字幕色婷婷在线视频| 日韩电影免费在线| 免费扒开女人下面使劲桶| 舔舔小核欲成欢| 国产男女猛视频在线观看| 久久久国产精品无码免费专区| 欧美黑人XXXX高潮猛交| 四库影院永久在线精品| 91偷偷久久做嫩草电影院| 天天操天天摸天天舔| 久久99精品久久水蜜桃| 欧美人xxxx| 免费99精品国产自在现线| 精品无码成人片一区二区98 | 国语对白在线视频| 亚州1区2区3区4区产品乱码2021| 窝窝人体色www| 国产热の有码热の无码视频| 午夜免费福利网站| 亚洲aⅴ男人的天堂在线观看| 精品国产一区二区| 国产在线精品一区二区不卡麻豆| www.九色视频| 小雄和三个护士阅读| 久久久噜噜噜久久久午夜 | 夫妇当面交换中文字幕小说| 亚洲中文字幕久在线|