你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32的FLASH写入问题

[复制链接]
PaulRambo 提问时间:2018-3-6 15:55 /
本帖最后由 PaulRambo 于 2018-3-6 16:57 编辑

大家好,我现在遇到FLASH写入的问题,我使用的是HAL库。
1、正常写入,整bank擦除,能够成功写入flash
2、写入后卡死,擦除几个page,无法写入,并且程序卡死

以下为卡死的代码:
/* Unlock the Flash to enable the flash control register access *************/
  HAL_FLASH_Unlock();

  /* Erase the user Flash area
    (area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/

  /* Get the 1st page to erase */
  FirstPage = GetPage(ADDR_FLASH_PAGE_500);
  /* Get the number of pages to erase from 1st page */
  NbOfPages = GetPage(ADDR_FLASH_PAGE_501) - FirstPage + 1;
  /* Get the bank */
  BankNumber = GetBank(ADDR_FLASH_PAGE_500);
  /* Fill EraseInit structure*/
  EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
  EraseInitStruct.Banks       = BankNumber;
  EraseInitStruct.Page        = FirstPage;
  EraseInitStruct.NbPages     = NbOfPages;
        
        if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK)
  {
                printf("Erase error\r\n");
  }
        else
        {
                //        printf("Erase OK\r\n");
        }

--------------------------------------------------------------------------------------------------------
写入
                Address = ((uint32_t)ADDR_FLASH_PAGE_500);               
                status = FLASH_If_Write(Address, (uint32_t*) ramsource, 512 / 4);

-------------------------------------------------------------------------------------------------------
摘抄部分写入函数:卡死在这里
uint32_t FLASH_If_Write(uint32_t destination, uint32_t *p_source, uint32_t length)
{
  uint32_t status = FLASHIF_OK;
  uint32_t bank_to_erase, error = 0;
  uint32_t i = 0;
  uint32_t bank_active =0;
        uint8_t retry=0;
  FLASH_EraseInitTypeDef pEraseInit;
//----------------------------------卡死在这里----------------------这里就卡主了-----------------------程序无法运行下去
        if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, destination, *((uint64_t *)(p_source + 2*i))) == HAL_OK)
    {
                        printf("HAL_FLASH_Program HAL_OK \r\n");
    }
--------------------------------------------------------------------------------------------------------------------------------------

请问下大家,为什么整个bank擦除能用,擦除几页就不能用?

        


收藏 评论12 发布时间:2018-3-6 15:55

举报

12个回答
琦子 回答时间:2018-3-6 16:01:18
楼主,你写flash时,是不是没设临界段啊?这样也会造成卡死。
琦子 回答时间:2018-3-6 16:03:01
还有一个可能就是FLASH擦除期间,必须禁止数据fetch。请楼主自查程序

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

废鱼 回答时间:2018-3-6 16:06:02
如果擦除整个可以写,可以考虑一下写入的地址不再擦除页的范围之内。

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

wudianjun2001 回答时间:2018-3-6 16:24:14
自己看下地址,是不是溢出了

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

Angel_YY_ST 回答时间:2018-3-6 17:10:15
提示: 作者被禁止或删除 内容自动屏蔽
PaulRambo 回答时间:2018-3-6 19:52:19
bargagebaobei 发表于 2018-3-6 16:01
楼主,你写flash时,是不是没设临界段啊?这样也会造成卡死。

你好!感谢你的回复,目前没有设置临界段。但是应该不影响,我只写512字节就停止,后面lock之后就是while(1)。应该不会出临界段。
PaulRambo 回答时间:2018-3-6 19:54:33
bargagebaobei 发表于 2018-3-6 16:03
还有一个可能就是FLASH擦除期间,必须禁止数据fetch。请楼主自查程序

flash擦除的时候没有注意fetch问题,因为测试内容比较单一,只有flash擦除,所以应该不会有fetch打断。
PaulRambo 回答时间:2018-3-6 19:56:19
安 发表于 2018-3-6 16:06
如果擦除整个可以写,可以考虑一下写入的地址不再擦除页的范围之内。

你好,我擦除和写入的都是第500页。可以确定写入的flash已经擦除过了。
PaulRambo 回答时间:2018-3-6 19:57:07
wudianjun2001 发表于 2018-3-6 16:24
自己看下地址,是不是溢出了

你好,我现在测试的地址是第500页,我现在的STM32L476是由512页的。没有溢出
PaulRambo 回答时间:2018-3-6 19:57:48
本帖最后由 PaulRambo 于 2018-3-6 19:58 编辑
Angel_YY 发表于 2018-3-6 17:10
可以在程序中把flash的Page固定死,一个一个的擦除,每擦除一个修改程序重新擦除,可以定位到擦除哪一个页 ...

你好!我测试了擦除单页,并写入单页。同样的结果。擦除成功,但是写入时卡死。下面是测试结果:
---------------------------------------------------------------
FirstPage =  240
NbOfPages =  1
Erase OK, BankNumber = 1
destination = 0x8078000
source = 0x3020100
FLASH->SR = 0x0

后面本应该反馈flash_program成功或者失败,但是程序卡死,不往下运行了。
埃斯提爱慕 回答时间:2018-3-21 11:26:53
提示: 作者被禁止或删除 内容自动屏蔽
zhao.zhao 回答时间:2018-3-21 11:44:10
擦除之前要解锁,写完以后要加锁

    // 擦除该页面
    HAL_FLASH_Unlock();  // 解锁
    /* Fill EraseInit structure*/
    EraseInitStruct.TypeErase   = FLASH_TYPEERASE_PAGES;
    EraseInitStruct.PageAddress = page_start_addr;
    EraseInitStruct.NbPages     = 1;
    PageError = 0;
    if (HAL_FLASHEx_Erase(&EraseInitStruct, &PageError) != HAL_OK)
    {
        retvalue = HAL_ERROR;      // 页面擦除失败 ,退出
    }
    else
    {   // 页面擦除成功,写入该页面的数据     
        retvalue = HAL_OK;
        addrbuf  = page_start_addr;
        for(i=0;i<FLASH_PAGE_SIZE_IN_WORD;i++)          // 一个页面按字节算为64个单元
        {
            if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addrbuf, DataBuf[i]) == HAL_OK)
            {
                addrbuf += 4;
            }
            else
            {
                retvalue = HAL_ERROR;
                i           = FLASH_PAGE_SIZE_IN_WORD;
            }
        }
    }

    HAL_FLASH_Lock();

return  retvalue;

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版