设置完成DMA传输的描述符表后,需要通过设置DMA控制寄存器,告诉设备主机描述表的起始物理地址和描述符的个数。这里,也有上面类似的要求。即要求描述表的低32位地址为16的倍数,否则将导致设备FIFO每个周期接收的描述符不是一个完整的描述符,即可能是由前一个描述符的后8字节和后一个描述符的前8字节组成。这将导致以后DMA数据传输的混乱和错误。为此,在调用WDC_DMASGBufLock函数对描述符表存储区域进行锁定时,可以进行上面类似的地址对齐处理。
因为在调用WDC_DMASGBufLock函数对一块存储区域进行锁定时,中间页的大小均是4 KB的倍数。这样就可以估算出一块内存区域大概可以分成几页,从而估计出描述符表由几个描述符组成。比如文中的设备存储器是一个32 KB的端点存储器,因此进行一次DMA传输的描述符个数不超过9个,描述符表占用的存储空间为:16+9*16=160字节。对于这种描述表所需空间少于2 KB的情况下,可以采用如下策略使得描述表的数据集中到一个物理页中,以便于对DMA控制寄存器的设置,即如果所需空间为x(x≤2032)字节,那么申请2(x+16)字节(≤4 KB)的空间,这样在调用WDC_DMASGBufLock函数进行存储区域锁定时,得到的页数最多为2页,且至少有一页的大小不小于x+16字节。于是,便可用此页作为描述符表的存储区域,并使描述符表的起始地址满足16的倍数的要求。
www.55dianzi.com
按照上面的策略,一次DMA传输至少可以处理含有(2032-16)/16=126个描述符的描述符表,至少可以传输124*4 KB=496 KB大小的数据。如果DAM传输的数据很多时,可以分成多次DMA传输,这样仍可使每次DMA传输时,描述表的数据占用一个物理页。
上面的策略,也可应用于DMA数据存储区的设置。例如在我们进行的加密卡设计中,使用DMA写模块完成加密结果的输出。对于公钥算法,其加密结果的长度往往是固定的,比如,对2 048位的RSA签名运算,其签名结果长度为256字节。此时采用上面的策略,我们就可以通过一次DMA传输读到签名结果,这样就简化了底层设备对输出接口的设计。
在设置完DMA控制寄存器后,设备开始进行MDA描述符检索,然后开始进行数据传输,主机需要知道什么时候数据传输结束,以便进行其他处理或读取传输结果。有两种处理方式:中断方式和查询方式。由于
Windows XP操作系统不支持消息中断请求(MSI),故采用查询的方式处理。这就需要设置描述符的控制域和DMA控制寄存器的控制域部分,以使设备更新描述符表的EPLAST域。需要指出的是:在设备DMA处理模块的实现中,描述表的描述符头中,最后一个双字的低16位是EPLAST域的实际值,即最后完成的描述符的索引号,而高16位是其他的信息。因此可以用下面的DMAWaitForCompletion函数进行查询处理。

在上面的函数中hDev为设备句柄;DT_HEAD_EPLAST为描述表的描述符头中,最后一个双字的地址指针;eplast_num为DMA传输的最后一个描述符的索引号,等于描述符表中描述符个数减1。函数的返回值为真,表示DMA传输正确完成。
为了使DMA缓冲区保持与CPU缓存、I/O缓存的同步,主机端应在设置DMA控制寄存器之前,对DMA传输的数据存储区和描述符表存储区调用WDC_DMASynCCpu函数,在完成DMA的传输查询之后,调用WDC_DMASyncIo函数和WDC_DMABufUnLOCk函数。
4 结束语
对基于ALTEra公司PCI Express硬核的链式DMA应用,Altera公司虽然提供了上层Demo示例程序,但其只进行了MDA传输的性能测试。文中给出了处理DMA数据传输时,主机端需要面对和解决的几个问题。通过这些处理方法和策略,保证了主机和设备之间DMA数据传输的正确性,简化了底层FPGA应用的设计,为利用DMA模块进行用户的应用逻辑设计提供了基础。
上一页 [1] [2]
本文关键字:暂无联系方式计算机应用,电子知识资料 - 计算机应用