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 platform import system
|
||||||
from os import makedirs
|
from os import makedirs
|
||||||
from os.path import isdir, join
|
from os.path import isdir, join
|
||||||
|
import re
|
||||||
|
|
||||||
from platformio.util import get_serial_ports
|
from platformio.util import get_serial_ports
|
||||||
|
|
||||||
@ -67,6 +68,9 @@ env.Replace(
|
|||||||
|
|
||||||
ARFLAGS=["rc"],
|
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+).*",
|
SIZEPROGREGEXP=r"^(?:\.text|\.data|\.rodata|\.text.align|\.ARM.exidx)\s+(\d+).*",
|
||||||
SIZEDATAREGEXP=r"^(?:\.data|\.bss|\.noinit)\s+(\d+).*",
|
SIZEDATAREGEXP=r"^(?:\.data|\.bss|\.noinit)\s+(\d+).*",
|
||||||
SIZECHECKCMD="$SIZETOOL -A -d $SOURCES",
|
SIZECHECKCMD="$SIZETOOL -A -d $SOURCES",
|
||||||
@ -109,6 +113,100 @@ env.Append(
|
|||||||
if not env.get("PIOFRAMEWORK"):
|
if not env.get("PIOFRAMEWORK"):
|
||||||
env.SConscript("frameworks/_bare.py")
|
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
|
# Target: Build executable and linkable firmware
|
||||||
#
|
#
|
||||||
@ -119,9 +217,15 @@ if "nobuild" in COMMAND_LINE_TARGETS:
|
|||||||
target_firm = join("$BUILD_DIR", "${PROGNAME}.bin")
|
target_firm = join("$BUILD_DIR", "${PROGNAME}.bin")
|
||||||
else:
|
else:
|
||||||
target_elf = env.BuildProgram()
|
target_elf = env.BuildProgram()
|
||||||
target_firm = env.ElfToBin(join("$BUILD_DIR", "${PROGNAME}"), target_elf)
|
if set(["buildfs", "uploadfs"]) & set(COMMAND_LINE_TARGETS):
|
||||||
env.Depends(target_firm, "checkprogsize")
|
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))
|
AlwaysBuild(env.Alias("nobuild", target_firm))
|
||||||
target_buildprog = env.Alias("buildprog", target_firm, 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")
|
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
|
# Target: Print binary size
|
||||||
#
|
#
|
||||||
@ -232,7 +351,7 @@ if not upload_actions:
|
|||||||
sys.stderr.write("Warning! Unknown upload protocol %s\n" % upload_protocol)
|
sys.stderr.write("Warning! Unknown upload protocol %s\n" % upload_protocol)
|
||||||
|
|
||||||
AlwaysBuild(env.Alias("upload", upload_source, upload_actions))
|
AlwaysBuild(env.Alias("upload", upload_source, upload_actions))
|
||||||
|
env.AddPlatformTarget("uploadfs", target_firm, upload_actions, "Upload Filesystem Image")
|
||||||
#
|
#
|
||||||
# Default targets
|
# Default targets
|
||||||
#
|
#
|
||||||
|
@ -65,6 +65,12 @@
|
|||||||
"optional": true,
|
"optional": true,
|
||||||
"owner": "platformio",
|
"owner": "platformio",
|
||||||
"version": "~1.72000.0"
|
"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(
|
sys.stderr.write(
|
||||||
"Error! Unknown build.core value '%s'. Don't know which Arduino core package to use." % build_core)
|
"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
|
# configure J-LINK tool
|
||||||
jlink_conds = [
|
jlink_conds = [
|
||||||
"jlink" in variables.get(option, "")
|
"jlink" in variables.get(option, "")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user