summaryrefslogtreecommitdiff
path: root/tools/gen_products.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/gen_products.py')
-rw-r--r--tools/gen_products.py23
1 files changed, 22 insertions, 1 deletions
diff --git a/tools/gen_products.py b/tools/gen_products.py
index 7504287..ff9cf67 100644
--- a/tools/gen_products.py
+++ b/tools/gen_products.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
# Author: cirakg & claude ai
-# Summary: Check that every product in manifest.xml is a watch with API 5.0+ and at least 512 KB for watch apps.
+# Summary: Check each manifest product: a watch with API 5.0+, 512 KB or more, and the watchdog the job runner assumes.
"""Check the manifest's product list against the downloaded device files.
The target rule (README section 14, decision D4): a product belongs in
@@ -9,6 +9,12 @@ variant supports Connect IQ API 5.0.0 or newer, and watch apps get at least
512 KB of memory. The data comes from each device's compiler.json, which
`make sdk` downloads for exactly the products in the manifest.
+The app's job runner (source/util/Jobs.mc) also assumes a watchdog limit
+from the memory size: watches with more than 600,000 bytes for watch apps
+run two job steps per event, which needs 240,000 bytecodes per event
+(simulator.json's watchdogCount); the others run one step and need at
+least 120,000.
+
Usage: gen_products.py --check [--manifest manifest.xml] [--devices DIR]
Exit: 0 every product qualifies, 1 some don't, 2 device files missing.
@@ -29,6 +35,9 @@ EXIT_OK, EXIT_UNQUALIFIED, EXIT_MISSING = 0, 1, 2
IQ_NS = "{http://www.garmin.com/xml/connectiq}"
MIN_API = (5, 0, 0)
MIN_WATCH_APP_MEMORY = 512 * 1024
+# Jobs.LARGE_WATCH_MEMORY and the watchdog each memory class needs.
+LARGE_WATCH_MEMORY = 600_000
+WATCHDOG_SMALL, WATCHDOG_LARGE = 120_000, 240_000
WATCH_GROUP = "Watches/Wearables"
DEFAULT_DEVICES = Path.home() / ".Garmin" / "ConnectIQ" / "Devices"
@@ -42,6 +51,7 @@ class Device:
group: str
min_api: tuple[int, ...]
watch_app_memory: int
+ watchdog: int
def problems(self) -> list[str]:
reasons = []
@@ -51,6 +61,12 @@ class Device:
reasons.append(f"API {'.'.join(map(str, self.min_api))} is below 5.0.0")
if self.watch_app_memory < MIN_WATCH_APP_MEMORY:
reasons.append(f"watch apps get {self.watch_app_memory // 1024} KB, below 512 KB")
+ needed = WATCHDOG_LARGE if self.watch_app_memory > LARGE_WATCH_MEMORY else WATCHDOG_SMALL
+ if self.watchdog < needed:
+ reasons.append(
+ f"watchdog allows {self.watchdog} bytecodes per event; the job runner needs {needed} at"
+ f" {self.watch_app_memory // 1024} KB (change Jobs.stepsPerTick)"
+ )
return reasons
@@ -61,12 +77,17 @@ def parse_version(text: str) -> tuple[int, ...]:
def load_device(devices: Path, product: str) -> Device:
compiler = json.loads((devices / product / "compiler.json").read_text(encoding="utf-8"))
memory = {app["type"]: int(app["memoryLimit"]) for app in compiler["appTypes"]}
+ simulator = devices / product / "simulator.json"
+ watchdog = 0
+ if simulator.exists():
+ watchdog = int(json.loads(simulator.read_text(encoding="utf-8")).get("watchdogCount", 0))
return Device(
product=product,
name=str(compiler.get("displayName", product)),
group=str(compiler.get("webDocDeviceGroup", "")),
min_api=min(parse_version(p["connectIQVersion"]) for p in compiler["partNumbers"]),
watch_app_memory=memory.get("watchApp", 0),
+ watchdog=watchdog,
)