Open wumingxu10 opened 6 months ago
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); }
我一开始是直接把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错误,所以我把②的函数修改成