初学NIOS II的可以看看! 先看看几个概念: Peripheral :地址固定模式的一方称为Peripheral。 Memory : 地址自增模式的一方称为Memory。 Transimit Channel:用于从地址自增一方传送到地址固定一方的通道。 Receive Channel :用于从地址固定一方传送到地址自增一方的通道。 Nios II的标准设备软IP中有一个DMA设备,在SoPC系统开发中是一个非常常用的设备。但在Nios II的文档对该设备的说明里,一些概念和说明方式跟一般有些不同,容易造成初次接触的人一些理解上的混乱。 DMA的概念其实挺简单,无非就是把一定长度的数据从源地址传送到目标地址。其中有一点比较重要的是对于地址的操作方式,一种是地址自增,另一种是地址固定。就是说DMA控制器读或写完一个数据后,对地址是自动增加,下次读写下一个地址,还是不变,下次还是读写同一个地址。由于地址固定模式一般是用在外设,所以在Nios的文档中,使用地址固定模式的一方就称为设备(Peripheral),而使用地址自增模式的一方则称为内存(Memory)。 在HAL的API中,对于地址自增一方,需要打开一个接收或发送的Channel,然后配置地址;而如果是地址固定的一方,则不需要打开一个Channel,只需要用alt_dma_rxchan_ioctl()的ALT_DMA_RX_ONLY_ON或ALT_DMA_TX_ONLY_ON参数设置,并配置地址即可。下面是三种方式的代码例子。 1、Memory to Memory传送,即是源和目标都是地址自增模式的: tx = alt_dma_txchan_open("/dev/dma_0"); dma_res = alt_dma_txchan_send(tx, tx_buf, 32, NULL, NULL); // tx_buf是源地址 rx = alt_dma_rxchan_open("/dev/dma_0"); dma_res = alt_dma_rxchan_prepare(rx, rx_buf, 32, dma_done, NULL); // rx_buf是目标地址,dma_done()是DMA完成后被调用的回调函数。 2、Peripheral to Memory传送,叫做Receive,即源地址是固定模式,而目标地址是自增模式: rx = alt_dma_rxchan_open("/dev/dma_0"); // 打开Receive通道 alt_dma_rxchan_ioctl(rx, ALT_DMA_RX_ONLY_ON, (void *)source_addr); // source_addr是源地址 dma_res = alt_dma_rxchan_prepare(rx, rx_buf, 32, dma_done, NULL); // rx_buf是目标地址 3、Memory to Peripherial传送,叫做Transmit,即源地址是自增模式,而目标地址是固定模式: tx = alt_dma_txchan_open("/dev/dma_0"); // 打开Transmit通道 alt_dma_txchan_ioctl(tx, ALT_DMA_TX_ONLY_ON, (void *)dst_addr); // dst_addr是目标地址 dma_res = alt_dma_txchan_send(tx, tx_buf, 32, dma_done, NULL); // tx_buf是源地址 |