Reduce/Optimize boot code memory C++

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

formatting link

Reply to
srao
Loading thread data ...

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 
 Click to see the full signature
Reply to
Tim Wescott

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

Reply to
John Speth

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.
  1. You are working on the main program anyway.

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!

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.

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.

Reply to
David Brown

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.

Reply to
David Brown

First, note the excellent cautions voiced about changing the bootloader.

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

Reply to
Dave Nadler

add

in

increased.

written

to

in

Thank you for the reply, please see answers below

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 .

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

formatting link

Reply to
srao

add

+application+ram

written

might

modules

Hopefully

confirm

however

small

small

Boot code including the application comes to 1MB

--------------------------------------- Posted through

formatting link

Reply to
srao
[Your attributions are seriously messed up BTW.]

The 80188 is a 16-bit processor, not 32-bit.

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
Reply to
Simon Clubley

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.

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

Reply to
George Neuner

The initialization of an 80186/80188 can hardly be done in Borland C, and IMHO, not at all in C++. The initial start-up modules are very probably assembly code.

The processor wakes up with only chip select 0 alive, with a 1 kbyte window into the start-up ROM/Flash/EPROM, and this is a very tight place (but doable for an experienced programmer) in Borland C, but the machinery of Borland C++ is definitively too much.

--

-TV
Reply to
Tauno Voipio

The application I'm working on TODAY uses Borland C 5.0 for startup on the AM186 (80186 clone), save a very tiny bit of assembler. That's for both the bootloader and the main application. C++ is just fine BUT one must be careful not to drag in lots of junk.

Hope that helps, Best Regards, Dave

Reply to
Dave Nadler

The 80186 is a 16-bit processor and thus you have a 16-bit application. Can you clarify:

1) what is the flash chip part number? 2) confirm: you are trying to reduce the number of PAGES used by the bootloader, so you can get an additional flash PAGE or two for the application? 3) What are you using for processing the linker output into HEX file? If it's Paradigm Locate, can you please post the CFG and LOC files?

Thanks, Best Regards, Dave

Reply to
Dave Nadler

Yep. I'm using the same toolchain and target as the OP today. Yesterday I saved 722 bytes, and today I'm filling it up. Digging holes and filling them back up does get tedious...

Amazing that this product, which I designed 2 decades ago, is still being produced and sold!

See ya, Dave

Reply to
Dave Nadler

IIRC this toolchain predates that debacle by a decade or so... It's an early C++ with lots of exciting bugs, like calling dtors multiple times and interesting issues with 16-bit x86 segmentation. But, it was the most powerful tool around 20 years ago, and its still possible to get lots of benefit from C++ despite the warts...

See ya, Dave

Reply to
Dave Nadler

(Please try to get your quotations and attributions correct, and reply to the correct messages. If you are hoping that people here provide free expert advice, the least you can do is follow the standards of Usenet.

formatting link
provides a rather poor interface into the comp.arch.embedded newsgroup, and I believe it takes quite an effort to use it appropriately. If you intend to use this newsgroup regularly (and it is full of helpful and experienced people, even if you don't always like the helpful advice you are given), consider getting a proper Usenet client and server. Thunderbird is free on all platforms, and eternal-september.org is a free newsserver - it's a combination that works for many of us here.)

Back to the case in point - it was not at all clear that it is the boot program you are expanding rather than the main program. But all the advice you have been given regarding reducing the size of the main program, also applies for the boot program. But you need to be even more careful about testing your changes to the code or compilation flags to be sure that you have not caused new problems.

Reply to
David Brown

On October 23,2015 Dave Nadler wrote:-

1) Flashchip part number - MX29GL320ET@TSOP48 2)Yes, trying to reduce the memory to add in a new protocol implementation in boot code. 3)Make File build creates the boot image or hex file.

--------------------------------------- Posted through

formatting link

Reply to
srao

I'm no C++ expert, but what I've seen C gives smaller code. You cannot reprogram to that to try?

Have you looked at the OpenWatcom compiler? I'm positive people made

16 bit embedded code with it. But if it's using real C++ object features OW might not generate the smallest code.

Mat Nieuwenhoven

Reply to
Mat Nieuwenhoven

OK

The first step would be to change to plain C and read the generated assembly code. It helps immensely for understanding which high-level constructions are costly in machine code.

It seems that you did not understand the question:

The make utility does not do the image - for Borland tools, there must be a locator, e.g. Paradign Locate. The Borland linker produces a segment/group -relocatable image, usually known as DOS exe. It cannot be directly executed on bare hardware.

--

-TV
Reply to
Tauno Voipio

The flash chips used for this generation are all page-erase, so the minimum size of memory consumed by bootloader is the size of the boot page. In the application I'm working on, that's 32kb, which is more than enough for the C/C++ bootloader plus some diagnostic code using Borland C++ 4.5 vintage tools.

Reply to
Dave Nadler

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.