I have an old product which needs a tune up. It's build with an old C51 UV3 compiler and has battery backed up RAM. I need to segment the battery backed up XDATA into zero initialized and not initialilzed data. There are are a few messages about which discuss modifying XDATASTART and XDATALENGTH in startupMX.a51 to zero init only part of XDATA and then locating variables that need to be preserved in the address range XDATASTART+XDATALENGTH range. Ok, I get that, but it appears one has to manually locate each preserved variable into that memory range with an __at__ keyword. As there are a large number of preserved variables, manually calcuating a ordered location for each one promises to be a hugely labor intensive process. In the ARM world, there's a NOINIT keyword which allows the linker to locate variables in the proper segment. Is there any equivalent in the C51 world?
Other embedded compilers (unfortunately none for 8051) which allow the creation of user defined segments, any one of which can be declared zero init or not. By declaring a variable as part of those segments, one can control it's initialization. Alas, now that I reflect those are all for ARM processors. Does such a linker definition capacity exist in Keil's C51 world?
Thanks for any help!
dlpaulsen said:it appears one has to manually locate each preserved variable into that memory range with an __at__ keyword
I don't think that's true.
IIRC, each source file gets its own (set of) memory segments - and you can get the linker to allocate the segment to a memory range...
Otherwise, the "standard" approach would be to gather your variables into a struct, and locate that.
Note that there are two Linkers:
does your use of "MX" suggest that you're using an "extended" 8051 ... ?
dlpaulsen said:I have an old product which needs a tune up. It's build with an old C51 UV3 compiler and has battery backed up RAM. I need to segment the battery backed up XDATA into zero initialized and not initialilzed data.
That description appears strange enough to be hard to believe..
Splitting up XRAM like that would never be just a "tune-up". Particularly not if it has you complaining about the amount of steps to do it being oh so cumbersome. If if this were really a tune-up, the majority of that work would be done already, and you'ld just be moving some variables from one side to the other of the divide.
At this point, it looks like user_classes might provide a solution.
I used one of the example programs to test out userclasses. I added the following file to the project:
pragma USERCLASS (XDATA=TEST) // data will be in XDATA_TEST
xdata int iXData1; xdata int iXData2; xdata int iXData3;
Then I added the following to the project->options->LX_Locate tabs User classes box:
Building the project and checking its .MAP file finds this (amongst a lot else):
START STOP LENGTH ALIGN RELOC MEMORY CLASS SEGMENT NAME ========================================================================= 000000H 000001H 000002H BYTE UNIT XDATA ?XD?MAIN_B 000002H 00FEFFH 00FEFEH --- --- **GAP** 00FF00H 00FF05H 000006H BYTE UNIT XDATA_TEST ?XD?USRCLSXDATA
It looks like the linker has located the three integers (6 bytes) specifically where I asked (0xFF00). Unless I'm missing something (which is certainly possible) I can use this technique to segment my xdata memory by specifying a start address and length in startupMX.a51 as memory to be initialize and leaving the remainder outside that range as un-initialized. The messy part will be modifying the original code so that all the variable definitions are in their own files with the appropriate #pragma USERCLASS definitions. Not the most intuitive way to get from here to there and back again, but hey! if it works....
Splitting up XRAM like that would never be just a "tune-up".
you missed that he is using battery backed RAM
View all questions in Keil forum