FreeRTOS+MPsoc-P5-Xilix, XAxiDma_Busy is always busy problem

My program runs in a task under freerots environment. I run the DMA loopback experiment (fifo loopback experiment) on the Xilix device of MPSoc-P5 to test the DMA performance. I have already known and modified the problem of external interrupt registration and deleted the external interrupt registration part. XScuGic_Connect and XScuGic_Enable are the only two registration interrupts left, but unfortunately, the DMA program still can’t run. The program keeps busy in the XAxiDma_Busy function while testing whether it is busy, so I wonder if the DMA controller is also registered in the FreeRTOS task. I do not need to use XAxiDma_CfgInitialize with XAxiDma_LookupConfig. If so, how the first argument pointer to XAxiDma_SimpleTransfer should be assigned. If it’s not here, what’s the problem? Thanks for your answer.
My program runs in a task created by the mian function, as follows.

int main()
{
xTaskCreate(main_fun,( const char * ) "main",MAIN_STACK_SIZE,NULL,tskIDLE_PRIORITY + 1,NULL);

return 0;

}

Task definition

static void main_fun( void *pvParameters )
{
for(;;)
{

if(i==0){
dma_test();
xil_printf("finish main \n\r");

}
}

Specific dma_test(); I added in the attachment, the results of the device serial port are as follows:

type or paste code here
#include "dma_test.h"

/************************** Constant Definitions *****************************/

#define DMA_DEV_ID          XPAR_AXIDMA_0_DEVICE_ID
#define RX_INTR_ID          121
#define TX_INTR_ID          122
#define INTC_DEVICE_ID      XPAR_SCUGIC_SINGLE_DEVICE_ID
#define DDR_BASE_ADDR       XPAR_PSU_DDR_0_S_AXI_BASEADDR   //0x00000000
#define MEM_BASE_ADDR       (DDR_BASE_ADDR + 0x01100000)     //0x01100000
#define TX_BUFFER_BASE      (MEM_BASE_ADDR + 0x00100000)    //0x01200000
#define RX_BUFFER_BASE      (MEM_BASE_ADDR + 0x00300000)    //0x01400000
#define RESET_TIMEOUT_COUNTER   10000    //��λʱ��
#define TEST_START_VALUE        0x0      //������ʼֵ
#define MAX_PKT_LEN             0x100    //���Ͱ�����

/************************** Function Prototypes ******************************/

/************************** Variable Definitions *****************************/

static XAxiDma axidma;     //XAxiDmaʵ��
static XScuGic intc;       //�жϿ�������ʵ��
volatile int tx_done;      //������ɱ�־
volatile int rx_done;      //������ɱ�־
volatile int error;        //���������־
//extern	 XScuGic xInterruptController;
/************************** Function Definitions *****************************/

int dma_test(void)
{
    int i;
    int status;
    u8 value;
    u8 *tx_buffer_ptr;
    u8 *rx_buffer_ptr;
    XAxiDma_Config *config;

    tx_buffer_ptr = (u8 *) TX_BUFFER_BASE;
    rx_buffer_ptr = (u8 *) RX_BUFFER_BASE;

    xil_printf("\r\n--- Entering main() --- \r\n");

    config = XAxiDma_LookupConfig(DMA_DEV_ID);
    if (!config) {
        xil_printf("No config found for %d\r\n", DMA_DEV_ID);
        return XST_FAILURE;
    }

    //��ʼ��DMA����
    status = XAxiDma_CfgInitialize(&axidma, config);
    if (status != XST_SUCCESS) {
        xil_printf("Initialization failed %d\r\n", status);
        return XST_FAILURE;
    }

    if (XAxiDma_HasSg(&axidma)) {
        xil_printf("Device configured as SG mode \r\n");
        return XST_FAILURE;
    }

    //�����ж�ϵͳ
    status = setup_intr_system(&intc, &axidma, TX_INTR_ID, RX_INTR_ID);
    if (status != XST_SUCCESS) {
        xil_printf("Failed intr setup\r\n");
        return XST_FAILURE;
    }
    xil_printf("flag10 \n\r");
    //��ʼ����־�ź�
    tx_done = 0;
    rx_done = 0;
    error   = 0;

    value = TEST_START_VALUE;
    for (i = 0; i < MAX_PKT_LEN; i++) {
        tx_buffer_ptr[i] = value;
        value = (value + 1) & 0xFF;
    }
 	if(XAxiDma_Busy(&axidma, XAXIDMA_DEVICE_TO_DMA) )
 	{
 		xil_printf("Someone DMA is busy! \r\n");
 		return XST_FAILURE;
 	}
    xil_printf("flag7 \n\r");
    Xil_DCacheFlushRange((UINTPTR) tx_buffer_ptr, MAX_PKT_LEN);   //ˢ��Data Cache
    xil_printf("flag6 \n\r");
    status = XAxiDma_SimpleTransfer(&axidma, (UINTPTR) tx_buffer_ptr,
    MAX_PKT_LEN, XAXIDMA_DMA_TO_DEVICE);
    if (status != XST_SUCCESS) {
        return XST_FAILURE;
    }
    xil_printf("flag5 \n\r");
    status = XAxiDma_SimpleTransfer(&axidma, (UINTPTR) rx_buffer_ptr,
    MAX_PKT_LEN, XAXIDMA_DEVICE_TO_DMA);
    if (status != XST_SUCCESS) {
        return XST_FAILURE;
    }
    xil_printf("flag4 \n\r");
    Xil_DCacheFlushRange((UINTPTR) rx_buffer_ptr, MAX_PKT_LEN);   //ˢ��Data Cache
    while (!tx_done && !rx_done && !error);
    xil_printf("flag8 \n\r");
    //�������
    if (error) {
        xil_printf("Failed test transmit%s done, "
                "receive%s done\r\n", tx_done ? "" : " not",
                rx_done ? "" : " not");
        goto Done;
    }

    //������ɣ���������Ƿ���ȷ
    status = check_data(MAX_PKT_LEN, TEST_START_VALUE);
    if (status != XST_SUCCESS) {
        xil_printf("Data check failed\r\n");
        goto Done;
    }

    xil_printf("Successfully ran AXI DMA Loop\r\n");
    disable_intr_system(&intc, TX_INTR_ID, RX_INTR_ID);

    Done: xil_printf("--- Exiting main() --- \r\n");
    return XST_SUCCESS;
}

//������ݻ�����
static int check_data(int length, u8 start_value)
{
    u8 value;
    u8 *rx_packet;
    int i = 0;

    value = start_value;
    rx_packet = (u8 *) RX_BUFFER_BASE;
    for (i = 0; i < length; i++) {
        if (rx_packet[i] != value) {
            xil_printf("Data error %d: %x/%x\r\n", i, rx_packet[i], value);
            return XST_FAILURE;
        }
        value = (value + 1) & 0xFF;
    }
    xil_printf("flag1 \n\r");
    return XST_SUCCESS;
}

//DMA TX�жϴ�������
static void tx_intr_handler(void *callback)
{
    int timeout;
    u32 irq_status;
    XAxiDma *axidma_inst = (XAxiDma *) callback;

    //��ȡ���������ж�
    irq_status = XAxiDma_IntrGetIrq(axidma_inst, XAXIDMA_DMA_TO_DEVICE);
    //ȷ�ϴ��������ж�
    XAxiDma_IntrAckIrq(axidma_inst, irq_status, XAXIDMA_DMA_TO_DEVICE);

    //Tx����
    if ((irq_status & XAXIDMA_IRQ_ERROR_MASK)) {
        error = 1;
        XAxiDma_Reset(axidma_inst);
        timeout = RESET_TIMEOUT_COUNTER;
        while (timeout) {
            if (XAxiDma_ResetIsDone(axidma_inst))
                break;
            timeout -= 1;
        }
        return;
    }
    xil_printf("flag2 \n\r");
    //Tx���
    if ((irq_status & XAXIDMA_IRQ_IOC_MASK))
        tx_done = 1;
}

//DMA RX�жϴ�������
static void rx_intr_handler(void *callback)
{
    u32 irq_status;
    int timeout;
    XAxiDma *axidma_inst = (XAxiDma *) callback;

    irq_status = XAxiDma_IntrGetIrq(axidma_inst, XAXIDMA_DEVICE_TO_DMA);
    XAxiDma_IntrAckIrq(axidma_inst, irq_status, XAXIDMA_DEVICE_TO_DMA);

    //Rx����
    if ((irq_status & XAXIDMA_IRQ_ERROR_MASK)) {
        error = 1;
        XAxiDma_Reset(axidma_inst);
        timeout = RESET_TIMEOUT_COUNTER;
        while (timeout) {
            if (XAxiDma_ResetIsDone(axidma_inst))
                break;
            timeout -= 1;
        }
        return;
    }
    xil_printf("flag3 \n\r");
    //Rx���
    if ((irq_status & XAXIDMA_IRQ_IOC_MASK))
        rx_done = 1;
}

//����DMA�ж�ϵͳ
//  @param   int_ins_ptr��ָ��XScuGicʵ����ָ��
//  @param   AxiDmaPtr��ָ��DMA����ʵ����ָ��
//  @param   tx_intr_id��TXͨ���ж�ID
//  @param   rx_intr_id��RXͨ���ж�ID
//  @return���ɹ�����XST_SUCCESS�����򷵻�XST_FAILURE
static int setup_intr_system(XScuGic * int_ins_ptr, XAxiDma * axidma_ptr,
        u16 tx_intr_id, u16 rx_intr_id)
{
    int status;
    XScuGic_Config *intc_config;

    //��ʼ���жϿ���������
//    intc_config = XScuGic_LookupConfig(INTC_DEVICE_ID);
//    if (NULL == intc_config) {
//        return XST_FAILURE;
//    }
//    status = XScuGic_CfgInitialize(int_ins_ptr, intc_config,
//            intc_config->CpuBaseAddress);
//    if (status != XST_SUCCESS) {
//        return XST_FAILURE;
//    }

//    �������ȼ��ʹ�������
//    XScuGic_SetPriorityTriggerType(int_ins_ptr, tx_intr_id, 0xA0, 0x3);
//    XScuGic_SetPriorityTriggerType(int_ins_ptr, rx_intr_id, 0xA0, 0x3);

    //Ϊ�ж������жϴ�������
    status = XScuGic_Connect(int_ins_ptr, tx_intr_id,
            (Xil_InterruptHandler) tx_intr_handler, axidma_ptr);
    if (status != XST_SUCCESS) {
        return status;
    }

    status = XScuGic_Connect(int_ins_ptr, rx_intr_id,
            (Xil_InterruptHandler) rx_intr_handler, axidma_ptr);
    if (status != XST_SUCCESS) {
        return status;
    }

    XScuGic_Enable(int_ins_ptr, tx_intr_id);
    XScuGic_Enable(int_ins_ptr, rx_intr_id);

    //��������Ӳ�����ж�
//    Xil_ExceptionInit();
//    Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
//            (Xil_ExceptionHandler) XScuGic_InterruptHandler,
//            (void *) int_ins_ptr);
//    Xil_ExceptionEnable();

    //ʹ��DMA�ж�
    XAxiDma_IntrEnable(&axidma, XAXIDMA_IRQ_ALL_MASK, XAXIDMA_DMA_TO_DEVICE);
    XAxiDma_IntrEnable(&axidma, XAXIDMA_IRQ_ALL_MASK, XAXIDMA_DEVICE_TO_DMA);

    return XST_SUCCESS;
}

//�˺�������DMA������ж�
static void disable_intr_system(XScuGic * int_ins_ptr, u16 tx_intr_id,
        u16 rx_intr_id)
{
    XScuGic_Disconnect(int_ins_ptr, tx_intr_id);
    XScuGic_Disconnect(int_ins_ptr, rx_intr_id);
}

main end have vTaskStartScheduler();I miss it,but the result is same

Are you able to make it work without FreeRTOS?

yes,i finally find the problem which is the design of haedware 。thank you for you suggest。

Thank you for reporting back!

Hi @majingqi ,

Can you share exact specifics of your resolution?

Facing the same issue. Working in standalone but not working when I am using it in a Task.

Thanks in advance,

-ZoroIchimonji

Are you initializing your interrupts in main? If yes, can you try moving the interrupt initialization code to task?