EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

Reduce/Optimize boot code memory C++

Started by srao October 22, 2015
I need to cut down the size occupied by the boot code drastically to add
in new code. The current memory occupied by boot code +application+ram in
an external flash memory chip is  together 1MB. This cannot be increased.
The boot code is located at the high address. All source code is written
in C++.

This is clearly an embedded/firmware query and would need help so as to
how to optimize the source code keeping in mind the memory constraint.
This problem might not have one single solution, I am looking for ways in
which i can approach it.

Details: Enhancement on a legacy code,  borland compiler, 32bit flash
memory chip.
Limitations: 
1. no IDE. Build process is using make, breakpoints cannot be added. 
2. boot Make file build the boot.hex image file based on its dependent
files. 

FOR EXAMPLE : The boot make file below has files a and b dependent on it
to be built to create an hex image file. These files a, b contribute to
the code memory and hence overall boot memory.

$(ObjDir)a.obj:  w:a.cpp
$(ObjDir)b.obj:  w:b.cpp
main_obj=
    $(ObjDir)a.obj
    $(ObjDir)b.obj
mainEXE.exe:$(main_obj)
    mainEXE.exe
    mainEXE.map

Could someone please help me with possible steps to be taken to
decrease/optimize existing code or how to go about looking at this
problem?
---------------------------------------
Posted through http://www.EmbeddedRelated.com
On Thu, 22 Oct 2015 17:34:58 -0500, srao wrote:

> I need to cut down the size occupied by the boot code drastically to add > in new code. The current memory occupied by boot code +application+ram > in an external flash memory chip is together 1MB. This cannot be > increased. > The boot code is located at the high address. All source code is written > in C++. > > This is clearly an embedded/firmware query and would need help so as to > how to optimize the source code keeping in mind the memory constraint. > This problem might not have one single solution, I am looking for ways > in which i can approach it. > > Details: Enhancement on a legacy code, borland compiler, 32bit flash > memory chip. > Limitations: > 1. no IDE. Build process is using make, breakpoints cannot be added. > 2. boot Make file build the boot.hex image file based on its dependent > files. > > FOR EXAMPLE : The boot make file below has files a and b dependent on it > to be built to create an hex image file. These files a, b contribute to > the code memory and hence overall boot memory. > > $(ObjDir)a.obj: w:a.cpp $(ObjDir)b.obj: w:b.cpp main_obj= > $(ObjDir)a.obj $(ObjDir)b.obj > mainEXE.exe:$(main_obj) > mainEXE.exe mainEXE.map > > Could someone please help me with possible steps to be taken to > decrease/optimize existing code or how to go about looking at this > problem?
I'd start by seeing if the compiler has optimization flags, and if so, if it can optimize by size. If it can, and it's not already being done -- try it. Then I'd put in the necessary lines in the make file to make an assembly file for every .o file made. Then I'd pick through the resulting assembly files for anything eggregiously big. Look for similar functions, see if you can collapse them into one. Etc. -- it's not an easy thing to do, it's mostly lots of really picky work by someone with some expertise. -- Tim Wescott Wescott Design Services http://www.wescottdesign.com
On 10/22/2015 3:34 PM, srao wrote:
> I need to cut down the size occupied by the boot code drastically to add > in new code. The current memory occupied by boot code +application+ram in > an external flash memory chip is together 1MB. This cannot be increased. > The boot code is located at the high address. All source code is written > in C++.
In addition Tim's answer, I would take a look at the map file. It's a one stop view of everything in your output image. As he said, you might find things there that surprise you. Be on the the lookout for modules that can accidentally become included in your output although you'll never use them. That can sometimes happen with library code. Hopefully you'll have the source code to your library code. That helps to confirm what you see in your map file. I'm not super experienced in the use of C++ in embedded systems however I do know there are a number of C++ behaviors that can bloat code dramatically. Google for the differences between "embedded C++" and full featured C++. Then comb your code for the non-embedded C++ code signatures. Simply adding a C++ header file can brag in all sorts of junk. I hope you've considered the possibility that your boot code is as small as you can get it. 1 MB boot code seems a little big but it's all really application dependent. You didn't state how much footprint you need to cut. The more you need to cut, the harder it gets. JJS
On 23/10/15 01:47, Tim Wescott wrote:
> On Thu, 22 Oct 2015 17:34:58 -0500, srao wrote: > >> I need to cut down the size occupied by the boot code drastically to add >> in new code. The current memory occupied by boot code +application+ram >> in an external flash memory chip is together 1MB. This cannot be >> increased. >> The boot code is located at the high address. All source code is written >> in C++. >> >> This is clearly an embedded/firmware query and would need help so as to >> how to optimize the source code keeping in mind the memory constraint. >> This problem might not have one single solution, I am looking for ways >> in which i can approach it. >> >> Details: Enhancement on a legacy code, borland compiler, 32bit flash >> memory chip. >> Limitations: >> 1. no IDE. Build process is using make, breakpoints cannot be added. >> 2. boot Make file build the boot.hex image file based on its dependent >> files. >> >> FOR EXAMPLE : The boot make file below has files a and b dependent on it >> to be built to create an hex image file. These files a, b contribute to >> the code memory and hence overall boot memory. >> >> $(ObjDir)a.obj: w:a.cpp $(ObjDir)b.obj: w:b.cpp main_obj= >> $(ObjDir)a.obj $(ObjDir)b.obj >> mainEXE.exe:$(main_obj) >> mainEXE.exe mainEXE.map >> >> Could someone please help me with possible steps to be taken to >> decrease/optimize existing code or how to go about looking at this >> problem?
First, forget the boot code. Aim to reduce the size of the main application, not the boot loader. There are three reasons for that: 1. Boot code is more critical in many cases, as it is often part of the software update system. If your main program has a bug but your boot code is fine, you can update the software. If the boot code is buggy, you are stuck. Don't mess with a working bootloader. 2. If you save 1% of space on the bootloader, you have saved perhaps 100 bytes. If you save 1% of the space on the main program, you have saved 5K. The main program is bigger, so you have far more scope for improvement, and the changes are more effective. 3. You are working on the main program anyway.
> > I'd start by seeing if the compiler has optimization flags, and if so, if > it can optimize by size. If it can, and it's not already being done -- > try it.
Be /extremely/ careful about changing optimisation flags, especially on legacy projects, and especially if the toolchains have changed. It is depressingly common to hear people saying that their code works with -O0, but fails when optimising, because the programmer doesn't understand how C really works. You only need one such issue to get in serious trouble - and I presume the OP does not have access to any of the original developers for ideas. So while changing optimisation flags is worth a try, it must be combined with very extensive testing of the new version - test /everything/. And be particularly careful about data shared between different contexts (different threads, or main loop code and interrupt code, or between code and hardware). If the code has been developed without optimisation, the chances are high that there are some "volatile" qualifiers missing or other related problems. Other low-hanging fruit for compiler flags are ones to discard unused code and functions from the final image. And check that you are not putting debug information into the final image!
> > Then I'd put in the necessary lines in the make file to make an assembly > file for every .o file made. Then I'd pick through the resulting > assembly files for anything eggregiously big.
The key tool here is the map file, not assembly listing files. The map file will give summaries of the sizes used by each module, and give a starting point for finding out what is using most code space. Assembly files are good for detailed work later, but the OP is not at that stage yet.
> > Look for similar functions, see if you can collapse them into one. > > Etc. -- it's not an easy thing to do, it's mostly lots of really picky > work by someone with some expertise. >
Absolutely true. I have worked on projects that were so full that I have had to fight for a few bytes of code space (or /bits/ of data space!) in order to get changes into the system. It can be difficult work.
On 23/10/15 02:15, John Speth wrote:
> On 10/22/2015 3:34 PM, srao wrote: >> I need to cut down the size occupied by the boot code drastically to add >> in new code. The current memory occupied by boot code +application+ram in >> an external flash memory chip is together 1MB. This cannot be increased. >> The boot code is located at the high address. All source code is written >> in C++. > > In addition Tim's answer, I would take a look at the map file. It's a > one stop view of everything in your output image. As he said, you might > find things there that surprise you. Be on the the lookout for modules > that can accidentally become included in your output although you'll > never use them. That can sometimes happen with library code. Hopefully > you'll have the source code to your library code. That helps to confirm > what you see in your map file. > > I'm not super experienced in the use of C++ in embedded systems however > I do know there are a number of C++ behaviors that can bloat code > dramatically. Google for the differences between "embedded C++" and > full featured C++. Then comb your code for the non-embedded C++ code > signatures. Simply adding a C++ header file can brag in all sorts of junk.
This is a legacy system, and presumably old tools and old-style C++, which are far less efficient than modern C++. So this is definitely a potential issue. (Regarding compiler flags, you may be able to disable exceptions and RTTI if you are not using them - that can quickly save space.) I hope you meant "C++ for embedded programming" here, rather than "Embedded C++" - the disastrous EC++ semi-standard that was attempted a fair number of years, and although dead continues to haunt people to this day.
> > I hope you've considered the possibility that your boot code is as small > as you can get it. 1 MB boot code seems a little big but it's all > really application dependent. You didn't state how much footprint you > need to cut. The more you need to cut, the harder it gets. > > JJS > >
On Thursday, October 22, 2015 at 6:35:04 PM UTC-4, srao wrote:
> I need to cut down the size occupied by the boot code drastically to add > in new code. The current memory occupied by boot code +application+ram in > an external flash memory chip is together 1MB. This cannot be increased. > The boot code is located at the high address. All source code is written > in C++.
First, note the excellent cautions voiced about changing the bootloader.
> This is clearly an embedded/firmware query and would need help so as to > how to optimize the source code keeping in mind the memory constraint. > This problem might not have one single solution, I am looking for ways in > which i can approach it. > > Details: Enhancement on a legacy code, borland compiler, 32bit flash > memory chip.
Can you tell us: - 16-bit or 32-bit application? - what is the processor chip? - which version of the Borland toolchain? Older versions of the Borland toolchain have "issues" with some optimization settings - change these at your peril. Care must be taken with this toolchain to avoid dragging in all kinds of unwanted runtime parts. However, whomever originally did the bootloader was most likely somewhat aware of the issues. A review of the MAP file will show where the space is used. There are a number of techniques you can use to minimize memory use with this toolchain - suppressing inclusion of free storage management, forcing constants into ROM, etc... I'm still supporting an app with these tools (also 1MB total memory, including bootloader, and also using C++)... Hope this helps! Best Regards, Dave
>On Thursday, October 22, 2015 at 6:35:04 PM UTC-4, srao wrote: >> I need to cut down the size occupied by the boot code drastically to
add
>> in new code. The current memory occupied by boot code +application+ram
in
>> an external flash memory chip is together 1MB. This cannot be
increased.
>> The boot code is located at the high address. All source code is
written
>> in C++. > >First, note the excellent cautions voiced about changing the bootloader. > >> This is clearly an embedded/firmware query and would need help so as
to
>> how to optimize the source code keeping in mind the memory constraint. >> This problem might not have one single solution, I am looking for ways
in
>> which i can approach it. >> >> Details: Enhancement on a legacy code, borland compiler, 32bit flash >> memory chip. > >Can you tell us: >- 16-bit or 32-bit application? >- what is the processor chip? >- which version of the Borland toolchain? > >Older versions of the Borland toolchain have "issues" with some >optimization settings - change these at your peril. > >Care must be taken with this toolchain to avoid dragging in >all kinds of unwanted runtime parts. However, whomever originally >did the bootloader was most likely somewhat aware of the issues. >A review of the MAP file will show where the space is used. > >There are a number of techniques you can use to minimize >memory use with this toolchain - suppressing inclusion of >free storage management, forcing constants into ROM, etc... > >I'm still supporting an app with these tools (also 1MB total >memory, including bootloader, and also using C++)... > >Hope this helps! >Best Regards, Dave
Thank you for the reply, please see answers below
>Can you tell us: >- 16-bit or 32-bit application? >- what is the processor chip? >- which version of the Borland toolchain?
Its a 32 bit application Processor is 80188/86 intel however the flash ship on which the bootloader goes is an external memory chip. Borland version 4.5 .
>First, forget the boot code. Aim to reduce the size of the main >application, not the boot loader. There are three reasons for that:
I don't have privilege to do that, boot code would reside in high address and is allocated a particular amount of region. :( --------------------------------------- Posted through http://www.EmbeddedRelated.com
>On 23/10/15 02:15, John Speth wrote: >> On 10/22/2015 3:34 PM, srao wrote: >>> I need to cut down the size occupied by the boot code drastically to
add
>>> in new code. The current memory occupied by boot code
+application+ram
>in >>> an external flash memory chip is together 1MB. This cannot be >increased. >>> The boot code is located at the high address. All source code is
written
>>> in C++. >> >> In addition Tim's answer, I would take a look at the map file. It's a >> one stop view of everything in your output image. As he said, you
might
>> find things there that surprise you. Be on the the lookout for
modules
>> that can accidentally become included in your output although you'll >> never use them. That can sometimes happen with library code.
Hopefully
>> you'll have the source code to your library code. That helps to
confirm
>> what you see in your map file. >> >> I'm not super experienced in the use of C++ in embedded systems
however
>> I do know there are a number of C++ behaviors that can bloat code >> dramatically. Google for the differences between "embedded C++" and >> full featured C++. Then comb your code for the non-embedded C++ code >> signatures. Simply adding a C++ header file can brag in all sorts of >junk. > >This is a legacy system, and presumably old tools and old-style C++, >which are far less efficient than modern C++. So this is definitely a >potential issue. (Regarding compiler flags, you may be able to disable >exceptions and RTTI if you are not using them - that can quickly save >space.) > > >I hope you meant "C++ for embedded programming" here, rather than >"Embedded C++" - the disastrous EC++ semi-standard that was attempted a >fair number of years, and although dead continues to haunt people to >this day. > > > >> >> I hope you've considered the possibility that your boot code is as
small
>> as you can get it. 1 MB boot code seems a little big but it's all >> really application dependent. You didn't state how much footprint you >> need to cut. The more you need to cut, the harder it gets. >> >> JJS
> I hope you've considered the possibility that your boot code is as
small
> as you can get it. 1 MB boot code seems a little big but it's all > really application dependent. You didn't state how much footprint you
Boot code including the application comes to 1MB --------------------------------------- Posted through http://www.EmbeddedRelated.com
On 2015-10-23, srao <109468@EmbeddedRelated> wrote:

[Your attributions are seriously messed up BTW.]

> >>Can you tell us: >>- 16-bit or 32-bit application? >>- what is the processor chip? >>- which version of the Borland toolchain? > > > Its a 32 bit application > Processor is 80188/86 intel however the flash ship on which the bootloader > goes is an external memory chip.
The 80188 is a 16-bit processor, not 32-bit.
> Borland version 4.5 . > >>First, forget the boot code. Aim to reduce the size of the main >>application, not the boot loader. There are three reasons for that: > > I don't have privilege to do that, boot code would reside in high address > and is allocated a particular amount of region. :( >
If you are not allowed to do that, then are there any secondary functions which can be placed in the application area (those that don't need to be present for the primary bootloader code to work) ? What kind of functionality do you need to add into the bootloader code ? Is the bootloader downloading and burning the later versions of the application or are you physically burning bootloader + application using some external programmer ? Simon. -- Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP Microsoft: Bringing you 1980s technology to a 21st century world
On Fri, 23 Oct 2015 18:10:05 +0000 (UTC), Simon Clubley
<clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:

>On 2015-10-23, srao <109468@EmbeddedRelated> wrote: > >> David Brown wrote: >>>First, forget the boot code. Aim to reduce the size of the main >>>application, not the boot loader. There are three reasons for that: >>> : >> >> I don't have privilege to do that, boot code would reside in high address >> and is allocated a particular amount of region. :( > >If you are not allowed to do that, then are there any secondary functions >which can be placed in the application area (those that don't need to be >present for the primary bootloader code to work) ? > >What kind of functionality do you need to add into the bootloader code ? > >Is the bootloader downloading and burning the later versions of the >application or are you physically burning bootloader + application using >some external programmer ?
I think there may be a misunderstanding here. From the discussion I have formed the (maybe wrong) impression that the OP considers the "boot" code to be the entirety of the init/loader and application because they are linked (or at least bound) together into a single file. In contrast, others here are distinguishing those logical sections and advocating concentrating on the "program" portion. From the original post, srao wrote:
> FOR EXAMPLE : The boot make file below has files a and b > dependent on it to be built to create an hex image file. These > files a, b contribute to the code memory and hence overall boot > memory. > > $(ObjDir)a.obj: w:a.cpp > $(ObjDir)b.obj: w:b.cpp > main_obj= > $(ObjDir)a.obj > $(ObjDir)b.obj > mainEXE.exe:$(main_obj) > mainEXE.exe mainEXE.map > > Could someone please help me with possible steps to be taken to > decrease/optimize existing code or how to go about looking at this > problem?
Thus my question to srao is: Understanding that you didn't show us your actual makefile - what exactly is in the files you called "a.cpp" and "b.cpp"? Are they: - hardware initialization? - code which copies information from Flash to RAM? - code for the application's actual purpose? - something else? I think we need to make sure we are all talking about the same things. YMMV, George

The 2024 Embedded Online Conference