CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Is it "safe" to use malloc()/free() in bootloader?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
allenhuffman



Joined: 17 Jun 2019
Posts: 557
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

Is it "safe" to use malloc()/free() in bootloader?
PostPosted: Thu Dec 19, 2019 4:09 pm     Reply with quote

I am want to free up as much memory as possible that my bootloader uses when it jumps to the main application(). I am looking for suggestions.

My custom bootloader uses a FLASH_ERASE_SIZE buffer. This is currently static, so when I jump to the application() code, that memory is unavailable to the rest of the system. Our existing design uses a similar buffer in the application() (no bootloader) code, so it's no different if I do this now, but I wondered...

Are there any gotchas if I wanted to use a malloc() then free() it before I jump to application(), freeing up that memory for the rest of the system?

I am planning on moving my jump to application() back into main(), so there will be very little stack (stack variables, return stack, etc.) in use.

EDIT: I have to confess, I have *never* used malloc()/free() on an embedded non-OS system so I may just be more fearful of using it than I should.
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
jeremiah



Joined: 20 Jul 2010
Posts: 1355

View user's profile Send private message

PostPosted: Thu Dec 19, 2019 6:53 pm     Reply with quote

unless the application knows that the bootloader uses that buffer, it will use any available RAM, including that space. It doesn't matter if it was declared static in the bootloader or not.

Unless you are not compiling them separately (which defeats the purpose of a bootloader)?

I definitely don't recommend any heap usage though.
allenhuffman



Joined: 17 Jun 2019
Posts: 557
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PostPosted: Fri Dec 20, 2019 8:22 am     Reply with quote

jeremiah wrote:
unless the application knows that the bootloader uses that buffer, it will use any available RAM, including that space. It doesn't matter if it was declared static in the bootloader or not.

Unless you are not compiling them separately (which defeats the purpose of a bootloader)?

I definitely don't recommend any heap usage though.


Are you sure? In the bootloader code, it "runs" the main application by doing:

application()

And that is stubbed to live at a certain location, which gets overwritten by the application code.

Thus, if the system starts up and is using 2K, then calls application(), it is being treated like a function call. I expect if I returned from the application(), it would take me back to the bootloader.
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
allenhuffman



Joined: 17 Jun 2019
Posts: 557
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PostPosted: Fri Dec 20, 2019 8:30 am     Reply with quote

And to be clear -- I guess what I am asking is if there are any known gotchas if I have something like this in my code:

uint8_t *buffer = malloc(SIZE);

....then before I jump into the application() code...

free (buffer);

I worry about memory fragmentation that might prevent that memory from being used or seen by the application() code. With other environments, stack grows one way, and dynamic memory the other, but I don't know how this PIC environment behaves (Harvard architecture and all, if that even makes a different since RAM is RAM I would expect).
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
jeremiah



Joined: 20 Jul 2010
Posts: 1355

View user's profile Send private message

PostPosted: Fri Dec 20, 2019 3:30 pm     Reply with quote

allenhuffman wrote:
jeremiah wrote:
unless the application knows that the bootloader uses that buffer, it will use any available RAM, including that space. It doesn't matter if it was declared static in the bootloader or not.

Unless you are not compiling them separately (which defeats the purpose of a bootloader)?

I definitely don't recommend any heap usage though.


Are you sure? In the bootloader code, it "runs" the main application by doing:

application()

And that is stubbed to live at a certain location, which gets overwritten by the application code.

Thus, if the system starts up and is using 2K, then calls application(), it is being treated like a function call. I expect if I returned from the application(), it would take me back to the bootloader.


Think about it this way. When you create the bootloader, say you create 1 global variable. On the PIC24 this global variable will be normally placed at RAM address 0x800.

Now say you separately compile the application and you also have 1 global variable. The compiler will also normally place that variable at RAM address 0x800.

So now both the bootloader and the application have a global variable at the same address. Neither knows about the other's version sitting there. Honestly this is normally fine. The bootloader doesn't need the buffer while you are running the application, so it doesn't matter if the application uses that space. Additionally, IF the application needs to return to the bootloader, you typically can only go back to the application in the context of "restarting" your code, so it will most likely reset your global variable anyways.

That said, if you want to reserve RAM space for the bootloader only, you can do that, but you have to let the application know and what you generally do is reserve some RAM space in your application that it doesn't ever use (#locate is one method). That said, I don't believe your buffer falls into this category unless you have some requirement for the bootloader to remember what was in the buffer before launching the application. 99% of the time you don't care that they share RAM locations since each run of either the bootloader or the application is normally "from the beginning".
jeremiah



Joined: 20 Jul 2010
Posts: 1355

View user's profile Send private message

PostPosted: Fri Dec 20, 2019 3:33 pm     Reply with quote

allenhuffman wrote:
And to be clear -- I guess what I am asking is if there are any known gotchas if I have something like this in my code:

uint8_t *buffer = malloc(SIZE);

....then before I jump into the application() code...

free (buffer);

I worry about memory fragmentation that might prevent that memory from being used or seen by the application() code. With other environments, stack grows one way, and dynamic memory the other, but I don't know how this PIC environment behaves (Harvard architecture and all, if that even makes a different since RAM is RAM I would expect).


I would not recommend malloc in general for embedded programs. Per my previous post: The application is going to potentially use the same RAM as your HEAP does in the bootloader, so if you have any expectations of returning to the bootloader and it remembering the last HEAP state, then that will cause you problems if there is overlap. This isn't a malloc or HEAP specific problem, just a problem with RAM sharing in general. That said, I can't think of a single reason for your bootloader to need to remember what it last malloc'ed when coming back from an application. It normally just restarts at that point, which would reset your HEAP anyways.
allenhuffman



Joined: 17 Jun 2019
Posts: 557
Location: Des Moines, Iowa, USA

View user's profile Send private message Visit poster's website

PostPosted: Mon Dec 30, 2019 4:05 pm     Reply with quote

jeremiah wrote:
I would not recommend malloc in general for embedded programs. Per my previous post: The application is going to potentially use the same RAM as your HEAP does in the bootloader, so if you have any expectations of returning to the bootloader and it remembering the last HEAP state, then that will cause you problems if there is overlap. This isn't a malloc or HEAP specific problem, just a problem with RAM sharing in general. That said, I can't think of a single reason for your bootloader to need to remember what it last malloc'ed when coming back from an application. It normally just restarts at that point, which would reset your HEAP anyways.


It's fully controlled in this example -- only used as a temporary ERASE_SIZE buffer for incoming data.

As to an earlier response -- Since my buffer and handful of variables is on the stack, the SP would be there when I jump to application(), so that still seems like the SP would be past that, and that memory would be allocated. At least, that's how it was with what we called Subroutine Modules for OS-9. They were just modules with C functions, and you'd obtain the address of them via a dispatch table and then assign function pointer and jump to it. They had no access to globals, and used the same stack. So if the caller had used 6K of stack space then jumped into the sub, it would start there and continue.
_________________
Allen C. Huffman, Sub-Etha Software (est. 1990) http://www.subethasoftware.com
Embedded C, Arduino, MSP430, ESP8266/32, BASIC Stamp and PIC24 programmer.
http://www.whywouldyouwanttodothat.com ?
Ttelmah



Joined: 11 Mar 2010
Posts: 19543

View user's profile Send private message

PostPosted: Tue Dec 31, 2019 3:56 am     Reply with quote

No.

The key point is the 'application', in this case is a completely separate
program which has no knowledge at all of anything that has been done
or used by the bootloader. It launches assuming it has full access to
everything available to the processor (except the ROM area that it
has been built to exclude for the bootloader). It is built separately, and
does not 'know' that it has been launched by the bootloader.
It will actually reconfigure the stack as part of it's initialisation.
asmallri



Joined: 12 Aug 2004
Posts: 1635
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Tue Dec 31, 2019 12:10 pm     Reply with quote

Hi Allen,

As indicated by Ttelmah, the bootloader and application are "ships in the night". The application is not aware of the bootloader's presence and does all the required processor initialization.

That being said, you need to bootloader to be as stable as possible. For this reason, I personally would avoid the use of dynamic allocation of memory space in a bootloader.
_________________
Regards, Andrew

http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!!
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group