搜索
bottom↓
回复: 18

【求助】STM32F407VET6 IAP升级 FLASH编程问题

[复制链接]

出0入0汤圆

发表于 2014-8-25 22:22:13 | 显示全部楼层 |阅读模式
本帖最后由 lingdianhao 于 2014-8-25 22:29 编辑

在使用IAP功能的过程中,调用 《flash_if.c》中的函数<FLASH_If_Init();>能解锁Flash,但FLSAH_SR状态寄存器中错误标志PGPERR、PGSERR位不能被清零。
导致在后续代码中调用《stm32f4xx_flash.c》中的<FLASH_GetStatus(void)>函数时,总是返回编程错误标志,不能进行下一步操作。


详细情况如下:
CPU:STM32F407VET6
编译软件:RealVeiw MDK V4.70.0.0
仿真器:Jlink V8
例程:来自STM32社区,http://www.stmcu.org/download/index.php?act=ziliao&id=150


仿真流程如下:
1:复位时:FLSAH_SR状态寄存器值为0.  FLASH_CR控制寄存器处于锁定状态LOCK bit为1.  正常。如下图,(右侧,红色方框内)


2:执行SystemInit系统初始化函数中第一条语句后:FLSAH_SR状态寄存器中PGPERR、PGSERR位被置1.  FLSAH_SR中LOCK bit为1. 如下图,(右侧,红色方框内)


3:初始化完成后跳转到主程序,首先执行的是FLASH_If_Init();函数。

    该函数中包含两个子函数 :FLASH_Unlock();  FLASH_ClearFlag();

执行FLASH_Unlock(); 函数后FLASH被解锁,FLASH_CR中LOCK位被清零。
执行 FLASH_ClearFlag();函数后,FLASH_SR中的PGPERR、PGSERR位并未被清零。(不正常)如下图。(右侧,红色方框内)



4:在后续的操作中会多次调用FLASH_GetStatus(void)函数,因FLASH_SR中PGPERR、PGSERR位不能被清零,导致返回值始终为FLASH_ERROR_PROGRAM; 显示编程错误,无法进行下一步操作。


不知道这是什么原因引起的?换了几个板子,都一样,不知道是否是Jlink问题,还是程序设计问题,或者是编译器问题?有没有类似情况的?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2014-8-25 22:42:47 | 显示全部楼层
楼主仔细检查检查程序吧,
这几天正在搞103的IAP,暂时没遇到问题

出0入0汤圆

 楼主| 发表于 2014-8-26 08:41:11 | 显示全部楼层
我用103的也没问题,FLASH_SR都正常,就407不正常,我看了编译后的汇编代码,寄存器地址,参数都是正常,就是清除不了FLASH_SR这个寄存器。再找找看吧。谢谢提醒。

出0入0汤圆

发表于 2014-8-26 08:53:44 | 显示全部楼层
给你发个可以正常使用的Flash代码,希望对你有所帮助
  1. /*
  2. * flash.c
  3. *
  4. *  Created on: 2013年10月23日
  5. *      Author: keinYe<keinYe@foxmail.com>
  6. *     Version: v1.0
  7. * Description: 内部flash擦除、写驱动。
  8. */
  9. #include "stm32f4xx.h"
  10. #include "flash.h"
  11. #include "global.h"

  12. #define MIN_SECTOR_SIZE              0x4000

  13. const uint32_t sector_addr[] =
  14. {
  15.   0x08000000,      //16K
  16.   0x08004000,      //16K
  17.   0x08008000,      //16K
  18.   0x0800C000,      //16K
  19.   0x08010000,      //64K
  20.   0x08020000,      //128K
  21.   0x08040000,      //128K
  22.   0x08060000,      //128K
  23.   0x08080000,      //128K
  24.   0x080A0000,      //128K
  25.   0x080C0000,      //128K
  26.   0x080E0000       //128K
  27. };


  28. /*
  29. *  Function: __inline void flash_unlock(void)
  30. * Parameter: none
  31. *    Return: none
  32. */
  33. __inline void flash_unlock(void)
  34. {
  35.   if (FLASH->CR & (1 << 31)) {
  36.     FLASH->KEYR = FLASH_KEY1;
  37.     FLASH->KEYR = FLASH_KEY2;
  38.   }
  39. }
  40. /*
  41. *  Function: __inline void flash_lock(void)
  42. * Parameter: none
  43. *    Return: none
  44. */
  45. __inline void flash_lock(void)
  46. {
  47.   FLASH->CR |= FLASH_CR_LOCK;
  48. }
  49. /*
  50. *  Function: void flash_erase(uint32_t sector)
  51. * Parameter: sector: 擦除flash段号。
  52. *    Return: none
  53. */
  54. void flash_erase(uint32_t sector)
  55. {
  56.   flash_unlock();
  57.   /*  wait busy flag  */
  58.   while(BIT_TST(FLASH->SR, FLASH_SR_BUSY));
  59.   FLASH->SR |= FLASH_SR_ERROR_MASK;

  60.   FLASH->CR &= ~FLASH_CR_PSIZE_MASK;
  61.   FLASH->CR |= FLASH_CR_PSIZE_32BIT;
  62.   FLASH->CR &= ~FLASH_CR_SECTOR_MASK;
  63.   FLASH->CR |= (sector << 3) | FLASH_CR_SER;
  64.   FLASH->CR |= FLASH_CR_STRT;

  65.   /*  wait busy flag  */
  66.   while(BIT_TST(FLASH->SR, FLASH_SR_BUSY));
  67.   FLASH->SR |= FLASH_SR_ERROR_MASK;
  68.   FLASH->CR &= ~FLASH_CR_PSIZE_MASK;
  69.   FLASH->CR &= ~(FLASH_CR_SECTOR_MASK | FLASH_CR_SER);
  70. }
  71. /*
  72. *  Function: inline void flash_lock(void)
  73. * Parameter: none
  74. *    Return: none
  75. */
  76. int32_t get_sector(uint32_t addr)
  77. {
  78.   uint32_t i;
  79.   for (i = 0; i < (sizeof(sector_addr)/sizeof(uint32_t)); i++)
  80.   {
  81.     if (addr == sector_addr[i])break;
  82.   }
  83.   if (i >= (sizeof(sector_addr)/sizeof(uint32_t)))return (-1);
  84.   return i;
  85. }
  86. /*
  87. *  Function: uint32_t flash_program(uint32_t addr, uint8_t *buf, uint32_t len)
  88. * Parameter: addr:  写flash 32位地址。
  89. *            *buf:  写flash数据缓冲区。
  90. *            len:   写flash数据长度。
  91. *    Return: 0:     写flash完成。
  92. *            1:     写flash错误。
  93. */
  94. uint32_t flash_program(uint32_t addr, uint8_t *buf, uint32_t len)
  95. {

  96.   flash_unlock();
  97.   /*  wait busy flag  */
  98.   while(BIT_TST(FLASH->SR, FLASH_SR_BUSY));
  99.   FLASH->SR |= FLASH_SR_ERROR_MASK;
  100.   BIT_SET(FLASH->CR, 0);
  101.   while(len--)
  102.   {
  103.     if ((addr % MIN_SECTOR_SIZE) == 0)
  104.     {
  105.       if (get_sector(addr) >= 0)
  106.       {
  107.         BIT_CLR(FLASH->CR, 0);
  108.         flash_erase(get_sector(addr));
  109.         BIT_SET(FLASH->CR, 0);
  110.       }
  111.     }
  112.     *(uint8_t*)addr = *buf;
  113.     /*  wait busy flag  */
  114.     while(BIT_TST(FLASH->SR, FLASH_SR_BUSY));
  115.     FLASH->SR |= FLASH_SR_ERROR_MASK;
  116.     if (*buf != *(uint8_t*)addr)return 1;
  117.     addr++;buf++;
  118.   }
  119.   BIT_CLR(FLASH->CR, 0);
  120.   flash_lock();
  121.   return 0;
  122. }

复制代码

  1. /*
  2. * flash.h
  3. *
  4. *  Created on: 2013年10月23日
  5. *      Author: keinYe<keinYe@foxmail.com>
  6. *     Version: v1.0
  7. * Description:
  8. */

  9. #ifndef __FLASH_H__
  10. #define __FLASH_H__

  11. #define FLASH_KEY1               ((uint32_t)0x45670123)
  12. #define FLASH_KEY2               ((uint32_t)0xCDEF89AB)

  13. /* flash status register */
  14. #define FLASH_SR_BUSY            16
  15. #define FLASH_SR_ERROR_MASK      0xF3

  16. /* flash control flash */
  17. #define FLASH_CR_PSIZE_MASK      (0x03 << 8)
  18. #define FLASH_CR_PSIZE_8BIT      (0x00 << 8)
  19. #define FLASH_CR_PSIZE_16BIT     (0x01 << 8)
  20. #define FLASH_CR_PSIZE_32BIT     (0x02 << 8)
  21. #define FLASH_CR_PSIZE_64BIT     (0x03 << 8)

  22. #define FLASH_CR_SECTOR_MASK     (0xF8)



  23. #endif /* __FLASH_H__ */
复制代码

出0入0汤圆

 楼主| 发表于 2014-8-28 20:59:26 | 显示全部楼层
本帖最后由 lingdianhao 于 2014-8-28 21:05 编辑
keinYe 发表于 2014-8-26 08:53
给你发个可以正常使用的Flash代码,希望对你有所帮助


多谢你的代码,测试了还是不行,ST技术支持发了测试代码,情况也还是一样。是否和仿真器有关系。关键的问题还不在于如何去写Flash,现在是FLASH_SR寄存器指示出现了编程错误,但还没有开始编程啊,没有对FLASH进行写操作。最关键的问题是手册上说得很清楚,对该寄存器相应位写1可清零该位为0。不管它是如何出现错误,但总得能清零吧,清零只是对一个普通寄存器进行写操作而已,这条语句通过编译后的汇编语句查看,确实是执行了,往FLASH_SR寄存器里面写的数据是0XF3,但就是清不了零。怀疑是否是芯片本身有问题,换了几个芯片也一样,难道这一批都有问题?



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-8-29 09:37:46 | 显示全部楼层
没使用过STM32F407。顶一下。

出0入0汤圆

发表于 2014-8-29 10:23:14 | 显示全部楼层
lingdianhao 发表于 2014-8-28 20:59
多谢你的代码,测试了还是不行,ST技术支持发了测试代码,情况也还是一样。是否和仿真器有关系。关键的问 ...

Flash是不是设置读写保护了,这个驱动我在407和4X9上使用都是正常的!

出0入0汤圆

发表于 2014-8-30 00:14:46 来自手机 | 显示全部楼层
遇到过同样得问题,jlink问题,换用stlink就好了,程序不一定有问题

出0入0汤圆

 楼主| 发表于 2014-8-30 10:52:04 | 显示全部楼层
clough2004 发表于 2014-8-30 00:14
遇到过同样得问题,jlink问题,换用stlink就好了,程序不一定有问题

我也觉得可能是Jlink的问题,芯片的不大可能一批都有问题,现在手头没有st-link,找一个测试一下。

出0入0汤圆

 楼主| 发表于 2014-8-30 10:54:55 | 显示全部楼层
keinYe 发表于 2014-8-29 10:23
Flash是不是设置读写保护了,这个驱动我在407和4X9上使用都是正常的!

我操作的是FLASH_SR寄存器,则个寄存器是数据RAM地址空间,不属于FLASH,  上电后除了FLASH_CR这个寄存器被锁定后,其他的应该都是可以操作的。可能和仿真器有关系吧,或者是芯片,再试试。

出0入0汤圆

发表于 2014-8-30 23:10:33 | 显示全部楼层
换个仿真器就好了,不用太担心

出0入0汤圆

 楼主| 发表于 2014-9-5 13:14:17 | 显示全部楼层
ST原厂来了技术支持,给搞定了,升级了软件版本,以前用MDK4.70,现在用MKD5.11,仿真器自动升级后,正常。确实是仿真器和编译软件的问题。

出5入4汤圆

发表于 2014-12-20 10:04:19 | 显示全部楼层
不错,以前用JLINK调试程序擦除flash时老是有问题,不仿真直接运行就没问题,原来是这个原因呀,谢谢啦

出0入0汤圆

发表于 2014-12-25 21:12:40 | 显示全部楼层
刚接触STM32的FLASH,学习一下

出0入0汤圆

发表于 2015-8-18 10:59:01 | 显示全部楼层
好像MDK 4.54 确实是存在问题的,对FLASH操作的时候

出0入0汤圆

发表于 2015-8-18 11:04:12 | 显示全部楼层
参考我们代码吧

出0入0汤圆

发表于 2015-9-9 19:49:51 | 显示全部楼层
楼主关于这个问题,您最终解决了吗?是怎么解决的呢?

出0入0汤圆

 楼主| 发表于 2015-9-10 08:35:36 | 显示全部楼层
孙为 发表于 2015-9-9 19:49
楼主关于这个问题,您最终解决了吗?是怎么解决的呢?

请看12楼。

出0入0汤圆

发表于 2019-1-21 19:09:20 | 显示全部楼层
mark下,谢谢楼主分享
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-24 16:25

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表