lfldalong 发表于 2022-3-29 15:21:07

RTX系统下串口DMA第一帧发送数据全为0,第二帧正常

1、使用RTX系统后,串口DMA发送数据第一帧全为0,但是数据个数是对的,封装的发送函数如下ALIGN_32BYTES(__attribute__((section(".ARM.__at_0x24000000")))) uint8_t send_com8_buff;//
ALIGN_32BYTES(__attribute__((section(".ARM.__at_0x24000100")))) uint8_t send_com1_buff;//
ALIGN_32BYTES(__attribute__((section(".ARM.__at_0x24000200")))) uint8_t send_com2_buff;//
ALIGN_32BYTES(__attribute__((section(".ARM.__at_0x24000300")))) uint8_t send_com4_buff;//
ALIGN_32BYTES(__attribute__((section(".ARM.__at_0x24000400")))) uint8_t send_com6_buff;//
ALIGN_32BYTES(__attribute__((section(".ARM.__at_0x24000500")))) uint8_t send_com3_buff;//
uint16_t comSendBuf(COM_PORT_E _ucPort, uint8_t* _ucaBuf, uint16_t _usLen)
{
        UART_T* pUart;

        pUart = ComToUart(_ucPort);

        USART_TypeDef* Usart = pUart->uart;
       

        if (Usart == USART1)
        {
                SCB_InvalidateDCache_by_Addr((uint32_t*)send_com1_buff, 256);
                memcpy(send_com1_buff, _ucaBuf, _usLen);
                if (HAL_DMA_GetState(&USART1_DMA_Handle_TX) == HAL_DMA_STATE_BUSY)//连续发送时后面加系统延时
                {
                        return 1;
                }
                HAL_UART_Transmit_DMA(&Usart1Handle, send_com1_buff, _usLen);
       
        }

        if (Usart == USART2)
        {
                SCB_InvalidateDCache_by_Addr((uint32_t*)send_com2_buff, 256);
                memcpy(send_com2_buff, _ucaBuf, _usLen);
                if (HAL_DMA_GetState(&USART2_DMA_Handle_TX) == HAL_DMA_STATE_BUSY)//连续发送时后面加系统延时
                {                        return 2;
                }
                HAL_UART_Transmit_DMA(&Usart2Handle, send_com2_buff, _usLen);
                /*for (i = 0; i < _usLen; i++)
                {
                        HAL_UART_Transmit(&Usart2Handle, _ucaBuf++, 1, 1000);
                }*/
        }
        if (Usart == USART3)
        {
                SCB_InvalidateDCache_by_Addr((uint32_t*)send_com3_buff, 256);
                memcpy(send_com3_buff, _ucaBuf, _usLen);
                if (HAL_DMA_GetState(&USART3_DMA_Handle_TX) != HAL_DMA_STATE_READY)//连续发送时后面加系统延时
                {
                        return 3;
                }

                HAL_UART_Transmit_DMA(&Usart3Handle, send_com3_buff, _usLen);
        }
        if (Usart == UART4)
        {
                SCB_InvalidateDCache_by_Addr((uint32_t*)send_com4_buff, 256);
                memcpy(send_com4_buff, _ucaBuf, _usLen);
                if (HAL_DMA_GetState(&UART4_DMA_Handle_TX) == HAL_DMA_STATE_BUSY)//连续发送时后面加系统延时
                {
                        return 4;
                }
                HAL_UART_Transmit_DMA(&Uart4Handle, send_com4_buff, _usLen);
               
        }

        if (Usart == USART6)
        {
                SCB_InvalidateDCache_by_Addr((uint32_t*)send_com6_buff, 256);
                memcpy(send_com6_buff, _ucaBuf, _usLen);
                if (HAL_DMA_GetState(&USART6_DMA_Handle_TX) == HAL_DMA_STATE_BUSY)//连续发送时后面加系统延时
                {
                       
                        return 6;
                }
                HAL_UART_Transmit_DMA(&Usart6Handle, send_com6_buff, _usLen);
               
        }


        if (Usart == UART8)
        {
                SCB_InvalidateDCache_by_Addr((uint32_t*)send_com8_buff, 256);
                memcpy(send_com8_buff, _ucaBuf, _usLen);
                if (HAL_DMA_GetState(&UART8_DMA_Handle_TX) == HAL_DMA_STATE_BUSY)//连续发送时后面加系统延时
                {
                        bsp_DelayMS(1);//使用操作系统时,使用系统延时
                        return 8;
                }
                HAL_UART_Transmit_DMA(&Uart8Handle, send_com8_buff, _usLen);
               
                                }
               
        }

        return _usLen;
}

2、在线程中调佣发送函数
void task_check(void *argument)
{
        const uint16_t usFrequency = 200; /* 延迟周期 */
        uint32_t tick;
        static unsigned int cnt = 0;
        static int num = 0;
        /* 获取当前时间 */

        int i=0;
        //my_file_opt_t msg;
       
    while(1)
    {


                osDelay(TASK_IDLE_CHECK*10);

                bsp_LedToggle(1);
                /* 相对延迟 */
                //tick += usFrequency;                        
                //osDelayUntil(tick);
               
                check_data_process();//自检信息处理
               
                cnt ++;



               
       
                if(cnt%25 == 0)
                {                       
                        run_event_create(1,1,&test_log);
                }

               

                test_buf = 0x12;


                test_buf = 0x23;
                test_buf = 0x34;
                test_buf = 0x45;
                test_buf = 0x56;
                test_buf = 0x67;
               
       
                        comSendBuf(COM3,test_buf,6);
                        comSendBuf(COM3,test_buf,6);       
       
       
    }
}


eric2013 发表于 2022-3-29 15:57:34

串口DMA发送前应该做Cache 的Clean操作,简单省事些,直接关闭AXI SRAM的Cache试试。

lfldalong 发表于 2022-3-29 17:19:29

硬汉哥,可以了,串口DMA发送前使用了SCB_CleanDCache();,能正常发送了。
页: [1]
查看完整版本: RTX系统下串口DMA第一帧发送数据全为0,第二帧正常