在实现反射内存卡驱动程序DMA完成中断死机蓝屏纠结N天的一个低级BUG

        本人负责软件从应用层一直到驱动层的全部研发任务,通过对GE产品的公开的资料反复研究,一共近70个函数接口,现在都搞明白了,由于GE产品光盘手册开源了Linux和VxWorks平台的全部软件代码,唯独不开源windows平台的动态库驱动程序代码,现在只好通过理解GE反射内存卡的Linux平台的开源代码,来参照并实现windows平台的反射内存软件系统。

          从今年三月中旬一直到现在一直都在开发这个产品软件,要求按标准接口走,真是几经周折,途中遇到太多的技术难题,涉及到不少的内核或驱动编程方面。这不,最近被一个低级的问题卡了三天,别笑啊,哈哈!!,在中断程序ISR例程调用了KeReleaseSemaphore,中断频率低的时候系统很是正常,但如果应用程序要是这样调用RFM2gRead()函数时就会出现死机或蓝屏,如:

                      RFMSetDMAThreshold( rh, 1);  //为了压力测试,就设置DMA触发条件为“当RFMRead()函数长度参数大于1时就启动DMA传输数据”

                       while(1)

                      {

                         RFMRead(.....);      //为了体现RFM2gRead()执行的频率高,缓冲区数组长度设置越小越好(假设不理DMA启动前的系统设置开销)

                      }

                      其实也就是GE测试DEMO代码Utill命令集里的"performancetest"命令,但该命令是为了测试板卡最大的性能指标的,为了简单测试自已的RFMRead接口

                      就直接用while(1)这样的压力测试高速DMA读数据性能。

                      这样一运行,蓝屏由 1秒~5秒间就挂死了,经反复大量的测试偶尔会有蓝屏现象,用WinDbg分析dump文件IRQL_NOT_LESS_OR_EQUAL
                      错误,基本上定位在中断例程ISR函数的最后一行“return TRUE;"这一行代码上,这个BUG的确费了我3天的时间,直到今天快下班了,看到一个仁兄的帖子,

                        提到:                                             

        ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
        LONG wassignalled = KeReleaseSemaphore(semaphore, boost, delta, wait);


                恍然大悟,早就知道中断处理函数ISR中代码执行的优先级是>DISPATCH_LEVEL的,然尔在这里调用KeReleaseSemaphore()肯定是有问题的!!

               其实之前做了好多PCI板卡驱都是把调用KeReleaseSemaphore()放在DPC延时中断处理函数中,只不过在实现这个反射内存板卡时几乎大部分

               逻辑都在驱动中实现,中断类型繁多,一时疏忽了这个细节问题,希望一个问题下次不能再犯,特此做笔记。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在Vitis中,可以使用Xilinx提供的DMA/Bridge Subsystem for PCI Express (DMA/Bridge Subsystem for PCIe) IP核来实现AXI DMA。以下是在Vitis中实现AXI DMA的基本步骤: 1. 配置DMA/Bridge Subsystem for PCIe IP核:在Vivado中,使用IP Catalog创建一个DMA/Bridge Subsystem for PCIe IP核,并根据需要进行配置,例如设置传输方向、数据长度、中断使能等。 2. 生成并导出IP核:在Vivado中,使用Generate Output Products功能生成IP核的输出产品,然后导出到Vitis中。 3. 在Vitis中创建工程:创建一个新的Vitis工程,并将DMA/Bridge Subsystem for PCIe IP核添加到该工程中。 4. 编写驱动程序:在Vitis中,可以使用Xilinx提供的XDMA驱动程序来对DMA/Bridge Subsystem for PCIe IP核进行操作。可以在Vitis工程中添加XDMA驱动程序并进行修改,以便与DMA/Bridge Subsystem for PCIe IP核进行通信。 5. 配置DMA传输:在驱动程序中,需要配置DMA传输相关的参数,例如传输方向、数据长度、中断使能等。可以使用Xilinx提供的DMA传输API来进行配置。例如: ``` struct dma_chan_cfg cfg; cfg.direction = DMA_DEV_TO_MEM; cfg.length = 1024; cfg.interrupt_enable = 1; xdma_config_chan(dma, 0, &cfg); ``` 其中dma是XDMA驱动程序提供的一个全局变量,用于表示DMA通道的句柄。xdma_config_chan是XDMA驱动程序提供的一个函数,用于配置DMA通道的参数。 6. 启动DMA传输:配置完成后,可以使用Xilinx提供的DMA传输API来启动DMA传输。例如: ``` char buf[1024]; dma_async_transfer(dma, 0, buf, 1024); ``` 其中dma_async_transfer是XDMA驱动程序提供的一个函数,用于启动异步DMA传输。 7. 等待DMA传输完成:可以使用Xilinx提供的DMA传输API来等待DMA传输完成,并获取传输状态。例如: ``` struct dma_tx_status status; while (1) { xdma_get_tx_status(dma, 0, &status); if (status.complete) break; } ``` 其中xdma_get_tx_status是XDMA驱动程序提供的一个函数,用于获取DMA传输状态。 以上是在Vitis中实现AXI DMA的基本步骤,具体实现方式可能因项目需求而有所不同。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值