通过Python脚本自动配置STM32从SDRAM上运行

        之前写过一篇文章《STM32(在F051上调试通过)配置从SDRAM上启动》https://mp.csdn.net/mp_blog/creation/editor/127169382,参考该文章可以手工配置从SDRAM上运行程序,但是学习过程中配置起来有些麻烦,每次需要一项项修改一些数据,而且还需要手工计算SDRAM的大小分配,挺麻烦的。开发板的配套光盘都是从Flash上运行,每次学习调试都需要重新配置。希望可以自动配置从Flash还是从SDRAM上运行程序。猜想Keil的工程配置应该在会以文本的方式保存下来,直接修改配置文件应该能达到效果。

        经过修改配置,用Beyond Compare工具比对修改前后的文件夹,终于找到了相关配置项保存的位置。main.uvproj和main.uvopt这两个XML文件都会保存,而且有些恶心的是有些配置修改后两个文件都有保存,经过N次尝试后,终于都找到相关配置了。

        本程序使用Python实现,通过xml.dom.minidom库修改XML文件,本人第一次使用这个库,不怎么会用,也没那么多时间去查资料,写的代码比较水,勉强能用,需要的可以自己更新。

        使用说明,配置如下三个选项即可

SizeInfoStr是KEIL的编译结果内容拷贝
XMLFilePath1:工程文件路径
DownLoadRunConfig :配置 从SDRAM上还是Flash上运行

主要工作量是在找到配置文件修改点,代码很简单自己查看,总体思路:解析编译结果,计算SDRAM分配,解析XML,修改XML,保存文件,计算SDRAM的时候先优先按整K字节分配,满足不了才使用精确字节数分配

 直接上代码了,随便拷贝

#!/usr/bin/python
# -*- coding: UTF-8 -*-

from xml.dom.minidom import parse
import xml.dom.minidom

#
SizeInfoStr="Program Size: Code=3368 RO-data=224 RW-data=36 ZI-data=1636"
#SizeInfoStr="Program Size: Code=6844 RO-data=224 RW-data=44 ZI-data=1668"

XMLFilePath1=r'D:\code\GreenWind\实验一:led闪烁(库函数)\user\main.uvproj'

DownLoadRunConfig="SDRAM"  #   Flash 在Flash上运行  SDRAM 在SDRAM上运行


##################################################
def AddFlag(ProcessStr):
    ProcessStr = ProcessStr.replace('''<?xml version="1.0" ?>''',
                            '''<?xml version="1.0" encoding="UTF-8" standalone="no" ?>\n''')
    ProcessStr = ProcessStr.replace('''&quot;''', '''"''')
    ProcessStrList = ProcessStr.split("\n")
    for i in range(0, len(ProcessStrList)):
        if "/>" in ProcessStrList[i]:
            TempFlag = ProcessStrList[i].strip(" ")
            LeftStr = TempFlag.replace("/>", ">")
            RightStr = LeftStr.replace("<", "</")
            ProcessStrList[i]=ProcessStrList[i].replace(TempFlag, LeftStr + RightStr)
            #print(i,ProcessStrList[i])
    ReturnStr=""
    for i in range(0, len(ProcessStrList)):
        ReturnStr=ReturnStr+ProcessStrList[i]+"\n"
    return ReturnStr


def SetNodeValue(RootNode,UpdateNode,Value):
    try:
        #print("节点已存在")
        UpdateNode[0].childNodes[0].data = Value
    except:
        print("节点不存在",Value)
        temp_text_value = RootNode.createTextNode(Value)
        UpdateNode[0].appendChild(temp_text_value)

    # Utilities


XMLFilePath2=XMLFilePath1[:-6]+"uvopt"
print(XMLFilePath2)

OutPutXML1=XMLFilePath1
OutPutXML2=XMLFilePath2




SDRAMSize=1024*8   # 8 Kbytes of SRAM with HW parity checking
SDRAMBaseAddr=0x20000000


SizeInfoStrList=SizeInfoStr.split(" ")
Code=SizeInfoStrList[2][5:]
ROdata=SizeInfoStrList[3][8:]
RWdata=SizeInfoStrList[4][8:]
ZIdata=SizeInfoStrList[5][8:]
print("Code=",Code)
print("ROdata=",ROdata)
print("RWdata=",RWdata)
print("ZIdata=",ZIdata)

ROMSize=int(Code)+int(ROdata)
RAMSize=int(RWdata)+int(ZIdata)

print("ROMSize=%d  0x%x Old " %(ROMSize,ROMSize))
print("RAMSize=%d  0x%x Old " %(RAMSize,RAMSize))

if(SDRAMSize<ROMSize+RAMSize):
    print("SDRAM 空间不足,无法使用SDRAM调试 SDRAMSize=%d  ROMSize+RAMSize=%d" %(SDRAMSize,ROMSize+RAMSize))
    exit(0)
else:
    print("SDRAM 空间满足,可以使用SDRAM调试 SDRAMSize=%d  ROMSize+RAMSize=%d" %(SDRAMSize,ROMSize+RAMSize))

bIntKSize=0  #内存按整K分配

ExtraSize=0 #对于ROM多评估一些字节
ROMInt=0
RAMInt=0
SDRAMMapList=[[7,1],[6,2],[5,3],[4,4],[3,5],[2,6]]
for i in range(0,len(SDRAMMapList)):
    ROMInt=SDRAMMapList[i][0]
    RAMInt=SDRAMMapList[i][1]
    if (ROMInt*1024>=ROMSize and RAMInt*1024>=RAMSize):
        print("选择方案 ",i+1," ",SDRAMMapList[i])
        bIntKSize=1
        break

if bIntKSize:
    ROMSize=ROMInt*1024
    RAMSize=RAMInt*1024
else:
    ROMSize=ROMSize+ExtraSize
    RAMSize=SDRAMSize-ROMSize

print("ROMSize=%d  0x%x" %(ROMSize,ROMSize))
print("RAMSize=%d  0x%x" %(RAMSize,RAMSize))

IROM1_Addr=SDRAMBaseAddr
IROM1_Size=ROMSize
IRAM1_Addr=SDRAMBaseAddr +ROMSize
IRAM1_Size=RAMSize

print("IROM1:0x%X 0x%X" %(IROM1_Addr,IROM1_Size))
print("IRAM1:0x%X 0x%X" %(IRAM1_Addr,IRAM1_Size))

RamForAlgorithmStart=IRAM1_Addr

print("RamForAlgorithm Start:0x%X Size:0x%X" %(IRAM1_Addr,IRAM1_Size))  #需要调试看是否需要修改为0x0800
print("Programming Algorithm Start:0x%0.8X Size:0x%0.8X" %(SDRAMBaseAddr,SDRAMSize))  #需要调试看是否需要修改为0x0800

#'''-U-O206 -O206 -S3 -C-1 -N00("ARM CoreSight SW-DP") -D00(0BB11477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO14 -FD20001800 -FC800 -FN1 -FF0STM32F0xx_64 -FS020000000 -FL02000'''

if(DownLoadRunConfig=="Flash"):
    SetRegEntryNameStr = (
                '''-U-O206 -O206 -S3 -C-1 -N00("ARM CoreSight SW-DP") -D00(0BB11477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD%0.8X -FC%X-FN1 -FF0STM32F0xx_64 -FS0%X -FL0%X''' % (
        0x20000000, 0x0800, 0x8000000, 0x10000))

else:
    SetRegEntryNameStr=('''-U-O206 -O206 -S3 -C-1 -N00("ARM CoreSight SW-DP") -D00(0BB11477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO14 -FD%0.8X -FC%X-FN1 -FF0STM32F0xx_64 -FS0%X -FL0%X''' %(IRAM1_Addr,IRAM1_Size,SDRAMBaseAddr,SDRAMSize))

#print("SetRegEntryName=",SetRegEntryNameStr)




# if RAMSize<0x0800:
#     print("内存分配不足 %x" %RAMSize)
#     exit(0)




#后面代码是修改XML文件


# 使用minidom解析器打开 XML 文档
DOMTree1 = xml.dom.minidom.parse(XMLFilePath1)
DOMTree2= xml.dom.minidom.parse(XMLFilePath2)





Project = DOMTree1.documentElement
ProjectOpt= DOMTree2.documentElement
# if Project.hasAttribute("xmlns:xsi"):
#     print("Root element : %s" % Project.getAttribute("xmlns:xsi"))


# 在集合中获取所有
Targets = Project.getElementsByTagName("Targets")
print("len(Targets)=",len(Targets))
Target=Targets[0]


#Target
TargetName = Target.getElementsByTagName('TargetName')
OutputName=Target.getElementsByTagName('OutputName')
CreateHexFile=Target.getElementsByTagName('CreateHexFile')

DebugOption=Target.getElementsByTagName('DebugOption')
DebugOptionTarget=DebugOption[0].getElementsByTagName('Target')
UseTarget=DebugOptionTarget[0].getElementsByTagName('UseTarget')
UseTargetLoadApplicationAtStartup=DebugOptionTarget[0].getElementsByTagName('LoadApplicationAtStartup')
UseTargetRunToMain=DebugOptionTarget[0].getElementsByTagName('RunToMain')

useUlib=Target.getElementsByTagName('useUlib')

TargetDlls=Target.getElementsByTagName('TargetDlls')
TargetDllsInitializationFile=TargetDlls[0].getElementsByTagName('InitializationFile')

OCR_RVCT4=Target.getElementsByTagName('OCR_RVCT4')
OCR_RVCT4_Type=OCR_RVCT4[0].getElementsByTagName('Type')
OCR_RVCT4_StartAddress=OCR_RVCT4[0].getElementsByTagName('StartAddress')
OCR_RVCT4_Size=OCR_RVCT4[0].getElementsByTagName('Size')

OCR_RVCT9=Target.getElementsByTagName('OCR_RVCT9')
OCR_RVCT9_Type=OCR_RVCT9[0].getElementsByTagName('Type')
OCR_RVCT9_StartAddress=OCR_RVCT9[0].getElementsByTagName('StartAddress')
OCR_RVCT9_Size=OCR_RVCT9[0].getElementsByTagName('Size')

UseSimulator=Target.getElementsByTagName('UseSimulator')

Utilities=Target.getElementsByTagName('Utilities')
bUseTDR=Utilities[0].getElementsByTagName('bUseTDR')
if(len(bUseTDR)==0):
    temp_node = DOMTree1.createElement("bUseTDR")
    Utilities[0].appendChild(temp_node)
    bUseTDR = Utilities[0].getElementsByTagName('bUseTDR')
    pass
UpdateFlashBeforeDebugging=Utilities[0].getElementsByTagName('UpdateFlashBeforeDebugging')


#####main.uvopt文件
OptSetRegEntry=ProjectOpt.getElementsByTagName('SetRegEntry')
for i in range(0,len(OptSetRegEntry)):
    if OptSetRegEntry[i].getElementsByTagName('Key')[0].childNodes[0].data=="ST-LINKIII-KEIL_SWO":
        OptSetRegEntryName=OptSetRegEntry[i].getElementsByTagName('Name')
        break

OptTargets=ProjectOpt.getElementsByTagName('Target')
OptTarget=OptTargets[0]
OptTargetName=OptTarget.getElementsByTagName('TargetName')

OptDebugOpt=OptTarget.getElementsByTagName('OptDebugOpt')
OptuSim=OptTarget.getElementsByTagName('uSim')
OptuTrg=OptTarget.getElementsByTagName('uTrg')
OpttIfile=OptTarget.getElementsByTagName('tIfile')
OpttLdApp=OptTarget.getElementsByTagName('tLdApp')
OpttGomain=OptTarget.getElementsByTagName('tGomain')


if(DownLoadRunConfig=="Flash"):
    # Project-  File Extensions
    SetNodeValue(DOMTree1, TargetName, "FlashOut")
    SetNodeValue(DOMTree2, OptTargetName, "FlashOut")
    # Target页面配置
    # Use Micro LIB
    SetNodeValue(DOMTree1, useUlib, "1")
    ##IROM1
    SetNodeValue(DOMTree1, OCR_RVCT4_Type, "1")
    SetNodeValue(DOMTree1, OCR_RVCT4_StartAddress, ("0x%X" % 0x8000000))
    SetNodeValue(DOMTree1, OCR_RVCT4_Size, ("0x%X" % 0x10000))
    ##IRAM1
    SetNodeValue(DOMTree1, OCR_RVCT9_Type, "0")
    SetNodeValue(DOMTree1, OCR_RVCT9_StartAddress, ("0x%X" % 0x20000000))
    SetNodeValue(DOMTree1, OCR_RVCT9_Size, ("0x%X" % 0x2000))
    # Output页面配置
    ##Name of Executable
    SetNodeValue(DOMTree1, OutputName, "main")
    ##Create HEX File
    SetNodeValue(DOMTree1, CreateHexFile, "1")
    # Debug页面配置
    ##Use Simulator
    SetNodeValue(DOMTree1, UseSimulator, "0")
    SetNodeValue(DOMTree2, OptuSim, "0")
    ##DebugOptionTarget
    SetNodeValue(DOMTree1, UseTarget, "1")
    SetNodeValue(DOMTree1, UseTargetLoadApplicationAtStartup, "1")
    SetNodeValue(DOMTree1, UseTargetRunToMain, "1")
    SetNodeValue(DOMTree2, OptuTrg, "1")
    SetNodeValue(DOMTree2, OpttLdApp, "1")
    SetNodeValue(DOMTree2, OpttGomain, "1")
    # ##TargetDlls
    # TargetDllsInitializationFile[0]
    # 创建phone节点,并设置textValue
    SetNodeValue(DOMTree1, TargetDllsInitializationFile, "")
    SetNodeValue(DOMTree2, OpttIfile, "")
    # Utilities
    SetNodeValue(DOMTree1, bUseTDR, "0")
    SetNodeValue(DOMTree1, UpdateFlashBeforeDebugging, "1")
    # Flash Download
    SetNodeValue(DOMTree2, OptSetRegEntryName, SetRegEntryNameStr)

else:
    #Project-  File Extensions
    SetNodeValue(DOMTree1,TargetName,"RamOut")
    SetNodeValue(DOMTree2,OptTargetName,"RamOut")
    #Target页面配置
    #Use Micro LIB
    SetNodeValue(DOMTree1,useUlib,"1")
    ##IROM1
    SetNodeValue(DOMTree1,OCR_RVCT4_Type,"1")
    SetNodeValue(DOMTree1,OCR_RVCT4_StartAddress,("0x%X" % SDRAMBaseAddr))
    SetNodeValue(DOMTree1,OCR_RVCT4_Size,("0x%X" % IROM1_Size))
    ##IRAM1
    SetNodeValue(DOMTree1,OCR_RVCT9_Type,"0")
    SetNodeValue(DOMTree1,OCR_RVCT9_StartAddress,("0x%X" % IRAM1_Addr))
    SetNodeValue(DOMTree1,OCR_RVCT9_Size,("0x%X" % IRAM1_Size))
    #Output页面配置
    ##Name of Executable
    SetNodeValue(DOMTree1,OutputName,"main")
    ##Create HEX File
    SetNodeValue(DOMTree1,CreateHexFile,"1")
    #Debug页面配置
    ##Use Simulator
    SetNodeValue(DOMTree1,UseSimulator,"0")
    SetNodeValue(DOMTree2,OptuSim,"0")
    ##DebugOptionTarget
    SetNodeValue(DOMTree1,UseTarget,"1")
    SetNodeValue(DOMTree1,UseTargetLoadApplicationAtStartup,"0")
    SetNodeValue(DOMTree1,UseTargetRunToMain,"0")
    SetNodeValue(DOMTree2,OptuTrg,"1")
    SetNodeValue(DOMTree2,OpttLdApp,"0")
    SetNodeValue(DOMTree2,OpttGomain,"0")
    # ##TargetDlls
    #TargetDllsInitializationFile[0]
    # 创建phone节点,并设置textValue
    SetNodeValue(DOMTree1,TargetDllsInitializationFile,"..\\..\\RAM2.ini")
    SetNodeValue(DOMTree2,OpttIfile,"..\\..\\RAM2.ini")
    #Utilities
    SetNodeValue(DOMTree1,bUseTDR,"0")
    SetNodeValue(DOMTree1,UpdateFlashBeforeDebugging,"1")
    #Flash Download
    SetNodeValue(DOMTree2,OptSetRegEntryName,SetRegEntryNameStr)




#保存文件
fw = open(OutPutXML1, 'w',encoding="utf-8")
fw.write(AddFlag(DOMTree1.toxml()))
fw.close()
fw = open(OutPutXML2, 'w',encoding="utf-8")
fw.write(AddFlag(DOMTree2.toxml()))
fw.close()



exit(1)






  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hyhsandy1803

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值