python自动化处理
自动化生成配置的.h .c文件
在开发中,有些需求参数是客户提供的,并且常常增加更新,汽车控制域开发中经常采集各通道上的CAN。可以用python脚本的模板库自动生成对应cfg.h cfg.c文件
from openpyxl import load_workbook
import warnings
warnings.filterwarnings("ignore", category=UserWarning, module="openpyxl")
from mako.template import Template
from datetime import datetime
# 获取当前时间
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
# 创建Mako模板
template_str = """
/*
* 文件名: str_cfg.c
* 生成时间: ${current_time}
* 作者: wl
*/
#ifndef _STR_CFG_H_
#define _STR_CFG_H_
#include <stdint.h>
// 定义结构体
typedef struct {
const char* name;
const uint6_t value;
} StrCfg;
// 定义结构体数组
StrCfg str_cfg_array[] = {
% for index,(name, value) in enumerate(data_list):
<% sapcenum = " " *(25-len(name)-len(str(value))) %> \
{"${name}", ${sapcenum} ${value}}, /* index:${index}, ${name},${value} */
% endfor
<% sapcenum = " " *(25-len("NULL")-4) %> \
{NULL, ${sapcenum} 0}
};
<% total_sum_befor = 0 %>
<% total_sum_update = 0 %>
// 计算宏的值
% for index,(name, value) in enumerate(data_list):
<% total_sum_update = int(value) + total_sum_befor %> \
/* ${total_sum_update} = ${value} + ${total_sum_befor} */ \
<% total_sum_befor = total_sum_update %>
% endfor
#define STR_CFG_ARRAY_SIZE (${total_sum_update}u)
#endif
"""
# Press the green button in the gutter to run the script.
if __name__ == '__main__':
workbook = load_workbook('./SmartMi V23 VCCM BigData_Upload_Cfg.xlsx')
# wb.get_sheet_names()
# Select the worksheet
worksheet = workbook['Upload_Config']
# 创建一个列表来存储结构体变量
data_list = []
# 遍历列D和列H,从第二行开始
for row in worksheet.iter_rows(min_row=2, values_only=True):
column_d_value = row[3]
column_e_value = row[7]
# 将列D和列H的数据作为一个元组添加到列表中
data_list.append((column_d_value, column_e_value))
# 打印结构体变量的内容
# print(f"Column D: {column_d_value}, Column E: {column_e_value}")
for index, (msgname, msglen) in enumerate(data_list):
print(f"Index: {index}, Msgname: {msgname}, Msglen: {msglen}")
# 计算宏的值
# macro_value = sum(int(value) for _, value in data_list)
#print(macro_value)
# 使用Mako渲染模板
rendered_c_code = Template(template_str).render(current_time=current_time,data_list=data_list)
# 将渲染后的C代码写入文件
with open('str_cfg.c', 'w') as f:
f.write(rendered_c_code)
上面的脚本主要采集excel脚本中对应的列内容,自动填充到str_cfg.c的结构体中并做一些必要的运算。可以省去大部分重复工作
自动化生成MCU RAM FLASH占用空间
下面截图是MCU生成ELF后的map文件,用python统计其各个section的占比,以及RAM FLash的占用量
#Configuration
INPUT_MAP_FILE = 'path/to/your_map_file.map' #Update with your actual map file path
OUTPUT_REPORT_FILE = 'memory_report.md' #Output report file name
def parse_map_file(map_file)
sections = {
'RAM': [],
'Local RAM': [],
'Flash': [],
}
ram_total_bytes = 0
local_ram_total_bytes = 0
flash_total_bytes = 0
with open(map_file,'r') as f:
lines = f.readlines()
start_parsing = False
header_found = False
for line in lines
line = line.strip()
if 'Image Summary' in line:
start_parsing = True
continue
if start_parsing and not header_found:
if 'Section' in line and 'Base' in line and 'Size(hex)' in line and 'Size(dec)' in line:
header_found = True
continue
if header_found:
if not line or line.startswith('\x0c'):
break;
parts = line.split()
if len(parts) < 5:
continue
section_name = parts[0]
if '.debug' in section_name:
continue
base = parts[1]
try:
size_dec = int(parts[1])
except (ValueError, IndexError):
continue
if size_dec = 0;
continue
base_prefinx = base[2].lower()
if base_prefix == 'fe':
sectine_type = 'RAM'
ram_total_bytes += size_dec
section['RAM'].append({'name':section_name, 'size_kb':size_dec/1024})
elif base_prefix == 'fd':
sectine_type = 'Local RAM'
local_ram_total_bytes += size_dec
section['LocalRAM'].append({'name':section_name, 'size_kb':size_dec/1024})
elif base_prefix == '00':
section_type = 'Flash'
flash_total_bytes += size_dec
section['Flash'].append({'name':section_name, 'size_kb':size_dec/1024})
else:
continue
totals = {
'RAM': ram_total_bytes / 1024,
'Local Ram':local_ram_total_bytes / 1024,
'Flash': flash_total_bytes / 1024
}
return sections,totals
def generate_markdown_report(sections,totals,output_file):
with open(output_file,'w') as f
f.write('## Memory Usage Report\n\n')
f.write('## Summary\n\n')
f.write(f"- **RAM**: {totals['RAM']:.2f} KB\n")
f.write(f"- **Local RAM**: {totals['Local RAM']:.2f} KB\n")
f.write(f"- **Flash RAM**: {totals['Flash']:.2f} KB\n")
for section_type in ['RAM','Local RAM','Flash']
entries = section[section_type]
if not entries:
continue
sorted_entries = sorted(entries,key=lambda x:-x['size_kb'])
f.write(f"## {section_type} Details\n\n")
f.write(f"| Section Name | Size (KB)\n")
f.write(f"| ---------|--------------\n")
for entry in sorted_entries:
f.write(f"| {entry['name']} | {entry['size_kb']:.2f} |\n")
f.write("\\n");
if __name__ == "__main__"
section,totals = parse_map_file(INPUT_MAP_FILE)
print(f"Total RAM Usage:{totals['RAM']:.2f} KB")
print(f"Total LOCAL RAM Usage:{totals['Local RAM']:.2f} KB")
print(f"Total Flash Usage:{totals['Flash']:.2f} KB")
generate_markdown_report(section,totals,OUTPUT_REPORT_FILE)
print(f"\n Repot generated successfully: {OUTPUT_REPORT_FILE}")