|
如题,我移植F407开发板例程中【V5-102_串行Flash读写例程(V1.2).rar】的SpiFlash操作函数时发现sf_AutoWritePage函数的一个bug,请硬汉哥确认下。
bug:第87行应该加一句:ucNeedErase = 1;原因见图片中的解释。
问题1:写完数据后为什么要比较两次呢?sf_CmpData条用了2次,谢谢
问题2:f_mkfs("0:",0,0);第三个参数为什么写0,这个值到底写多少合适?
- static uint8_t sf_AutoWritePage(uint8_t *_ucpSrc, uint32_t _uiWrAddr, uint16_t _usWrLen)
- {
- uint16_t i;
- uint16_t j; /* 用于延时 */
- uint32_t uiFirstAddr; /* 扇区首址 */
- uint8_t ucNeedErase; /* 1表示需要擦除 */
- uint8_t cRet;
- /* 长度为0时不继续操作,直接认为成功 */
- if (_usWrLen == 0)
- {
- return 1;
- }
- /* 如果偏移地址超过芯片容量则退出 */
- if (_uiWrAddr >= g_tSF.TotalSize)
- {
- return 0;
- }
- /* 如果数据长度大于扇区容量,则退出 */
- if (_usWrLen > g_tSF.PageSize)
- {
- return 0;
- }
- /* 如果FLASH中的数据没有变化,则不写FLASH */
- sf_ReadBuffer(s_spiBuf, _uiWrAddr, _usWrLen);
- if (memcmp(s_spiBuf, _ucpSrc, _usWrLen) == 0)
- {
- return 1;
- }
- /* 判断是否需要先擦除扇区 */
- /* 如果旧数据修改为新数据,所有位均是 1->0 或者 0->0, 则无需擦除,提高Flash寿命 */
- ucNeedErase = 0;
- if (sf_NeedErase(s_spiBuf, _ucpSrc, _usWrLen))
- {
- ucNeedErase = 1;
- }
- uiFirstAddr = _uiWrAddr & (~(g_tSF.PageSize - 1));
- if (_usWrLen == g_tSF.PageSize) /* 整个扇区都改写 */
- {
- for (i = 0; i < g_tSF.PageSize; i++)
- {
- s_spiBuf[i] = _ucpSrc[i];
- }
- }
- else /* 改写部分数据 */
- {
- /* 先将整个扇区的数据读出 */
- sf_ReadBuffer(s_spiBuf, uiFirstAddr, g_tSF.PageSize);
- /* 再用新数据覆盖 */
- i = _uiWrAddr & (g_tSF.PageSize - 1);
- memcpy(&s_spiBuf[i], _ucpSrc, _usWrLen);
- }
- /* 写完之后进行校验,如果不正确则重写,最多3次 */
- cRet = 0;
- for (i = 0; i < 3; i++)
- {
- /* 如果旧数据修改为新数据,所有位均是 1->0 或者 0->0, 则无需擦除,提高Flash寿命 */
- if (ucNeedErase == 1)
- {
- sf_EraseSector(uiFirstAddr); /* 擦除1个扇区 */
- }
- /* 编程一个PAGE */
- sf_PageWrite(s_spiBuf, uiFirstAddr, g_tSF.PageSize);
- if (sf_CmpData(_uiWrAddr, _ucpSrc, _usWrLen) == 0)
- {
- cRet = 1;
- break;
- }
- else
- {
- if (sf_CmpData(_uiWrAddr, _ucpSrc, _usWrLen) == 0)
- {
- cRet = 1;
- break;
- }
- /* 失败后延迟一段时间再重试 */
- for (j = 0; j < 10000; j++);
- }
- }
- return cRet;
- }
复制代码
编辑原因:又发现一个FatFs操作SpiFlash的bug。例程为:【V5-107e_FatFS文件系统例程(SPI串行Flash)(V1.2).rar】
dickio.c文件中写flash有问题:count次调用了sf_WriteBuffer,但是参数却没有变化,这里有问题哦。- #if _USE_WRITE
- DRESULT disk_write (
- BYTE pdrv, /* Physical drive nmuber (0..) */
- const BYTE *buff, /* Data to be written */
- DWORD sector, /* Sector address (LBA) */
- BYTE count /* Number of sectors to write (1..128) */
- )
- {
- switch (pdrv) {
- case FS_SPI_FLASH :
- {
- uint8_t i;
- for(i = 0; i < count; i++)
- {
- sf_WriteBuffer((uint8_t *)buff, sector << 12, 4096);
- }
- return RES_OK;
- }
- }
- return RES_PARERR;
- }
- #endif
复制代码 改法一:
- for(i = 0; i < count; i++)
- {
- sf_WriteBuffer((uint8_t *)buff, sector << 12, 4096);
- }
- 上面的for直接改为:
- sf_WriteBuffer((uint8_t *)buff, sector << 12, count<<12);
- 因为sf_WriteBuffer函数支持写多个扇区的功能,所以可以这样写
复制代码
改法二:- for循环改为如下的方式:
- for(i = 0; i < count; i++)
- {
- sf_WriteBuffer((uint8_t *)buff, sector << 12, 4096);
- sector++;
- buff +=4096;
- }
复制代码 |
|