搜索
bottom↓
回复: 26

stm32F7,开启 cache 后,uart+idl+dma 接收失败?

[复制链接]

出0入0汤圆

发表于 2017-3-30 12:03:19 | 显示全部楼层 |阅读模式
本帖最后由 hpdell 于 2017-3-30 12:05 编辑

F7的单片机,开启 cache 后,uart-idl+dma接收不到数据,中断可以进入,

SCB_EnableICache();   //使能I-Cache
SCB_EnableDCache();   //使能D-Cache    后,

使用usart+dma 接收就不行
屏蔽后uart+dam可以,但sd卡又不行

该如何处理啊 ??

sd卡使用 查询模式,

感觉这个f7的 cache 使用起来很麻烦,

其他的 mpu 保护还没有进行任何设置

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入90汤圆

发表于 2017-3-30 12:04:26 | 显示全部楼层
没玩到F7,还在F4呢。应该是还没搞明白,等搞明白了,估计就不麻烦了。

出0入0汤圆

 楼主| 发表于 2017-3-30 12:05:55 | 显示全部楼层
honami520 发表于 2017-3-30 12:04
没玩到F7,还在F4呢。应该是还没搞明白,等搞明白了,估计就不麻烦了。

有这个可能吧

出0入0汤圆

发表于 2017-3-30 13:07:59 | 显示全部楼层
F7 RAM有多快?
如果速度是F7速度的一半,就把数据CACHE关掉好了。因为用CACHE要解决数据一致性的问题。

仔细阅读一下ST的文档,看上面怎么说。

出0入0汤圆

发表于 2017-3-30 13:30:58 来自手机 | 显示全部楼层
编译f7而且能装在xp上的mdk版本是哪个?

出0入54汤圆

发表于 2017-3-30 13:51:20 | 显示全部楼层
这是我的FATFS中使用DMA和不使用DMA的调用,你可以参考看看,开启DMA前和读完数据后都要无效下cache。我比较了下速度,没有相差很多,所以最后没用DMA了。
  1. DRESULT SD_read(BYTE lun, BYTE *buff, DWORD sector, UINT count)
  2. {
  3.   DRESULT res = RES_OK;
  4. #ifdef READ_SD_USE_DMA
  5.   u32 addr = (u32)buff;
  6.   u32 size = count * BLOCK_SIZE;
  7.   if (addr & 0x1F) {                // align 32 byte
  8.           addr &= ~((u32)0x1F);
  9.         size += 0x20;
  10.   }
  11.   SCB_InvalidateDCache_by_Addr((u32*)addr, size);
  12.   if(BSP_SD_ReadBlocks_DMA((uint32_t*)buff,
  13.                        ((uint64_t)sector)*BLOCK_SIZE,
  14.                        BLOCK_SIZE,
  15.                        count) != MSD_OK)
  16.   {
  17.     res = RES_ERROR;
  18.   }
  19.   SCB_InvalidateDCache_by_Addr((u32*)addr, size);
  20. #else
  21.   if(BSP_SD_ReadBlocks((uint32_t*)buff,
  22.                        ((uint64_t)sector)*BLOCK_SIZE,
  23.                        BLOCK_SIZE,
  24.                        count) != MSD_OK)
  25.   {
  26.     res = RES_ERROR;
  27.   }
  28. #endif
  29.   return res;
  30. }
复制代码

出0入0汤圆

 楼主| 发表于 2017-3-30 14:11:40 | 显示全部楼层
lusson 发表于 2017-3-30 13:51
这是我的FATFS中使用DMA和不使用DMA的调用,你可以参考看看,开启DMA前和读完数据后都要无效下cache。我比 ...

你好,我现在的 sd 也是没有使用dma

出0入54汤圆

发表于 2017-3-30 14:18:25 | 显示全部楼层
hpdell 发表于 2017-3-30 14:11
你好,我现在的 sd 也是没有使用dma

不知道你的接收失败是什么失败?

出0入0汤圆

 楼主| 发表于 2017-3-30 14:34:23 | 显示全部楼层
lusson 发表于 2017-3-30 14:18
不知道你的接收失败是什么失败?

可以进入 uart idl 空闲中断里面,接收到的数据字节数是对的,

相关代码如下:


/* 此函数需要在主循环中调用 */
void USART1_DMA_IDLE_TEST(void)
{
        if(g_tUsart1.RxCompleteFlag ==1)
        {
//                printf("\r\ng_tUsart1.RxCnt = %d \r\n",g_tUsart1.RxCnt);   // 这个地方输出接收到的字节数与发送的字节数目完全一致
               
                printf("%s" ,  g_tUsart1.RxBuff);                        // 这个地方是吧接收到的数据 发回到电脑显示,但是这个地方木有内容输出 ?????????????????问题就在此处

                g_tUsart1.RxCnt=0;
                g_tUsart1.RxCompleteFlag=0;
        }
        HAL_UART_Receive_DMA(&huart1,g_tUsart1.RxBuff,USART1_MAX_RX_SIZE);

}


// 中断函数
void USART1_IRQHandler(void)
{
                uint32_t tmp_flag = 0;
                uint32_t temp;
   
                tmp_flag =  __HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE);
                if((tmp_flag != RESET))
                {
                                __HAL_UART_CLEAR_IDLEFLAG(&huart1);
        
        //先读SR后读DR清除Idle
                                temp = huart1.Instance->ISR;  
                                temp = huart1.Instance->RDR;
                                HAL_UART_DMAStop(&huart1);
                                temp  = hdma_usart1_rx.Instance->NDTR;
                                g_tUsart1.RxCnt =  USART1_MAX_RX_SIZE - temp;
        //                  printf("\r\ng_tUsart1.RxCnt = %d",g_tUsart1.RxCnt);                        // test user
                                g_tUsart1.RxCompleteFlag = 1;                                 // 接收完成标志职位       
                }       
}

出0入54汤圆

发表于 2017-3-30 14:52:54 | 显示全部楼层
%s,数据不会是0x00开头了吧。不是可以调试吗?直接在这个地方打断点看看啊

出0入0汤圆

 楼主| 发表于 2017-3-30 15:08:26 | 显示全部楼层
lusson 发表于 2017-3-30 14:52
%s,数据不会是0x00开头了吧。不是可以调试吗?直接在这个地方打断点看看啊 ...

因为我使用上位机发送的是字符,所以输出的也是字符,这个程序在以前的其他芯片上使用过,是没有问题的,

现在也不知道是怎么回事,每次仿真,iar 编译器就停止了,哎,悲催

出0入54汤圆

发表于 2017-3-30 16:02:10 | 显示全部楼层
加了cache的话,在使用DMA的数据前加上  SCB_InvalidateDCache_by_Addr((u32*)addr, size);试试看。

出0入0汤圆

 楼主| 发表于 2017-3-30 19:03:42 | 显示全部楼层
本帖最后由 hpdell 于 2017-3-30 19:10 编辑
lusson 发表于 2017-3-30 16:02
加了cache的话,在使用DMA的数据前加上  SCB_InvalidateDCache_by_Addr((u32*)addr, size);试试看。 ...


你好,

只找到这个函数
/**
  \brief   Clean & Invalidate D-Cache
  \details Cleans and Invalidates D-Cache
  */
__STATIC_INLINE void SCB_CleanInvalidateDCache (void)
{
  #if (__DCACHE_PRESENT == 1U)
    uint32_t ccsidr;
    uint32_t sets;
    uint32_t ways;

    SCB->CSSELR = (0U << 1U) | 0U;          /* Level 1 data cache */
    __DSB();

    ccsidr = SCB->CCSIDR;

                                            /* clean & invalidate D-Cache */
    sets = (uint32_t)(CCSIDR_SETS(ccsidr));
    do {
      ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
      do {
        SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) |
                       ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk)  );
        #if defined ( __CC_ARM )
          __schedule_barrier();
        #endif
      } while (ways--);
    } while(sets--);

    __DSB();
    __ISB();
  #endif
}


没有找到你所说的函数




仿真仿着放着就出现如下图片的内容:




下面这个图片显示我发送的数据字节数是完全正确的



我发送了40个Byte, 再加上回车换行,总共应该是 42个Byte,但是接收到的数据就是没有内容





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入54汤圆

发表于 2017-3-30 20:21:51 | 显示全部楼层
hpdell 发表于 2017-3-30 19:03
你好,

只找到这个函数

数量对不代表数据对,数据可能被cache掉了。我这个是Core_cm7.h中的函数啊。HAL库

/**
  \fn          void SCB_InvalidateDCache_by_Addr(volatile uint32_t *addr, int32_t dsize)
  \brief       D-Cache Invalidate by address
  \param[in]   addr    address (aligned to 32-byte boundary)
  \param[in]   dsize   size of memory block (in number of bytes)
*/
__STATIC_INLINE void SCB_InvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize)
{
  #if (__DCACHE_PRESENT == 1)
    int32_t  op_size = dsize;
    uint32_t op_addr = (uint32_t)addr;
    uint32_t linesize = 32UL;               // in Cortex-M7 size of cache line is fixed to 8 words (32 bytes)

    __DSB();

    while (op_size > 0) {
      SCB->DCIMVAC = op_addr;
      op_addr +=          linesize;
      op_size -= (int32_t)linesize;
    }

    __DSB();
    __ISB();
  #endif
}

出0入0汤圆

 楼主| 发表于 2017-3-31 09:13:05 | 显示全部楼层
lusson 发表于 2017-3-30 20:21
数量对不代表数据对,数据可能被cache掉了。我这个是Core_cm7.h中的函数啊。HAL库

/**

你好,按照你的这个方法 终于搞定了,你兄台对这个研究的很透彻啊,多谢多谢了

出0入54汤圆

发表于 2017-3-31 09:16:39 | 显示全部楼层
hpdell 发表于 2017-3-31 09:13
你好,按照你的这个方法 终于搞定了,你兄台对这个研究的很透彻啊,多谢多谢了  ...


我也是从F4用到F7的时候遇到了这些坑,网上查资料以及看M7的手册,M7手册中好像有这一点的介绍,特别是关于使用DMA的时候要注意
不使能D-cache的话,我实际跑下来的速度连F4都不如。

出0入0汤圆

 楼主| 发表于 2017-3-31 20:21:47 | 显示全部楼层
lusson 发表于 2017-3-31 09:16
我也是从F4用到F7的时候遇到了这些坑,网上查资料以及看M7的手册,M7手册中好像有这一点的介绍,特别是关 ...

确实是这样的啊,我在刷屏时,如果不开启 cache ,刷屏速度很慢,开启cache 后,刷屏速度那是快的不要不要的

出0入0汤圆

发表于 2017-4-2 08:06:59 来自手机 | 显示全部楼层
标记一下!最近在裸奔sama5d3,sd卡用dma读取总是不正确,估计也是这样。

出0入8汤圆

发表于 2017-4-2 08:47:01 | 显示全部楼层
我没用接触过过 STM32,更别说是 F7 系列,但我从理论上扯几句:
- 使用 DMA,就要注意 cache 一致性的问题。
- DMA 是绕过 CPU,直接进行的数据搬运操作。
- 如果开启数据 cache 的话,CPU 对于内存的认知来源,是源自 cache,cache 的数据分布,是由 CPU 管控的。
- 而 DMA,却自己改变了物理内存的数据分布,此时 CPU 一无所知,CPU 依旧认为内存数据木有变化, 也就不会去无效化、重新刷新 cache。
- 此时,就会出现 cache 数据与物理内存数据的不一致问题。
- 因此,DMA 操作,要嘛关闭 cache,要嘛就是要注意主动去无效化 cache,而不是什么也不做,因为你不做,CPU 也不会去做什么(它压根就感知不到数据有变化)。

出0入0汤圆

发表于 2017-4-2 10:05:36 | 显示全部楼层
security 发表于 2017-4-2 08:47
我没用接触过过 STM32,更别说是 F7 系列,但我从理论上扯几句:
- 使用 DMA,就要注意 cache 一致性的问题 ...

正解,我在st社区查到的就是这样,看样子要注意了。

出0入0汤圆

 楼主| 发表于 2017-4-2 11:48:07 | 显示全部楼层
XA144F 发表于 2017-4-2 10:05
正解,我在st社区查到的就是这样,看样子要注意了。

你好,st 社区 是哪个帖子啊 ??

出0入0汤圆

发表于 2017-4-2 15:31:20 | 显示全部楼层
hpdell 发表于 2017-4-2 11:48
你好,st 社区 是哪个帖子啊 ??

是这个帖子:
http://www.stmcu.org/module/forum/thread-610737-1-1.html

出0入13汤圆

发表于 2017-4-2 16:47:48 来自手机 | 显示全部楼层
手上有板子不过还没玩起来

出0入0汤圆

 楼主| 发表于 2017-4-3 09:50:05 | 显示全部楼层
weiwei4 发表于 2017-4-2 16:47
手上有板子不过还没玩起来

感觉这个f7 折腾起来比较麻烦啊

出0入0汤圆

发表于 2017-8-19 02:16:50 | 显示全部楼层
security 发表于 2017-4-2 08:47
我没用接触过过 STM32,更别说是 F7 系列,但我从理论上扯几句:
- 使用 DMA,就要注意 cache 一致性的问题 ...

您说得很好,请问这方面的理论知识在什么书上有介绍?我想系统地去了解一下

出0入8汤圆

发表于 2017-8-19 08:41:18 | 显示全部楼层
4317mjh 发表于 2017-8-19 02:16
您说得很好,请问这方面的理论知识在什么书上有介绍?我想系统地去了解一下 ...

可以在『ARM体系结构与编程杜春雷,这本书里面找到相关的描述。
详见: 5.4.6 存储系统的一致性问题

出0入0汤圆

发表于 2017-8-19 10:23:47 | 显示全部楼层
lusson 发表于 2017-3-30 13:51
这是我的FATFS中使用DMA和不使用DMA的调用,你可以参考看看,开启DMA前和读完数据后都要无效下cache。我比 ...

非常感谢兄弟您的分享!
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-22 10:41

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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