【项目笔记_rp552d】Partition write error! Flash device(onchip_flash) write error!
程序员文章站
2024-02-23 20:35:58
...
问题描述
在使用 easy_falsh 的是时候出现问题,这个问题是发现在 触发 gc 的时候突然断电就出现了错误,一旦出现这个问题无论怎样都无法恢复,除非重新擦除数据区
需要擦除才能恢复,这个问题是不可接受的
问题分析
估计是触发在STM32上面触发GC机制的问题在备份在转移数据的时候突然断电会导致状态异常,这个异常的状态是写入在FLASH中的,导致即使上电数据也不能恢复,于是查找数据出错的地方:
int stm32_flash_write(rt_uint32_t addr, const rt_uint8_t *buf, size_t size)
{
rt_err_t result = RT_EOK;
rt_uint32_t end_addr = addr + size;
if (addr % 4 != 0)
{
LOG_E("write addr must be 4-byte alignment");
return -RT_EINVAL;
}
if ((end_addr) > STM32_FLASH_END_ADDRESS)
{
LOG_E("write outrange flash size! addr is (0x%p)", (void *)(addr + size));
return -RT_EINVAL;
}
HAL_FLASH_Unlock();
while (addr < end_addr)
{
+ /* 写数据之前会进行错误检查,如果之前操作有错误积累,则之后无法操作成功,需要清除一下 */
+ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR |
+ FLASH_FLAG_BSY | FLASH_FLAG_EOP);
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, addr, *((rt_uint32_t *)buf)) == HAL_OK)
{
if (*(rt_uint32_t *)addr != *(rt_uint32_t *)buf)
{
result = -RT_ERROR;
break;
}
addr += 4;
buf += 4;
}
else
{
result = -RT_ERROR;
+ LOG_E(" HAL_FLASH_Program 写数据错误");
break;
}
}
HAL_FLASH_Lock();
if (result != RT_EOK)
{
return result;
}
return size;
}
添加错误数据之后发现数据还是无法写入成功,那个此处怀疑需要格式化扇区才能恢复逻辑,于是查找代码,在写数据失败的地方增加恢复 默认状态
// ef_fal_port.c
EfErrCode ef_port_write(uint32_t addr, const uint32_t *buf, size_t size) {
EfErrCode result = EF_NO_ERR;
if (fal_partition_write(part, addr, (uint8_t *)buf, size) < 0)
{
result = EF_WRITE_ERR;
+ ef_port_env_unlock();
+ ef_env_set_default();
+ rt_thread_mdelay(50);
+ rt_hw_cpu_reset();
}
return result;
}
再次上电测试发现
\ | /
- RT - Thread Operating System
/ | \ 4.0.2 build Nov 11 2020
2006 - 2019 Copyright by rt-thread team
[1] I/NO_TAG: hw_ver:0, name:si522 find spi bus ok
[154] I/NO_TAG: hw_ver:0, name: si522 init ok
[155] D/main: d_LCD:thread:thd_beep init OK
[D/FAL] (fal_flash_init:63) Flash device | onchip_flash | addr: 0x08000000 | len: 0x00040000 | blk_size: 0x00000800 |initialized finish.
[I/FAL] ==================== FAL partition table ====================
[I/FAL] | name | flash_dev | offset | length |
[I/FAL] -------------------------------------------------------------
[I/FAL] | app | onchip_flash | 0x00000000 | 0x00032000 |
[I/FAL] | dat | onchip_flash | 0x00032000 | 0x0000e000 |
[I/FAL] =============================================================
[I/FAL] RT-Thread Flash Abstraction Layer (V0.5.0) initialize success.
[Flash] (../packages/EasyFlash-v4.1.0/src/ef_env.c:1818) ENV start address is 0x00000000, size is 32768 bytes.
[Flash] EasyFlash V4.1.0 is initialize success.
[Flash] You can get the latest version on https://github.com/armink/EasyFlash .
easyflash_init ret:0
===============================================
The system now boot 353 times
boot_delay: 120
uID_id: 3065517179
HEX_id: b6b8147b
===============================================
[222] D/fee: sys_tcb_val.tx_power: 5
[223] D/fee: sys_tcb_val.rf_ch: 96
[224] D/fee: sys_tcb_val.port_max: 120
[227] D/fee: next_pos: 30
D/HEX use_tab: 0000-000F: FF FF FF 7F 00 00 00 00 00 00 00 00 00 00 00 00 ................
[287] D/fee: end check upos:120
[288] I/NO_TAG: hw_ver:0, name: si522 card_pcd_init ok
[289] I/NO_TAG: m_CARD: thread:thd_card init OK
[289] I/esb: hw_ver:0, esb_rx_hw_sem init ret:0
[290] I/esb: hw_ver:0, esb_rx find spi bus ok
[291] D/esb: s_PORT: thread:thd_esb_rx init OK
msh >[304] D/dtq: r_PORT0: v1.x SET_CONFIG ErrCode:0 !
[310] D/dtq: r_PORT0: v1.x SET_CONFIG ErrCode:0 !
此时发现这个问题已经修复,且发现实际上环境变量的数据并未全部丢失(可能某次转移的数据丢失,但是有已经能保证设备正常使用了)
实测数据确实会丢失:(原本数据有120个uID)
msh >wl
uID_000: 1000000000 uID_001: 1000000001 uID_002: 1000000002
uID_003: 1000000003 uID_004: 1000000004 uID_005: 1000000005
uID_006: 1000000006 uID_007: 1000000007 uID_008: 1000000008
uID_009: 1000000009 uID_010: 1000000010 uID_011: 1000000011
uID_012: 1000000012 uID_013: 1000000013 uID_014: 1000000014
uID_015: 1000000015 uID_016: 1000000016 uID_017: 1000000017
uID_018: 1000000018 uID_019: 1000000019 uID_020: 1000000020
uID_021: 1000000021 uID_022: 1000000022 msh >