932 lines
41 KiB
Python
932 lines
41 KiB
Python
#!/usr/bin/python3
|
||
# -*- coding: utf-8 -*-
|
||
|
||
|
||
import openpyxl
|
||
import os
|
||
import time
|
||
import re
|
||
import sys
|
||
import getopt
|
||
|
||
STORAGE_DICS = [
|
||
["PARAM_STORE_ADDR", "C1", "存储区域基地址", "D1",],
|
||
["PARAM_STORE_NAME", "C2", "存储区域命名", "D2",],
|
||
["PARAM_STORE_UNIT", "C3", "存储区域擦写单元", "D3",],
|
||
["PARAM_DATA_UNIT", "C4", "存储区域单分区大小", "D4",],
|
||
["PARAM_NUM", "C5", "参数个数", "D5",],
|
||
["PARAM_RAM", "C6", "是否需要RAM参数对象", "D6",],
|
||
["PARAM_STORAGE_TYPE","C7", "存储器类型", "D7",],
|
||
["PARAM_FILE_PATH", "C8", "参数文件路径", "D8",],
|
||
]
|
||
|
||
class ParamItem(object):
|
||
'''
|
||
从excel表格中读取到的参数信息体
|
||
index:参数索引
|
||
DI:参数唯一编码
|
||
str_name:参数名称(汉字)
|
||
name:参数标识符
|
||
store_type:参数存储类型
|
||
size:参数数据域大小
|
||
default_val:参数默认值
|
||
local_type:参数本地使用类型
|
||
ratio:缩放倍率
|
||
min:参数范围-最小值
|
||
max:参数范围-最大值
|
||
flag:参数标记
|
||
check_func:参数修改前的有效性检查函数
|
||
updata_func:参数更新后的回调函数
|
||
infomation:当前参数注释
|
||
offset:当前参数的内存对象偏移
|
||
offset_str:当前参数的存储偏移
|
||
size_string:参数的数据域大小宏定义
|
||
'''
|
||
def __init__(self, row):
|
||
'''
|
||
将excel中的一行数据转换为参数信息体
|
||
'''
|
||
self.index = row[0].value
|
||
self.DI = row[1].value
|
||
self.str_name = row[2].value
|
||
self.name = row[3].value
|
||
self.store_type = row[4].value
|
||
self.size = row[5].value
|
||
self.default_value = row[6].value
|
||
self.local_type = row[7].value
|
||
self.ratio = row[8].value
|
||
self.min = row[9].value
|
||
self.max = row[10].value
|
||
self.flag = row[11].value
|
||
self.check_func = row[12].value
|
||
self.updata_func = row[13].value
|
||
self.infomation = row[14].value
|
||
self.offset = ""
|
||
self.offset_str = ""
|
||
self.size_string = ""
|
||
def __str__(self):
|
||
return "%s,\t%s,\t%s,\t%s,\t%s,\t%s,\t%s,\t%s,\t%s,\t%s,\t%s,\t%s,\t%s,\t%s,\t%s"%(
|
||
self.index, self.DI, self.str_name, self.name, self.store_type, self.size, self.default_value,
|
||
self.local_type, self.ratio, self.min, self.max, self.flag, self.check_func, self.updata_func, self.infomation)
|
||
|
||
class StorageConfig(object):
|
||
'''
|
||
读取excel中的所有sheet,将sheet中的数据转换为参数信息结构体
|
||
'''
|
||
def __init__(self):
|
||
self.workbook = openpyxl.load_workbook("tools/param_input.xlsx", data_only=True)
|
||
self.config_set = {}
|
||
self.param_index = ""
|
||
for sheet_name in self.workbook.sheetnames:
|
||
self.config_set[sheet_name] = {}
|
||
self.config_set[sheet_name]["name"] = sheet_name
|
||
sheet = self.workbook[sheet_name]
|
||
self.config_set[sheet_name]["param_storage_addr"] = {sheet["C1"].value:sheet["D1"].value}
|
||
self.config_set[sheet_name]["param_storage_name"] = {sheet["C2"].value:sheet["D2"].value}
|
||
self.config_set[sheet_name]["param_storage_unit"] = {sheet["C3"].value:sheet["D3"].value}
|
||
self.config_set[sheet_name]["param_data_unit"] = {sheet["C4"].value:sheet["D4"].value}
|
||
self.config_set[sheet_name]["param_num"] = {sheet["C5"].value:sheet["D5"].value}
|
||
self.config_set[sheet_name]["param_ram"] = {sheet["C6"].value:sheet["D6"].value}
|
||
self.config_set[sheet_name]["storage_type"] = {sheet["C7"].value:sheet["D7"].value}
|
||
self.config_set[sheet_name]["file_path_prefix"] = {sheet["C8"].value:sheet["D8"].value}
|
||
|
||
cell_table = sheet["A11":"O%d"%(11+self.config_set[sheet_name]['param_num']["参数个数"])]
|
||
self.config_set[sheet_name]["param_info_list"] = []
|
||
offset = 0
|
||
for row_cel in cell_table[1:]:
|
||
param = ParamItem(row_cel)
|
||
offset = offset + int(param.size) + 7 #PARAM_INFO_SIZE
|
||
param.offset = "%s_PARAM_%s_OFFSET"%(sheet_name.upper(), param.name.upper())
|
||
param.size_string = "%s_PARAM_%s_SIZE"%(sheet_name.upper(), param.name.upper())
|
||
self.config_set[sheet_name]["param_info_list"].append([param,offset])
|
||
|
||
def data_check(self):
|
||
for sheet in self.workbook:
|
||
for item in STORAGE_DICS:
|
||
if sheet[item[1]].value != item[2]:
|
||
print(item,sheet[item[1]].value, item[2], "bad file")
|
||
|
||
|
||
def __generate_definations(self):
|
||
'''生成defination.h'''
|
||
|
||
file_name_formate = "param_%s_defination.h"
|
||
|
||
file_title_formate = '''/*
|
||
* =====================================================================================
|
||
*
|
||
* Filename: param_%s_defination.h
|
||
*
|
||
* Description:
|
||
*
|
||
* Version: 1.0
|
||
* Created: %s
|
||
* Revision: none
|
||
* Compiler: gcc
|
||
*
|
||
* Author: Autogenerated
|
||
* Organization: Topscomm
|
||
*
|
||
* =====================================================================================
|
||
*/
|
||
|
||
#ifndef __PARAM_%s_DEFINATION_H__
|
||
#define __PARAM_%s_DEFINATION_H__
|
||
|
||
#include <stdint.h>
|
||
#include <stddef.h>
|
||
|
||
|
||
#define %s_PARAM_NUM (%s)
|
||
|
||
|
||
'''
|
||
file_end_formate = '''
|
||
#endif /* ----- #ifndef __PARAM_%s_DEFINATION_H__ ----- */
|
||
'''
|
||
|
||
for key, value in self.config_set.items():
|
||
|
||
file_name = file_name_formate % key.lower();
|
||
|
||
ret_str = ""
|
||
ret_str = ret_str + file_title_formate%(key.lower(), time.strftime("%d/%m/%Y %H:%M:%S"), key.upper(),key.upper(),key.upper(),value["param_num"]["参数个数"])
|
||
|
||
format_str = "#define {:<50} {}\n"
|
||
|
||
max_line_len = 0
|
||
|
||
for size_item in value["param_info_list"]:
|
||
curr_line = key.upper()+"_PARAM_"+size_item[0].name.upper()+"_SIZE"
|
||
if len(curr_line) > max_line_len :
|
||
max_line_len = len(curr_line)
|
||
|
||
if size_item[0].store_type == "PARAM_ARRAY":
|
||
ret_str = ret_str + format_str.format(curr_line, '('+str(size_item[0].size)+')')
|
||
if size_item[0].store_type == "PARAM_FLOAT":
|
||
ret_str = ret_str + format_str.format(curr_line, '(sizeof(float))')
|
||
if size_item[0].store_type == "PARAM_UINT8":
|
||
ret_str = ret_str + format_str.format(curr_line, '(sizeof(uint8_t))')
|
||
if size_item[0].store_type == "PARAM_INT8":
|
||
ret_str = ret_str + format_str.format(curr_line, '(sizeof(int8_t))')
|
||
if size_item[0].store_type == "PARAM_UINT16":
|
||
ret_str = ret_str + format_str.format(curr_line, '(sizeof(uint16_t))')
|
||
if size_item[0].store_type == "PARAM_INT16":
|
||
ret_str = ret_str + format_str.format(curr_line, '(sizeof(int16_t))')
|
||
if size_item[0].store_type == "PARAM_UINT32":
|
||
ret_str = ret_str + format_str.format(curr_line, '(sizeof(uint32_t))')
|
||
if size_item[0].store_type == "PARAM_INT32":
|
||
ret_str = ret_str + format_str.format(curr_line, '(sizeof(int32_t))')
|
||
if size_item[0].store_type == "PARAM_UINT64":
|
||
ret_str = ret_str + format_str.format(curr_line, '(sizeof(uint64_t))')
|
||
if size_item[0].store_type == "PARAM_INT64":
|
||
ret_str = ret_str + format_str.format(curr_line, '(sizeof(int64_t))')
|
||
if size_item[0].store_type == "PARAM_DOUBLE":
|
||
ret_str = ret_str + format_str.format(curr_line, '(sizeof(double))')
|
||
|
||
size_item[0].size_string = "%s_PARAM_%s_SIZE"%(key.upper(), size_item[0].name.upper())
|
||
|
||
ret_str = ret_str + "\n\n"
|
||
format_str = " {:<%s}/* {} */\n"%(2*max_line_len)
|
||
|
||
ret_str = ret_str + """typedef struct\n{\n"""
|
||
|
||
for size_item in value["param_info_list"]:
|
||
if size_item[0].store_type == "PARAM_ARRAY":
|
||
ret_str = ret_str + format_str.format ("uint8_t "+size_item[0].name+"["+size_item[0].size_string+"];", size_item[0].str_name)
|
||
if size_item[0].store_type == "PARAM_FLOAT":
|
||
ret_str = ret_str + format_str.format ("float "+size_item[0].name+";", size_item[0].str_name)
|
||
if size_item[0].store_type == "PARAM_UINT8":
|
||
ret_str = ret_str + format_str.format ("uint8_t "+size_item[0].name+";", size_item[0].str_name)
|
||
if size_item[0].store_type == "PARAM_INT8":
|
||
ret_str = ret_str + format_str.format ("int8_t "+size_item[0].name+";", size_item[0].str_name)
|
||
if size_item[0].store_type == "PARAM_UINT16":
|
||
ret_str = ret_str + format_str.format ("uint16_t "+size_item[0].name+";", size_item[0].str_name)
|
||
if size_item[0].store_type == "PARAM_INT16":
|
||
ret_str = ret_str + format_str.format ("int16_t "+size_item[0].name+";", size_item[0].str_name)
|
||
if size_item[0].store_type == "PARAM_UINT32":
|
||
ret_str = ret_str + format_str.format ("uint32_t "+size_item[0].name+";", size_item[0].str_name)
|
||
if size_item[0].store_type == "PARAM_INT32":
|
||
ret_str = ret_str + format_str.format ("int32_t "+size_item[0].name+";", size_item[0].str_name)
|
||
if size_item[0].store_type == "PARAM_UINT64":
|
||
ret_str = ret_str + format_str.format ("uint64_t "+size_item[0].name+";", size_item[0].str_name)
|
||
if size_item[0].store_type == "PARAM_INT64":
|
||
ret_str = ret_str + format_str.format ("int64_t "+size_item[0].name+";", size_item[0].str_name)
|
||
if size_item[0].store_type == "PARAM_DOUBLE":
|
||
ret_str = ret_str + format_str.format ("double "+size_item[0].name+";", size_item[0].str_name)
|
||
ret_str = ret_str + "} %s_param_t;\n\n"%key.lower()
|
||
|
||
ret_str = ret_str + file_end_formate%(key.upper())
|
||
|
||
|
||
with open("%s/"%self.file_path+file_name, 'w', encoding="utf-8") as f:
|
||
f.write(ret_str)
|
||
|
||
|
||
def __generate_internal_definations(self):
|
||
'''生成.h'''
|
||
file_name_formate = "param_%s.h"
|
||
file_title_formate = '''/*
|
||
* =====================================================================================
|
||
*
|
||
* Filename: param_%s.h
|
||
*
|
||
* Description:
|
||
*
|
||
* Version: 1.0
|
||
* Created: %s
|
||
* Revision: none
|
||
* Compiler: gcc
|
||
*
|
||
* Author: Autogenerated
|
||
* Organization: Topscomm
|
||
*
|
||
* =====================================================================================
|
||
*/
|
||
|
||
#ifndef __PARAM_%s_H__
|
||
#define __PARAM_%s_H__
|
||
|
||
#include <stdint.h>
|
||
|
||
#include "./param_config.h"
|
||
#include "../param_functional/param_block.h"
|
||
#include "./param_%s_defination.h"
|
||
|
||
#define %s_PARAM_STORE_ADDR (%s)
|
||
|
||
|
||
'''
|
||
file_end_formate = '''
|
||
|
||
#if ENABLE_PARAM_IN_RAM
|
||
#if ENABLE_PARAM_PRESET
|
||
typedef struct
|
||
{
|
||
%s_param_t preset_table;
|
||
} update_%s_param_t;
|
||
#endif
|
||
#endif
|
||
|
||
extern param_info_table_t %s_PARAM_INFO;
|
||
|
||
#endif /* ----- #ifndef __PARAM_%s_H__ ----- */
|
||
'''
|
||
|
||
for key, value in self.config_set.items():
|
||
|
||
file_name = file_name_formate%key.lower()
|
||
|
||
ret_str = ""
|
||
ret_str = ret_str + file_title_formate%(key.lower(), time.strftime("%d/%m/%Y %H:%M:%S"), key.upper(),key.upper(),key.lower(),key.upper(), value["param_storage_addr"]["存储区域基地址"])
|
||
|
||
format_str = "#define {:<%s} {}\n"
|
||
index = 0
|
||
last_str = ""
|
||
|
||
max_line_len = 0
|
||
for size_item in value["param_info_list"]:
|
||
if max_line_len <= len("%s_PARAM_%s_SIZE"%(key.upper(), size_item[0].name.upper())):
|
||
max_len_len = len("%s_PARAM_%s_SIZE"%(key.upper(), size_item[0].name.upper()))
|
||
|
||
format_str = format_str%(max_len_len + 5)
|
||
|
||
for size_item in value["param_info_list"]:
|
||
size_item[0].size_string = "%s_PARAM_%s_SIZE"%(key.upper(), size_item[0].name.upper())
|
||
|
||
if index == 0:
|
||
ret_str = ret_str + format_str.format(key.upper()+"_PARAM_"+size_item[0].name.upper()+"_OFFSET", '0')
|
||
else:
|
||
ret_str = ret_str + format_str.format(key.upper()+"_PARAM_"+size_item[0].name.upper()+"_OFFSET", last_str)
|
||
index = index + 1
|
||
last_str = ('({:<%s} + {:<%s} + PARAM_INFO_SIZE)' %(2*max_line_len, 3*max_line_len)).format(key.upper()+"_PARAM_"+size_item[0].name.upper()+"_OFFSET",
|
||
key.upper()+"_PARAM_"+size_item[0].name.upper()+"_SIZE")
|
||
|
||
ret_str = ret_str + "\n"
|
||
ret_str = ret_str + '''#define %s_PARAM_STORAGE_SIZE\t\t%s\n\n''' % (key.upper(), last_str)
|
||
|
||
ret_str = ret_str + file_end_formate%(key.lower(), key.lower(), key.upper(),key.upper())
|
||
|
||
|
||
with open("%s/"%self.file_path+file_name, 'w', encoding="utf-8") as f:
|
||
f.write(ret_str)
|
||
|
||
def __generate_infomatin(self):
|
||
'''生成.c'''
|
||
file_name_formate = "param_%s.c"
|
||
file_title_formate = '''/*
|
||
* =====================================================================================
|
||
*
|
||
* Filename: param_%s.c
|
||
*
|
||
* Description:
|
||
*
|
||
* Version: 1.0
|
||
* Created: %s
|
||
* Revision: none
|
||
* Compiler: gcc
|
||
*
|
||
* Author: Autogenerated
|
||
* Organization: Topscomm
|
||
*
|
||
* =====================================================================================
|
||
*/
|
||
|
||
#include <stddef.h>
|
||
|
||
#include "plm_type_def.h"
|
||
#include "../param_export.h"
|
||
|
||
#include "./param_%s.h"
|
||
|
||
|
||
#if ENABLE_PARAM_IN_RAM
|
||
#if ENABLE_PARAM_PRESET
|
||
update_%s_param_t g_update_%s_param_info; /*预存参数数据缓冲区 */
|
||
#endif
|
||
|
||
%s_param_t g_%s_param_in_ram; /*参数ram缓冲区*/
|
||
uint16_t g_check_%s_param_crc[%s_PARAM_NUM]; /*用于记录参数的校验crc结果*/
|
||
#endif
|
||
|
||
PARAM_CHANGE_FLAG_E g_%s_param_change_flag[%s_PARAM_NUM]; /*用于记录参数的修改标记*/
|
||
|
||
const %s_param_t %s_PARAM_DEFAULT_VALUE_TABLE =
|
||
{
|
||
'''
|
||
file_end_formate = '''
|
||
|
||
param_info_table_t %s_PARAM_INFO =
|
||
{
|
||
#if ENABLE_PARAM_MUTEX
|
||
.ptr_mutex = &g_param_resouce.param_mutex,
|
||
#endif
|
||
.ptr_category_name = %s_REGION_NAME,
|
||
.ptr_default_value_table = (void*)&%s_PARAM_DEFAULT_VALUE_TABLE, //默认参数值
|
||
.ptr_index_table = (void*)%s_PARAM_INDEX_TABLE, //参数索引表
|
||
.param_num = %s_PARAM_NUM, //参数个数
|
||
.param_data_size = %s_PARAM_STORAGE_SIZE, //数据长度
|
||
.param_base_addr = %s_PARAM_STORE_ADDR, //参数存储页地址
|
||
#if ENABLE_PARAM_IN_RAM
|
||
#if ENABLE_PARAM_PRESET
|
||
.ptr_preset_dataset = (void*)&g_update_%s_param_info.preset_table,//预设参数表
|
||
#endif
|
||
.ptr_param_in_ram = (void*)&g_%s_param_in_ram, //参数ram缓冲区
|
||
.ptr_crc_in_ram = g_check_%s_param_crc, //参数crc校验值
|
||
#endif
|
||
.ptr_change_flag = g_%s_param_change_flag, //参数变更标记
|
||
.backup_offset = %s, //备份之间的偏移
|
||
.idx_min = %s, //参数索引最小值
|
||
.idx_max = %s, //参数索引最大值
|
||
.ptr_exchange_unit = &g_param_resouce.ptr_param_unit_buff, //参数写入缓冲区
|
||
.exchange_size = %s, //按页写入的缓冲区的大小
|
||
};
|
||
|
||
'''
|
||
|
||
for key, value in self.config_set.items():
|
||
|
||
file_name = file_name_formate%key.lower()
|
||
|
||
ret_str = ""
|
||
ret_str = ret_str + file_title_formate%(key.lower(), time.strftime("%d/%m/%Y %H:%M:%S"), key.lower(), key.lower(), key.lower(), key.lower(), key.lower(), key.lower(), key.upper(), key.lower(), key.upper(), key.lower(), key.upper())
|
||
|
||
format_str = " .{:<20} = {:<40} //{}\n"
|
||
for size_item in value["param_info_list"]:
|
||
if size_item[0].store_type == "PARAM_ARRAY":
|
||
ret_str = ret_str + format_str.format(size_item[0].name, "{"+str(size_item[0].default_value)+"},", size_item[0].str_name)
|
||
else:
|
||
ret_str = ret_str + format_str.format(size_item[0].name, str(size_item[0].default_value)+",", size_item[0].str_name)
|
||
|
||
ret_str = ret_str + "};\n\n\n"
|
||
|
||
|
||
ret_str = ret_str + "const param_info_t %s_PARAM_INDEX_TABLE[%s_PARAM_NUM] =\n{\n"%(key.upper(),key.upper())
|
||
|
||
format_str = "{:<40} {:<30} {:<30} {:<30} {:<40} {:<50} {:<20} {:<20} {:<20} {:<30} {:<30} {:<40}\n"
|
||
for size_item in value["param_info_list"]:
|
||
ret_str = ret_str + format_str.format(" {.idx=PARA_IDX_%s"%size_item[0].name.upper()+",", ".identity="+str(size_item[0].DI)+",",
|
||
".store_type="+size_item[0].store_type+",", ".local_type="+str(size_item[0].local_type)+",",
|
||
".size="+size_item[0].size_string+",", ".offset="+"offsetof(%s_param_t, %s)"%(key.lower(),size_item[0].name)+",",
|
||
".ratio="+str(size_item[0].ratio)+",", ".min="+str(size_item[0].min)+",", ".max="+str(size_item[0].max)+",",
|
||
".check_func="+size_item[0].check_func+",", ".update_func="+size_item[0].updata_func+",},", "//"+size_item[0].str_name)
|
||
ret_str = ret_str + "};\n\n\n"
|
||
|
||
file_end = file_end_formate % (key.upper(), key.upper(),key.upper(),key.upper(),key.upper(),key.upper(),key.upper(),key.lower(),key.lower(),key.lower(),key.lower(),
|
||
value["param_data_unit"]["存储区域单分区大小"],
|
||
"PARA_IDX_%s"%value["param_info_list"][0][0].name.upper(),
|
||
"PARA_IDX_%s"%value["param_info_list"][value['param_num']["参数个数"]-1][0].name.upper(),
|
||
value["param_storage_unit"]["存储区域擦写单元"])
|
||
ret_str = ret_str + file_end
|
||
|
||
|
||
with open("%s/"%self.file_path+file_name, 'w', encoding="utf-8") as f:
|
||
f.write(ret_str)
|
||
|
||
def __generate_export(self):
|
||
'''生成interface.h的部分内容'''
|
||
file_title_formate = '''/*
|
||
* =====================================================================================
|
||
*
|
||
* Filename: param_defination.h
|
||
*
|
||
* Description:
|
||
*
|
||
* Version: 1.0
|
||
* Created: %s
|
||
* Revision: none
|
||
* Compiler: gcc
|
||
*
|
||
* Author: Autogenerated
|
||
* Organization: Topscomm
|
||
*
|
||
* =====================================================================================
|
||
*/
|
||
|
||
|
||
#ifndef __PARAM_DEFINATION_H__
|
||
#define __PARAM_DEFINATION_H__
|
||
|
||
#include <stdint.h>
|
||
|
||
/* ##### LOCAL INCLUDES #################################################### */
|
||
'''
|
||
file_title_formate = file_title_formate%(time.strftime("%d/%m/%Y %H:%M:%S"))
|
||
|
||
for t_item in self.config_set.items():
|
||
file_title_formate = file_title_formate + '#include {:<55} {}\n'.format('"param_defination/param_%s_defination.h"'%t_item[0].lower(), "/* %s参数个数及参数数据域大小 */" % t_item[0])
|
||
|
||
file_title_formate = file_title_formate + "\n/* ##### EXPORTED MACROS ######################################################## */\n"
|
||
|
||
ret_str = file_title_formate
|
||
|
||
for key, value in self.config_set.items():
|
||
ret_str = ret_str + "#define {:<25} {:<30} /* {}存储区域名 */\n".format(key.upper()+"_REGION_NAME", value['param_storage_name']['存储区域命名'], key.upper())
|
||
|
||
category_format = '''
|
||
|
||
/* ##### EXPORTED DATA TYPES #################################################### */
|
||
|
||
typedef enum
|
||
{
|
||
%s
|
||
PARAM_CATEGORY_MAX, /*参数表个数*/
|
||
}PARAM_CATEGORY_E; /* ---------- end of enum PARAM_CATEGORY_E ---------- */
|
||
|
||
'''
|
||
cat_str = ""
|
||
for key, value in self.config_set.items():
|
||
cat_str = cat_str + "{:<25} /*{}*/\n ".format(key.upper() + "_PARAM,",key)
|
||
|
||
ret_str = ret_str + category_format%cat_str
|
||
|
||
index_format = '''
|
||
typedef enum
|
||
{
|
||
%s
|
||
PARA_IDX_MAX, /*参数索引总个数*/
|
||
}PARAM_IDX_E; /* ---------- end of enum PARAM_IDX_E ---------- */
|
||
|
||
'''
|
||
index_str = ""
|
||
for key, value in self.config_set.items():
|
||
index_str = index_str + "\n /* %s */\n "%key
|
||
for size_item in value["param_info_list"]:
|
||
index_str = index_str + "{:<45} //{}\n ".format("PARA_IDX_"+size_item[0].name.upper()+",", size_item[0].str_name)
|
||
|
||
|
||
file_end = '''
|
||
#endif /* ----- #ifndef __PARAM_DEFINATION_H__ ----- */
|
||
|
||
'''
|
||
|
||
ret_str = ret_str + index_format%index_str + file_end
|
||
|
||
with open("%s/param_defination.h"%self.file_path, 'w', encoding="utf-8") as f:
|
||
f.write(ret_str)
|
||
|
||
def __generate_storage(self):
|
||
'''生成param_storage_config.c的部分内容'''
|
||
file_title_formate = '''/*
|
||
* =====================================================================================
|
||
*
|
||
* Filename: param_storage_config.c
|
||
*
|
||
* Description:
|
||
*
|
||
* Version: 1.0
|
||
* Created: %s
|
||
* Revision: none
|
||
* Compiler: gcc
|
||
*
|
||
* Author: Autogenerated
|
||
* Organization: Topscomm
|
||
*
|
||
* =====================================================================================
|
||
*/
|
||
|
||
#include "../param_storage/norflash_operation.h"
|
||
#include "../param_storage/eeprom_operation.h"
|
||
#include "../param_storage/file_system_operation.h"
|
||
#include "../param_storage/param_storage.h"
|
||
|
||
#if FILE_SYSTEM_EXIST
|
||
const char g_param_file_path_prefix[FILE_NAME_MAX_LEN]="%s"; /*存放参数文件的路径前缀*/
|
||
|
||
#define FILE_MAX_LEN (%s) /*文件最大长度*/
|
||
#endif
|
||
|
||
/* ##### VARIABLES - LOCAL TO THIS SOURCE FILE ################################ */
|
||
|
||
|
||
static const storage_info_t all_storage_info_table[PARAM_CATEGORY_MAX] =
|
||
{
|
||
'''
|
||
item_format=''' /* %s */
|
||
{
|
||
.ptr_name = %s_REGION_NAME,
|
||
.region = %s_PARAM,
|
||
#if FILE_SYSTEM_EXIST
|
||
.max_addr = 0+FILE_MAX_LEN - 1,
|
||
.min_addr = 0,
|
||
#else
|
||
.max_addr = %s,
|
||
.min_addr = %s,
|
||
#endif
|
||
|
||
.storage_read = %s_read,
|
||
.storage_write = %s_write,
|
||
.storage_clean = %s_clean,
|
||
},
|
||
'''
|
||
|
||
for t_item in self.config_set.items():
|
||
file_title_formate = file_title_formate%(time.strftime("%d/%m/%Y %H:%M:%S"),t_item[1]['file_path_prefix']['参数文件路径'],str(t_item[1]['param_data_unit']['存储区域单分区大小'])+ "*3")
|
||
break
|
||
|
||
for t_item in self.config_set.items():
|
||
file_title_formate = file_title_formate + item_format % (t_item[0].upper(),t_item[0].upper(), t_item[0].upper(),
|
||
str(t_item[1]['param_storage_addr']['存储区域基地址']) + "+" + str(t_item[1]['param_data_unit']['存储区域单分区大小'])+ "*3 - 1",
|
||
t_item[1]['param_storage_addr']['存储区域基地址'],
|
||
t_item[1]['storage_type']['存储器类型'],
|
||
t_item[1]['storage_type']['存储器类型'],
|
||
t_item[1]['storage_type']['存储器类型'])
|
||
|
||
|
||
file_end = '''
|
||
};
|
||
|
||
|
||
/* ##### FUNCTION DEFINITIONS - EXPORTED FUNCTIONS ############################ */
|
||
|
||
|
||
/*
|
||
* === FUNCTION ======================================================================
|
||
* Name: param_storage_get_info_table
|
||
* Description: 获取所有存储区域的汇总表,用于对存储区域进行检索
|
||
* =====================================================================================
|
||
*/
|
||
const storage_info_t* param_storage_get_info_table()
|
||
{
|
||
return &all_storage_info_table[0];
|
||
} /* ----- end of function param_storage_get_info_table ----- */
|
||
|
||
'''
|
||
ret_str = ""
|
||
ret_str = file_title_formate + file_end
|
||
|
||
with open("%s/param_storage_config.c"%self.file_path, 'w', encoding="utf-8") as f:
|
||
f.write(ret_str)
|
||
|
||
def generate_code_files(self, path):
|
||
'''
|
||
实际执行excel转代码,生成.c、.h、defination.h、param_export.h、
|
||
'''
|
||
self.file_path = path
|
||
self.__generate_definations()
|
||
self.__generate_internal_definations()
|
||
self.__generate_infomatin()
|
||
self.__generate_export()
|
||
self.__generate_storage()
|
||
|
||
def gen_param_info(content):
|
||
items = {}
|
||
|
||
match = re.search(r"offset=offsetof\(.*\)", content)
|
||
if match != None:
|
||
group_list = match.group().split("=")
|
||
items[group_list[0]] = group_list[1].split(", ")[1].strip(')')
|
||
else:
|
||
items["offset"] = ""
|
||
|
||
content = content.replace(".offset=offsetof(", "")
|
||
|
||
for item in content.split(","):
|
||
match = re.search(r"\..*=.*", item)
|
||
if match != None:
|
||
key_value = match.group().strip("}").strip(".").split('=')
|
||
items[key_value[0]] = key_value[1]
|
||
|
||
return items
|
||
|
||
class ParamCategory(object):
|
||
'''
|
||
用于存储从代码文件中读出的信息
|
||
cat_name:业务参数类型名称
|
||
base_addr:参数存储的基地址
|
||
data_size:参数数据存储的总大小(暂未使用)
|
||
param_num:当前类型中,参数的个数
|
||
backup_offset:备份之间的偏移
|
||
param_name_list:标识符列表
|
||
param_name_str_list:参数名称列表(汉字)
|
||
default_value:默认参数字典
|
||
index_table:默认索引表
|
||
exchange_size:存储区域擦写单元
|
||
'''
|
||
def __init__(self, cat_name):
|
||
'''
|
||
初始化代码文件信息,仅传入参数类型名,构造空的参数信息体
|
||
'''
|
||
self.cat_name = cat_name.upper()
|
||
self.base_addr = ""
|
||
self.data_size = 0
|
||
self.param_num = 0
|
||
self.backup_offset = ""
|
||
self.param_name_list=[]
|
||
self.param_name_str_list=[]
|
||
self.default_value={}
|
||
self.index_table=[]
|
||
self.storage_name=''
|
||
self.exchange_size = ""
|
||
|
||
def __str__(self):
|
||
'''
|
||
将对象转换为可打印的字符串
|
||
'''
|
||
ret = ""
|
||
ret = ret + "cat_name:\t" + self.cat_name + "\n"
|
||
ret = ret + "storage_name:\t" + self.storage_name + "\n"
|
||
ret = ret + "base_addr:\t"+ self.base_addr + "\n"
|
||
ret = ret + "data_size:\t"+ str(self.data_size) + "\n"
|
||
ret = ret + "param_num:\t"+ str(self.param_num) + "\n"
|
||
ret = ret + "backup_offset:\t"+ self.backup_offset + "\n"
|
||
ret = ret + "param_name_list"+ str(self.param_name_list) + "\n"
|
||
ret = ret + "param_name_str_list"+ str(self.param_name_str_list) + "\n"
|
||
ret = ret + "default_value"+ str(self.default_value) + "\n"
|
||
ret = ret + "index_table"+ str(self.index_table) + "\n"
|
||
ret = ret + "exchange_size:\t"+ self.exchange_size + "\n"
|
||
|
||
return ret
|
||
|
||
class CodeGeneration(object):
|
||
'''
|
||
将代码文件还原为excel文件
|
||
'''
|
||
categary_pattern = r'param_[a-z]*\.c'
|
||
|
||
def __find_param_category(self, path):
|
||
'''
|
||
找到path目录下可被逆向解析的文件,将可解析的文件构造成参数类型
|
||
'''
|
||
file_list = os.listdir(path)
|
||
cat_list = []
|
||
cat_temp_list = []
|
||
for file_item in os.listdir(path):
|
||
categary_pattern = r'param_[a-z]*\.c'
|
||
matches = re.search(categary_pattern, file_item)
|
||
if matches != None :
|
||
cat_temp_list.append(matches.group()[6:-2])
|
||
|
||
for cat_idx in cat_temp_list:
|
||
if "param_"+cat_idx+"_defination.h" in os.listdir(path) and "param_"+cat_idx+".h" in os.listdir(path):
|
||
cat_list.append(cat_idx)
|
||
|
||
return cat_list
|
||
|
||
def __build_local_info(self, path, cat_name):
|
||
'''
|
||
读取.h文件,通过.h文件构建存储基地址
|
||
'''
|
||
with open("%s/param_%s.h"%(path,cat_name.lower()), 'r', encoding="utf-8") as f:
|
||
param_h = f.read()
|
||
state = 0
|
||
for line in param_h.split('\n'):
|
||
line.strip()
|
||
|
||
if line.find("_PARAM_STORE_ADDR") != -1:
|
||
self.categorys[cat_name].base_addr = line.split("(")[1].split(')')[0].strip()
|
||
|
||
def __build_extern_info(self, path, cat_name):
|
||
'''
|
||
读取_defination.h文件,通过_defination.h文件构建各个参数的数据域大小
|
||
'''
|
||
with open("%s/param_%s_defination.h"%(path, cat_name.lower()), 'r', encoding="utf-8") as f:
|
||
param_h = f.read()
|
||
item_index = 0
|
||
state = 0
|
||
for line in param_h.split('\n'):
|
||
line.strip()
|
||
|
||
if line.find("_PARAM_NUM") != -1:
|
||
self.categorys[cat_name].param_num = int(line.split("(")[1].split(')')[0].strip())
|
||
|
||
categary_pattern = r'#define.*_SIZE.*\('
|
||
matches = re.search(categary_pattern, line)
|
||
if matches != None :
|
||
if self.categorys[cat_name].index_table[item_index]['size'] == line.split(' ')[1].split('(')[0].strip() :
|
||
if line.find("(sizeof(uint8_t))") != -1:
|
||
self.categorys[cat_name].index_table[item_index]['size'] = 1
|
||
elif line.find("(sizeof(int8_t))") != -1:
|
||
self.categorys[cat_name].index_table[item_index]['size'] = 1
|
||
elif line.find("(sizeof(uint16_t))") != -1:
|
||
self.categorys[cat_name].index_table[item_index]['size'] = 2
|
||
elif line.find("(sizeof(int16_t))") != -1:
|
||
self.categorys[cat_name].index_table[item_index]['size'] = 2
|
||
elif line.find("(sizeof(uint32_t))") != -1:
|
||
self.categorys[cat_name].index_table[item_index]['size'] = 4
|
||
elif line.find("(sizeof(int32_t))") != -1:
|
||
self.categorys[cat_name].index_table[item_index]['size'] = 4
|
||
elif line.find("(sizeof(uint64_t))") != -1:
|
||
self.categorys[cat_name].index_table[item_index]['size'] = 8
|
||
elif line.find("(sizeof(int64_t))") != -1:
|
||
self.categorys[cat_name].index_table[item_index]['size'] = 8
|
||
elif line.find("(sizeof(float))") != -1:
|
||
self.categorys[cat_name].index_table[item_index]['size'] = 4
|
||
elif line.find("(sizeof(double))") != -1:
|
||
self.categorys[cat_name].index_table[item_index]['size'] = 8
|
||
else:
|
||
self.categorys[cat_name].index_table[item_index]['size'] = int(line.split('(')[1].split(')')[0])
|
||
item_index = item_index + 1
|
||
|
||
|
||
def __build_list(self, path, cat_name):
|
||
'''
|
||
读取.c文件,通过.c文件构建各个参数的数据域的名称、名字、各索引项、默认值等
|
||
'''
|
||
with open("%s/param_%s.c"%(path, cat_name.lower()), 'r', encoding="utf-8") as f:
|
||
param_h = f.read()
|
||
state = 0
|
||
for line in param_h.split('\n'):
|
||
line.strip()
|
||
|
||
if line.find(".backup_offset") != -1:
|
||
self.categorys[cat_name].backup_offset = int(line.split(",")[0].split('=')[1].strip())
|
||
|
||
if line.find(".exchange_size") != -1:
|
||
self.categorys[cat_name].exchange_size = int(line.split(",")[0].split('=')[1].strip())
|
||
|
||
if state == 1 :
|
||
if line.startswith("};") != True :
|
||
if line.startswith("{") != True:
|
||
if line.find("}") == -1:
|
||
self.categorys[cat_name].default_value[line.split('=')[0].strip().strip(".")] = line.split("=")[1].split(",")[0].strip()
|
||
self.categorys[cat_name].param_name_str_list.append(line.split(',')[1].strip().strip("/"))
|
||
else:
|
||
self.categorys[cat_name].default_value[line.split('=')[0].strip().strip(".")] = line.split("{")[1].split("}")[0]
|
||
self.categorys[cat_name].param_name_str_list.append(line.split('},')[1].strip().strip("/"))
|
||
self.categorys[cat_name].param_name_list.append(line.split('=')[0].strip().strip("."))
|
||
else:
|
||
state = 0
|
||
|
||
if state == 2 :
|
||
if line.startswith("};") != True :
|
||
if line.startswith("{") != True:
|
||
self.categorys[cat_name].index_table.append(gen_param_info(line))
|
||
else:
|
||
state = 0
|
||
|
||
if line.startswith("const") and line.find("PARAM_DEFAULT_VALUE_TABLE") != -1:
|
||
state = 1
|
||
|
||
if line.startswith("const") and line.find("PARAM_INDEX_TABLE") != -1:
|
||
state = 2
|
||
|
||
def __build_export(self, path):
|
||
with open("%s/param_defination.h"%(path), 'r', encoding="utf-8") as f:
|
||
param_h = f.read()
|
||
state = 0
|
||
for line in param_h.split('\n'):
|
||
line.strip()
|
||
|
||
if line.find("_REGION_NAME") != -1:
|
||
self.storage_name_list[line.split("_REGION_NAME")[0].strip().split(' ')[1].lower()] = line.split("_REGION_NAME")[1].strip().split(' ')[0]
|
||
if line.find("_PARAM,") != -1:
|
||
self.cat_list.append(line.strip().split(',')[0].split('_')[0].upper())
|
||
|
||
def __build_storage(self, path):
|
||
with open("%s/param_storage_config.c"%(path), 'r', encoding="utf-8") as f:
|
||
param_c = f.read()
|
||
state = 0
|
||
self.storage_type = param_c.split("};")[0].split("all_storage_info_table")[1].split("},")[0].split(".storage_read")[1].split(".storage_write")[0].strip('= ').split("_read")[0]
|
||
self.file_path_prefix = param_c.split("]=\"")[1].split("\";")[0]
|
||
|
||
def __init__(self, path):
|
||
'''
|
||
传入路径path,解析路径下的代码文件,找到能够解析成参数类型的三种文件:param_*.h、param_*_defination.h、param_*.c
|
||
将找到的可被解析的文件构造成参数类型信息体,并写入到excel文件中。
|
||
'''
|
||
cat_list = self.__find_param_category(path)
|
||
self.cat_list = []
|
||
self.storage_name_list = {}
|
||
self.categorys = {}
|
||
self.storage_type = {}
|
||
self.__build_export(path)
|
||
self.__build_storage(path)
|
||
for cat_name in cat_list:
|
||
self.categorys[cat_name] = ParamCategory(cat_name)
|
||
self.__build_list(path, cat_name)
|
||
self.__build_extern_info(path, cat_name)
|
||
self.__build_local_info(path, cat_name)
|
||
|
||
def gen_data_file(self):
|
||
'''
|
||
实际执行将读取到的参数信息写入到xlsx文件中,文件名为"param_output.xlsx"
|
||
'''
|
||
wb = openpyxl.Workbook()
|
||
|
||
wb.remove(wb[wb.sheetnames[0]])
|
||
|
||
''' 单元格填充黄色 '''
|
||
fill = openpyxl.styles.PatternFill("solid", fgColor="FFFF00")
|
||
|
||
cell_name_list = ["序号", "唯一码(DI、点号等)", "参数名", "参数标识符", "参数存储类型", "参数数据大小(字节数)", "默认值", "对象解析类型", "缩放倍数", "参数最小值", "参数最大值", "参数标记", "参数有效性检查", "参数配置后回调", "注释"]
|
||
for sheet in codes.cat_list:
|
||
if sheet not in wb.sheetnames:
|
||
wb.create_sheet(sheet)
|
||
|
||
wb[sheet]["C1"].value = '存储区域基地址'
|
||
wb[sheet]["D1"].value = self.categorys[sheet.lower()].base_addr
|
||
wb[sheet]["C2"].value = '存储区域命名'
|
||
wb[sheet]["D2"].value = self.storage_name_list[sheet.lower()]
|
||
wb[sheet]["C3"].value = '存储区域擦写单元'
|
||
wb[sheet]["D3"].value = self.categorys[sheet.lower()].exchange_size
|
||
wb[sheet]["C4"].value = '存储区域单分区大小'
|
||
wb[sheet]["D4"].value = self.categorys[sheet.lower()].backup_offset
|
||
wb[sheet]["C5"].value = '参数个数'
|
||
wb[sheet]["D5"].value = self.categorys[sheet.lower()].param_num
|
||
wb[sheet]["C6"].value = '是否需要RAM参数对象'
|
||
wb[sheet]["D6"].value = 'true/false'
|
||
wb[sheet]["C7"].value = '存储器类型'
|
||
wb[sheet]["D7"].value = self.storage_type
|
||
wb[sheet]["C8"].value = '参数文件路径'
|
||
wb[sheet]["D8"].value = self.file_path_prefix
|
||
wb[sheet]["E8"].value = '注释:当存储器类型为fs时,需要填写参数文件路径'
|
||
|
||
''' 单元格填充黄色 '''
|
||
wb[sheet]["C1"].fill = fill
|
||
wb[sheet]["C2"].fill = fill
|
||
wb[sheet]["C3"].fill = fill
|
||
wb[sheet]["C4"].fill = fill
|
||
wb[sheet]["C5"].fill = fill
|
||
wb[sheet]["C6"].fill = fill
|
||
wb[sheet]["C7"].fill = fill
|
||
wb[sheet]["C8"].fill = fill
|
||
|
||
for i in range(1, 16):
|
||
wb[sheet].cell(row = 11, column = i, value = cell_name_list[i-1])
|
||
wb[sheet].cell(row = 11, column = i).fill = fill
|
||
|
||
for i in range(0, int(self.categorys[sheet.lower()].param_num)):
|
||
wb[sheet].cell(row = 12+i, column = 1, value = i+1)
|
||
wb[sheet].cell(row = 12+i, column = 2, value = self.categorys[sheet.lower()].index_table[i]['identity'])
|
||
wb[sheet].cell(row = 12+i, column = 3, value = self.categorys[sheet.lower()].param_name_str_list[i])
|
||
wb[sheet].cell(row = 12+i, column = 4, value = self.categorys[sheet.lower()].param_name_list[i])
|
||
wb[sheet].cell(row = 12+i, column = 5, value = self.categorys[sheet.lower()].index_table[i]['store_type'])
|
||
wb[sheet].cell(row = 12+i, column = 6, value = self.categorys[sheet.lower()].index_table[i]['size'])
|
||
wb[sheet].cell(row = 12+i, column = 7, value = self.categorys[sheet.lower()].default_value[self.categorys[sheet.lower()].index_table[i]['offset']])
|
||
wb[sheet].cell(row = 12+i, column = 8, value = self.categorys[sheet.lower()].index_table[i]['local_type'])
|
||
wb[sheet].cell(row = 12+i, column = 9, value = self.categorys[sheet.lower()].index_table[i]['ratio'])
|
||
wb[sheet].cell(row = 12+i, column = 10, value = self.categorys[sheet.lower()].index_table[i]['min'])
|
||
wb[sheet].cell(row = 12+i, column = 11, value = self.categorys[sheet.lower()].index_table[i]['max'])
|
||
wb[sheet].cell(row = 12+i, column = 12, value = "0")
|
||
wb[sheet].cell(row = 12+i, column = 13, value = self.categorys[sheet.lower()].index_table[i]['check_func'])
|
||
wb[sheet].cell(row = 12+i, column = 14, value = self.categorys[sheet.lower()].index_table[i]['update_func'])
|
||
wb[sheet].cell(row = 12+i, column = 15, value = "")
|
||
|
||
wb.save("tools/param_output.xlsx")
|
||
|
||
|
||
if __name__ == '__main__':
|
||
try:
|
||
opts, args = getopt.getopt(sys.argv[1:],"hgr")
|
||
except getopt.GetoptError:
|
||
print('param_code_automation.py -h -g -r')
|
||
sys.exit(2)
|
||
for opt, arg in opts:
|
||
if opt == '-h':
|
||
print('param_code_automation.py -h -g -r')
|
||
print(' -h for help')
|
||
print(' -g for generate param code, need param_input.xlsx')
|
||
print(' -r for generate excel, output file name is param_output.xlsx\n')
|
||
sys.exit()
|
||
elif opt in ("-g"):
|
||
#执行以下代码,从param_input.xlsx生成代码
|
||
storage_cofnig = StorageConfig()
|
||
storage_cofnig.generate_code_files("tools/param_code_generation/param/param_defination")
|
||
sys.exit()
|
||
elif opt in ("-r"):
|
||
##执行一下代码,从讲代码目录逆向为param_output.xlsx
|
||
codes = CodeGeneration("param/param_defination")
|
||
codes.gen_data_file()
|
||
sys.exit()
|