water11
驱动牛犊
驱动牛犊
  • 注册日期2001-04-29
  • 最后登录2005-09-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1980回复:14

哪种方式好?

楼主#
更多 发布于:2002-06-17 09:20
我们作了一块采集卡9054实现的板上有32KRAM。
分析了厂家自己带驱动PLX SDK后,发现它对板上RAM的读写是把板上RAM映射为APP的用户空间,然后直接读写RAM。
而通常驱动程序都是采用Readfile或DeviceIOControl,在内核进行
RAM拷贝把数据传给APP的。
这两种方式那种较好?既然能将板上的RAM映射为用户空间地址,为什么我们还要通过Readfile?直接操作板上RAM效率不是更高吗?
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2002-06-17 11:05
他是怎么把硬件的RAM映射为app的空间的?
water11
驱动牛犊
驱动牛犊
  • 注册日期2001-04-29
  • 最后登录2005-09-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-06-17 13:41

/******************************************************************************
 *
 * Function   :  MapInUserSpace
 *
 * Description:  Maps a physical address to user space
 *
 ******************************************************************************/
PVOID
MapInUserSpace(
    PHYSICAL_ADDRESS AddrPhysical,
    U32              Size
    )
{
    U32                VirtualAddress;
    ULONG              length;
    PVOID              PhysicalMemorySection;
    HANDLE             hPhysicalMemory;
    NTSTATUS           status;
    LARGE_INTEGER      ViewBase;
    UNICODE_STRING     PhysicalMemory_Unicode;
    OBJECT_ATTRIBUTES  ObjectAttributes;


    RtlInitUnicodeString(
        &PhysicalMemory_Unicode,
        L\"\\\\Device\\\\PhysicalMemory\"
        );

    InitializeObjectAttributes(
        &ObjectAttributes,
        &PhysicalMemory_Unicode,
        OBJ_CASE_INSENSITIVE,
        (HANDLE) NULL,
        (PSECURITY_DESCRIPTOR) NULL
        );

    status = ZwOpenSection(
                 &hPhysicalMemory,
                 SECTION_ALL_ACCESS,
                 &ObjectAttributes
                 );

    if (!NT_SUCCESS(status))
    {
        KdPrint((DBG_NAME \"ERROR - Unable to obtain a handle to the physical memory\\n\"));
        return NULL;
    }

    status = ObReferenceObjectByHandle(
                 hPhysicalMemory,
                 SECTION_ALL_ACCESS,
                 (POBJECT_TYPE) NULL,
                 KernelMode,
                 &PhysicalMemorySection,
                 (POBJECT_HANDLE_INFORMATION)NULL
                 );

    if (!NT_SUCCESS(status))
    {
        KdPrint((DBG_NAME \"ERROR - Unable to reference object by handle\\n\"));
        ZwClose(
            hPhysicalMemory
            );
        return NULL;
    }

    // Let the OS pick an address
    VirtualAddress = (U32) NULL;

    // Initialize view base that will receive the physical mapped address
    ViewBase = AddrPhysical;

    length = Size;

    // Map the section
    status = ZwMapViewOfSection(
                 hPhysicalMemory,
                 (HANDLE) -1,
                 &(PVOID)VirtualAddress,
                 0L,
                 length,
                 &ViewBase,
                 &length,
                 ViewShare,
                 0,
                 PAGE_READWRITE | PAGE_NOCACHE
                 );

    if (!NT_SUCCESS(status))
    {
        KdPrint((DBG_NAME \"ERROR - Unable to map view of section, status = 0x%x\\n\",
                 status));
        ZwClose(
            hPhysicalMemory
            );
        return NULL;
    }

    /*
       Mapping the section above rounded the physical address down to the
       nearest 64K boundary.  Now return a virtual address that sits where
       we want by adding in the offset from the beginning of the section.
     */
    VirtualAddress += (U32)(AddrPhysical.QuadPart - ViewBase.QuadPart);

    return (PVOID)VirtualAddress;
}
通过该函数实现,只能大概看懂。
magicx
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2014-08-18
  • 粉丝1
  • 关注0
  • 积分-14分
  • 威望13点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-06-17 20:49
我们作了一块采集卡9054实现的板上有32KRAM。
分析了厂家自己带驱动PLX SDK后,发现它对板上RAM的读写是把板上RAM映射为APP的用户空间,然后直接读写RAM。
而通常驱动程序都是采用Readfile或DeviceIOControl,在内核进行
RAM拷贝把数据传给APP的。
这两种方式那种较好?既然能将板上的RAM映射为用户空间地址,为什么我们还要通过Readfile?直接操作板上RAM效率不是更高吗?


\"既然能将板上的RAM映射为用户空间地址,为什么我们还要通过Readfile?直接操作板上RAM效率不是更高吗?\"

除了效率,还有其他。。。。。。。。。。

[color=red]大头鬼! :P[/color]
seaquester
驱动大牛
驱动大牛
  • 注册日期2002-05-22
  • 最后登录2016-06-16
  • 粉丝0
  • 关注0
  • 积分500分
  • 威望115点
  • 贡献值0点
  • 好评度107点
  • 原创分0分
  • 专家分52分
地下室#
发布于:2002-06-18 12:34
通过 ZwMapViewOfSection 得到的这个虚拟地址只在当前的进程环境(即调用ZwMapViewOfSection的进程)中有效,如果要在 DPC 或 ISR 中使用,必须将这段内存映射到系统地址空间。

The virtual address you get from the ZwMapViewOfSection is only valid in the context of the process it is mapped. If you want to access the memory in your driver\'s Deferred Procedure Call (DPC) or Interrupt Service Routine (ISR), which runs in an arbitrary process context, you should also map the memory in the system address space.

------------------------------------------------------------可以参考MSDN中的文章:
HOWTO: Map Adapter RAM into Process Address Space
Q189327

HOWTO: Share Memory Between User Mode and Kernel Mode
Q191840

SAMPLE: Section.exe on Sharing Memory Between Kernel & User Mode
Q194945

在NT DDK 中有一个例子 MAPMEM (C:\\DDK\\src\\general\\mapmem)
八风舞遥翩,九野弄清音。 鸣高常向月,善舞不迎人。
water11
驱动牛犊
驱动牛犊
  • 注册日期2001-04-29
  • 最后登录2005-09-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-06-18 12:58
楼上,你弄错我的意思了。


谁还能发表一点意见阿?
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2002-06-19 09:59
呵呵,你以为硬件都是自带大块RAM并都在主存空间么,自然需要一些通用的方法。想想很多字符设备、PIO模式下的硬盘也是需IO操作来读写的(你想把硬盘缓存也映射为主存么?呵呵)
water11
驱动牛犊
驱动牛犊
  • 注册日期2001-04-29
  • 最后登录2005-09-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-06-19 10:35
如果两种方式都可以用的话,选那种方式较好呢?比如采集卡
是在APP中直接操作呢?还是在通过READFile读呢?
pjf
pjf
驱动中牛
驱动中牛
  • 注册日期2001-07-08
  • 最后登录2006-10-23
  • 粉丝0
  • 关注0
  • 积分42分
  • 威望4点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2002-06-19 11:53
从效率计,用它的程序较好;从编程简单计惯用的方法方便。
若RAM不是很大且访问不是特别频繁,后者没什么不好的。
wuqix
驱动小牛
驱动小牛
  • 注册日期2001-03-23
  • 最后登录2008-06-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2002-06-19 12:50
小量的数据流动用哪种方式都没有问题,因为速度瓶颈一般不在这里,不过既然别人的sdk都作了,直接用也行。当遇到大量数据传输的时候,自己写程序一般也要做内核地址和应用层地址的转换,这样速度快一点。
petz
禁止发言
禁止发言
  • 注册日期2001-03-23
  • 最后登录2015-12-19
  • 粉丝0
  • 关注0
  • 积分-22276分
  • 威望15点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2002-06-19 13:03
用户被禁言,该主题自动屏蔽!
wuqix
驱动小牛
驱动小牛
  • 注册日期2001-03-23
  • 最后登录2008-06-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2002-06-19 13:25
[quote]我们作了一块采集卡9054实现的板上有32KRAM。
分析了厂家自己带驱动PLX SDK后,发现它对板上RAM的读写是把板上RAM映射为APP的用户空间,然后直接读写RAM。
而通常驱动程序都是采用Readfile或DeviceIOControl,在内核进行
RAM拷贝把数据传给APP的。
这两种方式那种较好?既然能将板上的RAM映射为用户空间地址,为什么我们还要通过Readfile?直接操作板上RAM效率不是更高吗?

厂家所用的方法没有采用DMA,用户编程倒是简单啦,但数据传输速率大大低于DMA方式。
如果采用readfile方式,则在驱动中就可以采用DMA方式。如果readfile在驱动中是采用READ_REGISTER_xxx这种方法,则数据传输速率与厂家采用的方法大致相当。 [/quote]

呵呵,连dma都没加,那这个库也太……
要搞规模大一点的数据量,还是自己写吧
water11
驱动牛犊
驱动牛犊
  • 注册日期2001-04-29
  • 最后登录2005-09-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2002-06-19 13:50
采用DMA也就是不用CPU参与把数据从板上RAM搬移到主机的RAM中,最终用户还是要处理RAM中数据,从这点上说既然数据已经在用户空间了我可以直接读写,有为何要DMA一次呢?
water11
驱动牛犊
驱动牛犊
  • 注册日期2001-04-29
  • 最后登录2005-09-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2002-06-19 14:05
采用DMA也就是不用CPU参与把数据从板上RAM搬移到主机的RAM中,最终用户还是要处理RAM中数据,从这点上说既然板上RAM已经映射为用户RAM空间了可以直接读写,又为何要DMA呢?
petz
禁止发言
禁止发言
  • 注册日期2001-03-23
  • 最后登录2015-12-19
  • 粉丝0
  • 关注0
  • 积分-22276分
  • 威望15点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2002-06-19 14:14
用户被禁言,该主题自动屏蔽!
游客

返回顶部