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.

Yet another BSL UART question

Other Parts Discussed in Thread: MSP430F2618

Greetings all,

I am trying to implement the type of field update as described by Jens in a previous post. That is, write the binary to upper memory 0x10000, erase app in lower memory and rewrite with the new. Then erase the upper. Everything will be double checked with CRC16 checksums to ensure correctness.

I am using MSP430F2618, IAR and am writing it in C. My approach is to have main() be the bootloader section in the first flash segments and the app be a function in some upper segments. Interrupt vectors to be left alone. If unit comes out of reset and sees 0xFFFF @ 0x1FFFF it simply jumps to the app. 

The application has a mode wherein it listens for commands via radio, then UART. If the command is to update the firmware it calls the function to upload a (massaged) TI.TXT file, convert it to binary and store it in upper memory.

I know that the bootloader and app must be "unlinked" as it were - not sharing any variables, functions, etc. What should I be on the lookout for? Any gotchas? I am not a compiler/linker guy so I'm unsure of all the things that go on. Does this sound reasonable? Any links to applicable documents or examples?

Thanks for any tips and advice.

  • Joining two independent applkications into one MSP is a tricky thing.
    Personally, I solved this by writing the BSC (BootStrapCopier) in assembly language. In the assembly code, I don't have to care for any variables used by the applicaiton (which isn't running yet or where I won't return to). And when I launch the applciation, it will initialize and overwrite everything the assembly code might have had in use.
    The two applicaitons can reside in one project and compiled together while still being two independent parts. Just two lines to change and two to add in the linker script. (one new section added and two existing sections changed)

    If both are written in C, then they cannot be compiled in one project, as they would share the variable space (not really critical) and the startup code (which is critical) and the vector table (critical too).

  • Thanks J-M. I appreciate the feedback. I don't do assembler so that is out. (Did years ago, but don't have time to relearn it now.)  I have the linker set up to place the sections in different segments, but they are getting compiled together so that is an error on my part if I understand you correctly. Thanks for the insight. 

  • eltury said:
    but they are getting compiled together

    Yes, that's the problem.

    When programming in C, the linker will add initialization code that sets the system up for running a C program. And the linekr does so under ther assumption that there will only be one single C program ever. This init code needs to be executed before the BSL (if the BSL is in C too) and will contain specific information for this specific BSL/application combo. So when you replace the applciaiton, teh BSL needs to be replaced too as its init code needs to be replaced.
    This won't work.
    You'll need two separate projects, which are compiled and linked separately, but then fused on binary level before being flashed through the FET (or only the new application, when doing a field update through your BSL).

  • I do not use c, but I think you could use c to write both a “Loader” and various “Applications” that can be loaded by that Loader.

    As part of the underlining hardware, I would add a jumper/switch at an otherwise unused GPIO pin to select whether to run Loader or Application after each Reset.

    To develop the Loader in c, nothing special need to be used to direct the c compiler/linker. However, I would constrain myself to not using ISR and depend on polling. As a result, the object code would use only the lower address part of the Main Flash and the Reset Vector at 0x0FFFE-0x0FFFF. It would not use any interrupt vectors.

    I would write this Loader as follows.

    Near the very beginning of main(), I would read the setting of my special jumper/switch. If it is says run Application, the code would use a “Reserved” (i.e., undefined) Interrupt Vectors as a pointer to a procedure and invoke that procedure. If this vector contains 0xFFFF (the default content) this would have produced the same result as power up a totally erased chip.

    On the other hand, if reading of the special jumper/switch says run Loader, the code would try to follow the BSL protocol to erase/write the rest of Main Flash. There are a few exceptions to the protocol.

    1. It should not destroy itself in the lower address part of the Main Flesh. When it is told to erase or program that part of Main Flash, it should send an error massage and quit. When told to do Mass Erase, it should do a sequence of Sector Erases instead in order to preserve itself.

    2. It should not destroy its own Reset Vector. Whenever the Sector containing 0x0FFFE-0xFFFF is erased, it should re-program its own Reset Vector at those locations immediately. When it is told to program the Reset Vector of the Application, it should program that vector at the “Reserved” (i.e., undefined) Interrupt Vectors mentioned earlier instead of at 0x0FFFE-0xFFFF.

    Once the above Loader is working, we can develop the Applications in c. But here we need to use a special linker-command file that excludes the low address part of Main Flash used by the Loader. This is so that the Application would not overlap our Loader in Main Flash. Aside from this, there is no other restriction or precaution.

    The resulting object code of the Application can be loaded into the chip the “normal” way. But doing so will render our Loader useless because the Reset Vector of our Loader will be replaced. Thus instead, we should tell the compiler/linker to generate an object file suitable for BSL. And we can use our Loader to load it. The difference is, 0x0FFFE-0x0FFFF would still point to the Loader and our “Reserved” (i.e., undefined) Interrupt Vectors would point to the Application. After every reset, we will always run the front end of our Loader that have the option of either start the current Application or start to load a new Application.

  • Thanks so much O_C_Y for taking the time to reply.

    I believe I'm doing most of this now with the exception of the UART receive interrupt which I can omit and try polling as you suggest. My linker file loads the app several segments above the BSL and doesn't rewrite the interrupt section.

    I haven't got the option of adding a hardware switch since the board is already in production. Coming out of reset I check for new code in upper memory. Finding none I load the program counter with the address that starts the app section. When the app receives a command to upload the new code it does so and then I force a software reset. Now the BSL sees new code and proceeds to erase the old app segments and rewrite using the new code. After this (plus copious CRC checking) I erase the upper segment again and do another reset. 

    Seeing no new code the BSL loads the PC with app address and off we go again.

    I think I'm getting closer, but something is still overlapping. I suspect the reset vector may be getting me. Checking that out today.

    Thanks again for your help.

  • I have another scheme to decide whether to run existing Application or to load new Application. This one does not need a jumper/switch, but is slightly slower at power-up.

    After a power-up reset (and only after a power-up reset) I would assume the user may want to load Application. Thus I would set up the UART and wait for the BSL sync signal. Only after a certain time-out period, I would then try to run the existing Application (if any) instead .

    The main difference from your method is, I do not want to depend on the current content of Flash to determine whether to run or load Application. My methods depend on the users action at the power-on reset -- either setting of a jumper/switch, or running the counterpart of BSL on a PC connected to the chip while powering up the chip.

    To include CRC is fine. But you should not depend on CRC going bad to start BSL. Using or not using upper memory are both fine too. But I think you should not depend on that to start BSl either. The loader needs very small amount of memory. There are usually plenty of lower memory left for the Application. If not enough, it may expend to higher memory as usual. But this should be totally independent of BSL.

    In my scheme, the Loader and the Application are two separate projects. They have very little interaction. At the very beginning of the Loader, it may "jump" to the existing Application without doing the real loading of new Application. During the real loading of new Application, the Loader hide the reset vector of the new Application into some known hiding place in order to "jump" to it at the subsequent reset if needed. That is all.  

  • Thanks again.

    I just this morning was able to configure my linker and start up files to allow both projects to be written in C and have the BSL call the app.....and actually have it run. 

    Having the reset vector point to the right place (thanks again)  as well as loading the program counter with the address of the app start up code (not main()) did the trick. 

    I prefer not to depend on user actions simply because our users have a tendency to ignore instructions and barge ahead which may leave us with bricked product in the field. 

    I only use the CRC to verify that my text file uploads via radio are correct. 

  • Hi Friend,

    I am also working on same kind of project in which Firmware Update by using UART by sending command through PC. I am making custom BSL ,now i am able to write data in flash and also program counter But when i am going to reset my code it is giving  "No source available for "0x00". i couldn't go my application code. please suggest me i need to erase Stack Memory / Stack Pointer .....?

  • Posting same content into four different threads which are couple of years old is qualified as annoying behavior. Please never do that again. Better create your own thread.

  • Hi, 

    all four posting content are same because i was thinking if i past in four different threads at least some buddy help me that why .

     

  • satish akhade said:
    all four posting content are same because i was thinking if i past in four different threads at least some buddy help me that why .

    By spamming and trolling you don't get positive response but opposite. At least in result you lost my attention to your actual problem for sure.

**Attention** This is a public forum