Hi,
In my compeny we are develope Embedded SW on the AT89C51RD2. The SW include BL & APP that compile together (due to no enough flash space). The purpose of this SW is to be able to upgrade only the Application section by writing the flash memory (The BL section is stored from 0x0054 to 0x5000 in the flash and the app is from 0x5001 to 0xFFFF). In order to be able to do it, i seted all the function in the BL section and the constants to absolute address in the flash memory (By using ?CO?, ?PR? - linker directive) and the uninitialized global variables were seted to fixed address by using _at_ keybord. The global variables of the App (0x5000 - 0xFFFF) section are free to link by linker.
My questions are: 1. What happened with the uninitialized global variables, where are they stored ? I know the the compiler initilaized thaem to zero but is there BSS locaation ? if so where is it ? and is it posible to set it for a absolute address in the XDATA ? 2. If the first sw was compiled and burn to the device and i changed only the application section (global variable was added) and compile it again but i want burn only the application (0x5000 and above) by using __api_wr_code_page, how is the SW will know about the new address of the new global ? 3. Where is the address of the global variables were stored (not initilaized, i know that the init global variables data were save in the C_INITSEG segment and it is copy to the RAM after the STARTUP and befure the main)?
I know it is complicated (and my english is bit bad) but i realy need your help. Thanks.
Building boot loader and application as one application is not really a good idea. You have no control of potential helper functions etc that the compiler may need to use to compute array offsets etc.
You really should try to build the boot loader stand-alone. And have the application perform a new initialization with a completely separate set of global initialized and cleared variables.
Per Westermark, thanks for the reply. I know it is not a good idea but i have to do it that way..
The globals likely have absolute addresses assigned to them, and embedded in the code, as the linker encounters them. The linker is trying to create a monolithic image, not one that can be easily separated, or combined with a different image.
You'd have to do a lot of work to partition the code and data into specific segments/sections.
You'd want to seriously look at splitting the two, you could perhaps reduce code size by putting common library code into the boot loader, at a known/fixed address, and have the application link to those routines.
"You'd want to seriously look at splitting the two, you could perhaps reduce code size by putting common library code into the boot loader, at a known/fixed address, and have the application link to those routines."
This tends to be a way better approach when being space-limited than building a single binary and later try to cut away some part of the image and replace with something else.
If I understand correctly, your recommendation is that if i have common function that the boot & the app use them, i need to create a libary, locate it in fix address and link it from the app ?
If so, how can i do it ? Do you have any explanation for creating libery ? and than how to link the app ?
Thanks !!
Is there BSS section ? If so, Can i set it to fix address ?
Fixed addresses doesn't work well when you can't at the same time have fixed sizes. Remember that an updated application is quite likely to need extra variables since it is seldom just a bug fix but often an improved software with some new functionality.
There are multiple ways to share code from a boot loader.
It is possible to it BIOS-style with fixed entry points or pointer tables. And it's also possible to let the linker know about the addresses of the functions so it can link an application to call directly instead of requiring a run-time indirection.
The one scary thing here is the architecture you are using, and the way C51 tries to play around and convert local variables and parameters into global variables based on call-tree analysis. The 8051 architecture just is so very hostile to high-level languages and software design.
All of this requires you learn a lot about your architecture, compiler and linker. I could provide you a comprehensive analysis based on my experience, but I would charge you for my time.
The 8051 is archaic, are you sure there aren't more cost effective solutions in 2014? There are ARM Cortex-M0 parts running $0.30
The ARM RealView linkers would take a definition file describing the address of functions in a ROM image, these addresses could be harvested from a .MAP file. I'm sure a similar method would exist in other linkers, or could be contrived from a suitably crafted object file.
You might want to start by analyzing the foot prints of the code you have now, what code is consume what amount of space, and what has shared commonality between the Boot Loader and Application if you split them.
What size memory do you have now? How much do the combined, and split, versions take? Identify the library functions that consume the most space.
The static space is typically initialized from a list of things to zero, and things to copy. Even if you partition where these allocations live, the list will still be difficult to separate.
You need to think in terms of what is easy and logical for the linker to generate, and apply those ideas to your problem, rather than come at it the other way and bludgeon the tools into the way you think you want to solve/address the problem.
Other than that, make the Boot Loader VERY simple, with enough suitably tailored and optimized code to perform the update function.
Building boot loader and application as one application is not really a good idea. I know it is not a good idea but i have to do it that way..
I ahve to build a car powered by dynamite, I know it is not a good idea but i have to do it that way
Erik