【一个STM32中Flash操作时uint64_t指针访问导致hardfault的问题和解决办法】

一个STM32中Flash操作时uint64_t指针访问导致hardfault的问题和解决办法

一、 问题描述

在一次用STM32G4的项目中,遇到一个问题,因Flash的操作函数:

HAL_StatusTypeDef  HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data);

需要用uint64_t指针去访问uint8_t的数组中的数据。程序每次运行到这里就会hardfault,如下面的程序所示:

unsigned char App_WriteFlash(unsigned int addr,unsigned char *mpt,unsigned int len)
{
    uint32_t Address = 0, PageError = 0;
    uint32_t i,cnt;
	uint64_t *pt = NULL;
	uint64_t temp;

    Address = addr;
    pt = (uint64_t *)mpt;
    i = 0;
    cnt = 0;
    while (cnt < len)
    {
        temp = *pt;       //这里会hardfault
        if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, temp) == HAL_OK)
        {
          Address = Address + 8;
          pt++;
          cnt += 8;
        }
        else
        {
               /* Error occurred while writing data in Flash memory.
                User can add here some code to deal with this error */
                return 1;
        }
    }
	
    return 0;	  
}

二、问题原因:

在单步执行时,运行到这里看汇编代码,在执行到如下一条语句时发生hardfault:

0x08000A9E E9DB4500  LDRD          r4,r5,[r11,#0]

这里是读取DWORD的数据到R4和R5中保存,这是的R11中地址是0x20000F1D,分析主要的原因是这里传入的起始地址没有对齐到word(字),LDRD指令操作就会产生hardfault。

M4内核文档中有这部分相关的描述,下面这里描述了对齐要求和无需对齐要求的指令:
在这里插入图片描述
另外,也指出了LDRD指令在未对其的情况下,一定会产生usagefault,且与设置无关:
在这里插入图片描述

三、解决办法:

1、不使用uint64_t 指针访问

这种方法可以将8个字节的数据一个个左移加或运算赋值到uint64_t 的局部变量中,然后再进行HAL_FLASH_Program的操作。

2、将输入数组定义在对齐的内存地址上

可以对输入数组定义后面用__attribute__((at(0x08000200)))修饰,绝对地址为4字节对齐的地址;例如:
userpara app_para __attribute__((at(0x08000200)));

3、定义输入数组为指定字节对齐方式

这种方式更好一点,输入数组定义后面用__attribute__((__aligned__(4)))修饰,定义为4字节对齐的数据;例如:
userpara app_para __attribute__((__aligned__(4)));

经过实测,以上三种方式任意一种都能解决该问题。

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值