This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

What is the extra information in my .HEX file?

Background:
I'm a noob. I'm attempting to add the ability to update the application on a NXP LPC2468 by using the USB and adding a bootloader. It sort of works. The unit has an LCD and a keypad. A very minor change to the main application will work without any problem. But for instance, if I add a character to a menu, it will cause a problem: The text for the rest of the application will be shifted or entirely wrong.

The bootloader and the USB driver is located in sectors 0-8 in the Flash. The main application is located in Sectors 9-20. When a USB drive with a correctly named .HEX file is connected, the bootloader will erase sectors 9-20, then load the new main application .HEX from the USB.

When comparing Hex files I can see the problem, but I don't know what it is. If I change an existing character lets say a "1" to a "2", I can see the corresponding value in the .HEX change from "0x31" to "0x32" just as it should. If i then remove that character things in the bootloader section will change. I think this is because the "lookup table" for the text is located here? also the area containing the text seems to be randomly pieced together like the compiler optimizes the locations to save memory. When removing a character this area gets changed quite alot.

Also I can see the now incorrect text in the on chip RAM. The IAP commands if i understand them correctly are only for the flash. How do I update the RAM after a USB upload?

Also the part of the .HEX that changes is not part of my code, at least it is not represented in the MAP file. I don't know what it is.

I'm sure I have alot of ignorance about the inner functions of the processor and the compiler. If fact I don't know even what to search for!

Please help!

Thanks,

Todd

  • But for instance, if I add a character to a menu, it will cause a problem: The text for the rest of the application will be shifted or entirely wrong.

    Why is this a problem? Why do you call it "entirely wrong"? What would be "right"?

    ... long description of HEX file transformations ...

    I cannot see how this is relevant.

    Are you trying to get firmware update functionality to work? If so, what's the use in deep-diving into the HEX file?

  • I don't think you need to look at this problem at .hex file lever. Did you try to debug this? The shift could be due to a buffer alignment problem, for example.

  • It sounds like the program is using absolute addresses to get access to the strings. So a change that moves the strings will make these absolute addresses point at the wrong data.

    But in the end, you really need to post some source code for us to be able to comment what may be wrong.

  • Yes I think you are correct. They are strings and the USB upload process does not update the addresses for the new string information. I have verified that with the debugger. What portion of the code do you need to see? All of it? This is for a company not a personal project. i'm a little hesitant to throw it all out there into cyberspace if I don't have too.

    If I load the same hex file through the ULINK2 it properly updates the entire memory.

  • Because the Hex file is what is being uploaded through the USB to update the application. My problem is that some information in the hex file is changing in the bootloader section when I make a change to the main application section. That change obviously needs to be with the app and not the boot loader. The Bootloader is removed from the hex file prior to copying it to the USB drive. My problem (well one of them) is that I don't know what this section of the Hex file is so I don't know how to fix it. it is not referenced at all by the Memory.MAP file that I can see.

  • Bootloader is removed from the hex file prior to copying it to the USB drive.

    Sounds like you are developing the bootloader and the main application as a single program. That is the wrong way to do it. They should be developed as two separate programs.

  • Sounds like you are developing the bootloader and the main application as a single program. That is the wrong way to do it. They should be developed as two separate programs.

    Yes that is correct all in one program. We currently program our units with the ULINK2. Is it possible to load 2 separate programs (bootloader and app) at the same time?

    Is it completely impossible to do it as one program or just much harder?

  • The USB loader in the bootloader does not contain any information for preprocessing the HEX data and convert all references where the "main" program references into the "bootloader" part, and that errs when you try to mix one boot loader with another "main" application. To perform reference fixups, there must be relocation information in the file you program your device with. But HEX files do not contain any relocation information. And your boot loader wouldn't know what to do with them anyway - it's a dumb loader. Not a full linker.

    Never, ever, try to get the compiler to build boot loader and application together. Even when you do everything 100% correct, you can't control the small helper functions that the compiler will use. Things like performing long division or similar, that the processor may not have native instruction-set support for and that is too big to just inline everytime it is needed.

    It is possible to have the same source code for both boot loader and application. But it does require two separate compilations, and would then result in two separate hex files. It's possible to merge these two hex files manually (or automatically with suitable tools) if you need a single file for factory production.

    But your project setup must guarantee that any change in the boot loader (as long as the size still fits in reserved space) will not change any single byte in the application. And any change in the application must not result in any single byte changed in the boot loader. Everything else is a big, epic, failure. What seems to work will fail when you are in most need of it to work.

  • Sounds like you are developing the bootloader and the main application as a single program. That is the wrong way to do it. They should be developed as two separate programs.

    Yes that is correct all in one program. We currently program our units with the ULINK2. Is it possible to load 2 separate programs (bootloader and app) at the same time?

    Is it completely impossible to do it as one program or just much harder?

    OK, let us see
    a compiler will have small routines like "mult16", "switch", .... they are unavoidable, a typical piece of C will call 10 or more. This is just a common compiler developement technique, nothing strange.

    Now visualize you have your "monoprogram" working and ship units and a small bug is found. You create another "monoprogram" with a small change and delete the bootloader part and load the app part. CRASH!! OOPS the bootloader 'remembers' where whatever small routines that happen to be in the app section used to be and the app will call whatever small routines that happen to be in the the boot section where the new link happened to locate them.

    Can you do it as a "monoprogram"? sure, if you do not mind nightmares and bleeding ulcers from overuse of aspirin.

    GET THE TWO MADE SEPAR$ATE PROGRAMS NOW

    Erik

  • first, Per brings up more things against a "monoprogram" than I thought of. I am sure that there are more

    second,
    But your project setup must guarantee that any change in the boot loader (as long as the size still fits in reserved space) will not change any single byte in the application. And any change in the application must not result in any single byte changed in the boot loader.
    even that will not guarantee functionality

    Erik

  • The Bootloader is removed from the hex file prior to copying it to the USB drive.

    Actually no, it isn't. The stuff you remove from the modified whole program's hex file is not "The Bootloader". It's something similar to it, but not the same thing as the actual bootloader portion sitting on the machine. And that's what's breaking your program.

    The core of your problem is that your bootloader part contains lots of references to addresses of things in the application part of your program --- the strings you already noticed, but there will be lots more. All those references will generally break apart every time you change anything in the application program. Stuff will move around effectively randomly.

    The solution for that problem is to not allow the bootloader to refer to any auto-assigned addresses outside itself. It should only refer to a very small number of absolute addresses, ultimately only one: the main program's base address. The easiest way to guarantee that is to build the boot loader as separate, stand-alone application project. It should have nothing to do with the main program.

  • You have all convinced me that I'm not going to get this to work reliably till I separate the bootloader from the app.

    Thanks for all your help! Wish me luck!

    Todd

  • "developing the bootloader and the main application as a single program"
    is a quite standard way here in my current company; and of course, it works well.

    "What seems to work will fail when you are in most need of it to work."
    It fails, mainly because a MCU design flaw, and/or a compiler design flaw.

    The bootloader I developed is a freak for my current company.

    My bootloader is able to dump the content of flash, so that I can compare the HEX file with the programmed flash to make sure the flash programming is successful. Of course this is a totally unnecessary functionality.

    --
    Hopeless Battle.

  • So if your company is making one compile/link pass that ends up generating both a boot loader and an application - how have you managed to get the compiler/linker to not call any helper function that gets stored in one memory area from the other memory area?

    Or is the boot loader written 100% in assembler?

    The nice thing with building both in the same step is that it looks like it works, until you make the wrong type of changes in the code. Suddenly a change in the boot loader generates changes in the application area. Or a change in the application generates changes in the boot loader area. And when that happens, you are in a deep pile of ***. The equipment already shipped can't be updated until the problem is solved. But if the shipped boot loader has a reference into the application area, you just have to figure out how to get the compiler to produce a new application that still has the exact same contents at that location.

    By the way - all boot loaders are expected to have code to verify that they correctly program the application area. But that is something completely different from having a boot loader that doesn't contain unexpected, "hidden" references into the application area, that makes the boot loader fail after an update of the application.

  • is a quite standard way here in my current company; and of course, it works well.

    The bootloader I am commonly using has a small dependency between it and the application in the form of a piece of RAM telling the bootloader whether it should perform IAP, in addition to some checksums of the data and the location of the data in RAM. No explicit dependencies exist beyond that - otherwise, the thing is becoming one program, really...