mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-24 00:35:39 +03:00
Prepare flash code for multiple device type support (#5683)
* Prepare flash drivers for multiple device type support * Add static assertions on device page and flashfs alloc sizes.
This commit is contained in:
parent
4a5e79a534
commit
864dba98c1
13 changed files with 387 additions and 187 deletions
|
@ -34,7 +34,6 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "drivers/flash.h"
|
||||
#include "drivers/flash_m25p16.h"
|
||||
|
||||
#include "io/flashfs.h"
|
||||
|
||||
|
@ -69,7 +68,7 @@ static void flashfsSetTailAddress(uint32_t address)
|
|||
|
||||
void flashfsEraseCompletely(void)
|
||||
{
|
||||
m25p16_eraseCompletely();
|
||||
flashEraseCompletely();
|
||||
|
||||
flashfsClearBuffer();
|
||||
|
||||
|
@ -82,7 +81,7 @@ void flashfsEraseCompletely(void)
|
|||
*/
|
||||
void flashfsEraseRange(uint32_t start, uint32_t end)
|
||||
{
|
||||
const flashGeometry_t *geometry = m25p16_getGeometry();
|
||||
const flashGeometry_t *geometry = flashGetGeometry();
|
||||
|
||||
if (geometry->sectorSize <= 0)
|
||||
return;
|
||||
|
@ -99,7 +98,7 @@ void flashfsEraseRange(uint32_t start, uint32_t end)
|
|||
}
|
||||
|
||||
for (int i = startSector; i < endSector; i++) {
|
||||
m25p16_eraseSector(i * geometry->sectorSize);
|
||||
flashEraseSector(i * geometry->sectorSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,7 +107,7 @@ void flashfsEraseRange(uint32_t start, uint32_t end)
|
|||
*/
|
||||
bool flashfsIsReady(void)
|
||||
{
|
||||
return m25p16_isReady();
|
||||
return flashIsReady();
|
||||
}
|
||||
|
||||
bool flashfsIsSupported(void)
|
||||
|
@ -118,7 +117,7 @@ bool flashfsIsSupported(void)
|
|||
|
||||
uint32_t flashfsGetSize(void)
|
||||
{
|
||||
return m25p16_getGeometry()->totalSize;
|
||||
return flashGetGeometry()->totalSize;
|
||||
}
|
||||
|
||||
static uint32_t flashfsTransmitBufferUsed(void)
|
||||
|
@ -147,7 +146,7 @@ uint32_t flashfsGetWriteBufferFreeSpace(void)
|
|||
|
||||
const flashGeometry_t* flashfsGetGeometry(void)
|
||||
{
|
||||
return m25p16_getGeometry();
|
||||
return flashGetGeometry();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -179,12 +178,14 @@ static uint32_t flashfsWriteBuffers(uint8_t const **buffers, uint32_t *bufferSiz
|
|||
bytesTotal += bufferSizes[i];
|
||||
}
|
||||
|
||||
if (!sync && !m25p16_isReady()) {
|
||||
if (!sync && !flashIsReady()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t bytesTotalRemaining = bytesTotal;
|
||||
|
||||
uint16_t pageSize = flashfsGetGeometry()->pageSize;
|
||||
|
||||
while (bytesTotalRemaining > 0) {
|
||||
uint32_t bytesTotalThisIteration;
|
||||
uint32_t bytesRemainThisIteration;
|
||||
|
@ -193,8 +194,8 @@ static uint32_t flashfsWriteBuffers(uint8_t const **buffers, uint32_t *bufferSiz
|
|||
* Each page needs to be saved in a separate program operation, so
|
||||
* if we would cross a page boundary, only write up to the boundary in this iteration:
|
||||
*/
|
||||
if (tailAddress % M25P16_PAGESIZE + bytesTotalRemaining > M25P16_PAGESIZE) {
|
||||
bytesTotalThisIteration = M25P16_PAGESIZE - tailAddress % M25P16_PAGESIZE;
|
||||
if (tailAddress % pageSize + bytesTotalRemaining > pageSize) {
|
||||
bytesTotalThisIteration = pageSize - tailAddress % pageSize;
|
||||
} else {
|
||||
bytesTotalThisIteration = bytesTotalRemaining;
|
||||
}
|
||||
|
@ -207,7 +208,7 @@ static uint32_t flashfsWriteBuffers(uint8_t const **buffers, uint32_t *bufferSiz
|
|||
break;
|
||||
}
|
||||
|
||||
m25p16_pageProgramBegin(tailAddress);
|
||||
flashPageProgramBegin(tailAddress);
|
||||
|
||||
bytesRemainThisIteration = bytesTotalThisIteration;
|
||||
|
||||
|
@ -215,7 +216,7 @@ static uint32_t flashfsWriteBuffers(uint8_t const **buffers, uint32_t *bufferSiz
|
|||
if (bufferSizes[i] > 0) {
|
||||
// Is buffer larger than our write limit? Write our limit out of it
|
||||
if (bufferSizes[i] >= bytesRemainThisIteration) {
|
||||
m25p16_pageProgramContinue(buffers[i], bytesRemainThisIteration);
|
||||
flashPageProgramContinue(buffers[i], bytesRemainThisIteration);
|
||||
|
||||
buffers[i] += bytesRemainThisIteration;
|
||||
bufferSizes[i] -= bytesRemainThisIteration;
|
||||
|
@ -224,7 +225,7 @@ static uint32_t flashfsWriteBuffers(uint8_t const **buffers, uint32_t *bufferSiz
|
|||
break;
|
||||
} else {
|
||||
// We'll still have more to write after finishing this buffer off
|
||||
m25p16_pageProgramContinue(buffers[i], bufferSizes[i]);
|
||||
flashPageProgramContinue(buffers[i], bufferSizes[i]);
|
||||
|
||||
bytesRemainThisIteration -= bufferSizes[i];
|
||||
|
||||
|
@ -234,7 +235,7 @@ static uint32_t flashfsWriteBuffers(uint8_t const **buffers, uint32_t *bufferSiz
|
|||
}
|
||||
}
|
||||
|
||||
m25p16_pageProgramFinish();
|
||||
flashPageProgramFinish();
|
||||
|
||||
bytesTotalRemaining -= bytesTotalThisIteration;
|
||||
|
||||
|
@ -481,7 +482,7 @@ int flashfsReadAbs(uint32_t address, uint8_t *buffer, unsigned int len)
|
|||
// Since the read could overlap data in our dirty buffers, force a sync to clear those first
|
||||
flashfsFlushSync();
|
||||
|
||||
bytesRead = m25p16_readBytes(address, buffer, len);
|
||||
bytesRead = flashReadBytes(address, buffer, len);
|
||||
|
||||
return bytesRead;
|
||||
}
|
||||
|
@ -504,13 +505,15 @@ int flashfsIdentifyStartOfFreeSpace(void)
|
|||
/* We can choose whatever power of 2 size we like, which determines how much wastage of free space we'll have
|
||||
* at the end of the last written data. But smaller blocksizes will require more searching.
|
||||
*/
|
||||
FREE_BLOCK_SIZE = 2048,
|
||||
FREE_BLOCK_SIZE = 2048, // XXX This can't be smaller than page size for underlying flash device.
|
||||
|
||||
/* We don't expect valid data to ever contain this many consecutive uint32_t's of all 1 bits: */
|
||||
FREE_BLOCK_TEST_SIZE_INTS = 4, // i.e. 16 bytes
|
||||
FREE_BLOCK_TEST_SIZE_BYTES = FREE_BLOCK_TEST_SIZE_INTS * sizeof(uint32_t)
|
||||
};
|
||||
|
||||
STATIC_ASSERT(FREE_BLOCK_SIZE >= FLASH_MAX_PAGE_SIZE, FREE_BLOCK_SIZE_too_small);
|
||||
|
||||
union {
|
||||
uint8_t bytes[FREE_BLOCK_TEST_SIZE_BYTES];
|
||||
uint32_t ints[FREE_BLOCK_TEST_SIZE_INTS];
|
||||
|
@ -526,7 +529,7 @@ int flashfsIdentifyStartOfFreeSpace(void)
|
|||
while (left < right) {
|
||||
mid = (left + right) / 2;
|
||||
|
||||
if (m25p16_readBytes(mid * FREE_BLOCK_SIZE, testBuffer.bytes, FREE_BLOCK_TEST_SIZE_BYTES) < FREE_BLOCK_TEST_SIZE_BYTES) {
|
||||
if (flashReadBytes(mid * FREE_BLOCK_SIZE, testBuffer.bytes, FREE_BLOCK_TEST_SIZE_BYTES) < FREE_BLOCK_TEST_SIZE_BYTES) {
|
||||
// Unexpected timeout from flash, so bail early (reporting the device fuller than it really is)
|
||||
break;
|
||||
}
|
||||
|
@ -563,6 +566,23 @@ bool flashfsIsEOF(void)
|
|||
return tailAddress >= flashfsGetSize();
|
||||
}
|
||||
|
||||
void flashfsClose(void)
|
||||
{
|
||||
switch(flashfsGetGeometry()->flashType) {
|
||||
case FLASH_TYPE_NOR:
|
||||
break;
|
||||
|
||||
case FLASH_TYPE_NAND:
|
||||
flashFlush();
|
||||
|
||||
// Advance tailAddress to next page boundary.
|
||||
uint32_t pageSize = flashfsGetGeometry()->pageSize;
|
||||
flashfsSetTailAddress((tailAddress + pageSize - 1) & ~(pageSize - 1));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Call after initializing the flash chip in order to set up the filesystem.
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue