Working on using AFATFS from Blackbox

This commit is contained in:
Nicholas Sherlock 2015-11-16 23:45:42 +13:00 committed by borisbstyle
parent 84d3cc6175
commit 96182c7c07
8 changed files with 3495 additions and 2 deletions

View File

@ -578,6 +578,8 @@ STM32F3DISCOVERY_SRC = \
drivers/compass_ak8975.c \
drivers/sdcard.c \
drivers/sdcard_standard.c \
io/asyncfatfs/asyncfatfs.c \
io/asyncfatfs/fat_standard.c \
$(HIGHEND_SRC) \
$(COMMON_SRC)

View File

@ -479,7 +479,7 @@ static void blackboxSetState(BlackboxState newState)
break;
case BLACKBOX_STATE_SHUTTING_DOWN:
xmitState.u.startTime = millis();
blackboxDeviceFlush();
blackboxDeviceEndLog();
break;
default:
;
@ -1401,7 +1401,7 @@ void handleBlackbox(void)
blackboxAdvanceIterationTimers();
break;
case BLACKBOX_STATE_SHUTTING_DOWN:
//On entry of this state, startTime is set and a flush is performed
//On entry of this state, startTime is set
/*
* Wait for the log we've transmitted to make its way to the logger before we release the serial port,

View File

@ -60,6 +60,7 @@
#include "config/config_master.h"
#include "io/flashfs.h"
#include "io/asyncfatfs/asyncfatfs.h"
#ifdef BLACKBOX
@ -74,6 +75,12 @@ int32_t blackboxHeaderBudget;
static serialPort_t *blackboxPort = NULL;
static portSharing_e blackboxPortSharing;
#ifdef USE_SDCARD
static afatfsFilePtr_t sdFile;
#endif
void blackboxWrite(uint8_t value)
{
switch (masterConfig.blackbox_device) {
@ -81,6 +88,11 @@ void blackboxWrite(uint8_t value)
case BLACKBOX_DEVICE_FLASH:
flashfsWriteByte(value); // Write byte asynchronously
break;
#endif
#ifdef USE_SDCARD
case BLACKBOX_DEVICE_SDCARD:
afatfs_fputc(sdFile, value);
break;
#endif
case BLACKBOX_DEVICE_SERIAL:
default:
@ -152,6 +164,13 @@ int blackboxPrint(const char *s)
break;
#endif
#ifdef USE_SDCARD
case BLACKBOX_DEVICE_SDCARD:
length = strlen(s);
afatfs_fwrite(sdFile, (const uint8_t*) s, length); // Ignore failures due to buffers filling up
break;
#endif
case BLACKBOX_DEVICE_SERIAL:
default:
pos = (uint8_t*) s;
@ -488,6 +507,11 @@ bool blackboxDeviceFlush(void)
return flashfsFlushAsync();
#endif
#ifdef USE_SDCARD
case BLACKBOX_DEVICE_SDCARD:
return afatfs_flush();
#endif
default:
return false;
}
@ -551,6 +575,17 @@ bool blackboxDeviceOpen(void)
return true;
break;
#endif
#ifdef USE_SDCARD
case BLACKBOX_DEVICE_SDCARD:
if (afatfs_getFilesystemState() != AFATFS_FILESYSTEM_STATE_READY || afatfs_isFull()) {
return false;
}
blackboxMaxHeaderBytesPerIteration = BLACKBOX_TARGET_HEADER_BUDGET_PER_ITERATION;
return true;
break;
#endif
default:
return false;
}
@ -578,6 +613,28 @@ void blackboxDeviceClose(void)
case BLACKBOX_DEVICE_FLASH:
// No-op since the flash doesn't have a "close" and there's nobody else to hand control of it to.
break;
#endif
#ifdef USE_SDCARD
case BLACKBOX_DEVICE_SDCARD:
afatfs_fclose(sdFile, NULL);
sdFile = NULL;
break;
#endif
}
}
/**
* Terminate the current log (for devices which support separations between the logs of multiple flights)
*/
void blackboxDeviceEndLog(void)
{
switch (masterConfig.blackbox_device) {
#ifdef USE_SDCARD
case BLACKBOX_DEVICE_SDCARD:
if (afatfs_fclose(sdFile, NULL)) {
sdFile = NULL;
}
break;
#endif
}
}
@ -593,6 +650,11 @@ bool isBlackboxDeviceFull(void)
return flashfsIsEOF();
#endif
#ifdef USE_SDCARD
case BLACKBOX_DEVICE_SDCARD:
return afatfs_isFull();
#endif
default:
return false;
}
@ -614,6 +676,11 @@ void blackboxReplenishHeaderBudget()
case BLACKBOX_DEVICE_FLASH:
freeSpace = flashfsGetWriteBufferFreeSpace();
break;
#endif
#ifdef USE_SDCARD
case BLACKBOX_DEVICE_SDCARD:
freeSpace = afatfs_getFreeBufferSpace();
break;
#endif
default:
freeSpace = 0;
@ -677,6 +744,12 @@ blackboxBufferReserveStatus_e blackboxDeviceReserveBufferSpace(int32_t bytes)
return BLACKBOX_RESERVE_TEMPORARY_FAILURE;
#endif
#ifdef USE_SDCARD
case BLACKBOX_DEVICE_SDCARD:
// Assume that all writes will fit in the SDCard's buffers
return BLACKBOX_RESERVE_TEMPORARY_FAILURE;
#endif
default:
return BLACKBOX_RESERVE_PERMANENT_FAILURE;
}

View File

@ -28,6 +28,9 @@ typedef enum BlackboxDevice {
#ifdef USE_FLASHFS
BLACKBOX_DEVICE_FLASH,
#endif
#ifdef USE_SDCARD
BLACKBOX_DEVICE_SDCARD,
#endif
BLACKBOX_DEVICE_END
} BlackboxDevice;
@ -72,6 +75,7 @@ void blackboxWriteFloat(float value);
bool blackboxDeviceFlush(void);
bool blackboxDeviceOpen(void);
void blackboxDeviceClose(void);
void blackboxDeviceEndLog(void);
bool isBlackboxDeviceFull(void);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,66 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include "fat_standard.h"
typedef struct afatfsFile_t *afatfsFilePtr_t;
typedef enum {
AFATFS_FILESYSTEM_STATE_UNKNOWN,
AFATFS_FILESYSTEM_STATE_FATAL,
AFATFS_FILESYSTEM_STATE_INITIALIZATION,
AFATFS_FILESYSTEM_STATE_READY,
} afatfsFilesystemState_e;
typedef enum {
AFATFS_OPERATION_IN_PROGRESS,
AFATFS_OPERATION_SUCCESS,
AFATFS_OPERATION_FAILURE,
} afatfsOperationStatus_e;
typedef struct afatfsDirEntryPointer_t {
uint32_t sectorNumberPhysical;
int16_t entryIndex;
} afatfsDirEntryPointer_t;
typedef afatfsDirEntryPointer_t afatfsFinder_t;
typedef enum {
AFATFS_SEEK_SET,
AFATFS_SEEK_CUR,
AFATFS_SEEK_END,
} afatfsSeek_e;
typedef void (*afatfsFileCallback_t)(afatfsFilePtr_t file);
typedef void (*afatfsCallback_t)();
bool afatfs_fopen(const char *filename, const char *mode, afatfsFileCallback_t complete);
bool afatfs_ftruncate(afatfsFilePtr_t file, afatfsFileCallback_t callback);
bool afatfs_fclose(afatfsFilePtr_t file, afatfsCallback_t callback);
bool afatfs_funlink(afatfsFilePtr_t file, afatfsCallback_t callback);
bool afatfs_feof(afatfsFilePtr_t file);
void afatfs_fputc(afatfsFilePtr_t file, uint8_t c);
uint32_t afatfs_fwrite(afatfsFilePtr_t file, const uint8_t *buffer, uint32_t len);
uint32_t afatfs_fread(afatfsFilePtr_t file, uint8_t *buffer, uint32_t len);
afatfsOperationStatus_e afatfs_fseek(afatfsFilePtr_t file, int32_t offset, afatfsSeek_e whence);
bool afatfs_ftell(afatfsFilePtr_t file, uint32_t *position);
afatfsFilePtr_t afatfs_mkdir(const char *filename, afatfsFileCallback_t complete);
bool afatfs_chdir(afatfsFilePtr_t dirHandle);
void afatfs_findFirst(afatfsFilePtr_t directory, afatfsFinder_t *finder);
afatfsOperationStatus_e afatfs_findNext(afatfsFilePtr_t directory, afatfsFinder_t *finder, fatDirectoryEntry_t **dirEntry);
bool afatfs_flush();
void afatfs_init();
bool afatfs_destroy();
void afatfs_poll();
uint32_t afatfs_getFreeBufferSpace();
uint32_t afatfs_getContiguousFreeSpace();
bool afatfs_isFull();
afatfsFilesystemState_e afatfs_getFilesystemState();

View File

@ -0,0 +1,72 @@
#include <ctype.h>
#include "fat_standard.h"
bool fat16_isEndOfChainMarker(uint16_t clusterNumber)
{
return clusterNumber >= 0xFFF8;
}
// Pass the cluster number after fat32_decodeClusterNumber().
bool fat32_isEndOfChainMarker(uint32_t clusterNumber)
{
return clusterNumber >= 0x0FFFFFF8;
}
/**
* FAT32 cluster numbers are really only 28 bits, and the top 4 bits must be left alone and not treated as part of the
* cluster number (so various FAT drivers can use those bits for their own purposes, or they can be used in later
* extensions)
*/
uint32_t fat32_decodeClusterNumber(uint32_t clusterNumber)
{
return clusterNumber & 0x0FFFFFFF;
}
// fat32 needs fat32_decodeClusterNumber() applied first.
bool fat_isFreeSpace(uint32_t clusterNumber)
{
return clusterNumber == 0;
}
bool fat_isDirectoryEntryTerminator(fatDirectoryEntry_t *entry)
{
return entry->filename[0] == 0x00;
}
bool fat_isDirectoryEntryEmpty(fatDirectoryEntry_t *entry)
{
return (unsigned char) entry->filename[0] == FAT_DELETED_FILE_MARKER;
}
/**
* Convert the given "prefix.ext" style filename to the FAT format to be stored on disk.
*
* fatFilename must point to a buffer which is FAT_FILENAME_LENGTH bytes long. The buffer is not null-terminated.
*/
void fat_convertFilenameToFATStyle(const char *filename, uint8_t *fatFilename)
{
for (int i = 0; i < 8; i++) {
if (*filename == '\0' || *filename == '.') {
*fatFilename = ' ';
} else {
*fatFilename = toupper((unsigned char)*filename);
filename++;
}
fatFilename++;
}
if (*filename == '.') {
filename++;
}
for (int i = 0; i < 3; i++) {
if (*filename == '\0') {
*fatFilename = ' ';
} else {
*fatFilename = toupper((unsigned char)*filename);
filename++;
}
fatFilename++;
}
}

View File

@ -0,0 +1,120 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
#define MBR_PARTITION_TYPE_FAT16 0x06
#define MBR_PARTITION_TYPE_FAT32 0x0B
#define MBR_PARTITION_TYPE_FAT32_LBA 0x0C
#define MBR_PARTITION_TYPE_FAT16_LBA 0x0E
// Signature bytes found at index 510 and 511 in the volume ID sector
#define FAT_VOLUME_ID_SIGNATURE_1 0x55
#define FAT_VOLUME_ID_SIGNATURE_2 0xAA
#define FAT_DIRECTORY_ENTRY_SIZE 32
#define FAT_SMALLEST_LEGAL_CLUSTER_NUMBER 2
#define FAT_MAXIMUM_FILESIZE 0xFFFFFFFF
#define FAT12_MAX_CLUSTERS 4084
#define FAT16_MAX_CLUSTERS 65524
#define FAT_FILE_ATTRIBUTE_READ_ONLY 0x01
#define FAT_FILE_ATTRIBUTE_HIDDEN 0x02
#define FAT_FILE_ATTRIBUTE_SYSTEM 0x04
#define FAT_FILE_ATTRIBUTE_VOLUME_ID 0x08
#define FAT_FILE_ATTRIBUTE_DIRECTORY 0x10
#define FAT_FILE_ATTRIBUTE_ARCHIVE 0x20
#define FAT_FILENAME_LENGTH 11
#define FAT_DELETED_FILE_MARKER 0xE5
typedef enum {
FAT_FILESYSTEM_TYPE_INVALID,
FAT_FILESYSTEM_TYPE_FAT12,
FAT_FILESYSTEM_TYPE_FAT16,
FAT_FILESYSTEM_TYPE_FAT32,
} fatFilesystemType_e;
typedef struct mbrPartitionEntry_t {
uint8_t bootFlag;
uint8_t chsBegin[3];
uint8_t type;
uint8_t chsEnd[3];
uint32_t lbaBegin;
uint32_t numSectors;
} __attribute__((packed)) mbrPartitionEntry_t;
typedef struct fat16Descriptor_t {
uint8_t driveNumber;
uint8_t reserved1;
uint8_t bootSignature;
uint32_t volumeID;
char volumeLabel[11];
char fileSystemType[8];
} __attribute__((packed)) fat16Descriptor_t;
typedef struct fat32Descriptor_t {
uint32_t FATSize32;
uint16_t extFlags;
uint16_t fsVer;
uint32_t rootCluster;
uint16_t fsInfo;
uint16_t backupBootSector;
uint8_t reserved[12];
uint8_t driveNumber;
uint8_t reserved1;
uint8_t bootSignature;
uint32_t volumeID;
char volumeLabel[11];
char fileSystemType[8];
} __attribute__((packed)) fat32Descriptor_t;
typedef struct fatVolumeID_t {
uint8_t jmpBoot[3];
char oemName[8];
uint16_t bytesPerSector;
uint8_t sectorsPerCluster;
uint16_t reservedSectorCount;
uint8_t numFATs;
uint16_t rootEntryCount;
uint16_t totalSectors16;
uint8_t media;
uint16_t FATSize16;
uint16_t sectorsPerTrack;
uint16_t numHeads;
uint32_t hiddenSectors;
uint32_t totalSectors32;
union {
fat16Descriptor_t fat16;
fat32Descriptor_t fat32;
} fatDescriptor;
} __attribute__((packed)) fatVolumeID_t;
typedef struct fatDirectoryEntry_t {
char filename[FAT_FILENAME_LENGTH];
uint8_t attrib;
uint8_t ntReserved;
uint8_t creationTimeTenths;
uint16_t creationTime;
uint16_t creationDate;
uint16_t lastAccessDate;
uint16_t firstClusterHigh;
uint16_t lastWriteTime;
uint16_t lastWriteDate;
uint16_t firstClusterLow;
uint32_t fileSize;
} __attribute__((packed)) fatDirectoryEntry_t;
uint32_t fat32_decodeClusterNumber(uint32_t clusterNumber);
bool fat32_isEndOfChainMarker(uint32_t clusterNumber);
bool fat16_isEndOfChainMarker(uint16_t clusterNumber);
bool fat_isFreeSpace(uint32_t clusterNumber);
bool fat_isDirectoryEntryTerminator(fatDirectoryEntry_t *entry);
bool fat_isDirectoryEntryEmpty(fatDirectoryEntry_t *entry);
void fat_convertFilenameToFATStyle(const char *filename, uint8_t *fatFilename);