Jump to content
L.R.A

TM4C and bootloaders

Recommended Posts

Hi everyone,

I am trying to make a custom boot loader. Yes I know there is one in Tivaware - getting some out of it.

I was making a small test.

I compile a application code and a bootloader code.

The app code starts at flash 0x4000. I converted the binary into a C array.
With this I was able to add to the boot test code, that same array and then copy it to flash at 0x4000. I checked the memory and everything seems I was copie as it should.

After that I change the vector table address to 0x4000 - the application code vector table address - and jump the PC to 0x4000.
The problem is that after 2 instructions the code jumps to 0x0 and then it just goes into somewhere in the RAM.

Anyone got any idea what could be happening? 

Share this post


Link to post
Share on other sites

How did you compile your app code?

 

I'm not 100% on the ISR implementation for the TM4C. I suspect that the value at 0x4000 actually directs the PC into the main routine as if the app code was loaded at 0x0000. You will need to atleast add some linker flags in order to push your .text block down to 0x4000, the linker needs to know where the program will be loaded in order to patch any absolute addresses.

 

Typically bootloaders can be designed to sit at the bottom of the FLASH, that way the app doesn't require special compiling options.

Share this post


Link to post
Share on other sites

I compile the app code as a normal code except I changed it to start at 0x4000 and also the vector table at 0x4000. This was to solve any absolute address problem.

I think one of the things I forgot is to also change the stack pointer, not sure on that one. I don't know how it works in the ARM. The example I saw would mean I jump the SP to 0x4000 and the PC to 0x4004.
The behavior I observed seems to be a lockup - I've been reading through a book on ARM-M3 and M4. It's when a really bad (double?) fault occurs (more detail I've still yet to read on).

Before that bottom of the flash issue, I want to first solve as is.
 

Share this post


Link to post
Share on other sites

@L.R.A The stack pointer will point to RAM unlikely you need to alter that in anyway. I suppose you've looked at the layout of the vectors on the TM4C. it appears that vector address 0 is actually the initial SP, hence jumping to that will case your program to jump into RAM. Try setting the PC to the address in vector 1?

post-274-0-39984500-1452504349_thumb.png

 

 

 

Thanks for the tip about the website, I haven't updated it for along time.... It's hosted on a server alongside some teamspeak servers me and some friends use for games. guess somehow the http server was closed. It's back up now for what it's worth. (hasn't been updated for 4 years....)

Share this post


Link to post
Share on other sites

Sorry for the lateness.

The linker script is the same as any Tivaware example. The difference is I change the APP_BASE on the app codes.

Found out the problems. I decided to copy a assembly code to jump the PC and it worked better (not sure why though, the address was the same).
Then added, before jumping, a load do the SP with the starting address of the application code.
Before jumping I also needed to change the vector table offset, but I had that previously I believe.

It's all working just fine now.



The thing is. I got my bootloader always running in flash but I have no problems at all (so why do all examples copy it and run it in RAM?)
The code is also in the main, not in the ResetISR. It seems to work just fine, not sure on the advantages but the basic default init on the ResetISR does just fine. I tried adding everything to the Reset ISR and it did not work - I think my substitute of _c_int00 did not work very well :/

Anyway, everything is working just fine now. Still, I would like to know more why run the bootloader from flash and use only the reset ISR.
 

Share this post


Link to post
Share on other sites

Glad to hear it's all working for you. It's been awhile since I did any work on MSP430 bootloaders. But recently I've done some AVR ones.

 

One reason I can think for running it in RAM is for speed. Typically when a write is initiated other Flash reads are stalled. So running in RAM may yeild performance benefits, especially if the CPU can be receiving new data over UART while page writes are in progress.

 

I also know that the MSP430 BSL makes use of a loadable bootloader that the Host PC loads into RAM, then runs it from the BSL interface. It can easily be updated by TI, and performs better than the inbuilt BSL code, which has to be very tight and only contains the essentials.

 

 

I'm not sure about the resetISR, but it may be to do with removing the other vector addresses from Flash? Which essentially are just wasting space since the bootloader doesn't enable interrupts.

Share this post


Link to post
Share on other sites

Hi everyone,

The process has a handshake so there won't be any packets being received while programming the flash, so no problem there.

The reset ISR I guess is to be as fast as possible and customize more what is turned on. As is it's working - and there must be a compromise on time developing so I am keeping it this way, everything in main().

It's pretty much all done if you count out optimizations.
I am now trying to get a library functions to be in a specific flash address. Unfortunately the only way I know also puts the variables there so it only works on RAM.

In the future I might adapt this to a stand alone bootloader over serial.

Share this post


Link to post
Share on other sites

You can add a .section attribute to your function declarations. Then add a .section relocation flag when you link.

 

It's more common to indirectly address functions. You can have a function table at a fixed address. With each index of the table mapped to a specific function. You then populate this table with pointers to each function. It does take up more FLASH.

 

Are you wanting to reuse some routines from within your main app? Typically this is avoided because it adds complications.

Share this post


Link to post
Share on other sites

Hi greeeg, thanks for the answer.


I am trying to erase the routines :P

Right now I gave up on trying to go by that way. Instead I am trying to use a post build script to convert the.bin into a C array into a file. That file will then be linked to the boot project.
Just trying to get a scrip - right now I always do that manually with a program-

Share this post


Link to post
Share on other sites

Yay got it working. Now when I build the first firmware it automatically creates a C array of the binary. The bootoader build is configured to search the debug output of the first firmware and include the file. :D
Now any updates I do on the first firmware go automatically into the full bootloader

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...