Files
MeshCore/scripts/nrf52_vl53l0x_const.py
T
mikecarper 2b55ff6a62 Recover RAK RAM without reducing OTA or sensor capacities
Cache each validated OTA descriptor field once and size manifest reassembly to the admitted wire format. Compile reviewed read-only VL53L0X tuning data in flash through a private dependency copy, retaining the original implementation for unknown revisions.
2026-10-27 08:17:23 -07:00

82 lines
3.6 KiB
Python

"""Keep the reviewed VL53L0X tuning tables in nRF52 flash.
The vendor tuning loader only reads these bytes and copies register writes
through a local buffer. Compile a private dependency copy with const inputs;
leave its public caller-owned tuning-buffer setter/getter unchanged. Unknown
library versions retain their ordinary implementation and RAM requirements.
"""
import hashlib
from pathlib import Path
import shutil
FILES = {
"vl53l0x_tuning.h": "0e0331b7df1084d183248355f75d835b3446200b22f71765b5c63a470ff01c63",
"vl53l0x_interrupt_threshold_settings.h": "9e5e6c00af66497d03d6c6a13a269521c12b33c90455efcd3b8494487e1780c2",
"vl53l0x_api_core.h": "948de4a0363339facc58c4e1bc5781b954b99cca1c13a4a105eb3969aeba8653",
"core/src/vl53l0x_api_core.cpp": "d31da82edbad0f7fd89106340f7a006b61cd2e5b7c353460fb394978ce55953b",
"core/src/vl53l0x_api.cpp": "6cfa0784600bd797e372b511761f4be10e97264b55d5c7269dd41ba607b8edb7",
}
REPLACEMENTS = {
"vl53l0x_tuning.h": ("uint8_t DefaultTuningSettings[]", "const uint8_t DefaultTuningSettings[]"),
"vl53l0x_interrupt_threshold_settings.h": (
"uint8_t InterruptThresholdSettings[]", "const uint8_t InterruptThresholdSettings[]"),
"vl53l0x_api_core.h": ("uint8_t* pTuningSettingBuffer);", "const uint8_t* pTuningSettingBuffer);"),
"core/src/vl53l0x_api_core.cpp": (
"uint8_t* pTuningSettingBuffer) {", "const uint8_t* pTuningSettingBuffer) {"),
"core/src/vl53l0x_api.cpp": ("uint8_t* pTuningSettingBuffer;", "const uint8_t* pTuningSettingBuffer;"),
}
def digest(text):
return hashlib.sha256(text.encode("utf-8")).hexdigest()
def patched_files(source_root):
result = {}
for name, expected in FILES.items():
text = (source_root / name).read_text(encoding="utf-8").replace("\r\n", "\n")
old, new = REPLACEMENTS[name]
if digest(text) != expected or text.count(old) != 1:
raise RuntimeError("changed reviewed VL53L0X dependency: " + name)
result[name] = text.replace(old, new, 1)
return result
def write_if_changed(path, content):
if not path.exists() or path.read_text(encoding="utf-8") != content:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(content, encoding="utf-8")
def replace_vl53_source(build_env, node):
source = Path(node.srcnode().get_abspath())
source_root = next((parent for parent in source.parents
if parent.name == "src" and parent.parent.name == "Adafruit_VL53L0X"), None)
if source_root is None or source.suffix != ".cpp":
return node
try:
patches = patched_files(source_root)
except (OSError, UnicodeError, RuntimeError) as error:
print("nRF52 VL53L0X const tables: ordinary source retained (" + str(error) + ")")
return node
destination = Path(build_env.subst("$BUILD_DIR")) / "readonly-nrf52-vl53l0x" / "src"
# Keep every quoted sibling/relative include inside the same private copy.
# All compilation units therefore see the same const loader declaration.
for path in source_root.rglob("*"):
if not path.is_file():
continue
relative = path.relative_to(source_root)
output = destination / relative
if relative.as_posix() in patches:
write_if_changed(output, patches[relative.as_posix()])
elif not output.exists() or output.read_bytes() != path.read_bytes():
output.parent.mkdir(parents=True, exist_ok=True)
shutil.copyfile(path, output)
return build_env.File(str(destination / source.relative_to(source_root)))
def install(build_env):
build_env.AddBuildMiddleware(replace_vl53_source, "*Adafruit_VL53L0X*/*.cpp")