#!/usr/bin/env python3 """ Excel 寄存器表格解析工具 - 生成寄存器定义头文件 - 生成自动化测试代码 - 生成测试描述文件 """ import pandas as pd import os import json def parse_register_excel(file_path): """解析 Excel 寄存器表格""" df = pd.read_excel(file_path) print(f"=== 解析: {file_path} ===") print(df.head()) print(f"\n总记录数: {len(df)}") return df def generate_header_file(df, output_path): """生成 C 头文件""" with open(output_path, 'w') as f: f.write("#ifndef REGISTERS_H\n") f.write("#define REGISTERS_H\n\n") f.write("// 自动生成的寄存器定义\n\n") for _, row in df.iterrows(): f.write(f"// {row['描述']}\n") f.write(f"#define {row['寄存器名']} ({row['地址']}UL)\n\n") f.write("#endif // REGISTERS_H\n") print(f"生成头文件: {output_path}") def generate_test_code(df, output_path, header_name): """生成自动化测试代码""" with open(output_path, 'w') as f: f.write("/**\n") f.write(" * 自动生成的寄存器测试代码\n") f.write(" */\n\n") f.write(f'#include "{header_name}"\n') f.write('#include \n\n') # 测试函数 f.write("void test_registers(void)\n") f.write("{\n") for _, row in df.iterrows(): reg_name = row['寄存器名'] addr = row['地址'] reset_val = row.get('复位值', 0) f.write(f" // 测试: {reg_name}\n") f.write(f' printf("[TEST] {reg_name}: 开始\\n");\n') # 读取复位值测试 f.write(f" uint32_t read_val = *(volatile uint32_t *){reg_name};\n") f.write(f' printf("[REG] {reg_name}: 复位值=0x%08X\\n", read_val);\n') # 复位值验证 f.write(f" if (read_val == {reset_val}UL) {{\n") f.write(f' printf("[PASS] {reg_name}: 复位值正确\\n");\n') f.write(" } else {\n") f.write(f' printf("[FAIL] {reg_name}: 期望值=0x{reset_val:08X}, 实际值=0x%08X\\n", read_val);\n') f.write(" }\n") # 写读测试 test_val = 0xAA55AA55 f.write(f" // 写读测试\n") f.write(f" *(volatile uint32_t *){reg_name} = 0x{test_val:08X}UL;\n") f.write(f" read_val = *(volatile uint32_t *){reg_name};\n") f.write(f' printf("[REG] {reg_name}: 写入值=0x{test_val:08X}, 读回值=0x%08X\\n", read_val);\n') f.write(f" if (read_val == 0x{test_val:08X}UL) {{\n") f.write(f' printf("[PASS] {reg_name}: 读写一致\\n");\n') f.write(" } else {\n") f.write(f' printf("[FAIL] {reg_name}: 期望值=0x{test_val:08X}, 实际值=0x%08X\\n", read_val);\n') f.write(" }\n") f.write(f' printf("[TEST] {reg_name}: 结束\\n");\n') f.write(" printf(\"\\n\");\n\n") f.write("}\n\n") # 主函数 f.write("int main(void)\n") f.write("{\n") f.write(' printf("=== 自动化寄存器测试开始 ===\\n\\n");\n') f.write(" test_registers();\n") f.write(' printf("\\n=== 自动化寄存器测试完成 ===\\n");\n') f.write(" while(1);\n") f.write(" return 0;\n") f.write("}\n") print(f"生成测试代码: {output_path}") def generate_test_specs(df, output_path): """生成测试描述文件 (JSON)""" specs = [] for _, row in df.iterrows(): spec = { 'name': row['寄存器名'], 'address': row['地址'], 'description': row.get('描述', ''), 'reset_value': row.get('复位值', 0), 'test_cases': [ 'reset_value_check', 'write_read_test' ] } specs.append(spec) with open(output_path, 'w', encoding='utf-8') as f: json.dump(specs, f, indent=2, ensure_ascii=False) print(f"生成测试描述: {output_path}") if __name__ == "__main__": register_dir = "docs/00_芯片资料/registers" if os.path.exists(register_dir): for filename in os.listdir(register_dir): if filename.endswith(('.xlsx', '.xls')): file_path = os.path.join(register_dir, filename) df = parse_register_excel(file_path) # 生成头文件 header_name = filename.replace('.xlsx', '.h').replace('.xls', '.h') output_header = os.path.join("projects/P01_chip_test/inc", header_name) generate_header_file(df, output_header) # 生成测试代码 test_name = filename.replace('.xlsx', '_test.c').replace('.xls', '_test.c') output_test = os.path.join("projects/P01_chip_test/src", test_name) generate_test_code(df, output_test, header_name) # 生成测试描述文件 spec_name = filename.replace('.xlsx', '_spec.json').replace('.xls', '_spec.json') output_spec = os.path.join("projects/P01_chip_test/tests", spec_name) generate_test_specs(df, output_spec) else: print(f"目录不存在: {register_dir}")