本篇文章针对map文件进行解析,提取各个模块数据资源使用情况,包括ram、flash等占用大小问题,并可针对使用情况进行优化代码,提高开发效率。

以下是python代码示例:

代码原理讲解:将map文件按行进行解析,根据关键字进行划分段,比如Image Summary 、Module Summary,然后再解析每个段内数据,将解析的数据写入excel表中。在统计Module Summary内容时,只有每个.c.o文件的信息,需要将其进行分类(看看自己的.c文件属于哪个模块),将属于同一个模块的.c.o文件统计到一起,这样就可以知道自己的每个模块占用空间大小了。

from prettytable import PrettyTable
import xlwt
import sys
import os
import datetime

MAP_FILE_NAME = "output/app/gendata/app.map"
XLS_FILE_NAME = "./EOP app Mapping Summary%s.xls"%datetime.datetime.now().strftime("%Y%m%d%H%M%S")
workbook = xlwt.Workbook(encoding="utf-8")

BLACK_LIST = ["debug", "ghrettbl", "ghcalltbl", "ghtailcalltbl", "gstackfix"]

RAM_ADDRESS_RANGE = {"PSRAM_DSARM":[0x18000000,0x18004000,0x4000]} #start,end,size=16kB

ROM_ADDRESS_RANGE = {"FLASH0":[0x11000000,0x11000600,0x6000],  #start,end,size=24kB
                        "FLASH1":[0x12002000,0x12020000,0x20000],  #start,end,size=128kB
                        }

BSWMODULE_D_CODE ={
    "CanIf":["CanIf_Cfg.c.o","CanIf_PBcfg.c.o"],
    "CanSM":["CanSM_Cfg.c.o"],
    "CanTp": ["CanTp_Callout.c.o","CanTp_Cfg.c.o","CanTp_PBcfg.c.o"],
    "Com": ["Com_Internal_Cbk.c.o","Com_Mainfunc.c.o","Com_PBcfg.c.o"],
    "Dcm": ["Dcm_Callout.c.o","Dcm_Cfg.c.o","Dcm_PBcfg.c.o","Rte_Dcm.c.o"],
    "EcuM": ["EcuM_Cfg.c.o"],
    "PduR": ["PduR_Cfg.c.o","PduR_PBcfg.c.o","PduR_Var.c.o"],
    "Os":["Os_Callout_Stubs.c.o","Os_Counter_Cfg.c.o","Os_Resource_Cfg.c.o",
          "Os_Hal_Cfg.c.o","Os_Hal_Timer.c.o",
          "Os_Hal_Vec.S.obj",
          "Os_Isr_Cfg.c.o","Os_Stack_Cfg.c.o",
          "Os_Task_Cfg.c.o","os_user.c.o",
          "tx_user.c.o"],
    "tle9891": ["IsrEntrySrc.c.o"],
}
BSWMODULE_S_CODE ={
    "CanIf":["libCanIf.a"],
    "CanSM":["libCanSM.a"],
    "CanTp": ["libCanTp.a"],
    "Com": ["libCom.a"],
    "Dcm": ["libDcm.a"],
    "EcuM": ["libEcuM.a"],
    "PduR": ["libPduR.a"],
    "Os": ["libos.a"],
    "soc": ["libtle9891.a"],
    "print": ["libprint.a"],
    "threadx": ["libthreadx.a"],
    "tx_cortex_m3_ghs": ["libtx_cortex_m3_ghs.a"],
    "ghs": ["libansi.a",
            "libwc_u16.a",
            "libmath_sf.a",
            "libind_sf.a",
            "libstartup.a",
            "libsys.a",
            "libarch.a",
            ],
}

APP_CDD_CODE ={
    "appl": ["libappl.a"],
    "asw": ["libasw.a"],
    "cdd": ["libcdd.a"],
    "rte": ["librte.a"],
    "motor": ["libmotor.a"],
    "mcal": ["libconfig.a"],
}

def getcurrentpath(filepath):
    #current_filepath = os.path.abspath(__file__)
    current_filepath = sys.argv[0]
    current_path = os.path.dirname(current_filepath)
    realpath = os.path.join(current_path, filepath)
    normpath = os.path.normpath(realpath)
    return normpath

class SummaryPrinter:
    lines = []
    table = ""

    def __init__(self, lines):
        self.info_group = []
        self.lines = lines
        self.find()
        self.process()
        self.print()

    def find(self):
        pass

    def process(self):
        pass

    def print(self):
        if len(self.info_group) > 0:
            for info in self.info_group:
                self.table.add_row(info)
        print(self.table)

    @staticmethod
    def calculate_mbyte_size(size: int):
        return "{:.3f}".format(size / (1024 * 1024)) + " MB"

    @staticmethod
    def calculate_kbyte_size(size: int):
        return "{:.3f}".format(size / 1024) + " KB"

    @staticmethod
    def calculate_byte_size(size: int):
        return str(size) + " B"


class ImageSummaryPrinter(SummaryPrinter):
    lines = []
    start_line = 0
    end_line = 0
    RAM_ADDRESS_RANGE = RAM_ADDRESS_RANGE
    ROM_ADDRESS_RANGE = ROM_ADDRESS_RANGE
    BLACK_LIST = BLACK_LIST

    table = PrettyTable()
    info_group = []

    def find(self):
        start_line = 0
        end_line = 0
        for index in range(len(self.lines)):
            if "Image Summary" in self.lines[index]:
                start_line = index + 3
            if "Module Summary" in self.lines[index]:
                end_line = index - 3
        if start_line < end_line:
            self.start_line = start_line
            self.end_line = end_line
        else:
            print("<Image Summary> is missing!")

    def process(self):
        number = 1
        total = 0
        percent = 0

        for line_index in range(self.start_line, self.end_line):
            items = self.lines[line_index].split(" ")
            keys = []

            for item in items:
                if item != "":
                    keys.append(item)

            Section = keys[0]
            Base = "0x" + keys[1]
            DecSize = int(keys[3])
            SecOffs = "0x" + keys[4]
            SecOffs = str(SecOffs).replace("\n", "")

            # 排除法
            valid = True

            # 长度
            if int(DecSize) <= 0:
                valid = False

            # 黑名单
            for black in self.BLACK_LIST:
                if black in Section:
                    valid = False

            # 添加信息
            if valid:
                total += int(DecSize)
                self.info_group.append([number, Section, Base, DecSize, SecOffs, total, percent])

                number += 1

        # 计算百分比
        ramsize = 0
        flash0size = 0
        flash1size = 0
        
        for info in self.info_group:
            
            address = int(info[2],16)
            for ramname,addrange in self.RAM_ADDRESS_RANGE.items():
                if address >= addrange[0] and address < addrange[1]:
                    info[6] = '{:.2f}%'.format(info[3] / addrange[2] * 100)
                    ramsize += info[3]

            for ramname,addrange in self.ROM_ADDRESS_RANGE.items():
                if address >= addrange[0] and address < addrange[1]:
                    info[6] = '{:.2f}%'.format(info[3] / addrange[2] * 100)
                    if  ramname == "FLASH0":
                        flash0size += info[3]
                    if  ramname == "FLASH1":
                        flash1size += info[3]
                        

        total_size = self.info_group[len(self.info_group) - 1][5]
        PlatformImageSummary = [["Image Summary ( Total = " + super().calculate_byte_size(total_size) + \
                                                      " = " + super().calculate_mbyte_size(total_size) + \
                                                       "=" + super().calculate_kbyte_size(total_size) + " )"]]
        
        
        RamSummary = [["Ram ( Total = " + super().calculate_byte_size(ramsize) + \
                                                      " = " + super().calculate_mbyte_size(ramsize) + \
                                                       "=" + super().calculate_kbyte_size(ramsize) + " )"]]
        Flash0Summary = [["Flash0 ( Total = " + super().calculate_byte_size(flash0size) + \
                                                      " = " + super().calculate_mbyte_size(flash0size) + \
                                                       "=" + super().calculate_kbyte_size(flash0size) + " )"]]
        Flash1Summary = [["Flash1 ( Total = " + super().calculate_byte_size(flash1size) + \
                                                      " = " + super().calculate_mbyte_size(flash1size) + \
                                                       "=" + super().calculate_kbyte_size(flash1size) + " )"]]
        
        # workbook = xlwt.Workbook(encoding="utf-8")
        sheet = workbook.add_sheet("Image Summary")
        for col,colum in enumerate(['No', 'Section', 'Base', 'DecSize', 'SecOffs', 'Total', "Percent"]):
            sheet.write(0,col,colum)
        for row,data in enumerate(self.info_group):
            for col,colun_data in enumerate(data):
                sheet.write(row+1,col,colun_data)
        for row, data in enumerate(PlatformImageSummary):
            for col, colun_data in enumerate(data):
                sheet.write(len(self.info_group) + 1, col, colun_data)
        for row, data in enumerate(RamSummary):
            for col, colun_data in enumerate(data):
                sheet.write(len(self.info_group) + 2, col, colun_data)
        for row, data in enumerate(Flash0Summary):
            for col, colun_data in enumerate(data):
                sheet.write(len(self.info_group) + 3, col, colun_data)
        for row, data in enumerate(Flash1Summary):
            for col, colun_data in enumerate(data):
                sheet.write(len(self.info_group) + 4, col, colun_data)

        workbook.save(getcurrentpath(XLS_FILE_NAME))

    def print(self):
        self.table = PrettyTable(['No', 'Section', 'Base', 'DecSize', 'SecOffs', 'Total', "Percent"])
        total_size = self.info_group[len(self.info_group) - 1][5]
        PrettyTable.title = "Image Summary ( Total = " + super().calculate_byte_size(total_size) + \
                            " = " + super().calculate_mbyte_size(total_size) + " )"
        #super().print()
class ModuleSummaryPrinter(SummaryPrinter):
    lines = []
    start_line = 0
    end_line = 0
    ofilegroup = []

    table = PrettyTable()
    module_list = {}
    info_group = []
    app_cdd_group = []
    gendata_group = []
    system_lib_group = []
    total = 0
    RAM_ADDRESS_RANGE = RAM_ADDRESS_RANGE
    ROM_ADDRESS_RANGE = ROM_ADDRESS_RANGE

    def find(self):
        start_line = 0
        end_line = 0
        for index in range(len(self.lines)):
            if "Module Summary" in self.lines[index]:
                start_line = index + 3
            if "Global Symbols" in self.lines[index]:
                end_line = index - 3
        if start_line < end_line:
            self.start_line = start_line
            self.end_line = end_line
        else:
            print("<Module Summary> is missing!")

    def process(self):
        for line_index in range(self.start_line, self.end_line):
            items = self.lines[line_index].split(" ")
            keys = []

            for item in items:
                if item != '':
                    keys.append(item)

            if "+" in items[0]:
                info = keys[0].split("+")
                address = int("0x" + info[0],16)
                size = int(info[1], 16)

                if len(keys) == 3:
                    keys[2] = str(keys[2]).replace("\n", "")
                    self.ofilegroup.append(keys[2])
                    #keys[2] = str(keys[2]).replace(".o", "")
                    if keys[2] not in self.module_list:
                        self.module_list[keys[2]] = {}
                        self.module_list[keys[2]]["ram"] = 0
                        self.module_list[keys[2]]["rom"] = 0
                        self.module_list[keys[2]]["total"] = 0

                    for ramname,addrange in self.RAM_ADDRESS_RANGE.items():
                        if address >= addrange[0] and address < addrange[1]:
                            self.module_list[keys[2]]["ram"] += size
                            self.module_list[keys[2]]["total"] += size

                    for ramname,addrange in self.ROM_ADDRESS_RANGE.items():
                        if address >= addrange[0] and address < addrange[1]:
                            self.module_list[keys[2]]["rom"] += size
                            self.module_list[keys[2]]["total"] += size

                if len(keys) == 5:
                    keys[4] = str(keys[4]).replace("\n", "")
                    self.ofilegroup.append(keys[4])
                    if keys[4] not in self.module_list:
                        self.module_list[keys[4]] = {}
                        self.module_list[keys[4]]["ram"] = 0
                        self.module_list[keys[4]]["rom"] = 0
                        self.module_list[keys[4]]["total"] = 0

                    for ramname,addrange in self.RAM_ADDRESS_RANGE.items():
                        if address >= addrange[0] and address < addrange[1]:
                            self.module_list[keys[4]]["ram"] += size
                            self.module_list[keys[4]]["total"] += size

                    for ramname,addrange in self.ROM_ADDRESS_RANGE.items():
                        if address >= addrange[0] and address < addrange[1]:
                            self.module_list[keys[4]]["rom"] += size
                            self.module_list[keys[4]]["total"] += size
                if len(keys) == 2 or len(keys) == 1 or len(keys) == 4 :
                    pass
        
        #统计 SWC BSW SUBSYS TotalSize
        BSWnumber = 1
        self.total = 0
        self.ramtotal = 0
        self.romtotal = 0
        for key, item in self.module_list.items():
            info = [BSWnumber, key, item["ram"], item["rom"], item["total"]]
            BSWnumber += 1
            self.total += item["total"]
            self.ramtotal += item["ram"]
            self.romtotal += item["rom"]
            self.info_group.append(info)
            #app
            for module,libnames in  APP_CDD_CODE.items():
                for libname in libnames:
                    if libname in key:
                        info1 = [BSWnumber, key, item["ram"], item["rom"], item["total"],module]
                        self.app_cdd_group.append(info1)
            #gendata
            for module,libnames in  BSWMODULE_D_CODE.items():
                for libname in libnames:
                    if libname in key:
                        info1 = [BSWnumber, key, item["ram"], item["rom"], item["total"],module]
                        self.gendata_group.append(info1)
            #noah lib
            for module,libnames in  BSWMODULE_S_CODE.items():
                for libname in libnames:
                    if libname in key:
                        info1 = [BSWnumber, key, item["ram"], item["rom"], item["total"],module]
                        self.system_lib_group.append(info1)
                    
        BSWModuleSummary= [["BSW Module Summary ( Total = " + super().calculate_kbyte_size(self.total) + \
                            " ram = " + super().calculate_kbyte_size(self.ramtotal) + \
                            " rom = " + super().calculate_kbyte_size(self.romtotal) + " )"]]
        #输出excel
        # workbook = xlwt.Workbook(encoding="utf-8")
        sheet = workbook.add_sheet("Module Summary")
        for col,colum in enumerate(['No', 'Name', 'Ram', 'Rom', 'Total']):
            sheet.write(0,col,colum)
        for row,data in enumerate(self.info_group):
            for col,colun_data in enumerate(data):
                sheet.write(row+1,col,colun_data)
        for row, data in enumerate(BSWModuleSummary):
            for col, colun_data in enumerate(data):
                sheet.write(len(self.info_group) + 5, col, colun_data)
        workbook.save(getcurrentpath(XLS_FILE_NAME))
        
        #分类
        sheet = workbook.add_sheet("Module Summary1")
        for col,colum in enumerate(['No', 'Name', 'Ram', 'Rom', 'Total','Module']):
            sheet.write(0,col,colum)
        # app
        sumrow =0
        for row,data in enumerate(self.app_cdd_group):
            for col,colun_data in enumerate(data):
                sheet.write(row+1,col,colun_data)
            sumrow = sumrow +1
        # gendata
        for row,data in enumerate(self.gendata_group):
            for col,colun_data in enumerate(data):
                sheet.write(sumrow+1,col,colun_data)
            sumrow = sumrow +1
        # noah lib
        for row,data in enumerate(self.system_lib_group):
            for col,colun_data in enumerate(data):
                sheet.write(sumrow+1,col,colun_data)
            sumrow = sumrow +1
        workbook.save(getcurrentpath(XLS_FILE_NAME))
        
        #汇总 统计每个模块数据总大小
        app_dict = {}
        gendata_dict = {}
        syslib_dict = {}
        #app
        for index,data in enumerate(self.app_cdd_group):
            if data[5] not in app_dict:
                app_dict[data[5]] = {}
                app_dict[data[5]]["ram"] = 0
                app_dict[data[5]]["rom"] = 0
                app_dict[data[5]]["total"] = 0
            #
            app_dict[data[5]]["no"] = data[0]
            app_dict[data[5]]["name"] = ""
            app_dict[data[5]]["ram"] += data[2]
            app_dict[data[5]]["rom"] += data[3]
            app_dict[data[5]]["total"] += data[4]
            app_dict[data[5]]["module"] = data[5]
        #gendata
        for index,data in enumerate(self.gendata_group):
            if data[5] not in gendata_dict:
                gendata_dict[data[5]] = {}
                gendata_dict[data[5]]["ram"] = 0
                gendata_dict[data[5]]["rom"] = 0
                gendata_dict[data[5]]["total"] = 0
            #
            gendata_dict[data[5]]["no"] = data[0]
            gendata_dict[data[5]]["name"] = ""
            gendata_dict[data[5]]["ram"] += data[2]
            gendata_dict[data[5]]["rom"] += data[3]
            gendata_dict[data[5]]["total"] += data[4]
            gendata_dict[data[5]]["module"] = data[5]
        #sys lib
        for index,data in enumerate(self.system_lib_group):
            if data[5] not in syslib_dict:
                syslib_dict[data[5]] = {}
                syslib_dict[data[5]]["ram"] = 0
                syslib_dict[data[5]]["rom"] = 0
                syslib_dict[data[5]]["total"] = 0
            #
            syslib_dict[data[5]]["no"] = data[0]
            syslib_dict[data[5]]["name"] = ""
            syslib_dict[data[5]]["ram"] += data[2]
            syslib_dict[data[5]]["rom"] += data[3]
            syslib_dict[data[5]]["total"] += data[4]
            syslib_dict[data[5]]["module"] = data[5]
            
        number =0
        sheet = workbook.add_sheet("classified Summary")
        for col,colum in enumerate(['No', 'Name', 'Ram', 'Rom', 'Total','Module']):
            sheet.write(0,col,colum)
        number = number + 1
        sheet.write(number,0,'app_cdd:')
        number = number + 1
        for row,data in enumerate(app_dict):
            sheet.write(number,0,number)
            sheet.write(number,1,app_dict[data]['name'])
            sheet.write(number,2,app_dict[data]['ram'])
            sheet.write(number,3,app_dict[data]['rom'])
            sheet.write(number,4,app_dict[data]['total'])
            sheet.write(number,5,app_dict[data]['module'])
            number = number + 1
        sheet.write(number,0,'gendata:')
        number = number + 1
        for row,data in enumerate(gendata_dict):
            sheet.write(number,0,number)
            sheet.write(number,1,gendata_dict[data]['name'])
            sheet.write(number,2,gendata_dict[data]['ram'])
            sheet.write(number,3,gendata_dict[data]['rom'])
            sheet.write(number,4,gendata_dict[data]['total'])
            sheet.write(number,5,gendata_dict[data]['module'])
            number = number + 1
        sheet.write(number,0,'system lib:')
        number = number + 1
        for row,data in enumerate(syslib_dict):
            sheet.write(number,0,number)
            sheet.write(number,1,syslib_dict[data]['name'])
            sheet.write(number,2,syslib_dict[data]['ram'])
            sheet.write(number,3,syslib_dict[data]['rom'])
            sheet.write(number,4,syslib_dict[data]['total'])
            sheet.write(number,5,syslib_dict[data]['module'])
            number = number + 1
        workbook.save(getcurrentpath(XLS_FILE_NAME))

    def print(self):
        self.table = PrettyTable(['No', 'Name', 'Ram', 'Rom', 'Total(Byte)'])
        PrettyTable.title = "Platform Module Summary ( Total = " + super().calculate_byte_size(self.total) + \
                            " = " + super().calculate_mbyte_size(self.total) + " )"
       # super().print()


class MapReader:
    def __init__(self, file_name):
        lines = MapReader.read_map_file(file_name)
        print("File: " + file_name)
        ImageSummaryPrinter(lines)
        ModuleSummaryPrinter(lines)


    @staticmethod
    def read_map_file(file_name):
        file_object = open(getcurrentpath(file_name), 'r')
        try:
            lines = file_object.readlines()
        finally:
            file_object.close()
        return lines


# 按间距中的绿色按钮以运行脚本
if __name__ == '__main__':
    MapReader(MAP_FILE_NAME)

生成excel数据如下:

1、Image Summary

统计出了占用ram \flash0\flash1使用情况

2、Module Summary1

统计出了每个.c文件大小及隶属于那个模块,比如appl下有main.c\appl_os.c\ISR_FUNC.c等等文件,这样就很清晰的知道每个模块的占用空间使用情况。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐