1
0
Fork 0
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:
Michael Keller 2020-06-03 07:02:39 +12:00 committed by GitHub
commit 4d11a14efa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 66 additions and 17 deletions

View file

@ -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:

View file

@ -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.
*/

View file

@ -46,6 +46,8 @@ int blackboxWriteString(const char *s);
void blackboxDeviceFlush(void);
bool blackboxDeviceFlushForce(void);
bool blackboxDeviceFlushForceComplete(void);
bool blackboxDeviceOpen(void);
void blackboxDeviceClose(void);

View file

@ -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.

View file

@ -93,3 +93,4 @@ bool afatfs_isFull(void);
afatfsFilesystemState_e afatfs_getFilesystemState(void);
afatfsError_e afatfs_getLastError(void);
bool afatfs_sectorCacheInSync(void);