[STM32F4]

调用标准库读写片内flash时,死机,求解

[复制链接]
4586|35
手机看帖
扫描二维码
随时随地手机跟帖
地瓜patch|  楼主 | 2018-6-29 21:39 | 显示全部楼层 |阅读模式
本帖最后由 地瓜patch 于 2018-7-13 14:40 编辑

在写片内flash进行擦除的时候,调用库函数FLASH_Status FLASH_EraseSector(uint32_t FLASH_Sector, uint8_t VoltageRange);执行擦除操作时死在语句FLASH->CR |= FLASH_CR_STRT;
此语句前程序可以正常运行,此语句后死机。没有任何反应。求高手解答。//自己编写的写flash函数
void WriteFlash(uint16_t WCount)
{
                        uint16_t uwCount,i,j;
         
                 uint32_t uwStartSector = 0;
                 uint32_t uwAddress = 0;
                 __IO uint32_t uwData32 = 0;
         
                __disable_irq();                        
                 FLASH_Unlock();
                        
                 FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
                                                                                 FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
                 uwStartSector = FLASH_Sector_11;
                 uwAddress = ADDR_FLASH_SECTOR_11;
                 uwCount=WCount;         

                                 if (FLASH_EraseSector(uwStartSector, VoltageRange_3) == FLASH_COMPLETE)
                                {                  
                                                for(i=0;i<uwCount;   )
                                                {                                
                                                                if(FLASH_ProgramWord(uwAddress+4*i, Write_Flash_data)== FLASH_COMPLETE)
                                                                {  i++;   }                                       
                                                }
                                 }
                FLASH_Lock();
                __enable_irq();
}

//调用stm32f4的头文件"stm32f4xx_flash.h"里的块擦除库函数
FLASH_Status FLASH_EraseSector(uint32_t FLASH_Sector, uint8_t VoltageRange)
{
  uint32_t tmp_psize = 0x0;
  FLASH_Status status = FLASH_COMPLETE;

  /* Check the parameters */
  assert_param(IS_FLASH_SECTOR(FLASH_Sector));
  assert_param(IS_VOLTAGERANGE(VoltageRange));

  if(VoltageRange == VoltageRange_1)
  {
     tmp_psize = FLASH_PSIZE_BYTE;
  }
  else if(VoltageRange == VoltageRange_2)
  {
    tmp_psize = FLASH_PSIZE_HALF_WORD;
  }
  else if(VoltageRange == VoltageRange_3)
  {
    tmp_psize = FLASH_PSIZE_WORD;
  }
  else
  {
    tmp_psize = FLASH_PSIZE_DOUBLE_WORD;
  }
  /* Wait for last operation to be completed */
  status = FLASH_WaitForLastOperation();
  if(status == FLASH_COMPLETE)
  {
    /* if the previous operation is completed, proceed to erase the sector */
    FLASH->CR &= CR_PSIZE_MASK;
    FLASH->CR |= tmp_psize;
    FLASH->CR &= SECTOR_MASK;
    FLASH->CR |= FLASH_CR_SER | FLASH_Sector;
    FLASH->CR |= FLASH_CR_STRT;//程序死在这一句
    /* Wait for last operation to be completed */
    status = FLASH_WaitForLastOperation();
    /* if the erase operation is completed, disable the SER Bit */
    FLASH->CR &= (~FLASH_CR_SER);
    FLASH->CR &= SECTOR_MASK;
  }
  /* Return the Erase Status */
  return status;
}


FLASH_CR_STRT根据数据手册的表述--------位 16 STRT:启动 (Start)
该位置 1 后可触发擦除操作。该位只能通过软件置 1,并在 BSY 位清零后随之清零。

已经按照6楼和 14.15楼老司机的指点,参考香水城的帖子
【实战经验】KEIL中如何让程序在 RAM 中运行测试过,依旧死机。
下图是将对flash操作的所有相关函数放到ram中。
809295b3b21c9b60ed.png
7月3日,现在将库函数FLASH_Status FLASH_EraseSector()中的 FLASH->CR |= FLASH_CR_STRT;注释掉了。竟然写flash成功了。
@香水城
最新进展,测试发现在uart3的初始化配置如下
{
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 ;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);


GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
}
将 uart3的RX语句GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;注释掉。
将库函数FLASH_Status FLASH_EraseSector()中的 FLASH->CR |= FLASH_CR_STRT;恢复。读写flash成功。
不明白串口3与flash有什么必然联系。uart3使用 DMA收发数据。

评论
地瓜patch 2018-7-17 09:19 回复TA
结贴了,细节请移步37楼 
地瓜patch|  楼主 | 2018-7-1 09:57 | 显示全部楼层
还没搞定.....

使用特权

评论回复
mmuuss586| | 2018-7-1 10:17 | 显示全部楼层
参考DESCOVERY板子的例程,应该是地址不对吧

使用特权

评论回复
mmuuss586| | 2018-7-1 10:18 | 显示全部楼层
另外最好这段程序贴上来;
就那么几句不好判断;

使用特权

评论回复
地瓜patch|  楼主 | 2018-7-1 10:30 | 显示全部楼层
mmuuss586 发表于 2018-7-1 10:18
另外最好这段程序贴上来;
就那么几句不好判断;

明天贴程序,周五太仓促,只把这两句发手机上了

使用特权

评论回复
airwill| | 2018-7-1 11:21 | 显示全部楼层
操作 FLASH 的时候, FLASH 会被锁住不能读取, 也就不能取指令了, 自然就卡在那里了.
可以把操作 FLASH 的代码先放到 SRAM 里再调用

使用特权

评论回复
地瓜patch|  楼主 | 2018-7-1 11:52 | 显示全部楼层
airwill 发表于 2018-7-1 11:21
操作 FLASH 的时候, FLASH 会被锁住不能读取, 也就不能取指令了, 自然就卡在那里了.
可以把操作 FLASH 的 ...

是如何操作将flash的代码放到sram里运行

使用特权

评论回复
airwill| | 2018-7-1 21:04 | 显示全部楼层
通常有2个办法.
1.  将 FLASH 里面的函数直接复制到 SRAM 里, 再调用
2. 通过连接配置文件, 把这个函数定义到 SRAM 空间里

使用特权

评论回复
caoenq| | 2018-7-1 22:19 | 显示全部楼层
果断换成HAL库

使用特权

评论回复
地瓜patch|  楼主 | 2018-7-2 10:39 | 显示全部楼层
airwill 发表于 2018-7-1 21:04
通常有2个办法.
1.  将 FLASH 里面的函数直接复制到 SRAM 里, 再调用
2. 通过连接配置文件, 把这个函数定义 ...

非常感谢,我试试第二种方法

使用特权

评论回复
df_flying| | 2018-7-2 10:56 | 显示全部楼层
一般防止写falsh的时候正在取值而导致系统崩溃,所以一般会有先将flash写代码COPY到RAM的操作。
不过不是经常操作,一般不需要这样操作,只需要在写flash前将全局中断关掉就可以了。

使用特权

评论回复
地瓜patch|  楼主 | 2018-7-2 13:43 | 显示全部楼层
df_flying 发表于 2018-7-2 10:56
一般防止写falsh的时候正在取值而导致系统崩溃,所以一般会有先将flash写代码COPY到RAM的操作。
不过不是经 ...

好的 ,谢谢,我测试一下

使用特权

评论回复
地瓜patch|  楼主 | 2018-7-2 13:44 | 显示全部楼层
airwill 发表于 2018-7-1 21:04
通常有2个办法.
1.  将 FLASH 里面的函数直接复制到 SRAM 里, 再调用
2. 通过连接配置文件, 把这个函数定义 ...

之前写flash读写程序的时候,看过不少历程,都没有提到写flash会导致程序不能取指令?求解

使用特权

评论回复
kingkits| | 2018-7-2 14:06 | 显示全部楼层
有的IC 是支持写FLASH期间可以读某些区块的代码,多数都不支持
普遍的方法就是把代码放在ram中,(只需要放几条指令)

使用特权

评论回复
kingkits| | 2018-7-2 15:45 | 显示全部楼层
关中断也是因为中断服务代码都在flash中,在flash写入的过程中,flash不会响应数据读取的指令

使用特权

评论回复
地瓜patch|  楼主 | 2018-7-2 22:33 | 显示全部楼层
df_flying 发表于 2018-7-2 10:56
一般防止写falsh的时候正在取值而导致系统崩溃,所以一般会有先将flash写代码COPY到RAM的操作。
不过不是经 ...

关中断的已经测试过,仍旧死机

使用特权

评论回复
地瓜patch|  楼主 | 2018-7-2 22:33 | 显示全部楼层
kingkits 发表于 2018-7-2 15:45
关中断也是因为中断服务代码都在flash中,在flash写入的过程中,flash不会响应数据读取的指令 ...

关中断的已经测试过,仍旧死机

使用特权

评论回复
airwill| | 2018-7-3 08:14 | 显示全部楼层
在 FLASH 编程的手册上有明确描述, 如果想认真的话, 你可以看一下

使用特权

评论回复
地瓜patch|  楼主 | 2018-7-3 11:27 | 显示全部楼层
airwill 发表于 2018-7-1 11:21
操作 FLASH 的时候, FLASH 会被锁住不能读取, 也就不能取指令了, 自然就卡在那里了.
可以把操作 FLASH 的 ...

我正在测试“把操作 FLASH 的代码先放到 SRAM 里再调用”。若是我将A函数放到sram中,那么被A函数调用的B函数是在flash运行?

使用特权

评论回复
kingkits| | 2018-7-3 13:01 | 显示全部楼层
地瓜patch 发表于 2018-7-2 22:33
关中断的已经测试过,仍旧死机

这里说的关中断,是要和前面那句一块用的。
你得先把关键代码写到RAM中,
就是那个等待Flash状态的 while()

使用特权

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

本版积分规则

1156

主题

11080

帖子

26

粉丝