fs: fcb: add option to disable CRC for fcb entries
Add option to disable CRC for fcb entries. This improves the write throughput significantly at the cost of not detecting corrupted data in flash. This is beneficial for aplications that needs the extra write throughput, where error detection is done elsewhere. Allow the FCB entries in flash to have a valid CRC when CRC is disabled in the FCB. This allows existing solutions to disable CRC checking, while keeping the CRC areas intact. Note that this is a one-way option. Fixes #53707 Signed-off-by: Eivind Jølsgard <eivind.jolsgard@nordicsemi.no>
This commit is contained in:
parent
da386cdc40
commit
cfa1ba1261
16 changed files with 204 additions and 49 deletions
|
@ -1,6 +1,6 @@
|
|||
# Flash Circular Buffer module
|
||||
|
||||
# Copyright (c) 2017 Nordic Semiconductor ASA
|
||||
# Copyright (c) 2017-2023 Nordic Semiconductor ASA
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#
|
||||
|
@ -13,3 +13,13 @@ config FCB
|
|||
select CRC
|
||||
help
|
||||
Enable support of Flash Circular Buffer.
|
||||
|
||||
if FCB
|
||||
|
||||
config FCB_ALLOW_FIXED_ENDMARKER
|
||||
bool "Allow FCB instances to have a fixed endmarker"
|
||||
help
|
||||
This allows the FCB instances to disable CRC checks in
|
||||
favor of increased write throughput.
|
||||
|
||||
endif
|
||||
|
|
|
@ -121,18 +121,18 @@ int
|
|||
fcb_append_finish(struct fcb *fcb, struct fcb_entry *loc)
|
||||
{
|
||||
int rc;
|
||||
uint8_t crc8[fcb->f_align];
|
||||
uint8_t em[fcb->f_align];
|
||||
off_t off;
|
||||
|
||||
(void)memset(crc8, 0xFF, sizeof(crc8));
|
||||
(void)memset(em, 0xFF, sizeof(em));
|
||||
|
||||
rc = fcb_elem_crc8(fcb, loc, &crc8[0]);
|
||||
rc = fcb_elem_endmarker(fcb, loc, &em[0]);
|
||||
if (rc) {
|
||||
return rc;
|
||||
}
|
||||
off = loc->fe_data_off + fcb_len_in_flash(fcb, loc->fe_data_len);
|
||||
|
||||
rc = fcb_flash_write(fcb, loc->fe_sector, off, crc8, fcb->f_align);
|
||||
rc = fcb_flash_write(fcb, loc->fe_sector, off, em, fcb->f_align);
|
||||
if (rc) {
|
||||
return -EIO;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2017 Nordic Semiconductor ASA
|
||||
* Copyright (c) 2017-2023 Nordic Semiconductor ASA
|
||||
* Copyright (c) 2015 Runtime Inc
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
|
@ -10,12 +10,14 @@
|
|||
#include <zephyr/fs/fcb.h>
|
||||
#include "fcb_priv.h"
|
||||
|
||||
#define FCB_FIXED_ENDMARKER 0xab
|
||||
|
||||
/*
|
||||
* Given offset in flash sector, fill in rest of the fcb_entry, and crc8 over
|
||||
* the data.
|
||||
*/
|
||||
int
|
||||
fcb_elem_crc8(struct fcb *fcb, struct fcb_entry *loc, uint8_t *c8p)
|
||||
static int
|
||||
fcb_elem_crc8(struct fcb *_fcb, struct fcb_entry *loc, uint8_t *c8p)
|
||||
{
|
||||
uint8_t tmp_str[FCB_TMP_BUF_SZ];
|
||||
int cnt;
|
||||
|
@ -29,16 +31,17 @@ fcb_elem_crc8(struct fcb *fcb, struct fcb_entry *loc, uint8_t *c8p)
|
|||
if (loc->fe_elem_off + 2 > loc->fe_sector->fs_size) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
rc = fcb_flash_read(fcb, loc->fe_sector, loc->fe_elem_off, tmp_str, 2);
|
||||
|
||||
rc = fcb_flash_read(_fcb, loc->fe_sector, loc->fe_elem_off, tmp_str, 2);
|
||||
if (rc) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
cnt = fcb_get_len(fcb, tmp_str, &len);
|
||||
cnt = fcb_get_len(_fcb, tmp_str, &len);
|
||||
if (cnt < 0) {
|
||||
return cnt;
|
||||
}
|
||||
loc->fe_data_off = loc->fe_elem_off + fcb_len_in_flash(fcb, cnt);
|
||||
loc->fe_data_off = loc->fe_elem_off + fcb_len_in_flash(_fcb, cnt);
|
||||
loc->fe_data_len = len;
|
||||
|
||||
crc8 = CRC8_CCITT_INITIAL_VALUE;
|
||||
|
@ -52,7 +55,7 @@ fcb_elem_crc8(struct fcb *fcb, struct fcb_entry *loc, uint8_t *c8p)
|
|||
blk_sz = sizeof(tmp_str);
|
||||
}
|
||||
|
||||
rc = fcb_flash_read(fcb, loc->fe_sector, off, tmp_str, blk_sz);
|
||||
rc = fcb_flash_read(_fcb, loc->fe_sector, off, tmp_str, blk_sz);
|
||||
if (rc) {
|
||||
return -EIO;
|
||||
}
|
||||
|
@ -63,25 +66,83 @@ fcb_elem_crc8(struct fcb *fcb, struct fcb_entry *loc, uint8_t *c8p)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int fcb_elem_info(struct fcb *fcb, struct fcb_entry *loc)
|
||||
#if IS_ENABLED(CONFIG_FCB_ALLOW_FIXED_ENDMARKER)
|
||||
/* Given the offset in flash sector, calculate the FCB entry data offset and size, and set
|
||||
* the fixed endmarker.
|
||||
*/
|
||||
static int
|
||||
fcb_elem_endmarker_fixed(struct fcb *_fcb, struct fcb_entry *loc, uint8_t *em)
|
||||
{
|
||||
uint8_t tmp_str[2];
|
||||
int cnt;
|
||||
uint16_t len;
|
||||
int rc;
|
||||
uint8_t crc8;
|
||||
uint8_t fl_crc8;
|
||||
off_t off;
|
||||
|
||||
rc = fcb_elem_crc8(fcb, loc, &crc8);
|
||||
if (rc) {
|
||||
return rc;
|
||||
if (loc->fe_elem_off + 2 > loc->fe_sector->fs_size) {
|
||||
return -ENOTSUP;
|
||||
}
|
||||
off = loc->fe_data_off + fcb_len_in_flash(fcb, loc->fe_data_len);
|
||||
|
||||
rc = fcb_flash_read(fcb, loc->fe_sector, off, &fl_crc8, sizeof(fl_crc8));
|
||||
rc = fcb_flash_read(_fcb, loc->fe_sector, loc->fe_elem_off, tmp_str, 2);
|
||||
if (rc) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (fl_crc8 != crc8) {
|
||||
cnt = fcb_get_len(_fcb, tmp_str, &len);
|
||||
if (cnt < 0) {
|
||||
return cnt;
|
||||
}
|
||||
loc->fe_data_off = loc->fe_elem_off + fcb_len_in_flash(_fcb, cnt);
|
||||
loc->fe_data_len = len;
|
||||
|
||||
*em = FCB_FIXED_ENDMARKER;
|
||||
return 0;
|
||||
}
|
||||
#endif /* IS_ENABLED(CONFIG_FCB_ALLOW_FIXED_ENDMARKER) */
|
||||
|
||||
/* Given the offset in flash sector, calculate the FCB entry data offset and size, and calculate
|
||||
* the expected endmarker.
|
||||
*/
|
||||
int
|
||||
fcb_elem_endmarker(struct fcb *_fcb, struct fcb_entry *loc, uint8_t *em)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_FCB_ALLOW_FIXED_ENDMARKER)
|
||||
if (_fcb->f_flags & FCB_FLAGS_CRC_DISABLED) {
|
||||
return fcb_elem_endmarker_fixed(_fcb, loc, em);
|
||||
}
|
||||
#endif /* IS_ENABLED(CONFIG_FCB_ALLOW_FIXED_ENDMARKER) */
|
||||
|
||||
return fcb_elem_crc8(_fcb, loc, em);
|
||||
}
|
||||
|
||||
/* Given the offset in flash sector, calculate the FCB entry data offset and size, and verify that
|
||||
* the FCB entry endmarker is correct.
|
||||
*/
|
||||
int fcb_elem_info(struct fcb *_fcb, struct fcb_entry *loc)
|
||||
{
|
||||
int rc;
|
||||
uint8_t em;
|
||||
uint8_t fl_em;
|
||||
off_t off;
|
||||
|
||||
rc = fcb_elem_endmarker(_fcb, loc, &em);
|
||||
if (rc) {
|
||||
return rc;
|
||||
}
|
||||
off = loc->fe_data_off + fcb_len_in_flash(_fcb, loc->fe_data_len);
|
||||
|
||||
rc = fcb_flash_read(_fcb, loc->fe_sector, off, &fl_em, sizeof(fl_em));
|
||||
if (rc) {
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_FCB_ALLOW_FIXED_ENDMARKER) && (fl_em != em)) {
|
||||
rc = fcb_elem_crc8(_fcb, loc, &em);
|
||||
if (rc) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
if (fl_em != em) {
|
||||
return -EBADMSG;
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2017-2020 Nordic Semiconductor ASA
|
||||
* Copyright (c) 2017-2023 Nordic Semiconductor ASA
|
||||
* Copyright (c) 2015 Runtime Inc
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
|
@ -70,7 +70,7 @@ struct flash_sector *fcb_getnext_sector(struct fcb *fcb,
|
|||
int fcb_getnext_nolock(struct fcb *fcb, struct fcb_entry *loc);
|
||||
|
||||
int fcb_elem_info(struct fcb *fcb, struct fcb_entry *loc);
|
||||
int fcb_elem_crc8(struct fcb *fcb, struct fcb_entry *loc, uint8_t *crc8p);
|
||||
int fcb_elem_endmarker(struct fcb *fcb, struct fcb_entry *loc, uint8_t *crc8p);
|
||||
|
||||
int fcb_sector_hdr_init(struct fcb *fcb, struct flash_sector *sector, uint16_t id);
|
||||
int fcb_sector_hdr_read(struct fcb *fcb, struct flash_sector *sector,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue