文章来源:http://www.cnblogs.com/scnutiger/archive/2010/02/06/1664980.html

在Quartus7.2之后的版本中,除了原有的基于avalon-mm总线的DMA之外,还增加了Scatter-Gather DMA这种基于avalon-ST流总线的DMA IP核,它更适合与大量数据流传输的场合,使用起来比较灵活,增加了与外设流器件配合的能力。由于网上关于SG-DMA介绍的资料比较少,因此这里简单介绍一下SG-DMA的使用,利用它可以搭配Altera的千兆网MAC核来实现千兆网方面的应用。

SG-DMA的数据手册已经介绍得非常详细,具体的相关寄存器和功能可能查阅相关手册。Altera为了开发的便利,已经为各个IP核设计好了HAL软件层的代码,SG-DMA也不例外,因此使用的时候我们没有必要逐个配置相关寄存器,直接调用HAL层代码即可。这也是使用这类IP核简便的地方,只是需要清楚这类代码如何调用。

1. 首先我们简单看看SG-DMA的应用环境,从数据手册中截下几张图片简单介绍。

SG-DMA有三种工作方式,可以工作在Memory-to-Stream即存储接口到流接口,或者Stream-to-Memory即流接口到存储接口,以及Memory-to-Memory的存储器到存储器工作方式。工作在存储器到存储器的工作方式与普通DMA并无差别,没有数据流处理的优势。另外SG-DMA增加了Descriptor Processor,可以实现批量工作,从而进一步减轻Nios处理器的工作。只需要将Descriptor命令字写入到相应的Descriptor memory中。我们简单看看以上的工作方式。

            图1. Memory-to-Stream

            图2. Stream-to-Memory

            图3. Memory-to-Memory

2. 然后我们直接进入主题,看在Altera的SOPC中如何连接使用SG-DMA器件。

M-to-M模式就不做介绍了,这里主要介绍M-to-S和S-to-M这两种方式。我们添加两个SG-DMA器件,让它们分别工作在这两个工作方式下。连接示意如下所示。注意到其中的descriptor memory的设置,原则上只要带有avalon-mm接口的存储器都可以用来做descriptor memroy,因此我们可以将decriptor memory与主存分离,亦可以直接使用主存的一部分作为descriptor memroy。但为了不影响主存的使用,最好将descriptor memroy分离。另外SG-DMA的有关设置,例如channel和error的位数控制可以参考avalon-st流接口数据手册,依照需要设置接口。由于在本例中只有一个通道,也不校验错误,所以我们都设置为零。

            图4. SOPC连接示意图

3. SG-DMA HAL代码调用。

要使得SG-DMA正式工作起来,我们可以直接调用HAL层代码,省去很多开发时间。下面直接使用一段程序,添加部分注释,相信SG-DMA的基本使用即可完成了,并没有想象中的这么复杂。

#include <stdio.h>
#include "altera_avalon_sgdma_descriptor.h"
#include "altera_avalon_sgdma_regs.h"
#include "altera_avalon_sgdma.h"
#include "system.h"
#include "alt_types.h"
//注意包含这几个头文件alt_sgdma_dev    *sgdma_tx_dev;  //sgdma_tx设备文件
alt_sgdma_dev    *sgdma_rx_dev;  //sgdma_rx设备文件
alt_sgdma_descriptor    *desc;        //descriptor memory指针char buf[1000];                         //SG-DMA传送缓存,暂定1000字节做测试
alt_u32 rx_payload[256];         //SG-DMA接收缓存void sgdma_rx_isr(void * context, u_long intnum);
//我们的基本思路就是,先配置好sgdma_rx和sgdma_tx的基本配置,然后设置好sgdma_rx的回调函数。
//即接收数据完成之后调用的函数,最后启动sgdma_tx完成dma发送。在这个过程中涵盖了sgdma_tx和sgdma_rx的基本使用
int main()
{int i;int timeout = 0;for(i=0; i<1000; i++)   //填充缓存数据buf[i] = i%256;//重定义desc DISCRIPTOR_MEMORY_BASE定义在system.h中,即descriptor_memory的基地址desc = (alt_sgdma_descriptor *)DISCRIPTOR_MEMORY_BASE;//打开sgdma_tx和sgdma_rxsgdma_tx_dev = alt_avalon_sgdma_open(SGDMA_TX_NAME);  //SGDMA_TX_NAME定义为"/dev/sgdma_tx"if(!sgdma_tx_dev) {printf("[triple_speed_ethernet_init] Error opening TX SGDMA\n");return -1;}sgdma_rx_dev = alt_avalon_sgdma_open(SGDMA_RX_NAME);if(!sgdma_rx_dev) {printf("[triple_speed_ethernet_init] Error opening RX SGDMA\n");return -1;}/* Reset RX-side SGDMA */IOWR_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_RX_BASE, ALTERA_AVALON_SGDMA_CONTROL_SOFTWARERESET_MSK);IOWR_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_RX_BASE, 0x0);/* Reset TX-side SGDMA */IOWR_ALTERA_AVALON_SGDMA_CONTROL(SGDMA_TX_BASE, 0);IOWR_ALTERA_AVALON_SGDMA_STATUS(SGDMA_TX_BASE, 0xFF);//注册sgdma_rx回调函数alt_avalon_sgdma_register_callback(sgdma_rx_dev,(alt_avalon_sgdma_callback) &sgdma_rx_isr,(alt_u16)ALTERA_AVALON_SGDMA_CONTROL_IE_DESC_COMPLETED_MSK | \ALTERA_AVALON_SGDMA_CONTROL_IE_CHAIN_COMPLETED_MSK | \ ALTERA_AVALON_SGDMA_CONTROL_IE_GLOBAL_MSK,
);//填充发送decriptor memory 并不需要自己填充,调用函数就好了。alt_avalon_sgdma_construct_stream_to_mem_desc(&desc[0],             //主描述字&desc[1],             //次描述字rx_payload,
,
);//填充接收decriptor memory alt_avalon_sgdma_construct_mem_to_stream_desc(&desc[2],                 //主描述字&desc[3],                 //次描述字(unsigned int*)buf,  //发送指针(256),                       //发送字数
,
,
,
);//启动sgdma_rx和sgdma_txalt_avalon_sgdma_do_async_transfer(sgdma_rx_dev, &desc[0]);alt_avalon_sgdma_do_sync_transfer(sgdma_tx_dev, &desc[2]);
}//回调函数,负责处理接收后数据,并重置sgdma_rx,本例中并未对数据进行处理
void sgdma_rx_isr(void * context, u_long intnum);
{int sgdma_status = IORD_ALTERA_AVALON_SGDMA_STATUS(SGDMA_RX_BASE);alt_sgdma_descriptor  *currdescriptor_ptr = &desc[0];if(sgdma_status & (ALTERA_AVALON_SGDMA_STATUS_CHAIN_COMPLETED_MSK | ALTERA_AVALON_SGDMA_STATUS_DESC_COMPLETED_MSK) ) {desc_status = IORD_ALTERA_TSE_SGDMA_DESC_STATUS(currdescriptor_ptr);if( (desc_status & (ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_CRC_MSK | ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_PARITY_MSK | ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_OVERFLOW_MSK |ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_SYNC_MSK | ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_UEOP_MSK | ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_MEOP_MSK | ALTERA_AVALON_SGDMA_DESCRIPTOR_STATUS_E_MSOP_MSK ) ) == 0){printf("RX descriptor reported OK\n");}        else {printf("RX descriptor reported error\n");}IOWR_32DIRECT(&(currdescriptor_ptr->write_addr), 0, (alt_u32)(rx_payload));             IOWR_32DIRECT(&(currdescriptor_ptr->actual_bytes_transferred), 0, (alt_u32) ((ALTERA_AVALON_SGDMA_DESCRIPTOR_CONTROL_OWNED_BY_HW_MSK |ALTERA_AVALON_SGDMA_DESCRIPTOR_CONTROL_GENERATE_EOP_MSK) << 24) );// Re-start SGDMA (always, if we have a single descriptor)alt_avalon_sgdma_do_async_transfer(sgdma_rx_dev, &desc[0]);}
}

Altera Scatter-Gather DMA (SG-DMA)的简单使用相关推荐

  1. 【Xilinx DMA SG】Xilinx DMA SG 模式

    DMA简介: AXI 直接存储器访问 (AXI DMA) IP 提供高带宽直接存储器 AXI4 存储器映射和 AXI4-Stream IP 接口之间的访问.它SG模式还可以从中央处理中卸载数据移动任务 ...

  2. AXI SG DMA 简易驱动 版本构思 (一)

    第一步: 利用mmap 在内核态和用户态形成内存映射关系,和进程间通信 shmat 的原理 一致 (节省内存,如果拷贝的话就是, double的关系) 第二步: mmap的 地址要映射到,dma 分配 ...

  3. JavaNIO - Scatter Gather

    Scatter & Gather指在多个缓冲区上实现一个简单的 I/O 操作.减少或避免了Buffer间的拷贝和系统调用. Channel Write操作 Write操作 Channel Re ...

  4. NIO - Scatter/Gather

    1.Scatter  从一个Channel读取的信息分散到N个缓冲区中(Buufer). 2.Gather  将N个Buffer里面内容按照顺序发送到一个Channel. Scatter/Gather ...

  5. RDMA技术详解(三):理解RDMA Scatter Gather List

    1. 前言 在使用RDMA操作之前,我们需要了解一些RDMA API中的一些需要的值.其中在ibv_send_wr我们需要一个sg_list的数组,sg_list是用来存放ibv_sge元素,那么什么 ...

  6. 【Java NIO的深入研究6】JAVA NIO之Scatter/Gather

    Java NIO开始支持scatter/gather,scatter/gather用于描述从Channel(译者注:Channel在中文经常翻译为通道)中读取或者写入到Channel的操作. 分散(s ...

  7. Java NIO系列教程(四) Scatter/Gather

    转载自   Java NIO系列教程(四) Scatter/Gather 译文地址  作者:Jakob Jenkov   译者:郭蕾 Java NIO开始支持scatter/gather,scatte ...

  8. java nio 系列教程 四_Java NIO系列教程(四) Scatter/Gather

    作者:Jakob Jenkov   译者:郭蕾 Java NIO开始支持scatter/gather,scatter/gather用于描述从Channel(译者注:Channel在中文经常翻译为通道) ...

  9. 【STM32】HAL库 STM32CubeMX教程十一---DMA (串口DMA发送接收)

    前言: 本系列教程将 对应外设原理,HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用 所用工具: 1.芯片: STM32F407ZET6/ STM32F103ZET6 ...

  10. STM32CubeMX | HAL库的ADC多通道数据采集(轮训、DMA、DMA+TIM)、读取内部传感器温度

    STM32CubeMX | HAL库的ADC多通道数据采集(轮训.DMA.DMA+TIM).读取内部传感器温度 目录 STM32CubeMX | HAL库的ADC多通道数据采集(轮训.DMA.DMA+ ...

最新文章

  1. JBoss下布署Spring2.5和Struts2系统
  2. 编程之美求二进制数中1的个数扩展题
  3. Vagrant挂载目录失败mount: unknown filesystem type ‘vboxsf’
  4. 基于RNN和CTC的语音识别模型,探索语境偏移解决之道
  5. 滚动时间选择器recyclerview_Android自定义可循环的滚动选择器CycleWheelView
  6. 通过MDaemon自带功能,实现同部门用同一账号对外收发邮件
  7. pe我的手机服务器存档文件,我的世界手机版怎么导出存档 pe版怎么把存档给别人用...
  8. nodejs学习笔记-1-文件系统
  9. Android 分享到新浪微博
  10. vue 使用 createjs 绘制扇形
  11. xp访问共享文件夹需要重启服务器,winXP共享文件夹断开、重新连接、重设置密码的方法...
  12. C# 判断文件是否在使用的状态FSDF
  13. gdown配置代理下载Google drive文件
  14. 康宁发布第五代大猩猩玻璃 坚韧度更强更耐摔
  15. java左手画圆右手画方_左手画圆、右手画方,双手齐用同时养护、开发你的左右大脑!...
  16. 植物大战僵尸数据修改总结
  17. 安全邮箱是什么,163邮箱安全中心,安全邮箱怎么注册?
  18. 使用python计算贝尔宾团队角色测评结果
  19. Unity3d用户手册用户攻略缓存效劳器常见疑问
  20. 示波器测量晶振、万用表测量晶振的方法

热门文章

  1. 性能优化指标的性能指标,及其如何量化
  2. 服务器seo优化,SEO诊断之网站服务器优化
  3. 弘辽科技:“拼夕夕”华丽变装为“拼爹爹”的成功秘诀
  4. TCP状态转换以及TIMEWAIT和FIN_WAIT_2状态
  5. 图像检索中一些特征索引技术
  6. html中的colspan是什么意思
  7. 他是“中国第一程序员”,一人之力单挑微软!
  8. pandas查看数据
  9. 面向搜索引擎的隐蔽式SEO木马---之查杀再现笔记
  10. revit二次开发2016