This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS320F28378D:矢量可将 Intel Hex 文件转换为 C2000 Hex 文件转换器

Guru**** 664280 points
Other Parts Discussed in Thread: UNIFLASH
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1226621/tms320f28378d-vector-canape-intel-hex-file-to-c2000-hex-file-converter

器件型号:TMS320F28378D
主题中讨论的其他器件:UNIFLASH

以下假设从 ECU 不支持通过 XCP 刷写。

对于 C2000器件、UniFlash 期望十六进制文件的 romwidth=16。 简而言之、如果您尝试使用 UniFlash 将常规 Intel Hex 文件下载到 C2000器件、则无法按预期进行编程。 更多信息:

 https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/1224488/uniflash-c2000-hex-file-format-compatibility


我将使用矢量 canape 进行数据采集和校准。 校准会话之后、可以保存包含校准常量(ASAP2中的特征表示)的存储器的图像文件(Intel hex)、想法是将文件刷写到器件中、以冻结该特定器件中的校准更改、而无需重新编译软件。

接下来的挑战是如何将 canape true Intel hex 文件转换为 UniFlash C2000 hex 文件(romwidth=16)、以便 canape (或任何其他 MCD 工具)可用于汽车工作流程。 我的解决方案是使用 Python 脚本解析 canape hex 文件、从而将八位位组放置在正确的地址的正确位置、从而允许 UniFlash 对 C2000器件进行编程。 请在下方找到 Python 脚本。

 它需要在该线程 https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1225978/tms320f28379d-implementation-of-xcp-on-can-for-c2000中概述的定制寻址方案 、其中 ASAP2地址空间是设备地址空间的2 x。 授权这是一个非常具体的用例、但可以修改脚本、以便可以生成真正的 Intel hex 文件的其他第三方工具配合 C2000/UniFlash 使用。

注1:输入一半由 Python IntelHex (https://pypi.org/project/intelhex/)完成。 一种快速的解决方案是使用其'HEX2BIN'脚本、只要您愿意手动输入起始地址、bin 文件就可以直接与 UniFlash 一起使用。 不过、我需要一个自包含可编程文件、而且格式与 hex2000实用程序从 CCS 输出的格式完全相同。 后者意味着我可以通过文件将编译器输出"校准"与 CA 输出校准进行比较。

注2:Python IntelHex 具有 IntelHex16位类、但我无法将其输出为 C2000 hex 文件。

# Python program to create a word addressable HEX file suitable for TI UniFlash
# to program a C2000 device from a byte addressable Intel HEX file generated by CANape.
#
# It expects that the CANape (XCP / ASAP2) addresses are 2 x C2000 device addresses.
#
# Usage : python.exe CANapeHex2UniFlashHex.py canape_input.hex uniflash_output.hex
#
# Tested with Python 3.10.

import sys

# Class for the input Intel hex file. Credit: pypi.org/.../
from intelhex import IntelHex


class UniFlashDict:
    '''Creates a dictionary of values with additional metadata suitable for UniFlash hex file construction from an IntelHex object'''

    def __init__(this, intelhex_obj):
        # New empty dictionary.
        this.dict = dict()

        # Get the ASAP2 Address range of Intel HEX file but 
        # halve to give the Device Address.
        this.min_addr = int(intelhex_obj.minaddr()/2)
        this.max_addr = int(intelhex_obj.maxaddr()/2)

        # Prepare values used for record construction.
        this.ext_linear_addr = this.min_addr >> 16 & 0xFFFF
        this.seg_base_addr   = this.min_addr & 0xFFFF

        # Iterate through the ASAP2 byte addressed dictionary and create a word addressed dictionary.
        idx_uf = this.min_addr
        idx_ih = intelhex_obj.minaddr()
        while idx_ih < intelhex_obj.maxaddr():
            this.dict[idx_uf] = intelhex_obj[idx_ih] | (intelhex_obj[idx_ih + 1] << 8)
            # Increment ASAP2 address by two bytes.
            idx_ih += 2
            # Increment C2000 address by one word.
            idx_uf += 1

    def minaddr(this):
        '''The absolute start address.'''
        return this.min_addr
        
    def maxaddr(this):
        '''The absolute end address.'''
        return this.max_addr

    def extended_linear_address(this):
        '''Returns the two data bytes (big endian) which specify the upper 16 bits of the 32 bit absolute address
           for all subsequent type 00 records; these upper address bits apply until the next 04 record.'''
        return this.ext_linear_addr

    def segment_base_address(this):
        '''The 16-bit starting address for the data.'''
        return this.seg_base_addr


def update_checksum( current_csum, new_data, num_of_bytes ):
    '''Updates the running total of the input checksum with new data.'''
    idx = num_of_bytes
    ret_csum = current_csum
    temp_new_data = new_data

    while(idx > 0):
        ret_csum += temp_new_data & 0xFF
        temp_new_data =  temp_new_data >> 8
        idx -= 1

    return ret_csum
   
def finalize_checksum( current_csum ):
    '''Returns the LSB of the two's complement of the input.'''
    ret_csum = current_csum
    
    ret_csum = ~ret_csum       # Invert
    ret_csum = ret_csum + 1    # Add 1
    ret_csum = ret_csum & 0xFF # Keep LSB only.

    return ret_csum


def main():
    DATA_REC_TYPE = 0x00
    DATA_REC_TYPE_STR = f'{DATA_REC_TYPE:0{2}X}'
    DATA_REC_BYTE_COUNT = 0x20 # Fixed at 32 bytes.
    DATA_REC_BYTE_COUNT_STR = f'{DATA_REC_BYTE_COUNT:0{2}X}'

    EXT_LIN_ADDR_REC_TYPE = 0x02000004
    EXT_LIN_ADDR_REC_TYPE_STR = f'{EXT_LIN_ADDR_REC_TYPE:0{8}X}'

    EOF_REC_STR = ':00000001FF'

    try:
        # Get an instance of the Intel HEX file input.
        ih_in = IntelHex(sys.argv[1])

        # Open/create a file for the output.
        uf_out_file = open(sys.argv[2], "w")

        # Get an instance of the UniFlash dictionary.
        uf_dict = UniFlashDict(ih_in)

        # Prepare and write the Extended Linear Address record. e.g. ":020000040009F1"
        record_str = ':' + EXT_LIN_ADDR_REC_TYPE_STR + f'{uf_dict.extended_linear_address():0{4}X}'
        record_csum = update_checksum(0,EXT_LIN_ADDR_REC_TYPE,4)

        record_csum = update_checksum(record_csum,uf_dict.extended_linear_address(),4)
        record_csum = finalize_checksum(record_csum)

        # Append checksum byte.
        record_str += f'{record_csum:0{2}X}'

        uf_out_file.write(record_str+"\n")

        # Get the address for the first record.
        record_start_address = uf_dict.segment_base_address()     

        # Initialise loop variables.
        idx = uf_dict.minaddr()
        word_counter = 0

        # Loop through all dictionary values and create multiple data records in the output file.
        while idx < (uf_dict.minaddr() + len(uf_dict.dict)):
           
            if word_counter == 0:
                # At the start of the record, concatenate the byte count, address and record type. e.g. ":20C13000"
                record_str = ':' + DATA_REC_BYTE_COUNT_STR + f'{record_start_address:0{4}X}' + DATA_REC_TYPE_STR
                record_csum = DATA_REC_BYTE_COUNT + ((record_start_address & 0xFF00) >> 8) + (record_start_address & 0x00FF) + DATA_REC_TYPE
            
            # Process a word.
            # Concatenate dictionary values (words)
            record_str += f'{uf_dict.dict[idx]:0{4}X}'
            # Keep a running total of each word (2 bytes) for the checksum.
            record_csum = update_checksum(record_csum, uf_dict.dict[idx], 2)

            # Keep a count of how many words have been processed for each record.
            word_counter += 1

            # After sixteen words: Finalize checksum, write to the file and prepare for a new record.
            if word_counter == 16:
                # Finalize checksum.
                record_csum = finalize_checksum( record_csum )

                # Append checksum byte.
                record_str += f'{record_csum:0{2}X}'

                # Record is now complete so output to file with a new line.
                uf_out_file.write(record_str+"\n")

                # Calculate next start address. i.e. Add 16 (words).
                record_start_address += 16
                # Force prepartion of a new record.
                word_counter = 0

            # Move to the next word in the dictionary.
            idx += 1

        # Write the End Of File record. It doesn't change so can use a literal.
        record_str = EOF_REC_STR

        uf_out_file.write(record_str+"\n")

        uf_out_file.close()

    except Exception as e:
      print("\nError! " + repr(e))


if (len(sys.argv) != 3):
    print("Usage:")
    print("python.exe IntelHex2UniFlashHex.py intel.hex uniflash.hex")
else:
    main()

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Kier:

    我将这个问题分配给了我们的编译器/hextool 团队、他们会审查后回复给您。   

    谢谢。此致、

    Vamsi

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我不知道你的帖子的目的。

    如果你分享你已经做的工作,以便他人可以受益,那么非常感谢你。

    如果您想获得 TI 的批准、那么我很抱歉地说我无法做到这一点。  我们不熟悉 Canape。  我们缺乏 Python 专业知识。  总的来说,我们 不能 提出任何意见。

    谢谢。此致、

    -George.

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    是的、我只是分享。 很抱歉、我没有说明。 无需响应。