硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1113|回复: 2
收起左侧

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

[复制链接]

5

主题

6

回帖

21

积分

新手上路

积分
21
发表于 2022-3-29 15:21:07 | 显示全部楼层 |阅读模式
1、使用RTX系统后,串口DMA发送数据第一帧全为0,但是数据个数是对的,封装的发送函数如下ALIGN_32BYTES(__attribute__((section(".ARM.__at_0x24000000")))) uint8_t send_com8_buff[BUFFER_SIZE];//
ALIGN_32BYTES(__attribute__((section(".ARM.__at_0x24000100")))) uint8_t send_com1_buff[BUFFER_SIZE];//
ALIGN_32BYTES(__attribute__((section(".ARM.__at_0x24000200")))) uint8_t send_com2_buff[BUFFER_SIZE];//
ALIGN_32BYTES(__attribute__((section(".ARM.__at_0x24000300")))) uint8_t send_com4_buff[BUFFER_SIZE];//
ALIGN_32BYTES(__attribute__((section(".ARM.__at_0x24000400")))) uint8_t send_com6_buff[BUFFER_SIZE];//
ALIGN_32BYTES(__attribute__((section(".ARM.__at_0x24000500")))) uint8_t send_com3_buff[BUFFER_SIZE];//
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[0]);
                }

               

                test_buf[0] = 0x12;


                test_buf[1] = 0x23;
                test_buf[2] = 0x34;
                test_buf[3] = 0x45;
                test_buf[4] = 0x56;
                test_buf[5] = 0x67;
               
       
                        comSendBuf(COM3,test_buf,6);
                        comSendBuf(COM3,test_buf,6);       
       
       
    }
}


回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106590
QQ
发表于 2022-3-29 15:57:34 | 显示全部楼层
串口DMA发送前应该做Cache 的Clean操作,简单省事些,直接关闭AXI SRAM的Cache试试。
回复

使用道具 举报

5

主题

6

回帖

21

积分

新手上路

积分
21
 楼主| 发表于 2022-3-29 17:19:29 | 显示全部楼层
硬汉哥,可以了,串口DMA发送前使用了SCB_CleanDCache();,能正常发送了。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-26 03:27 , Processed in 0.148149 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表