在MDK-ARM编译后用python解析map文件在编译窗口输出Flash和RAM使用及剩余情况

在MDK-ARM编译后用python解析map文件在编译窗口输出Flash和RAM使用及剩余情况

一、自动搜索最新map文件

  • 根据制定路劲自动搜索最新map文件
python 复制代码
import glob
import sys
import re
import os



# 搜索最新map文件
def find_latest_map_file(search_dir):
    """
    在指定目录及其子目录中搜索所有 .map 文件,并返回最新修改的那个。
    """

    # 转换为绝对路径,方便排错和确认路径是否正确
    abs_search_dir = os.path.abspath(search_dir)

    # 构建glob搜索模式
    search_pattern = os.path.join(abs_search_dir, '**', '*.map')
    map_files = glob.glob(search_pattern, recursive=True)

    if not map_files:
        print(f" [Error] 在目录中未找到任何.map文件:{abs_search_dir}")
        return None
    
    # 按文件的最后修改时间排序,获取最新的文件
    latest_map_file = max(map_files, key=os.path.getmtime)
    return latest_map_file

二、解析map文件信息

  • 解析map文件获取Flash和RAM使用情况及百分比
python 复制代码
#解析map文件
def analysis_map_file(file_path, total_flash, total_ram):
    if not os.path.exists(file_path):
        print(f" [Error] 找不到文件: {file_path}")
        return

    # 编译正则表达式,匹配 Keil Map 文件末尾的固定格式
    # 匹配: Total RW  Size (RW Data + ZI Data)              3664 (   3.58kB)
    re_rw = re.compile(r"Total RW\s+Size \(RW Data \+ ZI Data\)\s+(\d+)")

    # 匹配: Total ROM Size (Code + RO Data + RW Data)      15916 (  15.54kB)
    re_rom = re.compile(r"Total ROM\s+Size \(Code \+ RO Data \+ RW Data\)\s+(\d+)")

    flash_used = 0
    ram_used   = 0

    # 读取并解析文件
    with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
        for line in f:
            match_rw = re_rw.search(line)
            if match_rw:
                ram_used = int(match_rw.group(1))
            
            match_rom = re_rom.search(line)
            if match_rom:
                flash_used = int(match_rom.group(1))

    # 打印结果界面
    print("\r\n" + "=" * 72)
    print(f"    Memory Usage Analysis for: {os.path.basename(file_path)}")
    print("-" * 72)

    if flash_used == 0 and ram_used == 0:
        print("    [Warn] 解析失败:未能在 map 文件中找到大小汇总信息。")
        print("    请确认魔术棒 -> Listing -> 勾选了 Linker Listing (*.map)")
    else:
        # 计算 Flash
        flash_free = total_flash - flash_used
        flash_percent = (flash_used / total_flash) * 100
        print(f"    Flash (ROM) : {flash_used:6} Bytes Used | {flash_free:6} Bytes Free | [{flash_percent:5.1f}% ]")

        # 计算 RAM
        ram_free = total_ram - ram_used
        ram_percent = (ram_used / total_ram) * 100
        print(f"    RAM   (RAM) : {ram_used:6} Bytes Used | {ram_free:6} Bytes Free | [{ram_percent:5.1f}% ]")
    
    print("=" * 72 + "\r\n")

三、主函数

  • 可设置芯片Flash和RAM总大小
  • 可设置编译器名称和项目名称,主要是查找map文件路径
python 复制代码
if __name__ == "__main__":
    COMPILER_NAME = 'MDK-ARM'   # 编译器名称
    PROJECT_NAME  = 'XXXXXXX'   # 项目名称
    TOTAL_FLASH   = 64 * 1024   # 总FLASH大小
    TOTAL_RAM     = 8  * 1024   # 总RAM大小

    target_dir = os.path.join("..", COMPILER_NAME, PROJECT_NAME)
    latest_map = find_latest_map_file(target_dir)
    analysis_map_file(latest_map, TOTAL_FLASH, TOTAL_RAM)

四、MDK-ARM相关设置

  1. 魔术棒(Options for Target) -> Listing -> Linker Lisiting
  1. 魔术棒(Options for Target) -> User -> After Build/Rebuild
  • fromelf --bin -o "$L@L.bin" "#L" 生成bin文件

  • python ...\xxxxxxxA\xxxxxxxB\xxxxxxxC.py执行python脚本

  • 若python文件放在工程(.uvprojx)目录MDK-ARM下不需要劲径,直接python xxxC.py即可

  • 工程目录(.uvprojx所在位置) : \Project\MDK-ARM

  • .map目录 : \Project\MDK-ARM\AAA_map

  • python目录 : \Project\BBB_dir\CCC_dir

五、运行结果

python 复制代码
========================================================================
    Memory Usage Analysis for: XXXXXX.map
------------------------------------------------------------------------
    Flash (ROM) :  48688 Bytes Used |  16848 Bytes Free | [ 74.3% ]
    RAM   (RAM) :   2656 Bytes Used |   5536 Bytes Free | [ 32.4% ]
========================================================================
相关推荐
GuokLiu2 小时前
260331-OpenWebUI统计所有Chat的对话字符个数
python
哈伦20192 小时前
Python 生成随机数
python·机器学习·pandas
zzwq.2 小时前
魔法方法 __init__ 与 __new__ 的区别与使用场景
python
傻啦嘿哟2 小时前
如何使用 Python 操作 Excel 图片:插入、提取与压缩
开发语言·python·excel
Dxy12393102162 小时前
Python 如何反向 `enumerate` 遍历枚举
python
XiYang-DING2 小时前
【LeetCode】206. 反转链表
算法·leetcode·链表
程序员杰哥2 小时前
软件测试之黑盒测试详解
自动化测试·软件测试·python·功能测试·测试工具·职场和发展·测试用例
_深海凉_2 小时前
LeetCode热题100-合并两个有序链表
算法·leetcode·链表
第一程序员2 小时前
Python深度学习实战:从理论到应用
python·github