bperez77 / xilinx_axidma

A zero-copy Linux driver and a userspace interface library for Xilinx's AXI DMA and VDMA IP blocks. These serve as bridges for communication between the processing system and FPGA programmable logic fabric, through one of the DMA ports on the Zynq processing system. Distributed under the MIT License.
MIT License
450 stars 225 forks source link

problem about "axidma_oneway_transfer " #138

Open Monster-Kee opened 2 years ago

Monster-Kee commented 2 years ago

No problem with write channel when I use the "axidma_oneway_transfer ",but when I use the "axidma_oneway_transfer " for read channel,I read nothing. As the same time,the kernel did not report any error.when I use the "axidma_oneway_transfer " for write channel,the ILA on the PL side can correctly capture,but the read channel has nothing.

code for read channel:

`

static int transfer_file(axidma_dev_t dev, struct dma_transfer *trans)
{
      int rc;
      // Allocate a buffer for the output file
      trans->output_buf = axidma_malloc(dev, trans->output_size);
      if (trans->output_buf == NULL) {
          rc = -ENOMEM;
          goto free_output_buf;
      }

  // Perform the transfer
  // Perform the main transaction
  rc = axidma_oneway_transfer(dev, trans->output_channel, trans->output_buf,
          trans->output_size, true);

  if (rc < 0) {
      fprintf(stderr, "DMA transaction failed.\n");
      goto free_output_buf;
  }

  // Write the data to the output file
  printf("reading....\n");

  free_output_buf:
      axidma_free(dev, trans->output_buf, trans->output_size);

      return rc;
 }

int main(int argc, char **argv)
{
      int rc;
      char *output_path;
      axidma_dev_t axidma_dev;
      struct dma_transfer trans;
      const array_t *rx_chans;

     // Parse the input arguments
      memset(&trans, 0, sizeof(trans));
      if (parse_args(argc, argv, &output_path, &trans.output_channel,&trans.output_size) < 0) {
          rc = 1;
          goto ret;
      }

  // Try opening the input and output images
  trans.output_fd = open(output_path, O_WRONLY|O_CREAT|O_TRUNC,
                   S_IWUSR|S_IRUSR|S_IRGRP|S_IWGRP|S_IROTH);
  if (trans.output_fd < 0) {
      perror("Error opening output file");
      rc = -1;
      goto close_output;
  }
  // Initialize the AXIDMA device
  axidma_dev = axidma_init();
  if (axidma_dev == NULL) {
      fprintf(stderr, "Error: Failed to initialize the AXI DMA device.\n");
      rc = 1;
      goto close_output;
  }

  // Get the tx and rx channels if they're not already specified
  rx_chans = axidma_get_dma_rx(axidma_dev);
  if (rx_chans->len < 1) {
      fprintf(stderr, "Error: No receive channels were found.\n");
      rc = -ENODEV;
      goto destroy_axidma;
  }
      /* If the user didn't specify the channels, we assume that the transmit and
   * receive channels are the lowest numbered ones. */
  if (trans.output_channel == -1 ) {
      trans.output_channel = rx_chans->data[0];
  }
  printf("AXI DMA File Transfer Info:\n");
  printf("\tReceive Channel: %d\n", trans.output_channel);
  printf("\tOutput File Size: %.2f MiB\n\n", BYTE_TO_MIB(trans.output_size));

  // Transfer the file over the AXI DMA
  rc = transfer_file(axidma_dev, &trans);
  rc = (rc < 0) ? -rc : 0;

destroy_axidma:
      axidma_destroy(axidma_dev);
close_output:
     assert(close(trans.output_fd) == 0);
ret:
    return rc;

}

`