Merge branch 'develop' into serialHal

This commit is contained in:
Jonathan Bennett
2026-05-04 13:09:22 -05:00
committed by GitHub
16 changed files with 224 additions and 208 deletions
+1 -1
View File
@@ -120,7 +120,7 @@ lib_deps =
[radiolib_base]
lib_deps =
# renovate: datasource=github-tags depName=RadioLib packageName=jgromes/RadioLib
https://github.com/jgromes/RadioLib/archive/refs/tags/7.6.0.zip
https://github.com/jgromes/RadioLib/archive/afe72ae46a343e15e3cac7f26ac585c7f98bffe5.zip
[device-ui_base]
lib_deps =
+64 -94
View File
@@ -79,28 +79,46 @@ bool copyFile(const char *from, const char *to)
bool renameFile(const char *pathFrom, const char *pathTo)
{
#ifdef FSCom
#ifdef ARCH_ESP32
// take SPI Lock
spiLock->lock();
// rename was fixed for ESP32 IDF LittleFS in April
bool result = FSCom.rename(pathFrom, pathTo);
spiLock->unlock();
return result;
#else
// copyFile does its own locking.
if (copyFile(pathFrom, pathTo) && FSCom.remove(pathFrom)) {
return true;
} else {
return false;
}
#endif
return false;
#endif
}
#include <vector>
/**
* @brief Platform-agnostic filesystem format / wipe.
*
* On embedded targets (ESP32, NRF52, STM32WL, RP2040) this calls the
* native FSCom.format() which erases and reinitialises the LittleFS
* partition.
*
* On Portduino the fs::FS backend has no format() method. We instead
* delete /prefs (the only meshtastic data directory written at runtime)
* and return. rmDir("/prefs") is already called unconditionally by
* factoryReset() so this is a proven primitive on Portduino.
* FSBegin() is a no-op (#define FSBegin() true) on Portduino.
*
* @return true on success, false on failure or if no filesystem is configured.
*/
bool fsFormat()
{
#ifdef FSCom
#if defined(ARCH_PORTDUINO)
rmDir("/prefs");
return FSBegin();
#else
return FSCom.format();
#endif
#else
return false;
#endif
}
/**
* @brief Get the list of files in a directory.
*
@@ -123,23 +141,21 @@ std::vector<meshtastic_FileInfo> getFiles(const char *dirname, uint8_t levels)
File file = root.openNextFile();
while (file) {
#ifdef ARCH_ESP32
const char *filepath = file.path();
#else
const char *filepath = file.name();
#endif
if (file.isDirectory() && !String(file.name()).endsWith(".")) {
if (levels) {
#ifdef ARCH_ESP32
std::vector<meshtastic_FileInfo> subDirFilenames = getFiles(file.path(), levels - 1);
#else
std::vector<meshtastic_FileInfo> subDirFilenames = getFiles(file.name(), levels - 1);
#endif
std::vector<meshtastic_FileInfo> subDirFilenames = getFiles(filepath, levels - 1);
filenames.insert(filenames.end(), subDirFilenames.begin(), subDirFilenames.end());
file.close();
}
} else {
meshtastic_FileInfo fileInfo = {"", static_cast<uint32_t>(file.size())};
#ifdef ARCH_ESP32
strcpy(fileInfo.file_name, file.path());
#else
strcpy(fileInfo.file_name, file.name());
#endif
strncpy(fileInfo.file_name, filepath, sizeof(fileInfo.file_name) - 1);
fileInfo.file_name[sizeof(fileInfo.file_name) - 1] = '\0';
if (!String(fileInfo.file_name).endsWith(".")) {
filenames.push_back(fileInfo);
}
@@ -163,98 +179,59 @@ std::vector<meshtastic_FileInfo> getFiles(const char *dirname, uint8_t levels)
void listDir(const char *dirname, uint8_t levels, bool del)
{
#ifdef FSCom
#if (defined(ARCH_ESP32) || defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
char buffer[255];
#endif
File root = FSCom.open(dirname, FILE_O_READ);
if (!root) {
if (!root || !root.isDirectory())
return;
}
if (!root.isDirectory()) {
return;
}
File file = root.openNextFile();
while (
file &&
file.name()[0]) { // This file.name() check is a workaround for a bug in the Adafruit LittleFS nrf52 glue (see issue 4395)
while (file && file.name()[0]) { // file.name()[0] check: workaround for Adafruit LittleFS nRF52 bug #4395
#ifdef ARCH_ESP32
const char *filepath = file.path();
#else
const char *filepath = file.name();
#endif
if (file.isDirectory() && !String(file.name()).endsWith(".")) {
if (levels) {
#ifdef ARCH_ESP32
listDir(file.path(), levels - 1, del);
listDir(filepath, levels - 1, del);
if (del) {
LOG_DEBUG("Remove %s", file.path());
strncpy(buffer, file.path(), sizeof(buffer));
LOG_DEBUG("Remove %s", filepath);
strncpy(buffer, filepath, sizeof(buffer) - 1);
buffer[sizeof(buffer) - 1] = '\0';
file.close();
FSCom.rmdir(buffer);
} else {
file.close();
}
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
listDir(file.name(), levels - 1, del);
if (del) {
LOG_DEBUG("Remove %s", file.name());
strncpy(buffer, file.name(), sizeof(buffer));
file.close();
FSCom.rmdir(buffer);
} else {
file.close();
}
#else
LOG_DEBUG(" %s (directory)", file.name());
listDir(file.name(), levels - 1, del);
file.close();
#endif
}
} else {
#ifdef ARCH_ESP32
if (del) {
LOG_DEBUG("Delete %s", file.path());
strncpy(buffer, file.path(), sizeof(buffer));
LOG_DEBUG("Delete %s", filepath);
strncpy(buffer, filepath, sizeof(buffer) - 1);
buffer[sizeof(buffer) - 1] = '\0';
file.close();
FSCom.remove(buffer);
} else {
LOG_DEBUG(" %s (%i Bytes)", file.path(), file.size());
LOG_DEBUG(" %s (%i Bytes)", filepath, file.size());
file.close();
}
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
if (del) {
LOG_DEBUG("Delete %s", file.name());
strncpy(buffer, file.name(), sizeof(buffer));
file.close();
FSCom.remove(buffer);
} else {
LOG_DEBUG(" %s (%i Bytes)", file.name(), file.size());
file.close();
}
#else
LOG_DEBUG(" %s (%i Bytes)", file.name(), file.size());
file.close();
#endif
}
file = root.openNextFile();
}
#ifdef ARCH_ESP32
if (del) {
LOG_DEBUG("Remove %s", root.path());
strncpy(buffer, root.path(), sizeof(buffer));
root.close();
FSCom.rmdir(buffer);
} else {
root.close();
}
#elif (defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
if (del) {
LOG_DEBUG("Remove %s", root.name());
strncpy(buffer, root.name(), sizeof(buffer));
root.close();
FSCom.rmdir(buffer);
} else {
root.close();
}
const char *rootpath = root.path();
#else
root.close();
const char *rootpath = root.name();
#endif
if (del) {
LOG_DEBUG("Remove %s", rootpath);
strncpy(buffer, rootpath, sizeof(buffer) - 1);
buffer[sizeof(buffer) - 1] = '\0';
root.close();
FSCom.rmdir(buffer);
} else {
root.close();
}
#endif
}
@@ -268,14 +245,7 @@ void listDir(const char *dirname, uint8_t levels, bool del)
void rmDir(const char *dirname)
{
#ifdef FSCom
#if (defined(ARCH_ESP32) || defined(ARCH_RP2040) || defined(ARCH_PORTDUINO))
listDir(dirname, 10, true);
#elif defined(ARCH_NRF52)
// nRF52 implementation of LittleFS has a recursive delete function
FSCom.rmdir_r(dirname);
#endif
#endif
}
+1
View File
@@ -52,6 +52,7 @@ void fsInit();
void fsListFiles();
bool copyFile(const char *from, const char *to);
bool renameFile(const char *pathFrom, const char *pathTo);
bool fsFormat();
std::vector<meshtastic_FileInfo> getFiles(const char *dirname, uint8_t levels);
void listDir(const char *dirname, uint8_t levels, bool del = false);
void rmDir(const char *dirname);
-7
View File
@@ -7,10 +7,6 @@ static File openFile(const char *filename, bool fullAtomic)
{
concurrency::LockGuard g(spiLock);
LOG_DEBUG("Opening %s, fullAtomic=%d", filename, fullAtomic);
#ifdef ARCH_NRF52
FSCom.remove(filename);
return FSCom.open(filename, FILE_O_WRITE);
#endif
if (!fullAtomic) {
FSCom.remove(filename); // Nuke the old file to make space (ignore if it !exists)
}
@@ -67,9 +63,6 @@ bool SafeFile::close()
f.close();
spiLock->unlock();
#ifdef ARCH_NRF52
return true;
#endif
if (!testReadback())
return false;
+1 -1
View File
@@ -80,7 +80,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// Pre-hop drop handling (compile-time flag).
#ifndef MESHTASTIC_PREHOP_DROP
#define MESHTASTIC_PREHOP_DROP 0
#define MESHTASTIC_PREHOP_DROP 1
#endif
/// Convert a preprocessor name into a quoted string
+1 -3
View File
@@ -1611,12 +1611,10 @@ bool NodeDB::saveToDisk(int saveWhat)
if (!success) {
LOG_ERROR("Failed to save to disk, retrying");
#ifdef ARCH_NRF52 // @geeksville is not ready yet to say we should do this on other platforms. See bug #4184 discussion
spiLock->lock();
FSCom.format();
fsFormat();
spiLock->unlock();
#endif
success = saveToDiskNoRetry(saveWhat);
RECORD_CRITICALERROR(success ? meshtastic_CriticalErrorCode_FLASH_CORRUPTION_RECOVERABLE
+2
View File
@@ -1412,7 +1412,9 @@ void AdminModule::saveChanges(int saveWhat, bool shouldReboot)
void AdminModule::handleStoreDeviceUIConfig(const meshtastic_DeviceUIConfig &uicfg)
{
#if HAS_SCREEN
nodeDB->saveProto("/prefs/uiconfig.proto", meshtastic_DeviceUIConfig_size, &meshtastic_DeviceUIConfig_msg, &uicfg);
#endif
}
void AdminModule::handleSetHamMode(const meshtastic_HamParameters &p)
+142 -93
View File
@@ -25,23 +25,27 @@
#include "LittleFS.h"
#include "stm32wlxx_hal_flash.h"
/**********************************************************************************************************************
* Macro definitions
**********************************************************************************************************************/
/** This macro is used to suppress compiler messages about a parameter not being used in a function. */
/** Suppress unused-parameter warnings. */
#define LFS_UNUSED(p) (void)((p))
#define STM32WL_PAGE_SIZE (FLASH_PAGE_SIZE)
#define STM32WL_PAGE_SIZE (FLASH_PAGE_SIZE) // physical flash erase granularity: 2048 B
#define STM32WL_PAGE_COUNT (FLASH_PAGE_NB)
#define STM32WL_FLASH_BASE (FLASH_BASE)
/*
* FLASH_SIZE from stm32wle5xx.h will read the actual FLASH size from the chip.
* FLASH_END_ADDR is calculated from FLASH_SIZE.
* Use the last 28 KiB of the FLASH
* LFS tunables — all of these are stored in the LFS superblock.
* Changing ANY of them is incompatible with the existing on-disk format;
* the filesystem will be detected as corrupted and reformatted on first boot.
*
* LFS_FLASH_TOTAL_SIZE and LFS_BLOCK_SIZE are the only values to edit here.
* All other parameters are derived.
*
* FLASH_END_ADDR is computed from FLASH_SIZE (read from the chip at link time).
*/
#define LFS_FLASH_TOTAL_SIZE (14 * 2048) /* needs to be a multiple of LFS_BLOCK_SIZE */
#define LFS_BLOCK_SIZE (2048)
#define LFS_FLASH_TOTAL_SIZE \
(7 * STM32WL_PAGE_SIZE) /* 14 KiB — last 7 physical pages (FORMAT BREAK: reduced from 10 pages / 20 KiB) */
#define LFS_BLOCK_SIZE (256) /* virtual block size (FORMAT BREAK if changed) */
#define LFS_FLASH_ADDR_END (FLASH_END_ADDR)
#define LFS_FLASH_ADDR_BASE (LFS_FLASH_ADDR_END - LFS_FLASH_TOTAL_SIZE + 1)
@@ -51,6 +55,80 @@
#define _LFS_DBG(fmt, ...) printf("%s:%d (%s): " fmt "\n", __FILE__, __LINE__, __func__, __VA_ARGS__)
#endif
//--------------------------------------------------------------------+
// Write-behind page cache
//
// LFS requires block_size == erase granularity, but the STM32WL flash
// erases in 2048-byte pages. To use smaller virtual LFS blocks we
// maintain a single-page RAM cache: the LFS erase/prog callbacks only
// update this buffer; the physical erase+reprogram is deferred to
// _internal_flash_sync() (or triggered automatically when a different
// physical page is addressed).
//
// This mirrors the approach used by the NRF52 Adafruit driver
// (flash_cache.c / flash_nrf5x.c) but adapted for the 2048-byte STM32WL
// page size and HAL doubleword-program requirement.
//--------------------------------------------------------------------+
alignas(8) static uint8_t _page_cache[STM32WL_PAGE_SIZE];
static uint32_t _page_cache_addr = UINT32_MAX; // UINT32_MAX = no page cached
static bool _page_cache_dirty = false;
/** Flush the cached page to flash (physical erase + doubleword program). */
static int _flash_cache_flush(void)
{
if (!_page_cache_dirty)
return LFS_ERR_OK;
FLASH_EraseInitTypeDef erase = {
.TypeErase = FLASH_TYPEERASE_PAGES,
.Page = (_page_cache_addr - STM32WL_FLASH_BASE) / STM32WL_PAGE_SIZE,
.NbPages = 1,
};
uint32_t page_error = 0;
if (HAL_FLASH_Unlock() != HAL_OK)
return LFS_ERR_IO;
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
HAL_StatusTypeDef rc = HAL_FLASHEx_Erase(&erase, &page_error);
if (rc == HAL_OK) {
const uint64_t *p = (const uint64_t *)_page_cache;
uint32_t addr = _page_cache_addr;
for (size_t i = 0; i < STM32WL_PAGE_SIZE / 8; i++) {
rc = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, addr, *p++);
if (rc != HAL_OK)
break;
addr += 8;
}
}
HAL_StatusTypeDef lock_rc = HAL_FLASH_Lock();
if (rc == HAL_OK)
rc = lock_rc;
if (rc == HAL_OK)
_page_cache_dirty = false;
return rc == HAL_OK ? LFS_ERR_OK : LFS_ERR_IO;
}
/**
* Ensure the physical page containing `page_addr` is loaded into the cache.
* If a different dirty page is already cached it is flushed first.
*/
static int _flash_cache_load(uint32_t page_addr)
{
if (_page_cache_addr == page_addr)
return LFS_ERR_OK; // already cached
int rc = _flash_cache_flush();
if (rc != LFS_ERR_OK)
return rc;
memcpy(_page_cache, (const void *)page_addr, STM32WL_PAGE_SIZE);
_page_cache_addr = page_addr;
return LFS_ERR_OK;
}
//--------------------------------------------------------------------+
// LFS Disk IO
//--------------------------------------------------------------------+
@@ -59,111 +137,82 @@ static int _internal_flash_read(const struct lfs_config *c, lfs_block_t block, l
{
LFS_UNUSED(c);
if (!buffer || !size) {
_LFS_DBG("%s Invalid parameter!\r\n", __func__);
return LFS_ERR_INVAL;
}
uint32_t addr = LFS_FLASH_ADDR_BASE + block * LFS_BLOCK_SIZE + off;
uint32_t page_addr = addr & ~(uint32_t)(STM32WL_PAGE_SIZE - 1);
uint32_t page_off = addr & (uint32_t)(STM32WL_PAGE_SIZE - 1);
lfs_block_t address = LFS_FLASH_ADDR_BASE + (block * STM32WL_PAGE_SIZE + off);
memcpy(buffer, (void *)address, size);
if (_page_cache_addr == page_addr)
memcpy(buffer, _page_cache + page_off, size);
else
memcpy(buffer, (const void *)addr, size);
return LFS_ERR_OK;
}
// Program a region in a block. The block must have previously
// been erased. Negative error codes are propogated to the user.
// May return LFS_ERR_CORRUPT if the block should be considered bad.
// Program a region in a block. The block must have previously been erased.
// Writes are accumulated in the page cache and flushed on sync or page eviction.
static int _internal_flash_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size)
{
lfs_block_t address = LFS_FLASH_ADDR_BASE + (block * STM32WL_PAGE_SIZE + off);
HAL_StatusTypeDef hal_rc = HAL_OK;
uint32_t dw_count = size / 8;
uint64_t *bufp = (uint64_t *)buffer;
LFS_UNUSED(c);
_LFS_DBG("Programming %d bytes/%d doublewords at address 0x%08x/block %d, offset %d.", size, dw_count, address, block, off);
if (HAL_FLASH_Unlock() != HAL_OK) {
return LFS_ERR_IO;
}
for (uint32_t i = 0; i < dw_count; i++) {
if ((address < LFS_FLASH_ADDR_BASE) || (address > LFS_FLASH_ADDR_END)) {
_LFS_DBG("Wanted to program out of bound of FLASH: 0x%08x.\n", address);
HAL_FLASH_Lock();
return LFS_ERR_INVAL;
}
hal_rc = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, *bufp);
if (hal_rc != HAL_OK) {
/* Error occurred while writing data in Flash memory.
* User can add here some code to deal with this error.
*/
_LFS_DBG("Program error at (0x%08x), 0x%X, error: 0x%08x\n", address, hal_rc, HAL_FLASH_GetError());
}
address += 8;
bufp += 1;
}
if (HAL_FLASH_Lock() != HAL_OK) {
return LFS_ERR_IO;
}
uint32_t addr = LFS_FLASH_ADDR_BASE + block * LFS_BLOCK_SIZE + off;
uint32_t page_addr = addr & ~(uint32_t)(STM32WL_PAGE_SIZE - 1);
uint32_t page_off = addr & (uint32_t)(STM32WL_PAGE_SIZE - 1);
return hal_rc == HAL_OK ? LFS_ERR_OK : LFS_ERR_IO; // If HAL_OK, return LFS_ERR_OK, else return LFS_ERR_IO
int rc = _flash_cache_load(page_addr);
if (rc != LFS_ERR_OK)
return rc;
memcpy(_page_cache + page_off, buffer, size);
_page_cache_dirty = true;
return LFS_ERR_OK;
}
// Erase a block. A block must be erased before being programmed.
// The state of an erased block is undefined. Negative error codes
// are propogated to the user.
// May return LFS_ERR_CORRUPT if the block should be considered bad.
// Erase a virtual block. Marks the corresponding region in the page cache as 0xFF.
// Physical erase of the containing page is deferred until sync or page eviction.
static int _internal_flash_erase(const struct lfs_config *c, lfs_block_t block)
{
lfs_block_t address = LFS_FLASH_ADDR_BASE + (block * STM32WL_PAGE_SIZE);
HAL_StatusTypeDef hal_rc;
FLASH_EraseInitTypeDef EraseInitStruct = {.TypeErase = FLASH_TYPEERASE_PAGES, .Page = 0, .NbPages = 1};
uint32_t PAGEError = 0;
LFS_UNUSED(c);
if ((address < LFS_FLASH_ADDR_BASE) || (address > LFS_FLASH_ADDR_END)) {
_LFS_DBG("Wanted to erase out of bound of FLASH: 0x%08x.\n", address);
return LFS_ERR_INVAL;
}
/* calculate the absolute page, i.e. what the ST wants */
EraseInitStruct.Page = (address - STM32WL_FLASH_BASE) / STM32WL_PAGE_SIZE;
_LFS_DBG("Erasing block %d at 0x%08x... ", block, address);
HAL_FLASH_Unlock();
hal_rc = HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError);
HAL_FLASH_Lock();
uint32_t addr = LFS_FLASH_ADDR_BASE + block * LFS_BLOCK_SIZE;
uint32_t page_addr = addr & ~(uint32_t)(STM32WL_PAGE_SIZE - 1);
uint32_t page_off = addr & (uint32_t)(STM32WL_PAGE_SIZE - 1);
return hal_rc == HAL_OK ? LFS_ERR_OK : LFS_ERR_IO; // If HAL_OK, return LFS_ERR_OK, else return LFS_ERR_IO
int rc = _flash_cache_load(page_addr);
if (rc != LFS_ERR_OK)
return rc;
memset(_page_cache + page_off, 0xFF, LFS_BLOCK_SIZE);
_page_cache_dirty = true;
return LFS_ERR_OK;
}
// Sync the state of the underlying block device. Negative error codes
// are propogated to the user.
// Flush the write-behind cache to flash.
static int _internal_flash_sync(const struct lfs_config *c)
{
LFS_UNUSED(c);
// write function performs no caching. No need for sync.
return LFS_ERR_OK;
return _flash_cache_flush();
}
static struct lfs_config _InternalFSConfig = {.context = NULL,
static struct lfs_config _InternalFSConfig = {
.context = NULL,
.read = _internal_flash_read,
.prog = _internal_flash_prog,
.erase = _internal_flash_erase,
.sync = _internal_flash_sync,
.read = _internal_flash_read,
.prog = _internal_flash_prog,
.erase = _internal_flash_erase,
.sync = _internal_flash_sync,
.read_size = LFS_BLOCK_SIZE,
.prog_size = LFS_BLOCK_SIZE,
.block_size = LFS_BLOCK_SIZE,
.block_count = LFS_FLASH_TOTAL_SIZE / LFS_BLOCK_SIZE,
.lookahead = 128,
.read_size = LFS_BLOCK_SIZE,
.prog_size = LFS_BLOCK_SIZE,
.block_size = LFS_BLOCK_SIZE,
.block_count = LFS_FLASH_TOTAL_SIZE / LFS_BLOCK_SIZE,
.lookahead = 128,
.read_buffer = NULL,
.prog_buffer = NULL,
.lookahead_buffer = NULL,
.file_buffer = NULL};
.read_buffer = NULL,
.prog_buffer = NULL,
.lookahead_buffer = NULL,
.file_buffer = NULL,
};
LittleFS InternalFS;
@@ -179,17 +228,17 @@ bool LittleFS::begin(void)
/* There is not enough space on this device for a filesystem. */
return false;
}
// failed to mount, erase all pages then format and mount again
// failed to mount, erase all virtual blocks then format and mount again
if (!STM32_LittleFS::begin()) {
// Erase all pages of internal flash region for Filesystem.
for (uint32_t addr = LFS_FLASH_ADDR_BASE; addr < (LFS_FLASH_ADDR_END + 1); addr += STM32WL_PAGE_SIZE) {
_internal_flash_erase(&_InternalFSConfig, (addr - LFS_FLASH_ADDR_BASE) / STM32WL_PAGE_SIZE);
for (lfs_block_t block = 0; block < _InternalFSConfig.block_count; block++) {
_internal_flash_erase(&_InternalFSConfig, block);
}
_flash_cache_flush(); // flush the last cached page
// lfs format
this->format();
// mount again if still failed, give up
// mount again; if still failed, give up
if (!STM32_LittleFS::begin())
return false;
}
@@ -22,6 +22,7 @@
* THE SOFTWARE.
*/
#include "LittleFS.h"
#include "STM32_LittleFS.h"
#include <Arduino.h>
@@ -391,3 +392,8 @@ void File::rewindDirectory(void)
}
_fs->_unlockFS();
}
// Default constructor — binds to the global InternalFS instance.
// Allows File to be declared without an explicit filesystem argument,
// matching the API of ESP32/RP2040/Portduino File objects.
File::File() : File(InternalFS) {}
@@ -44,6 +44,7 @@ class File : public Stream
public:
explicit File(STM32_LittleFS &fs);
File(char const *filename, uint8_t mode, STM32_LittleFS &fs);
File(); // default-constructs against InternalFS; defined in STM32_LittleFS_File.cpp
public:
bool open(char const *filename, uint8_t mode);
-4
View File
@@ -61,11 +61,7 @@ class XModemAdapter
uint16_t packetno = 0;
#if defined(ARCH_NRF52) || defined(ARCH_STM32WL)
File file = File(FSCom);
#else
File file;
#endif
char filename[sizeof(meshtastic_XModem_buffer_t::bytes)] = {0};
@@ -1,7 +1,7 @@
[env:CDEBYTE_E77-MBL]
extends = stm32_base
board = ebyte_e77_dev
board_upload.maximum_size = 233472 ; reserve the last 28KB for filesystem
board_upload.maximum_size = 247808 ; reserve the last 14KB for filesystem (reduced from 20KB in LittleFS.cpp)
board_level = extra
build_flags =
${stm32_base.build_flags}
@@ -4,7 +4,7 @@
extends = stm32_base
board = wiscore_rak3172 ; Convenient choice as the same USART is used for programming/debug
board_level = extra
board_upload.maximum_size = 233472 ; reserve the last 28KB for filesystem
board_upload.maximum_size = 247808 ; reserve the last 14KB for filesystem (reduced from 20KB in LittleFS.cpp)
build_flags =
${stm32_base.build_flags}
-Ivariants/stm32/milesight_gs301
+1 -1
View File
@@ -2,7 +2,7 @@
extends = stm32_base
board = wiscore_rak3172
board_level = pr
board_upload.maximum_size = 233472 ; reserve the last 28KB for filesystem
board_upload.maximum_size = 247808 ; reserve the last 14KB for filesystem (reduced from 20KB in LittleFS.cpp)
build_flags =
${stm32_base.build_flags}
-Ivariants/stm32/rak3172
+1 -1
View File
@@ -8,7 +8,7 @@
extends = stm32_base
board = wiscore_rak3172
board_level = extra
board_upload.maximum_size = 233472 ; reserve the last 28KB for filesystem
board_upload.maximum_size = 247808 ; reserve the last 14KB for filesystem (reduced from 20KB in LittleFS.cpp)
build_flags =
${stm32_base.build_flags}
-Ivariants/stm32/russell
+1 -1
View File
@@ -2,7 +2,7 @@
extends = stm32_base
board = lora_e5_dev_board
board_level = pr
board_upload.maximum_size = 233472 ; reserve the last 28KB for filesystem
board_upload.maximum_size = 247808 ; reserve the last 14KB for filesystem (reduced from 20KB in LittleFS.cpp)
build_flags =
${stm32_base.build_flags}
-Ivariants/stm32/wio-e5