mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-19 14:25:20 +03:00
Merge pull request #9857 from etracer65/blackbox_sdcard_flush_header
Blackbox flush SD card sector cache after writing header and before logging starts
This commit is contained in:
commit
4d11a14efa
5 changed files with 66 additions and 17 deletions
|
@ -42,17 +42,13 @@
|
|||
#include "common/time.h"
|
||||
#include "common/utils.h"
|
||||
|
||||
#include "config/config.h"
|
||||
#include "config/feature.h"
|
||||
#include "pg/pg.h"
|
||||
#include "pg/pg_ids.h"
|
||||
#include "pg/motor.h"
|
||||
#include "pg/rx.h"
|
||||
|
||||
#include "drivers/compass/compass.h"
|
||||
#include "drivers/sensor.h"
|
||||
#include "drivers/time.h"
|
||||
|
||||
#include "config/config.h"
|
||||
#include "fc/board_info.h"
|
||||
#include "fc/controlrate_profile.h"
|
||||
#include "fc/rc.h"
|
||||
|
@ -70,6 +66,11 @@
|
|||
#include "io/gps.h"
|
||||
#include "io/serial.h"
|
||||
|
||||
#include "pg/pg.h"
|
||||
#include "pg/pg_ids.h"
|
||||
#include "pg/motor.h"
|
||||
#include "pg/rx.h"
|
||||
|
||||
#include "rx/rx.h"
|
||||
|
||||
#include "sensors/acceleration.h"
|
||||
|
@ -281,6 +282,7 @@ typedef enum BlackboxState {
|
|||
BLACKBOX_STATE_SEND_GPS_G_HEADER,
|
||||
BLACKBOX_STATE_SEND_SLOW_HEADER,
|
||||
BLACKBOX_STATE_SEND_SYSINFO,
|
||||
BLACKBOX_STATE_CACHE_FLUSH,
|
||||
BLACKBOX_STATE_PAUSED,
|
||||
BLACKBOX_STATE_RUNNING,
|
||||
BLACKBOX_STATE_SHUTTING_DOWN,
|
||||
|
@ -1607,6 +1609,8 @@ STATIC_UNIT_TESTED void blackboxLogIteration(timeUs_t currentTimeUs)
|
|||
*/
|
||||
void blackboxUpdate(timeUs_t currentTimeUs)
|
||||
{
|
||||
static BlackboxState cacheFlushNextState;
|
||||
|
||||
switch (blackboxState) {
|
||||
case BLACKBOX_STATE_STOPPED:
|
||||
if (ARMING_FLAG(ARMED)) {
|
||||
|
@ -1680,7 +1684,8 @@ void blackboxUpdate(timeUs_t currentTimeUs)
|
|||
//On entry of this state, xmitState.headerIndex is 0 and xmitState.u.fieldIndex is -1
|
||||
if (!sendFieldDefinition('S', 0, blackboxSlowFields, blackboxSlowFields + 1, ARRAYLEN(blackboxSlowFields),
|
||||
NULL, NULL)) {
|
||||
blackboxSetState(BLACKBOX_STATE_SEND_SYSINFO);
|
||||
cacheFlushNextState = BLACKBOX_STATE_SEND_SYSINFO;
|
||||
blackboxSetState(BLACKBOX_STATE_CACHE_FLUSH);
|
||||
}
|
||||
break;
|
||||
case BLACKBOX_STATE_SEND_SYSINFO:
|
||||
|
@ -1694,9 +1699,14 @@ void blackboxUpdate(timeUs_t currentTimeUs)
|
|||
* (overflowing circular buffers causes all data to be discarded, so the first few logged iterations
|
||||
* could wipe out the end of the header if we weren't careful)
|
||||
*/
|
||||
if (blackboxDeviceFlushForce()) {
|
||||
blackboxSetState(BLACKBOX_STATE_RUNNING);
|
||||
}
|
||||
cacheFlushNextState = BLACKBOX_STATE_RUNNING;
|
||||
blackboxSetState(BLACKBOX_STATE_CACHE_FLUSH);
|
||||
}
|
||||
break;
|
||||
case BLACKBOX_STATE_CACHE_FLUSH:
|
||||
// Flush the cache and wait until all possible entries have been written to the media
|
||||
if (blackboxDeviceFlushForceComplete()) {
|
||||
blackboxSetState(cacheFlushNextState);
|
||||
}
|
||||
break;
|
||||
case BLACKBOX_STATE_PAUSED:
|
||||
|
|
|
@ -242,9 +242,11 @@ bool blackboxDeviceFlushForce(void)
|
|||
|
||||
#ifdef USE_SDCARD
|
||||
case BLACKBOX_DEVICE_SDCARD:
|
||||
/* SD card will flush itself without us calling it, but we need to call flush manually in order to check
|
||||
* if it's done yet or not!
|
||||
*/
|
||||
// SD card will flush itself without us calling it, but we need to call flush manually in order to check
|
||||
// if it's done yet or not!
|
||||
// However the "flush" only queues one dirty sector each time and the process is asynchronous. So after
|
||||
// the last dirty sector is queued the flush returns true even though the sector may not actually have
|
||||
// been physically written to the SD card yet.
|
||||
return afatfs_flush();
|
||||
#endif // USE_SDCARD
|
||||
|
||||
|
@ -253,6 +255,26 @@ bool blackboxDeviceFlushForce(void)
|
|||
}
|
||||
}
|
||||
|
||||
// Flush the blackbox device and only return true if sync is actually complete.
|
||||
// Primarily to ensure the async operations of SD card sector writes complete thus freeing the cache entries.
|
||||
bool blackboxDeviceFlushForceComplete(void)
|
||||
{
|
||||
switch (blackboxConfig()->device) {
|
||||
#ifdef USE_SDCARD
|
||||
case BLACKBOX_DEVICE_SDCARD:
|
||||
if (afatfs_sectorCacheInSync()) {
|
||||
return true;
|
||||
} else {
|
||||
blackboxDeviceFlushForce();
|
||||
return false;
|
||||
}
|
||||
#endif // USE_SDCARD
|
||||
|
||||
default:
|
||||
return blackboxDeviceFlushForce();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to open the logging device. Returns true if successful.
|
||||
*/
|
||||
|
|
|
@ -46,6 +46,8 @@ int blackboxWriteString(const char *s);
|
|||
|
||||
void blackboxDeviceFlush(void);
|
||||
bool blackboxDeviceFlushForce(void);
|
||||
bool blackboxDeviceFlushForceComplete(void);
|
||||
|
||||
bool blackboxDeviceOpen(void);
|
||||
void blackboxDeviceClose(void);
|
||||
|
||||
|
|
|
@ -44,21 +44,23 @@
|
|||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include "asyncfatfs.h"
|
||||
|
||||
#include "fat_standard.h"
|
||||
#include "drivers/sdcard.h"
|
||||
#include "common/maths.h"
|
||||
#include "common/time.h"
|
||||
#include "common/utils.h"
|
||||
|
||||
#include "drivers/sdcard.h"
|
||||
|
||||
#include "fat_standard.h"
|
||||
|
||||
#include "asyncfatfs.h"
|
||||
|
||||
#ifdef AFATFS_DEBUG
|
||||
#define ONLY_EXPOSE_FOR_TESTING
|
||||
#else
|
||||
#define ONLY_EXPOSE_FOR_TESTING static
|
||||
#endif
|
||||
|
||||
#define AFATFS_NUM_CACHE_SECTORS 10
|
||||
#define AFATFS_NUM_CACHE_SECTORS 11
|
||||
|
||||
// FAT filesystems are allowed to differ from these parameters, but we choose not to support those weird filesystems:
|
||||
#define AFATFS_SECTOR_SIZE 512
|
||||
|
@ -736,6 +738,18 @@ static void afatfs_cacheFlushSector(int cacheIndex)
|
|||
}
|
||||
}
|
||||
|
||||
// Check whether every sector in the cache that can be flushed has been synchronized
|
||||
bool afatfs_sectorCacheInSync(void)
|
||||
{
|
||||
for (int i = 0; i < AFATFS_NUM_CACHE_SECTORS; i++) {
|
||||
if ((afatfs.cacheDescriptor[i].state == AFATFS_CACHE_STATE_WRITING) ||
|
||||
((afatfs.cacheDescriptor[i].state == AFATFS_CACHE_STATE_DIRTY) && !afatfs.cacheDescriptor[i].locked)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a sector in the cache which corresponds to the given physical sector index, or NULL if the sector isn't
|
||||
* cached. Note that the cached sector could be in any state including completely empty.
|
||||
|
|
|
@ -93,3 +93,4 @@ bool afatfs_isFull(void);
|
|||
|
||||
afatfsFilesystemState_e afatfs_getFilesystemState(void);
|
||||
afatfsError_e afatfs_getLastError(void);
|
||||
bool afatfs_sectorCacheInSync(void);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue