ST意法半导体
直播中

申根换

8年用户 1681经验值
私信 关注
[问答]

求助,关于U575RI的GPDMA_LINKED_list模式的疑问求解

使用HAL_DCMI_Start_DMA(&g_dcmi_handle, DCMI_MODE_CONtiNUOUS, (uint32_t)p_jpeg_data_buf, 15*1024*4);
启动后,只有链表1、2生效,链表3无报错但是无效

/**

* @brief  DMA Linked-list DCMIQueue configuration
* @param  None
* @retval None
  */
  HAL_StatusTypeDef MX_DCMIQueue_Config(void)
  {
  HAL_StatusTypeDef ret = HAL_OK;
  /* DMA node configuration declaration */
  DMA_NodeConfTypeDef pNodeConfig;

/* Set node configuration */
pNodeConfig.NodeType = DMA_GPDMA_LINEAR_NODE;//DMA_GPDMA_2D_NODE;//GPDMA二维寻址
pNodeConfig.Init.Request = GPDMA1_REQUEST_DCMI;
pNodeConfig.Init.BlkHWRequest = DMA_BREQ_SINGLE_BURST;//DMA传输硬件协议,单个传输或者块传输
pNodeConfig.Init.Direction = DMA_PERIPH_TO_MEMORY;//数据搬运方向,外设到内存
pNodeConfig.Init.SrcInc = DMA_SINC_FIXED;//外设地址非自增
pNodeConfig.Init.DestInc = DMA_DINC_INCREMENTED;//内存地址自增
pNodeConfig.Init.SrcDataWidth = DMA_SRC_DATAWIDTH_WORD;//32位
pNodeConfig.Init.DestDataWidth = DMA_DEST_DATAWIDTH_WORD;
pNodeConfig.Init.SrcBurstLength = 1;
pNodeConfig.Init.DestBurstLength = 1;
pNodeConfig.Init.TransferAllocatedPort = DMA_SRC_ALLOCATED_PORT0|DMA_DEST_ALLOCATED_PORT0;
pNodeConfig.Init.TransferEventMode = DMA_TCEM_EACH_LL_ITEM_TRANSFER;//DMA_TCEM_BLOCK_TRANSFER;//传输完成事件产生方式
pNodeConfig.RepeatBlockConfig.RepeatCount = 1;//通道重复次数
pNodeConfig.RepeatBlockConfig.SrcAddrOffset = 0;
pNodeConfig.RepeatBlockConfig.DestAddrOffset = 0;
pNodeConfig.RepeatBlockConfig.BlkSrcAddrOffset = 0;
pNodeConfig.RepeatBlockConfig.BlkDestAddrOffset = 0;
pNodeConfig.TriggerConfig.TriggerPolarity = DMA_TRIG_POLARITY_MASKED;//电平边沿,无
pNodeConfig.DataHandlingConfig.DataExchange = DMA_EXCHANGE_NONE;//不开启,字节序交换
pNodeConfig.DataHandlingConfig.DataAlignment = DMA_DATA_RIGHTALIGN_ZEROPADDED;//如果源的数据和目标内存数据宽度不一致,字节对齐的方式
pNodeConfig.SrcAddress = 0;
pNodeConfig.DstAddress = 0;
pNodeConfig.DataSize = 0;

/* Build DCMINode1 Node */
ret |= HAL_DMAEx_List_BuildNode(&pNodeConfig, &DCMINode1);
/* Insert DCMINode1 to Queue */
ret |= HAL_DMAEx_List_InsertNode_Tail(&DCMIQueue, &DCMINode1);

//        printf("DCMIQueue.State = %u rn", DCMIQueue.State);
//        printf("DCMIQueue.ErrorCode = %u rn", DCMIQueue.ErrorCode);
//        printf("DCMIQueue.NodeNumber = %u rn", DCMIQueue.NodeNumber);
/******************************************************************/
pNodeConfig.SrcAddress = (uint32_t)p_jpeg_data_buf + 15*1024*4*1;
pNodeConfig.DstAddress = (uint32_t)&g_dcmi_handle.Instance->DR;
pNodeConfig.DataSize = 15*1024*4;

/* Build DCMINode2 Node */
ret |= HAL_DMAEx_List_BuildNode(&pNodeConfig, &DCMINode2);
/* Insert DCMINode2 to Queue */
ret |= HAL_DMAEx_List_InsertNode_Tail(&DCMIQueue, &DCMINode2);
/******************************************************************/
pNodeConfig.SrcAddress = (uint32_t)p_jpeg_data_buf + 15*1024*4*2;
pNodeConfig.DstAddress = (uint32_t)&g_dcmi_handle.Instance->DR;
pNodeConfig.DataSize = 15*1024*4;

/* Build DCMINode3 Node */
ret |= HAL_DMAEx_List_BuildNode(&pNodeConfig, &DCMINode3);
/* Insert DCMINode3 to Queue */
ret |= HAL_DMAEx_List_InsertNode_Tail(&DCMIQueue, &DCMINode3);

ret |= HAL_DMAEx_List_SetCircularModeConfig(&DCMIQueue, &DCMINode1);//GPDMA链表开启循环模式
//printf("ret2 = %d rn", ret);//返回值是0,hal_ok
return ret;
}

回帖(2)

马昆秀

2025-3-7 14:50:17
我看你用的gpdma的2D 模式和链表模式,之前有碰到类似问题,即1个链表中多个节点,后面节点不工作的情况。


最终发现是配置方面的疏忽导致的。此刻没法一眼指出你的问题在哪。


这里给你分享两篇有关GPDMA 2D模式和链表应用的文章,供参考。其中一篇分享文章是
基于STM32H5的,这个地方H5和U5是一样的。
举报

李丹

2025-3-10 16:32:31

在使用GPDMA(General Purpose DMA)的Linked-list模式时,如果只有链表1和2生效,而链表3无效但没有报错,可能是由于以下几个原因导致的:


1. 链表配置问题



  • 节点配置错误:检查链表3的节点配置是否正确,包括源地址、目标地址、数据长度、传输方向等。确保每个节点的配置与链表1和2一致。

  • 链表链接错误:确保链表3的节点正确链接到前一个链表的末尾。如果链表3的节点没有正确链接,DMA可能不会继续执行链表3的传输。


2. 链表使能问题



  • 链表使能:确保链表3的节点已经正确使能。在配置完链表3的节点后,需要调用相应的HAL函数来使能链表。


3. DMA中断处理



  • 中断处理:检查DMA的中断处理函数,确保在链表1和2完成后,链表3能够正确触发。如果中断处理函数没有正确处理链表3的传输,可能会导致链表3无效。


4. DMA资源冲突



  • 资源冲突:检查是否有其他DMA通道或外设正在使用相同的资源,导致链表3无法正常执行。


5. HAL库版本问题



  • 库版本:确保使用的HAL库版本是最新的,或者至少是兼容的版本。某些旧版本的HAL库可能存在Bug,导致链表3无法正常工作。


6. 调试信息



  • 调试信息:通过调试器查看DMA寄存器的状态,确认链表3的节点是否正确加载和执行。可以查看DMA的当前节点指针、状态寄存器等信息。


示例代码检查


在你的代码中,MX_DCMIQueue_Config函数的实现可能存在问题。以下是一个可能的配置示例:


HAL_StatusTypeDef MX_DCMIQueue_Config(void)
{
    HAL_StatusTypeDef ret = HAL_OK;
    DMA_NodeConfTypeDef pNodeConfig;

    /* 配置链表1 */
    pNodeConfig.SrcAddress = (uint32_t)&source1;
    pNodeConfig.DstAddress = (uint32_t)&destination1;
    pNodeConfig.DataSize = 1024;
    ret |= HAL_DMAEx_List_InsertNode(&hdma, &pNodeConfig, 1);

    /* 配置链表2 */
    pNodeConfig.SrcAddress = (uint32_t)&source2;
    pNodeConfig.DstAddress = (uint32_t)&destination2;
    pNodeConfig.DataSize = 1024;
    ret |= HAL_DMAEx_List_InsertNode(&hdma, &pNodeConfig, 2);

    /* 配置链表3 */
    pNodeConfig.SrcAddress = (uint32_t)&source3;
    pNodeConfig.DstAddress = (uint32_t)&destination3;
    pNodeConfig.DataSize = 1024;
    ret |= HAL_DMAEx_List_InsertNode(&hdma, &pNodeConfig, 3);

    /* 使能链表 */
    ret |= HAL_DMAEx_List_Start(&hdma);

    return ret;
}

调试步骤



  1. 检查返回值:确保每个HAL_DMAEx_List_InsertNodeHAL_DMAEx_List_Start的返回值都是HAL_OK

  2. 查看寄存器:通过调试器查看DMA相关的寄存器,确认链表3的节点是否正确加载。

  3. 增加调试信息:在代码中增加调试信息,输出链表3的配置和状态,确认链表3是否被正确执行。


通过以上步骤,你应该能够找到链表3无效的原因并解决问题。如果问题依然存在,建议参考芯片的参考手册和HAL库的文档,进一步排查问题。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分