"""IDS 数据共享模块。 提供 JSON 加载和 HTML 表格渲染函数, 供 render_ids_acq_map / render_ids_exc_map / render_ids_daq_reg / render_ids_awg_reg 复用。 """ import json from pathlib import Path from collections import OrderedDict # 输出顺序(先列出的模块排在前面) ACQ_MODULE_ORDER = ["MCU_INS", "MCU_DAT", "DAQ_REG", "DAQ_PAR", "DAQ_FLT"] EXC_MODULE_ORDER = ["MCU_INS", "MCU_DAT", "AWG_REG", "AWG_IDX", "AWG_WVE"] # ---------- 数据加载 ---------- def _load_ids(filepath: str) -> dict: """加载 IDS JSON 文件并返回解析后的 dict。""" path = Path(filepath) if not path.exists(): raise FileNotFoundError(f"IDS 文件不存在: {path}") with open(path, "r", encoding="utf-8") as f: return json.load(f) # ---------- HTML 工具 ---------- def _td(text: str, **kwargs) -> str: """生成 单元格,支持 rowspan / style 等属性。""" attrs = " ".join(f'{k}="{v}"' for k, v in kwargs.items() if v is not None) return f"{text}" if attrs else f"{text}" def _th(text: str) -> str: return f"{text}" def _bit_range_str(bits: list) -> str: """将 [15, 8] 或 [7] 转为位段字符串。""" if len(bits) == 1: return str(bits[0]) return f"{bits[0]}:{bits[-1]}" # ---------- 映射表渲染 ---------- def render_mapping_acq_table(data: dict) -> str: """渲染 msmt_acq 通道模块基地址表。""" mi = data.get("MappingInfo", {}).get("msmt_acq", {}) return _render_mapping_table(mi, ACQ_MODULE_ORDER, "ACQ") def render_mapping_exc_table(data: dict) -> str: """渲染 msmt_exc 通道模块基地址表。""" mi = data.get("MappingInfo", {}).get("msmt_exc", {}) return _render_mapping_table(mi, EXC_MODULE_ORDER, "EXC") def _render_mapping_table(mapping: dict, module_order: list, label: str) -> str: """通用的通道模块基地址渲染。""" rows = [] # 收集所有模块名 all_modules = set() for ch_info in mapping.values(): all_modules.update(ch_info.get("Modules", {}).keys()) # 按 module_order 排序,未在列表中的放最后 ordered = [m for m in module_order if m in all_modules] ordered += sorted(all_modules - set(module_order)) for mod_name in ordered: for ch in sorted(mapping.keys(), key=int): info = mapping[ch] modules = info.get("Modules", {}) if mod_name not in modules: continue m = modules[mod_name] exaddr = info.get("Exaddr", "") cid = info.get("Cid", "") rows.append( "" f"ch{ch}" f"{exaddr}" f"{cid}" f"{mod_name}" f"{m.get('StartAddress', '')}" f"{m.get('Size', '')}" f"{m.get('Info', '')}" "" ) if not rows: return "

(无映射数据)

" header = ( "" "通道ExaddrCid" "模块起始地址大小说明" "" ) return f"{header}{''.join(rows)}
" # ---------- 寄存器表渲染 ---------- def render_daq_reg_table(data: dict) -> str: """渲染 DAQ_REG 寄存器汇总表 + 位域明细。""" regs = data.get("Modules", {}).get("DAQ_REG", {}) return _render_reg_table(regs, "DAQ_REG") def render_awg_reg_table(data: dict) -> str: """渲染 AWG_REG 寄存器汇总表 + 位域明细。""" regs = data.get("Modules", {}).get("AWG_REG", {}) return _render_reg_table(regs, "AWG_REG") def _render_reg_table(regs: dict, label: str) -> str: """通用寄存器表渲染(汇总表 + 每位域明细)。""" if not regs: return "

(无寄存器数据)

" # 按偏移地址排序 sorted_regs = sorted(regs.values(), key=lambda r: int(r.get("OffsetAddress", "0x0"), 16)) # ---- 汇总表 ---- summary_rows = [] for r in sorted_regs: name = list(regs.keys())[list(regs.values()).index(r)] offset = r.get("OffsetAddress", "") perm = r.get("Permission", "") desc = r.get("SegDescription", "") summary_rows.append( "" f"{name}" f"{offset}" f"{perm}" f"{desc}" "" ) summary = ( "" "" f"{''.join(summary_rows)}" "
寄存器名偏移地址权限描述
" ) # ---- 位域明细表(仅含字段数 > 0 的寄存器) ---- detail_parts = [] for r in sorted_regs: fields = r.get("Fields", []) if not fields: continue name = list(regs.keys())[list(regs.values()).index(r)] offset = r.get("OffsetAddress", "") field_rows = [] for f in fields: bits = f.get("Bits", []) field_name = f.get("FieldName", "") fdesc = (f.get("FieldDescription", "") or "").replace("\n", "
") reset = f.get("ResetValue", "") field_rows.append( "" f"[{_bit_range_str(bits)}]" f"{field_name}" f"{reset}" f"{fdesc}" "" ) if field_rows: detail_parts.append( f"

{name}({offset})

" "" "" f"{''.join(field_rows)}" "
位段字段名复位值描述
" ) if detail_parts: return f"{summary}
{''.join(detail_parts)}" return summary