STM32H7写入flash时死机,进入default_Handler卡死
想实现把一个变量最后的运行结果存入flash,掉电后初始化把该flash地址的值赋给该变量
以下是自己封装的flash读写函数 flash为2M 有两个bank 已确认代码长度 定义要写入的地址Flash_Add= 0x081E1000 不会影响到程序代码 主程序调用Flash_Write(ZERO) ZERO是一个 uint32_t的全局变量
void Flash_Erase(void)
{
EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
EraseInitStruct.Banks=FLASH_BANK_2;
EraseInitStruct.Sector=7;
EraseInitStruct.NbSectors= 1;
EraseInitStruct.VoltageRange=FLASH_VOLTAGE_RANGE_3;
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) != HAL_OK)
{
HAL_FLASH_Lock();
printf(" Error...1\r\n");
Error_Handler();
}
}
void Flash_Write(u32 Flash_data)
{
HAL_FLASH_Unlock(); //解锁
Flash_Erase( ); //先擦除
//再写入
// printf(" 擦除完成,准备写入......\r\n");
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, Flash_Add, Flash_data) != HAL_OK)
{
printf(" Error...2\r\n");
Error_Handler( );
}
HAL_FLASH_Lock(); //上锁
}
调用的hal库函数
HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
{
HAL_StatusTypeDef status;
__IO uint32_t *dest_addr = (__IO uint32_t *)FlashAddress;
__IO uint32_t *src_addr = (__IO uint32_t*)DataAddress;
uint32_t bank;
uint8_t row_index = FLASH_NB_32BITWORD_IN_FLASHWORD;
/* Check the parameters */
assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
assert_param(IS_FLASH_PROGRAM_ADDRESS(FlashAddress));
/* Process Locked */
__HAL_LOCK(&pFlash);
#if defined (FLASH_OPTCR_PG_OTP)
if((IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress)) || (IS_FLASH_PROGRAM_ADDRESS_OTP(FlashAddress)))
#else
if(IS_FLASH_PROGRAM_ADDRESS_BANK1(FlashAddress))
#endif /* FLASH_OPTCR_PG_OTP */
{
bank = FLASH_BANK_1;
}
#if defined (DUAL_BANK)
else if(IS_FLASH_PROGRAM_ADDRESS_BANK2(FlashAddress))
{
bank = FLASH_BANK_2;
}
#endif /* DUAL_BANK */
else
{
return HAL_ERROR;
}
/* Reset error code */
pFlash.ErrorCode = HAL_FLASH_ERROR_NONE;
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);
if(status == HAL_OK)
{
#if defined (DUAL_BANK)
if(bank == FLASH_BANK_1)
{
#if defined (FLASH_OPTCR_PG_OTP)
if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
{
/* Set OTP_PG bit */
SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
}
else
#endif /* FLASH_OPTCR_PG_OTP */
{
/* Set PG bit */
SET_BIT(FLASH->CR1, FLASH_CR_PG);
}
}
else
{
/* Set PG bit */
SET_BIT(FLASH->CR2, FLASH_CR_PG);
}
#else /* Single Bank */
#if defined (FLASH_OPTCR_PG_OTP)
if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
{
/* Set OTP_PG bit */
SET_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
}
else
#endif /* FLASH_OPTCR_PG_OTP */
{
/* Set PG bit */
SET_BIT(FLASH->CR1, FLASH_CR_PG);
}
#endif /* DUAL_BANK */
__ISB();
__DSB();
#if defined (FLASH_OPTCR_PG_OTP)
if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
{
/* Program an OTP word (16 bits) */
*(__IO uint16_t *)FlashAddress = *(__IO uint16_t*)DataAddress;
}
else
#endif /* FLASH_OPTCR_PG_OTP */
{
/* Program the flash word */
do
{
*dest_addr = *src_addr;
dest_addr++;
src_addr++;
row_index--;
} while (row_index != 0U);
}
__ISB();
__DSB();
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE, bank);
#if defined (DUAL_BANK)
#if defined (FLASH_OPTCR_PG_OTP)
if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
{
/* If the program operation is completed, disable the OTP_PG */
CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
}
else
#endif /* FLASH_OPTCR_PG_OTP */
{
if(bank == FLASH_BANK_1)
{
/* If the program operation is completed, disable the PG */
CLEAR_BIT(FLASH->CR1, FLASH_CR_PG);
}
else
{
/* If the program operation is completed, disable the PG */
CLEAR_BIT(FLASH->CR2, FLASH_CR_PG);
}
}
#else /* Single Bank */
#if defined (FLASH_OPTCR_PG_OTP)
if (TypeProgram == FLASH_TYPEPROGRAM_OTPWORD)
{
/* If the program operation is completed, disable the OTP_PG */
CLEAR_BIT(FLASH->OPTCR, FLASH_OPTCR_PG_OTP);
}
else
#endif /* FLASH_OPTCR_PG_OTP */
{
/* If the program operation is completed, disable the PG */
CLEAR_BIT(FLASH->CR1, FLASH_CR_PG);
}
#endif /* DUAL_BANK */
}
/* Process Unlocked */
__HAL_UNLOCK(&pFlash);
return status;
}
我单步调试,发现运行到 *dest_addr = *src_addr;这一句时就会死机,进入default_Handler,本身对这句所在的while循环我也不太能理解,直接用的这个hal库函数,为什么前面 __IO uint32_t src_addr = (__IO uint32_t)DataAddress;DataAddress难道不是我要写入的数据ZERO的值吗
求大家给看看,不知道咋解决了,排查了很久,都不知道