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.

.bin File Format/Manually Downloading a .bin File

Other Parts Discussed in Thread: UNIFLASH, TM4C1231H6PZ, LMFLASHPROGRAMMER

Hello,

I am trying to do a field upgrade on my TM4C1231H6PZ processor by manually downloading the binary (erasing the flash then programming the flash with the .bin data directly) rather than using a utility such as uniflash or LM Flash Programmer.  However, when I compare the .bin file to the disassembled code that runs from the .bin, I notice that the .bin file is not loaded byte for byte into the microcontroller- in fact, the byte manipulation that takes place seems to vary depending on the address within the binary (data prior to address 0x26c seem to be byte swapped over 4 bytes, while data after that address seem to be byte swapped over two bytes).  

The process I'm using involves placing the "upgrade loader" code into a portion of flash that is not erased or overwritten, by modifying the .cmd file- that portion of the process is working fine.  I will read the .bin data from an external flash.

Two questions: is there documentation on the format of the .bin file I'm dealing with?  I've searched for it without success.  And my second question is if there is a problem with this approach other than getting the .bin data into the proper format?

Thanks!

Cindy

  • You're comparing to disassembled code?

    It would be quite unusual for a binary file to be anything other than a raw image. How, exactly are you getting your binaries?

    Robert
  • Hello Cindy,

    en.wikipedia.org/.../Binary_file

    Sometimes hex reader represent the data in Big Endian. Note that TM4C uses the Little endian format. Also since the flash locations are always 32-bits (4 bytes wide), a byte wide program is not going to be a good solution.

    Regards
    Amit
  • Hi Robert,

    Yes, disassembled code.

    The binary is generated using the post-processing step within code composer- the binaries in question can be downloaded and used successfully via LM Flash Programmer, so I'm not questioning the accuracy of the .bin files.  So when I download the .bin file and look at the disassembly, then compare that with what I see in the .bin file (viewed with a hex editor), the two don't match.  Each byte is there, but there is byte swapping going on.

    Thanks for helping me again!

    Cindy

  • Your comparison method is suspect. Matching disassembly to binary can be an 'interesting' process. I've seen assembly/ disassembly views switch byte order depending on what they were presenting, sometimes with options. Which only confounds the confusion when the disassembler loses sync.

    Robert
  • Hi Amit,
    If I took the .bin file and read it in byte by byte (without any reordering) and used that data to program the flash (maintaining the order), would that create a working program? I know my flash requires 32-bit words, but it appears the .bin files are always a multiple of 4 bytes. And my flash programs in 1K blocks, so I would need to make sure that partial blocks are filled with 0xFFFFFFFF in the unused sections.

    Thanks,
    Cindy
  • Lovely. However, if I manually download a binary (write the binary to the flash in the byte order within the file) and then look at the disassembly, I should see the same thing as if I download the binary with LM Flash Programmer. And I'm pretty sure that's not the case. I'm going to try that and see...

    Cindy
  • Your best bet by far is to do a binary compare. Don't fool around with intermediates.

    Robert
  • Hello Cindy

    Are you using the Serial Interfaces to download the binary (since you explicitly mentioned the "non" use of LMFlashProgrammer and Uniflash)?

    Regards
    Amit
  • Hello Cynthia

    The programming unit on the device is 4 bytes (32-bit words). So even if you want you cannot program 1KByte in a single shot.

    Regards
    Amit
  • Hi Amit,
    Maybe there's a fundamental flaw in what I'm trying to do. I have a .bin file sitting in an external flash. I was going to read the file, 4 bytes at a time, creating the 32bit words needed by the flash programmer. I would then use the FlashProgram command to program the flash, starting at address 0 and continuing on until the entire binary was loaded. I thought FlashProgram could program up to one block at a time? It's mute if my approach is flawed...
    Thanks,
    Cindy
  • Thanks Robert. Actually, I think my hex editor is giving me what's actually in the binary- but I might be trying to do the impossible as far as using the binary information to program my microcontroller manually...
    Cindy
  • Hello Cynthia

    You can program upto 32 words using the Flash Write Buffer, but the concept of flash program still remains on a 32-bit word boundary

    Regards
    Amit
  • Cindy, do you mean the FlashProgram TivaWare function? Or are you referring to some sort of command instead?

    If the former, have you looked at the bootloader and flash programming examples?

    Robert
  • Hi Amit,

    Yes, I understand how the flash is programmed- and it IS getting programmed with the data, but not exactly how I would expect.  Using the BLInternalFlashProgram() utility provided in the TIVA examples, here is some disassembly after the download, and the disassembly of code when I download directly from Code Composer.  Things in the beginning track, but things go south at 0x26C, where it looks like there are some endian issues.

    Thanks for you help,

    Cindy

    Using flash utility:

    00000000: 20000200 ANDCS R0, R0, R0, LSL #4
    00000004: 000007D3 LDREQD R0, [R0], -R3
    00000008: 000007D9 LDREQD R0, [R0], -R9
    0000000c: 000007DB LDREQD R0, [R0], -R11
    00000010: 000007DD LDREQD R0, [R0], -R13
    00000014: 000007DD LDREQD R0, [R0], -R13
    00000018: 000007DD LDREQD R0, [R0], -R13

    ...

    00000268: 000007DD LDREQD R0, [R0], -R13
    0000026c: 4684B5F8 PKHTBMI R11, R4, R8, ASR, #11
    00000270: F04F2500 SUBNV R2, PC, R0, LSL #10
    00000274: 27030E01 STRCS R0, [R3, -PC, ROR R1]
    00000278: F005FA0E ANDNV PC, R5, R14, LSL #20
    0000027c: D00F4201 ANDLE R4, PC, R1, LSL #4
    00000280: 4FC4F8DC SVCMI #12908764

    Using Code Composer (correct result):

    00000000: 20000200 ANDCS R0, R0, R0, LSL #4
    00000004: 000007D3 LDREQD R0, [R0], -R3
    00000008: 000007D9 LDREQD R0, [R0], -R9
    0000000c: 000007DB LDREQD R0, [R0], -R11
    00000010: 000007DD LDREQD R0, [R0], -R13
    00000014: 000007DD LDREQD R0, [R0], -R13
    00000018: 000007DD LDREQD R0, [R0], -R13

    ...

    00000268: 000007DD LDREQD R0, [R0], -R13
    GPIOPadConfigSet():
    0000026c: B5F8 PUSH {R3, R4, R5, R6, R7, LR}
    0000026e: 4684 MOV R12, R0
    00000270: 2500 MOVS R5, #0
    00000272: F04F0E01 MOV.W R14, #1
    00000276: 2703 MOVS R7, #3
    $C$DW$L$GPIOPadConfigSet$2$B, $C$L1:
    00000278: FA0EF005 LSL.W R0, R14, R5
    0000027c: 4201 TST R1, R0
    0000027e: D00F BEQ $C$DW$L$GPIOPadConfigSet$4$B
    $C$DW$L$GPIOPadConfigSet$2$E, $C$DW$L$GPIOPadConfigSet$3$B:
    00000280: F8DC4FC4 LDR.W R4, [R12, #4036]

  • Hi Robert,
    I've tried using the TivaWare FlashProgram and also the BLInternalFlashProgram() routine from the bootloader example. The flash is getting erased and programmed, but WHAT is programmed is not quite right. Please see my response to Amit with what I see when I use Code Composer to look at the flash when I load the code normally using Code Composer and also when I use the flash routine.
    Thanks, Cindy
  • Hello Cindy

    It does not seem to be an endian issue, but missing bytes (half words) and it's reassembly. Can you achieve the same result with LMFlashProgrammer?

    Regards
    Amit
  • Hi Amit,

    LMFlashProgrammer works fine with the binary- but the binary I'm struggling with has been written to a flash that's external to my microcontroller. A crc is passed with the data, and I've done a byte by byte comparison by hand, and the data and the original binary match.

    Where do you see missing bytes? If you look at the bytes starting at 0x26C:

    Original Binary: f8 b5 84 46
    Working Disassembly: b5 f8 46 84
    Failing Disassembly: 46 84 b5 f8

    I think the bytes are all there, but the ordering is different. Here's what the hex editor show for the original .bin file starting at address 0x260:

    dd 07 00 00 dd 07 00 00 dd 07 00 00 f8 b5 84 46
    00 25 4f f0 01 0e 03 27 0e fa 05 f0 01 42 0f d0
    dc f8 c4 4f 6e 00 07 fa 06 f0 84 43 cc f8 c4 4f

    Oddly enough, the data PRIOR to 0x26C looks the same in all instances:
    Original Binary: dd 07 00 00
    Working Disassembly: 00 00 07 dd
    Failing Disassembly: 00 00 07 dd

    It looks like the Working Disassembly is showing different data handling before and after 0x26C... at the beginning of the binary bytes are swapped in groups of 4, and after 0x26C bytes are swapped in groups of two...

    Thanks

    Cindy
  • Ok, somehow I missed the important detail of you copying from external Flash. That leads to several suggestions

    First, definitely review the existing bootloaders in detail.

    Second, for your initial testing do not use a program. Use well defined data. It's inability to be executed is not relevant to your problem. Fill a small block of with a series of bytes that increase in value as your first pattern. Write this to the micro using standard JTAG tools. Read It back and write it to your external storage. Compare the two files. Use a binary compare not a disassembler. For that matter the pattern is simple enough that you can see any differences by eye in a hex editor or viewer.

    Don't overlook binary compare utilities just because they are part of your host OS. Sure, there are more sophisticated utilities available but the simple ones are a start.

    Robert
  • Please see reply below- I didn't get notified that I posted, so I'm thinking you didn't either...
  • Hi Robert,

    I can move data in and out of the micro's flash and get what I would expect- a counting pattern of 00 01 02 03 04 05 06 07 ... will show up as 03 02 01 00 07 06 05 04 ... in the flash and I can read those 32-bit words out. Comparison isn't straight-forward because of the way data is loaded into the flash with bytes reversed. But in this simple situation, I can tell everything works as expected, visually. Note that the loading and unloading of data here is done by my software.

    I can load a binary into the micro's flash via JTAG (LM Flash Programmer), but I'm not sure how to look at the data once it's loaded- I normally access it via Code Composer, and I need to have valid code in place for the debug to work for that.

    I'm pretty confident that the data I load is actually going in as expected. I'm back to my original question of why the following binary disassembles as follows:

    dd 07 00 00 dd 07 00 00 dd 07 00 00 f8 b5 84 46
    00 25 4f f0 01 0e 03 27 0e fa 05 f0 01 42 0f d0->

    00000260: 000007DD LDREQD R0, [R0], -R13
    00000264: 000007DD LDREQD R0, [R0], -R13
    00000268: 000007DD LDREQD R0, [R0], -R13
    GPIOPadConfigSet():
    0000026c: B5F8 PUSH {R3, R4, R5, R6, R7, LR}
    0000026e: 4684 MOV R12, R0
    00000270: 2500 MOVS R5, #0
    00000272: F04F0E01 MOV.W R14, #1

    My downloader yields:
    00000268: 000007DD LDREQD R0, [R0], -R13
    0000026c: 4684B5F8 PKHTBMI R11, R4, R8, ASR, #11
    00000270: F04F2500 SUBNV R2, PC, R0, LSL #10
    00000274: 27030E01 STRCS R0, [R3, -PC, ROR R1]
    00000278: F005FA0E ANDNV PC, R5, R14, LSL #20

    And note that the binary data above I got in TWO ways. First I looked at the .bin file with a hex editor, and second, I wrote a program to print out the data byte by byte, so I could make sure the hex editor was correct. My version is simply putting bytes into the flash the way I would expect, while the other version is doing something different.

    Thanks again for your help...

    Cindy
  • Hello Cindy

    In the working disassembly the image shows up as

    00000268: 000007DD LDREQD R0, [R0], -R13
    GPIOPadConfigSet():
    0000026c: B5F8 PUSH {R3, R4, R5, R6, R7, LR}
    0000026e: 4684 MOV R12, R0

    In the failing it shows as

    00000268: 000007DD LDREQD R0, [R0], -R13
    0000026c: 4684B5F8 PKHTBMI R11, R4, R8, ASR, #11

    If you would notice that working image has 4684B5F8 at 0x26C which is same as failing one. It is the next 32-bit word which is out of order

    Failing: 00000270: F04F2500 SUBNV R2, PC, R0, LSL #10

    Working: 00000270: 2500 MOVS R5, #0
    00000272: F04F0E01 MOV.W R14, #1

    Some how 0E01 has got deleted.

    Regards
    Amit
  • Hi Amit,

    Thanks for looking over my problem, but unfortunately, all the bytes are accounted for in the working and the failing versions.  Here's a longer version:

    dd 07 00 00 dd 07 00 00 dd 07 00 00 f8 b5 84 46
    00 25 4f f0 01 0e 03 27 0e fa 05 f0 01 42 0f d0->

    Via Code Composer download:
    00000260: 000007DD LDREQD R0, [R0], -R13
    00000264: 000007DD LDREQD R0, [R0], -R13
    00000268: 000007DD LDREQD R0, [R0], -R13
    GPIOPadConfigSet():
    0000026c: B5F8 PUSH {R3, R4, R5, R6, R7, LR}
    0000026e: 4684 MOV R12, R0
    00000270: 2500 MOVS R5, #0
    00000272: F04F0E01 MOV.W R14, #1

    My downloader yields:
    00000268: 000007DD LDREQD R0, [R0], -R13
    0000026c: 4684B5F8 PKHTBMI R11, R4, R8, ASR, #11
    00000270: F04F2500 SUBNV R2, PC, R0, LSL #10
    00000274: 27030E01 STRCS R0, [R3, -PC, ROR R1]
    00000278: F005FA0E ANDNV PC, R5, R14, LSL #20

    Note that my downloader downloads the binary byte by byte always in the same order, but the working version doesn't.  Also my version is attempting to create 32-bit instructions every time, while the working version has 16-bit instructions as well.  

    Thanks again for your help,

    Cindy

  • Hello Cindy,

    Since you have your own downloader, can you add a debug print on the PC side where the bytes being sent to the TM4C is printed as well on the PC application to a file to see if the issue is on the transmit or during reassembly?

    Regards
    Amit
  • Hi Amit,

    I did that yesterday for Robert- I wrote a series of bytes into the flash and then read them back and also looked at them in the debugger. Everything is getting into the processor as expected. It's the assembly that's having a problem.

    I'm wondering if this has something to do with thumb vs. ARM instructions? How does the processor know that an instruction is 16 bits vs 32 bits? My version has problems with the very first instruction, trying to make it 32 bits when it should be 16, which results in immediate failure.

    Thanks,
    Cindy
  • Cynthia Crutchfield said:
    I can move data in and out of the micro's flash and get what I would expect- a counting pattern of 00 01 02 03 04 05 06 07 ... will show up as 03 02 01 00 07 06 05 04 ... in the flash and I can read those 32-bit words out.

    Of the length you are encountering problems? If not you need to do longer.

    Also have you checked this using both programming methods?

    Cynthia Crutchfield said:
    Comparison isn't straight-forward because of the way data is loaded into the flash with bytes reversed.

    Sorry, no the comparison is very straightforward. 

    • Program using the conventional method (using JTAG)
    • Download from the micro into file A (using JTAG)
    • Program using your external method
    • Download from the micro into file B (using JTAG)
    • Binary compare the two files (Do NOT use the disassembler, use your OS file compare or a hex editor. If you do not have a hex editor download something like PSPad)

    Cynthia Crutchfield said:
    . I'm back to my original question of why the following binary disassembles

    The disassembler is a big part of your problem. It can only confuse the issue.

    Robert

  • Cynthia Crutchfield said:
    It's the assembly that's having a problem.

    That makes no sense at all. It's not the "assembly".

    Robert

  • Hi Robert,

    I asked Amit this question, if you see my thread with him- how does the micro identify a 16 bit instruction vs a 32 bit one? Since my code is a mix (thumb and ARM I guess?) how does the micro know the difference? The first instruction should be 16 bits, but my failing version is trying to create a 32 bit instruction.

    I'll see if I can get the binary back out of the micro- I'll have to see if I can do it with uniflash or LM flash programmer...

    Thanks again for your help,

    Cindy
  • Hello Cindy

    No, it does not. The thumb or ARM instruction is a function of the processor and not the flash or download tool. Binary is a representation format. You can download a 64-bit wide word program it as 2x32 bit words and still get the CPU (does not matter ARM or Intel) to work.

    Regards
    Amit
  • ARM determined the start of a Thumb or ARM sequence based on the instruction address jumped to. The Cortex architecture largely eliminated the ARM instructions.

    You should be able to get the binary out of the micro with any programmer, it's a pretty basic function that's needed for verification. I've not seen any that aren't then able to write that to disk. I suppose such a broken tool could exist.

    Robert
  • Hi Robert,

    I was actually able to use code composer to do the extraction in both cases- I didn't know that was a tool.  So I downloaded the code in the traditional way and then extracted the binary, and then did the download in my code and extracted that binary.  Saved both files and did a linux "diff" which showed no difference.

    So at this point I'm wondering if there's a problem in the way I'm trying to execute the binary, after I manually load it.  I'm using:

    HWREG(NVIC_APINT) = NVIC_APINT_VECTKEY | NVIC_APINT_SYSRESETREQ;

    Is that appropriate?

    Thanks,

    Cindy

  • Hi Robert,

    Problem solved. I was able to achieve a proper reset using:

    ROM_SysCtlReset();

    HWREG(NVIC_APINT) = NVIC_APINT_VECTKEY | NVIC_APINT_SYSRESETREQ; was the problem. I'm not sure why is was failing- this is the method I've used when a user wants to do a software reboot.

    So you were right about the disassembler doing me no favors. The code was correct all along but I just wasn't able to get it to begin execution.

    Thanks SO MUCH for all your help and pointing me in the right direction. I learned a lot from this arduous journey- things that will help me with all my future work.

    Gratefully,

    Cindy
  • Hi Amit,

    My problem all along was NOT the binary, it was how I was resetting the micro after the load. I was using:

    HWREG(NVIC_APINT) = NVIC_APINT_VECTKEY | NVIC_APINT_SYSRESETREQ;

    which was failing for some reason. Switching to:

    ROM_SysCtlReset();

    did the trick. I'm still not sure why one reset method works and the other doesn't, but I'm now able to execute the manually downloaded binary. The binary was correct all along, I just was failing to start execution properly.

    Thanks again for all your help and for always being so responsive. I really didn't know if what I was attempting to do was valid, so you helped point me in the right direction.

    Gratefully,

    Cindy
  • Hello Cindy,

    ROM_SysCtlReset calls the same line that is stated to be "not working

    Regards
    Amit
  • Hi Amit,

    Stepping through the code, executing

    HWREG(NVIC_APINT) = NVIC_APINT_VECTKEY | NVIC_APINT_SYSRESETREQ;

    yields the warning: 'No source available for 0x7d2". I always gave up at that point, since in my previous experience, stepping over that line would have caused a reboot. In this case, however, if I had just run my program at that point, it would have caused a reboot and successful code execution. Taking out all break points and running the code, I observe no difference between the two reboot methods, as you asserted. I just never had enough confidence in what I was doing to ever try to run it without breakpoints.

    Thanks again for all your help.

    Cindy
  • Hello Cynthia

    May be that is because of the optimization of the code.

    Regards
    Amit
  • I recently had to look at the reset for another cortex processor. ARM notes that some precautions with memory barriers are necessary, pretty minor really. Perhaps stepping through has negative affects on the instruction sequence. There's not many places where you could run into something like that but this might be one.

    Robert
  • Hello Robert

    But I believe, Cindy was initially not using the debugger when the issue came up.

    Regards
    Amit
  • Glad we were of help

    Robert