【项目笔记_rp552d】Partition write error! Flash device(onchip_flash) write error!

问题描述

在使用 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 >

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值