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.

How to create a Flash bootable image for F28335

Hi guys,

I'm using F28335 MCU with "Jump To Flash" Boot mode and I would like to be able to perform a firware update. I already learned how to write the image into Flash using FlashAPI and read it back into a file on the host (I'm using CAN for communucation).

If I program my Flash using CCS menu Tools->F28xx On-Chip Flash Programmer, then read Flash Sectors A and D using FlashAPI, transmit that data to the host and save into file I'll get a loadable image. Now I want to be able to create this image directly from my .out COFF file.

What I need to know is how does CCS create a loadable image from the COFF file? I'm guessing it uses hex2000.exe with -b option, but I tried that and failed. I'm able to create an image, but it's invalid. I can see that because the complete Sector A in my image file is empty (0xFFFF).

The command file I tried is:

./2833x_FLASH/prog.out
-b
-image
-boot
-fill 0xFFFF
-memwidth 16

ROMS
{
    FLASHD : origin = 0x320000, length = 0x7FFF, files = { sectD.bin }
    FLASHA : origin = 0x338000, length = 0x7FFF, files = { sectA.bin }
}

I would appreciate any help.

Thanks,

Suren.

 

  • Suren,

    Hopefully I understood your question correctly and can be of some help:

    The "Boot to flash" boot mode only allows the boot ROM to jump to 0x33FFF6 (flash entry point) and start executing code from there. It does not allow you to program flash starting at that location.

    To create a boot-loadable image from your COFF .out file, as you said, you use the hex2000.exe tool.  For instance, you can create a CAN-bootable image from your .out file. Then select boot to CAN mode, and your code will be loaded into the RAM addresses specified by your image and begin executing from there. Perhaps the code you load there can invoke Flash API commands to program your Flash, etc. etc.

    To create a CAN bootable image, see section 3.2 of the 2823x/2833x Boot ROM Reference Guide (SPRU963), which shows you exactly what hex2000 command to use to create a CAN bootable image. All of Section 3 in that reference guide describes using the hex2000 tool to create images for bootloading.  For more information on hex2000 commands, you can also refer to TMS320C28x Assembly Language Tools User's Guide (SPRU513).

     

  • Chrissy,

    Thanks for the response. However my question is not about CAN boot option or how to build an image for CAN boot option. I can't change the boot mode because "Jump to Flash" is the normal boot mechanism for my system. Usually it should boot from Flash and work from there. Occasionally I want to upload a new image into Flash through CAN.

    >>The "Boot to flash" boot mode only allows the boot ROM to jump to 0x33FFF6 (flash entry point) and start executing code from there. It does not allow you to program flash starting at that location.

    I'm aware of that and I believe my COFF file is already built with the address 0033fff6 populated with the code to start execution. Here is a portion of my .map file for that address:

    codestart

    * 0 0033fff6 00000002

    0033fff6 00000002 DSP2833x_CodeStartBranch.obj (codestart)

    So what I need to know is how CCS converts my COFF file into a loadable image before uploading it to my target when I'm using CCS "Tools->F28xx On-Chip Flash Programmer" menu item. Or in other words how do I build a loadable image for "Jump to Flash" boot mode?

    Thanks,

    Suren.

  • Ok, I figured it out. hex2000 -b creates binary version of the hex file. I wrote a program to parse that file and place sections into correct places to build a continuous Flash image. I compared the image I built with the one that TI programmer programs and they match. I'll post my small converter code here after I verify everything works as expected.

    Thanks,

    Suren.

  • Here is a simple C# code to convert binary hex file generated by hex2000.exe into a Flash loadable image. It reads the sections from hex file and relocates them.

    8637.hex2img.txt
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;
    
    namespace hex2img
    {
        class hex2img
        {
            private const UInt16 HEX_FILE_SIGN = 0x08AA;
            private const byte FILL_CHAR = 0xFF;
            private const byte ADDR_SIZE = sizeof(UInt16);
    
            private class SectionInfo
            {
                private UInt32 addr;
                private UInt16 len;
    
                public UInt32 Addr
                {
                    get { return addr; }
                }
    
                public  UInt16 Len
                {
                    get { return len; }
                }
    
                public SectionInfo(UInt32 addr, UInt16 len)
                {
                    this.addr = addr;
                    this.len = len;
                }
            }
    
            private static UInt32 SwapUInt32(UInt32 dword)
            { 
                return ((dword & 0x0000FFFF) << 16) | ((dword & 0xFFFF0000) >> 16);
            }
    
            static void Main(string[] args)
            {
                if (args.Length >= 2)
                {
                    try
                    {
                        BinaryReader rd = new BinaryReader(File.Open(args[0], FileMode.Open));
                        UInt16 signature = rd.ReadUInt16();
                        if (signature == HEX_FILE_SIGN)
                        {
                            // skip 16 reserved double words
                            rd.BaseStream.Seek(16, SeekOrigin.Current);
                            // read enpty point
                            UInt32 entryPt = rd.ReadUInt32();
                            UInt32 minAddr = UInt32.MaxValue;
                            UInt32 maxAddr = UInt32.MinValue;
                            UInt16 secLen;
                            List<SectionInfo> secInfoList = new List<SectionInfo>();
                            do
                            {
                                // read section length
                                secLen = (UInt16)(rd.ReadUInt16() * ADDR_SIZE);
                                if (secLen > 0)
                                {
                                    // read section start address
                                    UInt32 secAddr = SwapUInt32(rd.ReadUInt32());
                                    secInfoList.Add(new SectionInfo(secAddr, secLen));
                                    Console.WriteLine("Found section: addr 0x" + secAddr.ToString("X") + " size " + secLen.ToString() + " bytes");
                                    rd.BaseStream.Seek(secLen, SeekOrigin.Current);
                                    if (minAddr > secAddr)
                                    {
                                        minAddr = secAddr;
                                    }
                                    if (maxAddr < secAddr + secLen)
                                    {
                                        maxAddr = secAddr + secLen;
                                    }
                                }
                            } while (secLen > 0);
                            if (minAddr < maxAddr)
                            {
                                BinaryWriter wr = new BinaryWriter(File.Open(args[1], FileMode.Create));
                                // fill in output file with fill character
                                UInt32 memSize = (maxAddr - minAddr) * ADDR_SIZE;
                                for (UInt32 bt = 0; bt < memSize; ++bt)
                                {
                                    wr.Write(FILL_CHAR);
                                }
                                // goto beginning of the section data (skip file signarute, reserved bytes, and entry point)
                                rd.BaseStream.Seek(22, SeekOrigin.Begin);
                                foreach (SectionInfo sectionInfo in secInfoList)
                                {
                                    // skip section size and address
                                    rd.BaseStream.Seek(6, SeekOrigin.Current);
                                    // position output file pointer
                                    wr.BaseStream.Seek((sectionInfo.Addr - minAddr) * ADDR_SIZE, SeekOrigin.Begin);
                                    // copy data from input into output file
                                    byte[] arr = new byte[sectionInfo.Len];
                                    rd.Read(arr, 0, sectionInfo.Len);
                                    wr.Write(arr, 0, sectionInfo.Len);
                                }
                                wr.Close();
                                Console.WriteLine("Image start address = 0x" + minAddr.ToString("X"));
                                Console.WriteLine("Image end address = 0x" + maxAddr.ToString("X"));                            
                            }
                            else
                            {
                                Console.WriteLine("Invalid input file format");
                            }
                        }
                        else
                        {
                            Console.WriteLine("Invalid input file format");
                        }
                        rd.Close();
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                }
                else
                {
                    Console.WriteLine("Invalid number of parameters! Usage: hex2img <hex file> <image file>");
                }
            }
        }
    }
    

  • Hello, Suren!

    I have similar task now and want to use FlashAPI to change firmware without JTAG.

    After compilling my code I get .out file and .map file.
    After using hex2000 with options

    -map out.map (initial .map file)
    -o out.hex (name of output file)
    -boot
    -a (ASCII mode)

    i get .hex file.
    But your C# utilite doesn't works (signature is 0xAA00 instead of 08AA).

    Where am I wrong?
    Could you give complete list of options for hex2000?

  • Hi Alex,

    Im using cmd file like this:

    hex2000.exe image.cmd

    and my image.cmd file contains:

    ./2833x_FLASH/Controller.out

    -b

    -boot

    -memwidth 16

    -o ./2833x_FLASH/hex.bin

    I get my hex file starting with 0xAA08

    The format of a HEX file is shortly described in "TMS320x2834x Delfino Boot ROM Rerference Guide", you may want to check that out.

    BTW, I end up loading the hex file instead of a flat image and I'm doing the section relocation on the target. That way you upload much smaller image and relocation code is very simple for DSP to handle (pretty much the same algorithm I implement in my utility).

  • Thanks for your answer!

  • hi i have a questioni am using 28335


    i am using asm(" LB 0x0032894a") in the main() based on the flash sector A
    above address is codestart on the f28335.cmd
    i want to jump to flash C so i called asm(" LB 0x0032894a") which address is codestart address in the flash sector c
    flash sector c have another program.
    i writed sector c with hex file(another project) through hex2000.
    following is hex.cmd file

    UPLOAD.out /* input COFF file */
    --map UPLOAD.map /* create a hex map file */
    -a /* create ASCII image */
    --image /* Create a memory image (no discontinuities) */
    --order=LS /* little endian */
    --zero /* reset address origin to 0 for output file(s) */
    --memwidth 16
    --boot /* create a boot table for all initialized sects */
    --entrypoint=_c_int00ROMS{
    FLASHC: org = 0x328000, len = 0x5000, romwidth = 16, files = {.\upload_final.hex}, fill = 0xffff
    }

    but after making hex file. i found FFFF at the 0x0032894a
    i think 0x0032894a having not ffff but a effective number. because 0x0032894a is codestart.
    please help me