Skip to content

Commit

Permalink
Flashfs Loop recording and initial erase (#209)
Browse files Browse the repository at this point in the history
* flashfs: add flashfs loop support and initial erase

When using loop mode, we will identify the "start of the data stream"
(by empty region followed by filled region). Also the usable size is
reduced to `full size - page size - buffer size`. (The - buffer size is
for code simplicity).
The original FLASHFS_FREE_BLOCK_SIZE is changed to page size to avoid
misalignment.

A new option blackbox_initial_erase is added to maintain a certain amount
of free space upon record start.

This also add (change) some cli cmds for diagnoses:
flash_fill
flash_verify
flash_erase_sector
flashfs_initial_erase

* Initial erase: change param unit to KiB

Change `initialEraseFreeSpace` to `....KiB` and update unit tests.
  • Loading branch information
gongtao0607 authored Jan 18, 2025
1 parent 245a556 commit 5fc85a8
Show file tree
Hide file tree
Showing 22 changed files with 1,536 additions and 75 deletions.
37 changes: 33 additions & 4 deletions src/main/blackbox/blackbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,8 @@ static const blackboxSimpleFieldDefinition_t blackboxSlowFields[] = {
typedef enum BlackboxState {
BLACKBOX_STATE_DISABLED = 0,
BLACKBOX_STATE_STOPPED,
BLACKBOX_STATE_WAIT_FOR_READY,
BLACKBOX_STATE_INITIAL_ERASE,
BLACKBOX_STATE_PREPARE_LOG_FILE,
BLACKBOX_STATE_SEND_HEADER,
BLACKBOX_STATE_SEND_MAIN_FIELD_HEADER,
Expand All @@ -345,6 +347,7 @@ typedef enum BlackboxState {
BLACKBOX_STATE_CACHE_FLUSH,
BLACKBOX_STATE_PAUSED,
BLACKBOX_STATE_RUNNING,
BLACKBOX_STATE_FULL,
BLACKBOX_STATE_SHUTTING_DOWN,
BLACKBOX_STATE_START_ERASE,
BLACKBOX_STATE_ERASING,
Expand Down Expand Up @@ -1175,7 +1178,7 @@ static void blackboxStart(void)
blackboxLastRescueState = getRescueState();
blackboxLastAirborneState = isAirborne();

blackboxSetState(BLACKBOX_STATE_PREPARE_LOG_FILE);
blackboxSetState(BLACKBOX_STATE_WAIT_FOR_READY);
}

void blackboxCheckEnabler(void)
Expand Down Expand Up @@ -1972,6 +1975,15 @@ bool isBlackboxErased(void)
return isBlackboxDeviceReady();
}

void blackboxInitialErase(void)
{
#ifdef USE_FLASHFS
if (blackboxConfig()->device == BLACKBOX_DEVICE_FLASH) {
blackboxDeviceInitialErase();
}
#endif
}

/**
* Call each flight loop iteration to perform blackbox logging.
*/
Expand All @@ -1993,6 +2005,17 @@ void blackboxUpdate(timeUs_t currentTimeUs)
blackboxStart();
}
break;
case BLACKBOX_STATE_WAIT_FOR_READY:
if (isBlackboxDeviceReady()) {
blackboxInitialErase();
blackboxSetState(BLACKBOX_STATE_INITIAL_ERASE);
}
break;
case BLACKBOX_STATE_INITIAL_ERASE:
if (isBlackboxDeviceReady()) {
blackboxSetState(BLACKBOX_STATE_PREPARE_LOG_FILE);
}
break;
case BLACKBOX_STATE_PREPARE_LOG_FILE:
if (blackboxDeviceBeginLog()) {
blackboxSetState(BLACKBOX_STATE_SEND_HEADER);
Expand Down Expand Up @@ -2138,16 +2161,22 @@ void blackboxUpdate(timeUs_t currentTimeUs)
blackboxSetState(BLACKBOX_STATE_STOPPED);
blackboxStarted = false;
}
break;
break;
case BLACKBOX_STATE_FULL:
if (!blackboxIsLoggingEnabled()) {
blackboxDeviceClose();
blackboxSetState(BLACKBOX_STATE_STOPPED);
}
break;
#endif
default:
break;
}

// Did we run out of room on the device? Stop!
if (isBlackboxDeviceFull()) {
if (blackboxState < BLACKBOX_STATE_START_ERASE) {
blackboxSetState(BLACKBOX_STATE_STOPPED);
if (blackboxState == BLACKBOX_STATE_RUNNING) {
blackboxSetState(BLACKBOX_STATE_FULL);
}
}
}
Expand Down
16 changes: 15 additions & 1 deletion src/main/blackbox/blackbox_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ bool blackboxDeviceOpen(void)
break;
#ifdef USE_FLASHFS
case BLACKBOX_DEVICE_FLASH:
if (!flashfsIsSupported() || isBlackboxDeviceFull()) {
if (!flashfsIsSupported()) {
return false;
}

Expand Down Expand Up @@ -376,18 +376,32 @@ void blackboxDeviceErase(void)
flashfsEraseCompletely();
}
}
#endif

/**
* Check to see if erasing is done
*/
bool isBlackboxDeviceReady(void)
{
#ifdef USE_FLASHFS
if (blackboxConfig()->device == BLACKBOX_DEVICE_FLASH) {
return flashfsIsReady();
}
#endif
return true;
}

/**
* Perform an initial erase to get some empty space.
*/
void blackboxDeviceInitialErase(void)
{
#ifdef USE_FLASHFS_LOOP
if (blackboxConfig()->device == BLACKBOX_DEVICE_FLASH) {
flashfsLoopInitialErase();
}
#endif
}

/**
* Close the Blackbox logging device.
Expand Down
2 changes: 2 additions & 0 deletions src/main/blackbox/blackbox_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,5 @@ int32_t blackboxGetLogNumber(void);
void blackboxReplenishHeaderBudget(void);
blackboxBufferReserveStatus_e blackboxDeviceReserveBufferSpace(int32_t bytes);
int8_t blackboxGetLogFileNo(void);

void blackboxDeviceInitialErase(void);
86 changes: 83 additions & 3 deletions src/main/cli/cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -2682,6 +2682,9 @@ static void cliFlashInfo(const char *cmdName, char *cmdline)
FLASH_PARTITION_SECTOR_COUNT(flashPartition) * layout->sectorSize,
flashfsGetOffset()
);
cliPrintLinef("FlashFSLoop Head = 0x%08x, Tail = 0x%08x",
flashfsGetHeadAddress(),
flashfsGetTailAddress());
#endif
}

Expand All @@ -2706,6 +2709,7 @@ static void cliFlashErase(const char *cmdName, char *cmdline)
flashfsEraseCompletely();

while (!flashfsIsReady()) {
flashfsEraseAsync();
#ifndef MINIMAL_CLI
cliPrintf(".");
if (i++ > 120) {
Expand All @@ -2724,6 +2728,16 @@ static void cliFlashErase(const char *cmdName, char *cmdline)

#ifdef USE_FLASH_TOOLS

static void cliFlashFill(const char *cmdName, char *cmdline)
{
UNUSED(cmdName);
UNUSED(cmdline);

cliPrintLine("Filling");
flashfsFillEntireFlash();
cliPrintLine("Done");
}

static void cliFlashVerify(const char *cmdName, char *cmdline)
{
UNUSED(cmdline);
Expand All @@ -2744,7 +2758,7 @@ static void cliFlashWrite(const char *cmdName, char *cmdline)
if (!text) {
cliShowInvalidArgumentCountError(cmdName);
} else {
flashfsSeekAbs(address);
flashfsSeekPhysical(address);
flashfsWrite((uint8_t*)text, strlen(text));
flashfsFlushSync();

Expand All @@ -2767,7 +2781,7 @@ static void cliFlashRead(const char *cmdName, char *cmdline)

uint8_t buffer[32];
while (length > 0) {
int bytesRead = flashfsReadAbs(address, buffer, length < sizeof(buffer) ? length : sizeof(buffer));
int bytesRead = flashfsReadPhysical(address, buffer, length < sizeof(buffer) ? length : sizeof(buffer));

for (int i = 0; i < bytesRead; i++) {
cliWrite(buffer[i]);
Expand All @@ -2785,6 +2799,67 @@ static void cliFlashRead(const char *cmdName, char *cmdline)
}
}

static void cliFlashEraseSector(const char *cmdName, char *cmdline)
{
UNUSED(cmdName);

const char *ptr = cmdline;
uint32_t address = atoi(ptr);
ptr = nextArg(cmdline);
uint32_t length = atoi(ptr);

const uint32_t sectorSize = flashGetGeometry()->sectorSize;
const uint32_t totalSize = flashGetGeometry()->totalSize;

if (length == 0) {
length = 1;
}

// Round down `address`, round up `end_address`, and update `length`
uint32_t end_address = address + length;
address = address / sectorSize * sectorSize;
end_address = (end_address + sectorSize - 1) / sectorSize * sectorSize;
length = end_address - address;

flashSector_t count = length / sectorSize;

if (address > totalSize - sectorSize) {
cliShowArgumentRangeError(cmdName, "address", 0,
totalSize - sectorSize);
return;
}
if (end_address > totalSize) {
cliShowArgumentRangeError(cmdName, "length", sectorSize,
totalSize - address);
return;
}
timeUs_t start = micros();
for (uint32_t i = 0; i < count; i++) {
flashEraseSector(address + i * sectorSize);
flashWaitForReady();
}
timeUs_t end = micros();
cliPrintLinef("Erased address %u length %u (%u sectors) in %u us", address,
length, count, end - start);
}

#ifdef USE_FLASHFS_LOOP
static void cliFlashfsInitialErase(const char *cmdName, char *cmdline)
{
UNUSED(cmdName);
UNUSED(cmdline);
flashfsInit();

timeUs_t start = micros();
flashfsLoopInitialErase();
while(!flashfsIsReady()) {
flashfsEraseAsync();
}
timeUs_t end = micros();
cliPrintLinef("FlashfsInitialErase %u us", end - start);
}
#endif // USE_FLASHFS_LOOP

#endif
#endif

Expand Down Expand Up @@ -6429,8 +6504,13 @@ const clicmd_t cmdTable[] = {
CLI_COMMAND_DEF("flash_info", "show flash chip info", NULL, cliFlashInfo),
#ifdef USE_FLASH_TOOLS
CLI_COMMAND_DEF("flash_read", NULL, "<length> <address>", cliFlashRead),
CLI_COMMAND_DEF("flash_scan", "scan flash device for errors", NULL, cliFlashVerify),
CLI_COMMAND_DEF("flash_fill", "fill device with predefined pattern", NULL, cliFlashFill),
CLI_COMMAND_DEF("flash_verify", "verify device with predefined pattern", NULL, cliFlashVerify),
CLI_COMMAND_DEF("flash_write", NULL, "<address> <message>", cliFlashWrite),
CLI_COMMAND_DEF("flash_erase_sector", "erase flash sector(s)", "<address> [<length>]", cliFlashEraseSector),
#ifdef USE_FLASHFS_LOOP
CLI_COMMAND_DEF("flashfs_initial_erase", "invoke initial erase", NULL, cliFlashfsInitialErase),
#endif // USE_FLASHFS_LOOP
#endif
#endif
CLI_COMMAND_DEF("get", "get variable value", "[name]", cliGet),
Expand Down
4 changes: 4 additions & 0 deletions src/main/cli/settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,10 @@ const clivalue_t valueTable[] = {
{ "blackbox_log_esc", VAR_UINT32 | MASTER_VALUE | MODE_BITSET, .config.bitpos = FLIGHT_LOG_FIELD_SELECT_ESC, PG_BLACKBOX_CONFIG, offsetof(blackboxConfig_t, fields) },
{ "blackbox_log_bec", VAR_UINT32 | MASTER_VALUE | MODE_BITSET, .config.bitpos = FLIGHT_LOG_FIELD_SELECT_BEC, PG_BLACKBOX_CONFIG, offsetof(blackboxConfig_t, fields) },
{ "blackbox_log_esc2", VAR_UINT32 | MASTER_VALUE | MODE_BITSET, .config.bitpos = FLIGHT_LOG_FIELD_SELECT_ESC2, PG_BLACKBOX_CONFIG, offsetof(blackboxConfig_t, fields) },

#ifdef USE_FLASHFS_LOOP
{ "blackbox_initial_erase_kb", VAR_UINT16 | MASTER_VALUE, .config.minmaxUnsigned = { 0, UINT16_MAX }, PG_BLACKBOX_CONFIG, offsetof(blackboxConfig_t, initialEraseFreeSpaceKiB) },
#endif
#endif

// PG_MOTOR_CONFIG
Expand Down
1 change: 0 additions & 1 deletion src/main/fc/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@

#include "core.h"


enum {
ALIGN_GYRO = 0,
ALIGN_ACCEL = 1,
Expand Down
Loading

0 comments on commit 5fc85a8

Please sign in to comment.