Skip to content

64bit 写入粒度,计算env_hdr.crc32错误 #165

Description

@wumingxu10
static EfErrCode create_env_blob(sector_meta_data_t sector, const char *key, const void *value, size_t len)
{
    EfErrCode result = EF_NO_ERR;
    struct env_hdr_data env_hdr;
    bool is_full = false;
    uint32_t env_addr = sector->empty_env;

    if (strlen(key) > EF_ENV_NAME_MAX) {
        EF_INFO("Error: The ENV name length is more than %d\n", EF_ENV_NAME_MAX);
        return EF_ENV_NAME_ERR;
    }

    memset(&env_hdr, 0xFF, sizeof(struct env_hdr_data));//《---------初始化为FF,会漏掉最后4字节,导致后面计算crc错误
    env_hdr.magic = ENV_MAGIC_WORD;
    env_hdr.name_len = strlen(key);
    env_hdr.value_len = len;
    env_hdr.len = ENV_HDR_DATA_SIZE + EF_WG_ALIGN(env_hdr.name_len) + EF_WG_ALIGN(env_hdr.value_len);

    if (env_hdr.len > SECTOR_SIZE - SECTOR_HDR_DATA_SIZE) {
        EF_INFO("Error: The ENV size is too big\n");
        return EF_ENV_FULL;
    }

    if (env_addr != FAILED_ADDR || (env_addr = new_env(sector, env_hdr.len)) != FAILED_ADDR) {
        size_t align_remain;
        /* update the sector status */
        if (result == EF_NO_ERR) {
            result = update_sec_status(sector, env_hdr.len, &is_full);//《--------①
        }
        if (result == EF_NO_ERR) {
            uint8_t ff = 0xFF;
            /* start calculate CRC32 */
            env_hdr.crc32 = ef_calc_crc32(0, &env_hdr.name_len, ENV_HDR_DATA_SIZE - ENV_NAME_LEN_OFFSET);//《-----② 计算错误, 计算从&env_hdr.name_len开始的12字节(ENV_HDR_DATA_SIZE - ENV_NAME_LEN_OFFSET),最后4字节可能因为flash残留的数据且上面memset时没有为FF导致crc错误。
            env_hdr.crc32 = ef_calc_crc32(env_hdr.crc32, key, env_hdr.name_len);
            align_remain = EF_WG_ALIGN(env_hdr.name_len) - env_hdr.name_len;
            while (align_remain--) {
                env_hdr.crc32 = ef_calc_crc32(env_hdr.crc32, &ff, 1);
            }
            env_hdr.crc32 = ef_calc_crc32(env_hdr.crc32, value, env_hdr.value_len);
            align_remain = EF_WG_ALIGN(env_hdr.value_len) - env_hdr.value_len;
            while (align_remain--) {
                env_hdr.crc32 = ef_calc_crc32(env_hdr.crc32, &ff, 1);
            }
            /* write ENV header data */
            result = write_env_hdr(env_addr, &env_hdr);

        }
        /* write key name */
        if (result == EF_NO_ERR) {
            result = align_write(env_addr + ENV_HDR_DATA_SIZE, (uint32_t *) key, env_hdr.name_len);

#ifdef EF_ENV_USING_CACHE
            if (!is_full) {
                update_sector_cache(sector->addr,
                        env_addr + ENV_HDR_DATA_SIZE + EF_WG_ALIGN(env_hdr.name_len) + EF_WG_ALIGN(env_hdr.value_len));
            }
            update_env_cache(key, env_hdr.name_len, env_addr);
#endif /* EF_ENV_USING_CACHE */
        }
        /* write value */
        if (result == EF_NO_ERR) {
            result = align_write(env_addr + ENV_HDR_DATA_SIZE + EF_WG_ALIGN(env_hdr.name_len), value,
                    env_hdr.value_len);
        }
        /* change the ENV status to ENV_WRITE */
        if (result == EF_NO_ERR) {
            result = write_status(env_addr, env_hdr.status_table, ENV_STATUS_NUM, ENV_WRITE);
        }
        /* trigger GC collect when current sector is full */
        if (result == EF_NO_ERR && is_full) {
            EF_DEBUG("Trigger a GC check after created ENV.\n");
            gc_request = true;
        }
    } else {
        result = EF_ENV_FULL;
    }

    return result;
}

我一开始是直接把memset(&env_hdr, 0xFF, sizeof(struct env_hdr_data));改为memset(&env_hdr, 0xFF, ENV_HDR_DATA_SIZE);,第一个env的数据是正常了,但是第二个以后后面还是会因为crc校验错误,导致无法拿到env数据,调试后发现,在①函数执行后,我的env_hdr最后的四字节应该是FF FF FF FF,变成了00 FF FF FF,导致我crc错误,所以我把②的函数修改成

            env_hdr.crc32 = ef_calc_crc32(0, &env_hdr.name_len, sizeof(struct env_hdr_data) - ENV_NAME_LEN_OFFSET);
            align_remain = ENV_HDR_DATA_SIZE - sizeof(struct env_hdr_data);
            while (align_remain--) {
			   env_hdr.crc32 = ef_calc_crc32(env_hdr.crc32, &ff, 1);
		   }

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions