stmflash.c代码有BUG

2019-07-20 18:57发布

    最近都在学习STM32F429I-DISCOVERY的开发板,发现看惯了原子的代码,还不是很适应官方的DOME,官方的调用太多层层,如果想很快调用官方函数去实现自己的想法,比如显示一段文字,不是很容易,而且又是英文注释,所以就有了把原子哥的代码移植到F429I-DIS上去使用,移植过程也蛮辛苦的,主要是替换原来的驱动函数,上层的函数都没有做改动,目前已经实现了显示、触摸、按键、LED。其他触摸的参数保存于地址为0x8100000上,也是在调试触摸功能的保存参数上才发现stmflash.c的BUG:数据无法写入12扇区及以上扇区。  
  发现问题后我便使用STVLINK调试代码,发现错误为写保护错误,如果将地址改为0x800C000,则完全正常。
  地址为:0x800C000时,STMFLASH_EraseSector函数的FLASH->CR|=sectoraddr<<3;代码时,FLASH_CR的LOCK位清0.
  地址为:0x8100000时,STMFLASH_EraseSector函数的FLASH->CR|=sectoraddr<<3;代码时,FLASH_CR的LOCK位仍为1.

  所以执行擦除时,返回写保护错误码,WRPERR为1.
  
  因此可以得出结论:如果使用stmflash.c时,FLASH空间在1M以下,是完全没有问题,如果大于1M就会有问题。在结合官方擦除代码和参考手册,发现以下描述:

  官方代码:
        /* Need to add offset of 4 when sector higher than FLASH_SECTOR_11 */
  if(Sector > FLASH_SECTOR_11)
  {
    Sector += 4;
  }


  参考手册:用于 STM32F42xxx STM32F43xxx
Flash 控制寄存器 (FLASH_CR)位 7:3 SNB: 扇区编号 (Sector number)
这些位用于选择要擦除的扇区。
0000:扇区 0
0001:扇区 1
...
01011:扇区 11
01100:不允许
01101:不允许
01110:不允许
01111:不允许
10000:扇区 12
10001:扇区 13
...
11011 扇区 23
11100:不允许
11101:不允许
11110:不允许
11111:不允许

    看到这里也就明白了,F42和F41、F40的寄存器是不一样的,故解决方法有两个:


方法一:修改STMFLASH_EraseSector函数,
            if(sectoraddr > 11)         //
                sectoraddr += 4;
           FLASH->CR|=sectoraddr<<3;

方法二:修改STMFLASH_GetFlashSector
       else if(addr<ADDR_FLASH_SECTOR_13)return 16;         else if(addr<ADDR_FLASH_SECTOR_14)return 17;
        else if(addr<ADDR_FLASH_SECTOR_15)return 18;
        else if(addr<ADDR_FLASH_SECTOR_16)return 19;
        else if(addr<ADDR_FLASH_SECTOR_17)return 20;
        else if(addr<ADDR_FLASH_SECTOR_18)return 21;
        else if(addr<ADDR_FLASH_SECTOR_19)return 22;
        else if(addr<ADDR_FLASH_SECTOR_20)return 23;
        else if(addr<ADDR_FLASH_SECTOR_21)return 24;
        else if(addr<ADDR_FLASH_SECTOR_22)return 25;
        else if(addr<ADDR_FLASH_SECTOR_23)return 26;  
        return 27;       


@正点原子

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。