首先你得有一个模板,通过python脚本打开编译后的.map文件自动填写到A2L文件对应位置,目前只实现了填写Mesurement 区域,但是这个填写主要是更新变量名和对应的ECU ADRRESS,因为.map文件不包含更多的信息。
.sdata : AT (__SDATA_ROM)
{
. = ALIGN(4);
__SDATA_RAM = .;
__sdata_start__ = .; /* Create a global symbol at sdata start. */
*(.sdata)
*(.sdata.*)
. = ALIGN(4);
__sdata_end__ = .; /* Define a global symbol at sdata end. */
} > m_data
__SDATA_END = __SDATA_ROM + (__sdata_end__ - __sdata_start__);
.mesurement_sec : AT (__SDATA_END)
{
. = ALIGN(4);
__me_start__ = .; /* Create a global symbol at sdata start. */
*(.mesurement_work_page)
*(.mesurement_work_page.*)
. = ALIGN(4);
__me_end__ = .; /* Define a global symbol at sdata end. */
} > m_data
__ME_END = __SDATA_END + (__me_end__ - __me_start__);
这样生成的.map文件中
.mesurement_sec
0x40001474 0x18 load address 0x0100ccc8
0x40001474 . = ALIGN (0x4)
0x40001474 __me_start__ = .
*(.mesurement_work_page)
.mesurement_work_page
0x40001474 0x18 ./Sources/main.o
0x40001474 test1
0x40001484 adc_test
0x40001488 hehe
*(.mesurement_work_page.*)
0x4000148c . = ALIGN (0x4)
0x4000148c __me_end__ = .
0x0100cce0 __ME_END = (__SDATA_END + (__me_end__ - __me_start__))
包含了这样的信息,我在这里定义了test1,adc_test1,hehe三个测试变量,但是变量的类型等是没有信息的,所以你只能通过map file 更新A2L中的变量名和ECU ADRR ,如果你是基于模型的开发,你可以在simulink中定义完整的变量信息,并且通过asap2post函数进行更新(不知道为什么我更新失败,所以才自己写个脚本来完成这样的事)
下面直接上Python code
import re
from copy import deepcopy
class Map_to_A2L(object):
def __init__(self):
self.__mapfile_buf=[]
self.__a2lfile_buf=[]
self.mapfile_adrr="C:/Users/wangk/Desktop/S32DS_WORK_PA/busoff/busoff.map"
self.a2lfile_adrr="C:/Users/wangk/Desktop/S32DS_WORK_PA/busoff/MPC5744P.a2l"
self.__measurement_vars_list=[]
self.__a2file_buflen_previous=0
self.__insert_pos=0
self.measurement_sec_template=" /begin MEASUREMENT"+"\n"+" name"+"\n"+" \"this is for test\""\
+"\n"+" FLOAT32_IEEE"+"\n"+" none"+"\n"+" 0"+"\n"+" 0"+"\n"\
+" 0"+"\n"+" 0"+"\n"+" ECU Address"+" "+"0X32"+"\n"+\
" /end MEASUREMENT"+"\r\n"
def __open_and_get_mapfile(self):
with open(self.mapfile_adrr, mode="rb") as f:
while True:
line = f.readline().decode('ascii', 'ignore')
if not line:
break
else:
self.__mapfile_buf.append(line)
def __get_info_from_map_file(self):
row = 0
buf_measurement_index = []
while row != len(self.__mapfile_buf):
if re.findall(r"r*(.mesurement_work_page)", self.__mapfile_buf[row], re.I):
buf_measurement_index.append(row)
row = row + 1
buf_measurement_index = buf_measurement_index[1:]
measurement_dict = {"Name": None, "ECU Address": None}
for i in range(len(buf_measurement_index)):
if i == len(buf_measurement_index) - 1:
break
index1 = buf_measurement_index[i]
index2 = buf_measurement_index[i + 1]
for j in range(index1 + 2, index2):
dict_ = deepcopy(measurement_dict)
data = self.__mapfile_buf[j].replace("\r\n", "").strip().split()
dict_["Name"] = data[1]
dict_["ECU Address"] = data[0]
self.__measurement_vars_list.append(dict_)
def __open_and_get_a2l_file(self): #store origin a2l file in buf and then rewrite it(I consider to use the default template and create a new a2l file in the same folder as mapfile)
with open(self.a2lfile_adrr, mode="r") as f:
while True:
line = f.readline()
if not line:
self.__a2file_buflen_previous=len(self.__a2lfile_buf)
break
else:
self.__a2lfile_buf.append(line)
def __del_old_measurement_sec_in_a2l_file(self): #find measurement sectors in origin or default a2l file and delete them (just in buf not in file)
a2l_buf_index = []
index=0
for line in self.__a2lfile_buf:
if re.findall(r'/begin MEASUREMENT',line,re.I) or re.findall(r'/end MEASUREMENT',line,re.I):
a2l_buf_index.append(index)
index=index+1
if len(a2l_buf_index) >=2 and len(a2l_buf_index)%2==0:
del self.__a2lfile_buf[a2l_buf_index[0]:a2l_buf_index[-1]+1]
a2file_buflen_change=self.__a2file_buflen_previous-len(self.__a2lfile_buf)-2
self.__insert_pos=a2l_buf_index[-1] - a2file_buflen_change
def __update_a2l_buf(self):
for i in range(len(self.__measurement_vars_list)):
name=self.__measurement_vars_list[i]["Name"]
ECU_ADRR=self.__measurement_vars_list[i]["ECU Address"]
self.__a2lfile_buf.insert(self.__insert_pos+i, self.measurement_sec_template.replace("name",name).replace("0X32",ECU_ADRR))
def __update_a2lfile(self):
with open(self.a2lfile_adrr, mode="w") as f:
for line in self.__a2lfile_buf:
f.write(line)
def exchange(self):
self.__open_and_get_mapfile()
if len(self.__mapfile_buf) >=1:
self.__get_info_from_map_file()
else:
print("map为空")
self.__open_and_get_a2l_file()
if len(self.__a2lfile_buf) >=1:
self.__del_old_measurement_sec_in_a2l_file()
else:
print("a2l文件为空")
self.__update_a2l_buf()
if len(self.__a2lfile_buf) >=10:
self.__update_a2lfile()
else:
print("你妈卖批")
ob=Map_to_A2L()
ob.exchange()
简单的实现了下功能,后续会添加GUI(基于PYQT5),可以选择文件夹和文件,添加对标定变量,内存分区信息的支持(虽然现在还没搞懂这部分在A2L文件的作用,没办法,没有CANAPE),仅供学习参考交流,python我也是用的时候学一点,不是很熟,但是写OOP真的是完爆C。