tanglyde 2022-11-09 15:10 采纳率: 42.9%
浏览 769
已结题

基于HAL库在STM32H7写入flash时死机,进入default_Handler卡死

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的值吗
求大家给看看,不知道咋解决了,排查了很久,都不知道
  • 写回答

1条回答 默认 最新

  • emXiaoMing 2022-11-09 16:10
    关注

    HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t FlashAddress, uint32_t DataAddress)
    很明显第三参数是要写入的数据的地址,而不是要写入的数据,所以要用
    if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD, Flash_Add, &Flash_data) != HAL_OK)

    但是我看我这里的HAL库,已经是直接写数据的了,可能版本不同

    HAL_StatusTypeDef HAL_FLASH_Program(uint32_t TypeProgram, uint32_t Address, uint64_t Data)
    {
      HAL_StatusTypeDef status = HAL_ERROR;
      
      /* Process Locked */
      __HAL_LOCK(&pFlash);
      
      /* Check the parameters */
      assert_param(IS_FLASH_TYPEPROGRAM(TypeProgram));
      
      /* Wait for last operation to be completed */
      status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
      
      if(status == HAL_OK)
      {
        if(TypeProgram == FLASH_TYPEPROGRAM_BYTE)
        {
          /*Program byte (8-bit) at a specified address.*/
          FLASH_Program_Byte(Address, (uint8_t) Data);
        }
        else if(TypeProgram == FLASH_TYPEPROGRAM_HALFWORD)
        {
          /*Program halfword (16-bit) at a specified address.*/
          FLASH_Program_HalfWord(Address, (uint16_t) Data);
        }
        else if(TypeProgram == FLASH_TYPEPROGRAM_WORD)
        {
          /*Program word (32-bit) at a specified address.*/
          FLASH_Program_Word(Address, (uint32_t) Data);
        }
        else
        {
          /*Program double word (64-bit) at a specified address.*/
          FLASH_Program_DoubleWord(Address, Data);
        }
        
        /* Wait for last operation to be completed */
        status = FLASH_WaitForLastOperation((uint32_t)FLASH_TIMEOUT_VALUE);
        
        /* If the program operation is completed, disable the PG Bit */
        FLASH->CR &= (~FLASH_CR_PG);  
      }
      
      /* Process Unlocked */
      __HAL_UNLOCK(&pFlash);
      
      return status;
    }
    
    static void FLASH_Program_Byte(uint32_t Address, uint8_t Data)
    {
      /* Check the parameters */
      assert_param(IS_FLASH_ADDRESS(Address));
      
      /* If the previous operation is completed, proceed to program the new data */
      CLEAR_BIT(FLASH->CR, FLASH_CR_PSIZE);
      FLASH->CR |= FLASH_PSIZE_BYTE;
      FLASH->CR |= FLASH_CR_PG;
    
      *(__IO uint8_t*)Address = Data;
    }
    
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 11月18日
  • 已采纳回答 11月10日
  • 修改了问题 11月9日
  • 赞助了问题酬金15元 11月9日
  • 展开全部

悬赏问题

  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料