feat: 发布固件底层开发 Skill 套件
This commit is contained in:
commit
c7ae3b4ce1
72 files changed
+10212
No files matched your search
@@ -0,0 +1,100 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Validate normalized pinmux data and write the final project CSV."""
|
||||
|
||||
import argparse
|
||||
import csv
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
HEADERS = ["引脚号", "功能名称", "引脚名称", "有效电平", "FMUX寄存器", "FMUX当前值", "FMUX默认值", "FMUX_list"]
|
||||
INPUT_FIELDS = ["pin_number", "function_name", "pin_name", "is_gpio", "active_level", "fmux_register", "fmux_current", "fmux_default", "fmux_list"]
|
||||
NUMBERED_MUX_RE = re.compile(r"(?:^|;\s*)([0-7])\s*:")
|
||||
UNSAFE_FILENAME_RE = re.compile(r"[/\\:*?\"<>|]+")
|
||||
|
||||
|
||||
def text(value):
|
||||
return "null" if value is None else str(value).strip()
|
||||
|
||||
|
||||
def safe_name(value):
|
||||
value = UNSAFE_FILENAME_RE.sub("_", value.strip())
|
||||
value = re.sub(r"\s+", "_", value)
|
||||
value = re.sub(r"_+", "_", value).strip(" ._")
|
||||
if not value:
|
||||
raise ValueError("project_name 清理后为空")
|
||||
return value
|
||||
|
||||
|
||||
def normalize(raw, index, seen):
|
||||
if not isinstance(raw, dict):
|
||||
raise ValueError(f"rows[{index}] 必须是对象")
|
||||
missing = [key for key in INPUT_FIELDS if key not in raw]
|
||||
if missing:
|
||||
raise ValueError(f"rows[{index}] 缺少字段: {', '.join(missing)}")
|
||||
pin = text(raw["pin_number"])
|
||||
if not pin or pin == "null":
|
||||
raise ValueError(f"rows[{index}] pin_number 为空")
|
||||
if pin in seen:
|
||||
raise ValueError(f"rows[{index}] 引脚号重复: {pin}")
|
||||
seen.add(pin)
|
||||
if not isinstance(raw["is_gpio"], bool):
|
||||
raise ValueError(f"rows[{index}] is_gpio 必须是布尔值")
|
||||
active = text(raw["active_level"])
|
||||
if raw["is_gpio"] and active not in {"高有效", "低有效", "待确认"}:
|
||||
raise ValueError(f"rows[{index}] GPIO 有效电平无效")
|
||||
if not raw["is_gpio"] and active != "null":
|
||||
raise ValueError(f"rows[{index}] 非 GPIO 有效电平必须为 null")
|
||||
mux_list = text(raw["fmux_list"])
|
||||
mux_numbers = set(NUMBERED_MUX_RE.findall(mux_list))
|
||||
current = text(raw["fmux_current"])
|
||||
if current in set("01234567") and current not in mux_numbers:
|
||||
raise ValueError(f"rows[{index}] 引脚 {pin}: FMUX当前值 {current} 未出现在 FMUX_list")
|
||||
row = {
|
||||
"引脚号": pin,
|
||||
"功能名称": text(raw["function_name"]),
|
||||
"引脚名称": text(raw["pin_name"]),
|
||||
"有效电平": active,
|
||||
"FMUX寄存器": text(raw["fmux_register"]),
|
||||
"FMUX当前值": current,
|
||||
"FMUX默认值": text(raw["fmux_default"]),
|
||||
"FMUX_list": mux_list,
|
||||
}
|
||||
return row, len(mux_numbers)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--input", required=True, type=Path)
|
||||
parser.add_argument("--project-name")
|
||||
parser.add_argument("--output-dir", type=Path, default=Path.cwd())
|
||||
parser.add_argument("--output", type=Path)
|
||||
args = parser.parse_args()
|
||||
try:
|
||||
with args.input.open(encoding="utf-8-sig") as handle:
|
||||
payload = json.load(handle)
|
||||
if not isinstance(payload, dict) or not isinstance(payload.get("rows"), list):
|
||||
raise ValueError("JSON 顶层必须是对象并包含 rows 数组")
|
||||
project = args.project_name or text(payload.get("project_name", ""))
|
||||
rows, seen = [], set()
|
||||
for index, raw in enumerate(payload["rows"]):
|
||||
row, mux_count = normalize(raw, index, seen)
|
||||
if mux_count >= 2:
|
||||
rows.append(row)
|
||||
output = args.output or args.output_dir / f"{safe_name(project)}_pinmux.csv"
|
||||
output.parent.mkdir(parents=True, exist_ok=True)
|
||||
with output.open("w", encoding="utf-8-sig", newline="") as handle:
|
||||
writer = csv.DictWriter(handle, fieldnames=HEADERS)
|
||||
writer.writeheader()
|
||||
writer.writerows(rows)
|
||||
print(f"已输出 {len(rows)} 行(输入 {len(payload['rows'])} 行): {output}")
|
||||
return 0
|
||||
except (OSError, ValueError, json.JSONDecodeError) as exc:
|
||||
print(f"ERROR: {exc}", file=sys.stderr)
|
||||
return 2
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in new issue
Block a user