Add LittleFS build support, move filesystem size parser code here
This commit is contained in:
parent
3560177601
commit
630c935d5d
125
builder/main.py
125
builder/main.py
@ -16,6 +16,7 @@ import sys
|
||||
from platform import system
|
||||
from os import makedirs
|
||||
from os.path import isdir, join
|
||||
import re
|
||||
|
||||
from platformio.util import get_serial_ports
|
||||
|
||||
@ -67,6 +68,9 @@ env.Replace(
|
||||
|
||||
ARFLAGS=["rc"],
|
||||
|
||||
MKFSTOOL="mklittlefs",
|
||||
PICO_FS_IMAGE_NAME=env.get("PICO_FS_IMAGE_NAME", "littlefs"),
|
||||
|
||||
SIZEPROGREGEXP=r"^(?:\.text|\.data|\.rodata|\.text.align|\.ARM.exidx)\s+(\d+).*",
|
||||
SIZEDATAREGEXP=r"^(?:\.data|\.bss|\.noinit)\s+(\d+).*",
|
||||
SIZECHECKCMD="$SIZETOOL -A -d $SOURCES",
|
||||
@ -109,6 +113,100 @@ env.Append(
|
||||
if not env.get("PIOFRAMEWORK"):
|
||||
env.SConscript("frameworks/_bare.py")
|
||||
|
||||
|
||||
def convert_size_expression_to_int(expression):
|
||||
conversion_factors = {
|
||||
"M": 1024*1024,
|
||||
"MB": 1024*1024,
|
||||
"K": 1024,
|
||||
"KB": 1024,
|
||||
"B": 1,
|
||||
"": 1 # giving no conversion factor is factor 1.
|
||||
}
|
||||
# match <floating pointer number><conversion factor>.
|
||||
extract_regex = r'^((?:[0-9]*[.])?[0-9]+)([mkbMKB]*)$'
|
||||
res = re.findall(extract_regex, expression)
|
||||
# unparsable expression? Warning.
|
||||
if len(res) == 0:
|
||||
sys.stderr.write(
|
||||
"Error: Could not parse filesystem size expression '%s'."
|
||||
" Will treat as size = 0.\n" % str(expression))
|
||||
return 0
|
||||
# access first result
|
||||
number, factor = res[0]
|
||||
number = float(number)
|
||||
number *= conversion_factors[factor.upper()]
|
||||
return int(number)
|
||||
|
||||
def fetch_fs_size(env):
|
||||
# follow generation formulas from makeboards.py for Earle Philhower core
|
||||
# given the total flash size, a user can specify
|
||||
# the amount for the filesystem (0MB, 2MB, 4MB, 8MB, 16MB)
|
||||
# via board_build.filesystem_size,
|
||||
# and we will calculate the flash size and eeprom size from that.
|
||||
flash_size = board.get("upload.maximum_size")
|
||||
filesystem_size = board.get("build.filesystem_size", "0MB")
|
||||
filesystem_size_int = convert_size_expression_to_int(filesystem_size)
|
||||
|
||||
maximum_size = flash_size - 4096 - filesystem_size_int
|
||||
|
||||
print("Flash size: %.2fMB" % (flash_size / 1024.0 / 1024.0))
|
||||
print("Sketch size: %.2fMB" % (maximum_size / 1024.0 / 1024.0))
|
||||
print("Filesystem size: %.2fMB" % (filesystem_size_int / 1024.0 / 1024.0))
|
||||
|
||||
flash_length = maximum_size
|
||||
eeprom_start = 0x10000000 + flash_size - 4096
|
||||
fs_start = 0x10000000 + flash_size - 4096 - filesystem_size_int
|
||||
fs_end = 0x10000000 + flash_size - 4096
|
||||
|
||||
if maximum_size <= 0:
|
||||
sys.stderr.write(
|
||||
"Error: Filesystem too large for given flash. "
|
||||
"Can at max be flash size - 4096 bytes. "
|
||||
"Available sketch size with current "
|
||||
"config would be %d bytes.\n" % maximum_size)
|
||||
sys.stderr.flush()
|
||||
env.Exit(-1)
|
||||
|
||||
env["PICO_FLASH_LENGTH"] = flash_length
|
||||
env["PICO_EEPROM_START"] = eeprom_start
|
||||
env["FS_START"] = fs_start
|
||||
env["FS_END"] = fs_end
|
||||
# LittleFS configuration paramters taken from
|
||||
# https://github.com/earlephilhower/arduino-pico-littlefs-plugin/blob/master/src/PicoLittleFS.java
|
||||
env["FS_PAGE"] = 256
|
||||
env["FS_BLOCK"] = 4096
|
||||
|
||||
print("Maximium size: %d Flash Length: %d "
|
||||
"EEPROM Start: %d Filesystem start %d "
|
||||
"Filesystem end %s" %
|
||||
(maximum_size,flash_length, eeprom_start, fs_start, fs_end))
|
||||
|
||||
|
||||
def __fetch_fs_size(target, source, env):
|
||||
fetch_fs_size(env)
|
||||
return (target, source)
|
||||
|
||||
env.Append(
|
||||
BUILDERS=dict(
|
||||
DataToBin=Builder(
|
||||
action=env.VerboseAction(" ".join([
|
||||
'"$MKFSTOOL"',
|
||||
"-c", "$SOURCES",
|
||||
"-p", "$FS_PAGE",
|
||||
"-b", "$FS_BLOCK",
|
||||
"-s", "${FS_END - FS_START}",
|
||||
"$TARGET"
|
||||
]), "Building file system image from '$SOURCES' directory to $TARGET"),
|
||||
emitter=__fetch_fs_size,
|
||||
source_factory=env.Dir,
|
||||
suffix=".bin"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
env["fetch_fs_size"] = fetch_fs_size
|
||||
|
||||
#
|
||||
# Target: Build executable and linkable firmware
|
||||
#
|
||||
@ -119,9 +217,15 @@ if "nobuild" in COMMAND_LINE_TARGETS:
|
||||
target_firm = join("$BUILD_DIR", "${PROGNAME}.bin")
|
||||
else:
|
||||
target_elf = env.BuildProgram()
|
||||
target_firm = env.ElfToBin(join("$BUILD_DIR", "${PROGNAME}"), target_elf)
|
||||
env.Depends(target_firm, "checkprogsize")
|
||||
if set(["buildfs", "uploadfs"]) & set(COMMAND_LINE_TARGETS):
|
||||
target_firm = env.DataToBin(
|
||||
join("$BUILD_DIR", "${PICO_FS_IMAGE_NAME}"), "$PROJECTDATA_DIR")
|
||||
AlwaysBuild(target_firm)
|
||||
else:
|
||||
target_firm = env.ElfToBin(join("$BUILD_DIR", "${PROGNAME}"), target_elf)
|
||||
env.Depends(target_firm, "checkprogsize")
|
||||
|
||||
env.AddPlatformTarget("buildfs", target_firm, target_firm, "Build Filesystem Image")
|
||||
AlwaysBuild(env.Alias("nobuild", target_firm))
|
||||
target_buildprog = env.Alias("buildprog", target_firm, target_firm)
|
||||
|
||||
@ -129,6 +233,21 @@ env.AddPostAction(
|
||||
target_elf, env.VerboseAction(generate_uf2, "Generating UF2 image")
|
||||
)
|
||||
|
||||
def _update_max_upload_size(env):
|
||||
fetch_fs_size(env)
|
||||
env.BoardConfig().update("upload.maximum_size", env["PICO_FLASH_LENGTH"])
|
||||
|
||||
# update max upload size based on CSV file
|
||||
if env.get("PIOMAINPROG"):
|
||||
env.AddPreAction(
|
||||
"checkprogsize",
|
||||
env.VerboseAction(
|
||||
lambda source, target, env: _update_max_upload_size(env),
|
||||
"Retrieving maximum program size $SOURCE"))
|
||||
# remove after PIO Core 3.6 release
|
||||
elif set(["checkprogsize", "upload"]) & set(COMMAND_LINE_TARGETS):
|
||||
_update_max_upload_size(env)
|
||||
|
||||
#
|
||||
# Target: Print binary size
|
||||
#
|
||||
@ -232,7 +351,7 @@ if not upload_actions:
|
||||
sys.stderr.write("Warning! Unknown upload protocol %s\n" % upload_protocol)
|
||||
|
||||
AlwaysBuild(env.Alias("upload", upload_source, upload_actions))
|
||||
|
||||
env.AddPlatformTarget("uploadfs", target_firm, upload_actions, "Upload Filesystem Image")
|
||||
#
|
||||
# Default targets
|
||||
#
|
||||
|
@ -65,6 +65,12 @@
|
||||
"optional": true,
|
||||
"owner": "platformio",
|
||||
"version": "~1.72000.0"
|
||||
},
|
||||
"tool-mklittlefs": {
|
||||
"type": "uploader",
|
||||
"optional": true,
|
||||
"owner": "platformio",
|
||||
"version": "~1.203.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,6 +46,10 @@ class RaspberrypiPlatform(PlatformBase):
|
||||
sys.stderr.write(
|
||||
"Error! Unknown build.core value '%s'. Don't know which Arduino core package to use." % build_core)
|
||||
|
||||
# if we want to build a filesystem, we need the tools.
|
||||
if "buildfs" in targets:
|
||||
self.packages['tool-mklittlefs']['optional'] = False
|
||||
|
||||
# configure J-LINK tool
|
||||
jlink_conds = [
|
||||
"jlink" in variables.get(option, "")
|
||||
|
Loading…
x
Reference in New Issue
Block a user