C51 RAM Segments Init and NoInit

Greetings!

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!

Parents
  • 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

       #include <reg51m.h>

       xdata int iXData1;
       xdata int iXData2;
       xdata int iXData3;

    Then I added the following to the project->options->LX_Locate tabs User classes box:

       XDATA_TEST(0xFF00-0xFF10)

    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....

Reply
  • 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

       #include <reg51m.h>

       xdata int iXData1;
       xdata int iXData2;
       xdata int iXData3;

    Then I added the following to the project->options->LX_Locate tabs User classes box:

       XDATA_TEST(0xFF00-0xFF10)

    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....

Children
No data
More questions in this forum