打印
[其他ST产品]

串口中断不触发的问题

[复制链接]
83|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lvuu|  楼主 | 2024-6-29 23:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在STM32H743中使用ICACHE(指令缓存)和DCACHE(数据缓存)后,可能会导致一些中断,尤其是串口中断不触发的问题。这通常是由于缓存的一些行为导致的,例如缓存一致性问题。以下是一些解决方法和建议:

1. 缓存一致性
确保缓存与内存的一致性。尤其是当DMA用于传输数据时,需要保证DMA使用的内存区域在缓存被更新之后。

2. 禁用缓存区域
如果缓存一致性问题难以解决,可以考虑禁用相关内存区域的缓存。

禁用数据缓存区域
可以通过配置MPU(内存保护单元)来禁用某些特定内存区域的数据缓存。具体操作如下:

c

#include "stm32h7xx_hal.h"

void MPU_Config(void)
{
    MPU_Region_InitTypeDef MPU_InitStruct;

    HAL_MPU_Disable();

    MPU_InitStruct.Enable = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress = 0x20000000; // 假设你使用的是SRAM1区域
    MPU_InitStruct.Size = MPU_REGION_SIZE_256KB; // 根据具体情况调整大小
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
    MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
    MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
    MPU_InitStruct.Number = MPU_REGION_NUMBER0;
    MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;

    HAL_MPU_ConfigRegion(&MPU_InitStruct);
    HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

在系统初始化时调用MPU_Config函数:

c

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MPU_Config();
    // 其他初始化代码
    while (1)
    {
    }
}



使用特权

评论回复
沙发
lvuu|  楼主 | 2024-6-29 23:45 | 只看该作者
确保DMA缓冲区不被缓存
DMA缓冲区应设置为非缓存区。可以使用特定的关键字来声明DMA缓冲区,例如:

c
__attribute__((section(".dma_buffer"))) uint8_t dma_rx_buffer[BUFFER_SIZE];

然后在链接脚本中定义.dma_buffer段为非缓存区:

ld

使用特权

评论回复
板凳
lvuu|  楼主 | 2024-6-29 23:45 | 只看该作者
/* 链接脚本示例 */
SECTIONS
{
    .dma_buffer (NOLOAD) :
    {
        . = ALIGN(4);
        *(.dma_buffer)
        . = ALIGN(4);
    } >RAM_D1
}

使用特权

评论回复
地板
lvuu|  楼主 | 2024-6-29 23:46 | 只看该作者
刷新和清除缓存
在DMA传输前后手动刷新和清除缓存:

c
SCB_CleanDCache_by_Addr((uint32_t *)dma_rx_buffer, BUFFER_SIZE);

使用特权

评论回复
5
lvuu|  楼主 | 2024-6-29 23:47 | 只看该作者
检查中断优先级
确保串口中断的优先级适当配置,不要低于其他可能抢占的中断:

c
HAL_NVIC_SetPriority(USARTx_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(USARTx_IRQn);

使用特权

评论回复
6
lvuu|  楼主 | 2024-6-29 23:47 | 只看该作者
检查缓存启用配置
确认你已经正确启用了ICACHE和DCACHE:

c
SCB_EnableICache();
SCB_EnableDCache();

使用特权

评论回复
7
lvuu|  楼主 | 2024-6-29 23:47 | 只看该作者
检查中断处理函数
确保串口中断处理函数正确配置且不会被优化掉:

c
void USARTx_IRQHandler(void)
{
    HAL_UART_IRQHandler(&huart);
}

使用特权

评论回复
8
lvuu|  楼主 | 2024-6-29 23:47 | 只看该作者
通过以上步骤,你应该能够解决使用ICACHE和DCACHE后串口中断不触发的问题。如果问题仍然存在,可以进一步检查具体代码和配置,以确保缓存和中断的正确性。

使用特权

评论回复
9
szt1993| | 2024-6-30 08:33 | 只看该作者
可以通过配置MPU(内存保护单元)来禁用某些特定内存区域的数据缓存。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

49

主题

414

帖子

0

粉丝