Attempt at building a platformio version before starting on changes to testing
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,259 @@
|
||||
#ifndef SDBlock_h
|
||||
#define SDBlock_h
|
||||
|
||||
// #define USE_SDCORE
|
||||
#define USE_SD2CARD
|
||||
// #define USE_SDFS
|
||||
|
||||
#ifdef USE_SDCORE
|
||||
#include <SDCore.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_SD2CARD
|
||||
#include <SPI.h>
|
||||
#include <SD.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_SDFS
|
||||
#include <SdFs.h>
|
||||
// if (!sd.card()->readSector(0, (uint8_t*)&mbr)) {
|
||||
#define SD_CS_PIN SS
|
||||
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI)
|
||||
#endif
|
||||
|
||||
#include <TimeLib.h>
|
||||
#include <CRC32.h>
|
||||
#include "SDBlockData.h"
|
||||
|
||||
// Define Callback with buffers
|
||||
// typedef void (*CallbackFunction) (uint32_t recId, uint32_t blockId, uint32_t blockCount, void *buf, uint16_t size);
|
||||
|
||||
#define ERASE_SIZE 262144L
|
||||
|
||||
class SDBlock {
|
||||
public:
|
||||
void begin(uint32_t dId);
|
||||
void end();
|
||||
|
||||
bool debug;
|
||||
Stream *stream;
|
||||
|
||||
#ifdef USE_SD2CARD
|
||||
Sd2Card sd;
|
||||
#endif
|
||||
|
||||
#ifdef USE_SDFS
|
||||
// SdFat sd;
|
||||
// SdExFat sd;
|
||||
SdCardFactory cardFactory;
|
||||
SdFs sd;
|
||||
#endif
|
||||
|
||||
uint32_t size;
|
||||
|
||||
// Erase card etc
|
||||
SDBlock_Allocation* allocation;
|
||||
SDBlock_Metadata* metadata;
|
||||
SDBlock_LogLines* loglines;
|
||||
SDBlock_Queue* queue;
|
||||
SDBlock_Block* block;
|
||||
|
||||
// Thew actual Buffer
|
||||
byte buffer[SDBLOCK_SECTOR_SIZE] = {0x00};
|
||||
|
||||
bool getMBR();
|
||||
|
||||
bool _sdinit();
|
||||
bool cardIsOpen();
|
||||
bool cardErase();
|
||||
bool cardOpen(uint32_t cId, bool format = false);
|
||||
bool cardClose();
|
||||
void cardForceClose();
|
||||
void checkInternals();
|
||||
|
||||
bool read(unsigned long address_in);
|
||||
bool write(unsigned long address_in);
|
||||
|
||||
bool allocationDefault();
|
||||
bool allocationUpdate();
|
||||
bool allocationWrite();
|
||||
bool allocationValid();
|
||||
bool allocationRead();
|
||||
|
||||
void crcUpdate();
|
||||
bool crcCheck();
|
||||
void crcSet();
|
||||
|
||||
bool validRange(char *str, uint32_t test, uint32_t start, uint32_t max);
|
||||
|
||||
bool dataIsOpen();
|
||||
bool dataOpen(uint32_t recId);
|
||||
bool dataClose(bool output);
|
||||
bool dataPrepare(void* in = NULL, uint16_t size = 0);
|
||||
bool dataWrite(void* in = NULL, uint16_t size = 0);
|
||||
|
||||
bool metadataPrepare(void* in = NULL, uint16_t size = 0);
|
||||
bool metadataWrite(void* in = NULL, uint16_t size = 0);
|
||||
bool metadataRead(uint32_t fromEnd);
|
||||
bool metadataReadBLK(uint32_t address_in);
|
||||
bool metadataUpdateStatus(uint32_t address_in, uint32_t record_in, uint32_t status_in);
|
||||
void metadataList(uint32_t fromEnd, uint32_t num, Print* altstream = NULL); //, CallbackFunction cb = NULL);
|
||||
|
||||
bool resultsRead(uint32_t adddress);
|
||||
bool resultsReadBLK(uint32_t adddress);
|
||||
|
||||
// Status Updats, note: BLK - means actual block (where ever it is)
|
||||
/*
|
||||
bool metadataStatusBLK(uint32_t block, uint32_t status);
|
||||
bool dataStatusBLK(uint32_t block, uint32_t status);
|
||||
*/
|
||||
|
||||
uint32_t metadataCount();
|
||||
|
||||
// void dataList(unsigned long address, Print* altstream = NULL, CallbackFunction metadata_cb = NULL, CallbackFunction data_cb = NULL);
|
||||
|
||||
bool singlePrepare(void* in = NULL, uint16_t size = 0);
|
||||
bool singleWrite(void* in = NULL, uint16_t size = 0);
|
||||
bool singleRead(uint32_t fromEnd);
|
||||
uint32_t singleCount();
|
||||
|
||||
void setDeviceId(uint32_t dId);
|
||||
void setRecordId(uint32_t rId);
|
||||
|
||||
void setAutoFormat(bool in);
|
||||
bool getAutoFormat();
|
||||
|
||||
// Very basic queue
|
||||
bool queuePrepare(uint32_t status, void* in = NULL, uint16_t in_size = 0, void* out = NULL, uint16_t out_size = 0);
|
||||
bool queueWrite(uint32_t status = 0, void* in = NULL, uint16_t in_size = 0, void* out = NULL, uint16_t out_size = 0);
|
||||
|
||||
// Update queue - fromEnd - like Single - include status cahnge, and optional data out
|
||||
bool queueUpdate(uint32_t fromEnd, uint32_t status, void* out = NULL, uint16_t out_size = 0);
|
||||
bool queueRead(uint32_t fromEnd);
|
||||
uint32_t queueCount();
|
||||
|
||||
uint32_t getDataNext(); // Get the next block for manual reading
|
||||
uint32_t getMetadataNext(); // Get the next block for manual reading
|
||||
uint8_t getCardId(); // Get the next block for manual reading
|
||||
|
||||
uint32_t getMetadataFirst(); // Get the next block for manual reading
|
||||
uint32_t getDataFirst(); // Get the next block for manual reading
|
||||
/*
|
||||
|
||||
Logging:
|
||||
|
||||
Logging:
|
||||
- Can be implemented completely outside of here.
|
||||
- And just use single or even a pecial set of singles.
|
||||
|
||||
Basics:
|
||||
- Balance memory with Blocks - a full 512 byte block in
|
||||
memory is probably too much for logging.
|
||||
- logAdd(level, string);
|
||||
. Return something.... to say buffer full, need to writeBlock
|
||||
|
||||
- logAuto(); // Automatiaclly prepare, write, etc.
|
||||
// Maybe pass param true, says write even if
|
||||
// only one log in the queue
|
||||
|
||||
- logPrepare();
|
||||
- logWrite();
|
||||
|
||||
*/
|
||||
|
||||
// Queue. - standard queue commands, work like Single
|
||||
/*
|
||||
|
||||
More advanced Queue Reader
|
||||
|
||||
- Next Low|High, Type
|
||||
e.g. High Iridium Send
|
||||
then low Iridium Send
|
||||
Iridium receive
|
||||
Slow to find?
|
||||
Status can be used for all the lookups
|
||||
- 32 bit,
|
||||
8 bit type
|
||||
8 bit status
|
||||
16 bit info (e.g. why it failed, or number of blocsk)
|
||||
|
||||
Size vs Data
|
||||
|
||||
WII4 Data
|
||||
* 2 blocks (two transmits)
|
||||
* 299 bytes - 6 blocks
|
||||
* 336 bytes - 7 blocsk
|
||||
* AKA - two blocks on the SD Card
|
||||
So we do have to use a whole SD Card block
|
||||
|
||||
Early optomisation is death
|
||||
* Use CaptureMode code or Iridium code to manage.
|
||||
|
||||
* Simplified walking
|
||||
queueRead(rec);
|
||||
|
||||
if (status - in range - ie. not sent, right type)
|
||||
sendIridium
|
||||
recordResults back in records
|
||||
queueUpdate(rec, X,Y,Z)
|
||||
|
||||
rec++;
|
||||
|
||||
if (rec > 10000) {
|
||||
// That will do. exit
|
||||
}
|
||||
|
||||
queueNextHigh(X)
|
||||
|
||||
queuePrepare
|
||||
queueWrite
|
||||
queueRead - like single, from end
|
||||
queueReadHigh - Read most resent high
|
||||
queueReadLow - Read most resent low
|
||||
queueUpdate(id, stuff - eg status)
|
||||
*/
|
||||
|
||||
|
||||
uint32_t dataLast;
|
||||
uint32_t metadataLast;
|
||||
uint32_t queueLast;
|
||||
uint32_t singleLast;
|
||||
|
||||
|
||||
protected:
|
||||
byte response; // Resuable for all read/write
|
||||
uint32_t crc;
|
||||
uint32_t address_local; // Temporary location of calculated addresses
|
||||
uint32_t count; // Reusable counter (for loops)
|
||||
|
||||
bool autoFormat; // Automatically format on failure
|
||||
|
||||
// Allocation tabler
|
||||
uint32_t dataBlockNext; // Next, becasue first record is 0, so initilaly we write there
|
||||
uint32_t metadataBlockNext; // And of course where is the Metadata
|
||||
uint32_t singleBlockNext; // And of course where is the Metadata
|
||||
uint32_t loglinesBlockNext; // And of course where is the Metadata
|
||||
uint32_t queueBlockNext; // And of course where is the Metadata
|
||||
|
||||
// Card read, open and valid
|
||||
bool valid;
|
||||
|
||||
// Current DATA
|
||||
uint32_t dataBlockStart;
|
||||
uint32_t dataBlockCurrent;
|
||||
uint32_t dataBlockRecordId;
|
||||
|
||||
uint32_t metadata_dataBlockStart;
|
||||
uint32_t metadata_dataBlocks;
|
||||
|
||||
uint32_t metadata_resultsBlockStart;
|
||||
uint32_t metadata_resultsBlocks;
|
||||
|
||||
uint32_t cardId;
|
||||
uint32_t deviceId;
|
||||
uint32_t recordId;
|
||||
};
|
||||
|
||||
extern SDBlock sdBlock;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,214 @@
|
||||
#ifndef SDBlockData_h
|
||||
#define SDBlockData_h
|
||||
|
||||
/*
|
||||
|
||||
Misc notes:
|
||||
|
||||
* Structure of all blocks:
|
||||
* Block type
|
||||
* Free form set of fields
|
||||
* Free block to be used
|
||||
* Status field - re-writable
|
||||
* CRC32 - TODO, consider leaving status out of the CRC
|
||||
(although only for time, as the block has to be in memory to change the status)
|
||||
|
||||
Sizes:
|
||||
* 32 Bit blocks allows for up to 2000 GB of Storage
|
||||
* Where as 32 Bit bytes (when moving an address) allows only 4GB
|
||||
|
||||
TODO:
|
||||
|
||||
* Status based searcher - like that being considered for Queues
|
||||
* Find me next with Status X or bitmap or < or >
|
||||
* But.... keep where we were up to to, so we don't have to serarh/load all them blocks again
|
||||
* Consider this only for memory for now.
|
||||
|
||||
Notes on WII5
|
||||
|
||||
|
||||
One Run = 40960 records. 15 Per Sector
|
||||
2730 data packets
|
||||
|
||||
Total packets = 62500000
|
||||
/ runs = 22893
|
||||
|
||||
4 per hour, 24 hours per day
|
||||
238 days
|
||||
|
||||
2 Cards - actually = 476
|
||||
|
||||
So make it 150 days
|
||||
14400 records
|
||||
|
||||
Data Size = 14400 * 2730 = 39312000 = 62%
|
||||
|
||||
Therefore Metadata minimum 14400, up to 20000
|
||||
|
||||
Queue - could have up to 8 messages per metadata, so 20000*8 = 160000
|
||||
|
||||
Number Start End Size Type File system Flags
|
||||
1 2048s 1251327s 1249280s primary fat32 lba
|
||||
|
||||
|
||||
sudo dd if=/dev/mmcblk2 of=block_fat1.img bs=512 count=1251328
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#define SDBLOCK_SECTOR_SIZE 512
|
||||
|
||||
// XXX Add super block information
|
||||
// Bytes:
|
||||
// 1 = Fixed = SDBlock, always 10101111
|
||||
// 2 = Version of SDBlock, 00000001
|
||||
// 3 = Block type & Bersion 1, 2, 3,4 + 1
|
||||
#define SDBLOCK_TYPE_SDBLOCK 101
|
||||
#define SDBLOCK_TYPE_SDBLOCK_VERSION 1
|
||||
#define SDBLOCK_TYPE_ALLOCATION 1
|
||||
#define SDBLOCK_TYPE_ALLOCATION_VERSION 1
|
||||
#define SDBLOCK_TYPE_ALLOCATION_FULL ((SDBLOCK_TYPE_SDBLOCK << 24) | (SDBLOCK_TYPE_SDBLOCK_VERSION << 16) | (SDBLOCK_TYPE_ALLOCATION << 8) | SDBLOCK_TYPE_ALLOCATION_VERSION)
|
||||
#define SDBLOCK_TYPE_METADATA 2
|
||||
#define SDBLOCK_TYPE_METADATA_VERSION 1
|
||||
#define SDBLOCK_TYPE_METADATA_FULL ((SDBLOCK_TYPE_SDBLOCK << 24) | (SDBLOCK_TYPE_SDBLOCK_VERSION << 16) | (SDBLOCK_TYPE_METADATA << 8) | SDBLOCK_TYPE_METADATA_VERSION)
|
||||
#define SDBLOCK_TYPE_LOGLINES 3
|
||||
#define SDBLOCK_TYPE_LOGLINES_VERSION 1
|
||||
#define SDBLOCK_TYPE_LOGLINES_FULL ((SDBLOCK_TYPE_SDBLOCK << 24) | (SDBLOCK_TYPE_SDBLOCK_VERSION << 16) | (SDBLOCK_TYPE_LOGLINES << 8) | SDBLOCK_TYPE_LOGLINES_VERSION)
|
||||
#define SDBLOCK_TYPE_SINGLE 4
|
||||
#define SDBLOCK_TYPE_SINGLE_VERSION 1
|
||||
#define SDBLOCK_TYPE_SINGLE_FULL ((SDBLOCK_TYPE_SDBLOCK << 24) | (SDBLOCK_TYPE_SDBLOCK_VERSION << 16) | (SDBLOCK_TYPE_SINGLE << 8) | SDBLOCK_TYPE_SINGLE_VERSION)
|
||||
#define SDBLOCK_TYPE_BLOCK 5
|
||||
#define SDBLOCK_TYPE_BLOCK_VERSION 1
|
||||
#define SDBLOCK_TYPE_BLOCK_FULL ((SDBLOCK_TYPE_SDBLOCK << 24) | (SDBLOCK_TYPE_SDBLOCK_VERSION << 16) | (SDBLOCK_TYPE_BLOCK << 8) | SDBLOCK_TYPE_BLOCK_VERSION)
|
||||
#define SDBLOCK_TYPE_QUEUE 5
|
||||
#define SDBLOCK_TYPE_QUEUE_VERSION 1
|
||||
#define SDBLOCK_TYPE_QUEUE_FULL ((SDBLOCK_TYPE_SDBLOCK << 24) | (SDBLOCK_TYPE_SDBLOCK_VERSION << 16) | (SDBLOCK_TYPE_QUEUE << 8) | SDBLOCK_TYPE_QUEUE_VERSION)
|
||||
|
||||
|
||||
// Special - Block Offset ! Where does this start
|
||||
#define SDBLOCK_OFFSET (uint32_t)1300000 // Absolute position start of allocation table
|
||||
#define SDBLOCK_MAX (uint32_t)62500000
|
||||
#define SDBLOCK_ALLOCATION_MAX (uint32_t)2 // How many we can have
|
||||
#define SDBLOCK_METADATA_MAX (uint32_t)20000 // How many we can have
|
||||
#define SDBLOCK_SINGLE_MAX (uint32_t)20000 // How many we can have
|
||||
#define SDBLOCK_LOGLINES_MAX (uint32_t)10000 // How many we can have
|
||||
#define SDBLOCK_QUEUE_MAX (uint32_t)300000 // How many we can have
|
||||
#define SDBLOCK_DATA_MAX (uint32_t)45000000 // How many we can have
|
||||
|
||||
#define SDBLOCK_ACTUAL_ALLOCATION (uint32_t)SDBLOCK_OFFSET
|
||||
#define SDBLOCK_ACTUAL_METADATA (uint32_t)(SDBLOCK_OFFSET + SDBLOCK_ALLOCATION_MAX)
|
||||
#define SDBLOCK_ACTUAL_SINGLE (uint32_t)(SDBLOCK_OFFSET + SDBLOCK_ALLOCATION_MAX + SDBLOCK_METADATA_MAX)
|
||||
#define SDBLOCK_ACTUAL_LOGLINES (uint32_t)(SDBLOCK_OFFSET + SDBLOCK_ALLOCATION_MAX + SDBLOCK_METADATA_MAX + SDBLOCK_SINGLE_MAX)
|
||||
#define SDBLOCK_ACTUAL_QUEUE (uint32_t)(SDBLOCK_OFFSET + SDBLOCK_ALLOCATION_MAX + SDBLOCK_METADATA_MAX + SDBLOCK_SINGLE_MAX + SDBLOCK_LOGLINES_MAX)
|
||||
#define SDBLOCK_ACTUAL_DATA (uint32_t)(SDBLOCK_OFFSET + SDBLOCK_ALLOCATION_MAX + SDBLOCK_METADATA_MAX + SDBLOCK_SINGLE_MAX + SDBLOCK_LOGLINES_MAX + SDBLOCK_QUEUE_MAX)
|
||||
|
||||
// ALLOCATION Block
|
||||
#define SDBLOCK_ALLOCATION_DATA_SIZE 460
|
||||
typedef struct {
|
||||
// 12
|
||||
uint32_t blockType;
|
||||
uint32_t deviceId; // Device and Record
|
||||
uint32_t recordId; // In this case, it will be the last actually used one
|
||||
uint32_t cardId; // In this case, it will be the last actually used one
|
||||
|
||||
// 16
|
||||
time_t currentTime; // Last updated?
|
||||
|
||||
// 16
|
||||
uint32_t metadataBlockNext; // And of course where is the Metadata
|
||||
uint32_t singleBlockNext; // And of course where is the Metadata
|
||||
uint32_t loglinesBlockNext; // And of course where is the Metadata
|
||||
uint32_t dataBlockNext; // Next, becasue first record is 0, so initilaly we write there
|
||||
|
||||
uint32_t queueBlockNext; // Next, becasue first record is 0, so initilaly we write there
|
||||
uint32_t queueHighDone; // What queue high have we done, read from here
|
||||
uint32_t queueLowDone; // What queue low have we done, read from here
|
||||
|
||||
uint8_t data[SDBLOCK_ALLOCATION_DATA_SIZE]; // Calcu;ate
|
||||
|
||||
uint32_t crc;
|
||||
} SDBlock_Allocation;
|
||||
|
||||
// METADATA Block
|
||||
#define SDBLOCK_METADATA_DATA_SIZE 476
|
||||
typedef struct {
|
||||
// 12
|
||||
uint32_t blockType;
|
||||
uint32_t deviceId; // Device and Record
|
||||
uint32_t recordId; // OR recordCount
|
||||
|
||||
// 8
|
||||
uint32_t dataBlockStart; // DATA: Where does it start
|
||||
uint32_t dataBlocks; // DATA: Number of blocks, 0 being none at all
|
||||
|
||||
// Keep these variables outside of this structure - see wii5Metadata
|
||||
char data[SDBLOCK_METADATA_DATA_SIZE];
|
||||
|
||||
// 8
|
||||
uint32_t resultsBlockStart; // RESULTS: Where does it start
|
||||
uint32_t resultsBlocks; // RESULTS: Number of blocks, 0 being none at all
|
||||
|
||||
// 8
|
||||
uint32_t status; // WII5 example - 0=NoResults, 1=Results, 4=Results+Sent, 5=
|
||||
/*
|
||||
|
||||
uint8_t
|
||||
. ?
|
||||
. ?
|
||||
. > 0 = Number of attempts sending - 1111 = Success
|
||||
. > 0 = Data saved
|
||||
*/
|
||||
|
||||
uint32_t crc;
|
||||
} SDBlock_Metadata;
|
||||
|
||||
#define SDBLOCK_LOG_DATA_SIZE 42
|
||||
#define SDBLOCK_LOG_DATA_LINES 10
|
||||
|
||||
// LogLine
|
||||
typedef struct {
|
||||
time_t logTime;
|
||||
// NOTE: Most of these integers, normally 1 byte, are set to 4 bytes for packing.
|
||||
uint32_t logLevel;
|
||||
char data[SDBLOCK_LOG_DATA_SIZE];
|
||||
} SDBlock_LogLine;
|
||||
|
||||
// LOG Block
|
||||
typedef struct {
|
||||
uint32_t blockType;
|
||||
uint32_t recordId; // OR recordCount
|
||||
|
||||
SDBlock_LogLine lines[SDBLOCK_LOG_DATA_LINES];
|
||||
|
||||
uint32_t crc;
|
||||
} SDBlock_LogLines;
|
||||
|
||||
#define SDBLOCK_QUEUE_DATAIN_SIZE 400
|
||||
#define SDBLOCK_QUEUE_DATAOUT_SIZE 92
|
||||
// Queue
|
||||
typedef struct {
|
||||
uint32_t blockType; // 4
|
||||
// deviceId, recordId ?
|
||||
|
||||
time_t currentTime;
|
||||
uint32_t priority;
|
||||
char dataIn[SDBLOCK_QUEUE_DATAIN_SIZE];
|
||||
char dataOut[SDBLOCK_QUEUE_DATAOUT_SIZE];
|
||||
uint32_t status;
|
||||
uint32_t crc;
|
||||
} SDBlock_Queue;
|
||||
|
||||
// BLOCK - Let us make them all the same !
|
||||
#define SDBLOCK_BLOCK_DATA_SIZE 496
|
||||
typedef struct {
|
||||
uint32_t blockType; // 4
|
||||
// Note: deviceId etc can all be taken from Metadata.
|
||||
uint32_t recordId; // Important to group these together.
|
||||
|
||||
uint8_t data[SDBLOCK_BLOCK_DATA_SIZE]; // All the data in the middle
|
||||
|
||||
uint32_t status;
|
||||
uint32_t crc;
|
||||
} SDBlock_Block;
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user