首页 资讯 应用 高压 设计 行业 低压 电路图 关于

单片机

旗下栏目: PLC 嵌入式 单片机 DCS

IAR使用Python脚本实现自动对烧录文件进行处理

单片机 | 发布时间:2018-11-02 | 人气: | #评论# | 本文关键字:IAR,Python,STM32,脚本,bin文件
摘要:这篇文章将要记录如何配置IAR调用外部工具实现对编译完成后自动对生成的hex文件进行合并、对bin文件进行额外操作。 问题背景: 我们目前的项目在STM32平台上开发,具备远程无线升级功能,

这篇文章将要记录如何配置IAR调用外部工具实现对编译完成后自动对生成的hex文件进行合并、对bin文件进行额外操作。

问题背景:

我们目前的项目在STM32平台上开发,具备远程无线升级功能,即通过GPRS网络实现远程IAP,IAP过程中使用的是bin文件(因为bin文件不包含地址,处理比较简单)。因此,在项目编译后我们就需要两个文件,一个是设备出厂时的烧录文件,该文件为hex格式,一个是设备部署后远程升级时用的bin文件。而出厂hex文件又由两个文件合并而成,分别是BOOT.hex: 用户启动代码,用于引导和远程升级,由BOOT工程编译得到;APP.hex :用户应用代码,由APP工程编译得到。同时,APP.bin: 用户应用代码二进制格式,通过APP工程编译得到。

所以每次重新编译app工程或者boot工程后都要进行一次复制粘贴,而且IAR链接时只能生成一种文件,hex或者bin,选择生成hex时就会删除bin,选择bin又会删除hex。因此要得到这两个文件需要编译连接两次。

另外,升级时我们需要知道bin文件的大小,CRC32校验码,烧录的起始地址,为了操作方便一个比较好的办法是将这三个信息都放到bin文件内部,所以编译生成bin文件后也要对该文件进行处理。

为了简化人工操作,减少出错几率,我就动手编写了一个脚本,每次编译连接完成后自动将APP.hex转为APP.bin,并且将APP.hex和BOOT.hex进行合并。

需要解决的问题:

1.写一个Python脚本,实现BOOT.hex和APP.hex的合并,主要涉及到文件的拷贝

2.写一个Python脚本,计算APP.bin文件的CRC32校验,计算文件内容长度,将这些数据以二进制形式写入到新的bin文件中,且要求高字节在前。

3.将py脚本转换为windows可执行的exe,使用py2exe,具体方法请参考这里

4.IAR的设置

容易出错的问题:

实现的功能很简单,没有什么容易出错的地方,但是路径的问题还是比较麻烦,发现运行路径和脚本所在路径不一致。

实现步骤(本文主要讲IAR的设置):

1.convertAPP.py 如下:

import ConfigParser

import os

def cont_file_size(filename):

    ”’count file size

    

    count and print total bytes of the file.”’

    fObj = open(filename,‘r’)

    try:

        allData = fObj.read()

        print ‘%s is %d Bytes’ % (filename,len(allData))

    finally:

        fObj.close()

        

        

def get_file_size(filename):

    ”’get file size

    

    count and return total bytes of the file.”’

    fObj = open(filename,‘r’)

    try:

        allData = fObj.read()

    finally:

        fObj.close()        

    return len(allData)

def read_config(filename):

    ”’read configure from the config file 

    

    get the resource file name and the destination file name from the config file”’

    global resFile

    global dstFile

    # read configuration form config.ini

    config = ConfigParser.ConfigParser()  

    # with open(“config.ini”,’r+’) as cfgfile:  

    #     config.readfp(cfgfile)  

    cfgfile = open(filename,‘r+’)

    config.readfp(cfgfile)

    resFile = config.get(“info”,“resFile”)  

    dstFile = config.get(“info”,“dstFile”)  

    cfgfile.close()

    

def copy_data(resFile,dstFile):

    ”’combine these two files

    

    append resource.txt content to file poem.txt”’

    fRes = file(resFile,‘r’)

    fDst = file(dstFile,‘a’)

    poem = fRes.read(1024)

    # print ”’The first content readed is:\n”%s””’ % (poem)

    while poem:

        fDst.write(poem)

        poem = fRes.read(1024)

    else:

    #     print ‘The file read over.’    

        pass

    fDst.close()

    fRes.close()        

print ‘Change to ‘ + os.getcwd()    # print current work directory

read_config(‘config.ini’)

cont_file_size(resFile)

cont_file_size(dstFile)

print “Append data from %s to %s…” % (resFile,dstFile)

copy_data(resFile,dstFile)

print ‘New %s is %d Bytes now’ % (dstFile,get_file_size(dstFile)) 

print ‘Please use %s to download.’ % (dstFile)

 

2.formatBIN.py文件如下:

import os

import binascii

import struct

import ConfigParser

def read_config(filename):

    ”’read configure from the config file 

    

    get the resource file name and the destination file name from the config file”’

    global resFile

    global dstFile

    global log

    # read configuration form config.ini

    config = ConfigParser.ConfigParser()  

    with open(“config.ini”,‘r+’as cfgfile:  

        log.write(‘\nopen config.ini’)

        config.readfp(cfgfile)  

#     cfgfile = open(filename,’r+’)

        config.readfp(cfgfile)

        resFile = config.get(“bin”,“resFile”)  

        dstFile = config.get(“bin”,“dstFile”)  

        cfgfile.close()

    

def computeFileCRC(filename):

    global log

    try:

        blocksize = 1024 * 64

        f = open(filename, rb)

        

        log.write(‘\nopen %s’ %(filename))

        str1 = f.read(blocksize)

        crc = 0

        while len(str1) != 0:

            crc = binascii.crc32(str1,crc) & 0xffffffff

            str1 = f.read(blocksize)

        f.close()

    except:

        print “compute file crc failed!”

        return 0

    return crc

def creatNewFile(oldFile,newFile):

    global log

    addr = 0x800c000

    crc = computeFileCRC(oldFile)

    parsedata_addr = struct.pack(“L”,addr)[::-1]

    parsedata_crc = struct.pack(“L”,crc)[::-1]

    with open(newFile,wbas newF:

        log.write(‘\nopen %s’ %(newFile))

        with open(oldFile,rbas oldF:

            print ‘open %s’ %(oldFile)

            allData = oldF.read()

            dataSize = len(allData)

            print ‘File: %s  %d Bytes’ %(oldFile,dataSize)

            print ‘CRC: 0x%08x’ %(crc)

            print Addr: 0x%08x’ %(addr)

            parsedata_dataSize = struct.pack(“L”,dataSize)[::-1]

            newF.write(parsedata_addr)

            newF.write(parsedata_dataSize)

            newF.write(parsedata_crc)

            newF.write(allData)

            print ‘%s has been created.’ % (newFile)

          

print ‘Change to ‘ + os.getcwd()

with open(“log.txt”,‘w’as log:           

    read_config(‘config.ini’)        

    creatNewFile(resFile,dstFile)

 

3.配置文件config.ini

[info]

resfile = BOOT.hex

dstfile = APP.hex

[bin]

resfile = APP.bin

dstfile = APP.bin1

 

4.IAR的配置

在IAR中调用外部工具有多种方法,方法一,作为一个外部工具进行配置,这个工具在所有工程中可以使用;方法二,在工程属性中进行配置,编译完成后自动调用外部程序,该方法对单个工程有效。

方法一:

step1:

step2:

如上设置就可以实现了,同时config.ini需要放置到Output目录下。

这里需要注意的是如果不指定 Initial Directory,则脚本的运行目录是IAR工程文件所在的目录。

 

方法二:

step1:

step2:

由于脚本的运行目录是IAR工程文件所在目录,所以config.ini需要放置到$PROJ_DIR$目录下,也就是 .eww 文件所在目录,且需要使用相对路径指定相应的文件。

config.ini文件内容如下:

[info]

resfile = ..\\Output\\BOOT.hex

dstfile = ..\\Output\\APP.hex

[bin]

resfile = ..\\Output\\APP.bin

dstfile = ..\\Output\\APP.bin1

这样就可以在每次编译完成后自动调用formatBIN.exe对APP.bin进行处理了。

方法2有一个问题就是不能将工具打印信息回显到IAR中,如果出错IAR会提示有一个错误。

责任编辑:Python脚本
首页 | 电气资讯 | 应用技术 | 高压电器 | 电气设计 | 行业应用 | 低压电器 | 电路图 | 关于我们 | 版权声明

Copyright 2017-2018 电气自动化网 版权所有 辽ICP备17010593号-1

电脑版 | 移动版 原创声明:本站大部分内容为原创,转载请注明电气自动化网转载;部分内容来源网络,如侵犯您的权益请发送邮件到[email protected]联系我们删除。