i am building for a board with the mc9s12xep100 target and using the banked memory model. When the data allocated to the DEFAULT_RAM section exceeds the 8K RAM, i need to modify my linker prm file to map additional data/variables into paged RAM so that everything will fit, for instance...
DEFAULT_RAM
INTO RAM, RAM_F4, RAM_F5, RAM_F6, RAM_F7, RAM_F8, RAM_F9, RAM_FA, RAM_FB, RAM_FC, RAM_FD;
PAGED_RAM INTO RAM_F0, RAM_F1, RAM_F2, RAM_F3;
this allows the link to suceed instead of failing due to insuffient RAM allocation. Examing the resultant .map file shows the variables that get mapped to the RAM pages starting with RAM_F4. The problem we get is that our generated source code doesn't know what variables/objects the linker ends up mapping into paged ram and therefore doesn't know to add the __rptr or __far pointer qualifiers to pointers that are used to access this data. Alternatively, i've used the #pragma to force certain large data arrays into a RAM page as follows...(as per TN238)
#pragma DATA_SEG __RPAGE_SEG PAGED_RAM
extern LargeDataStruct TestParams;
#pragma DATA_SEG DEFAULT
but we still have the same problem in that our generated source code doesn't know that pointers to the TestParams data need to have the __rptr qualifier, so....
Is there a default compiler setting i can use that will cause all pointers to be declared with __far qualifier? If so, what are the ramifications of that change, presumably some performance hit due to extra code required to use 24 bit pointers?
rmbvector wrote:i am building for a board with the mc9s12xep100 target and using the banked memory model. When the data allocated to the DEFAULT_RAM section exceeds the 8K RAM, i need to modify my linker prm file to map additional data/variables into paged RAM so that everything will fit, for instance...
DEFAULT_RAM
INTO RAM, RAM_F4, RAM_F5, RAM_F6, RAM_F7, RAM_F8, RAM_F9, RAM_FA, RAM_FB, RAM_FC, RAM_FD;
PAGED_RAM INTO RAM_F0, RAM_F1, RAM_F2, RAM_F3;
this allows the link to suceed instead of failing due to insuffient RAM allocation. Examing the resultant .map file shows the variables that get mapped to the RAM pages starting with RAM_F4. The problem we get is that our generated source code doesn't know what variables/objects the linker ends up mapping into paged ram and therefore doesn't know to add the __rptr or __far pointer qualifiers to pointers that are used to access this data.
Don't do that. As you noted the code does not work and it is far better to fail during linking than to see that the code fails to access variables at runtime.
DEFAULT_RAM must be placed only into non paged ram in the banked memory model.
So use your second attempt.
Alternatively, i've used the #pragma to force certain large data arrays into a RAM page as follows...(as per TN238)
#pragma DATA_SEG __RPAGE_SEG PAGED_RAM
extern LargeDataStruct TestParams;
#pragma DATA_SEG DEFAULT
but we still have the same problem in that our generated source code doesn't know that pointers to the TestParams data need to have the __rptr qualifier, so....
I don't think that pointer and direct accesses are the "same" problem. For pointers I would hope you get a warning when taking the address of a paged variable and assign it to a non paged pointer. This is the setup I normally recommend if it is doable. Note that both __far and __rptr pointers can point to TestParams. __rptr pointers are more efficient but restricted to RAM, __far pointers can point to anything, including flash and EEPROM.
Is there a default compiler setting i can use that will cause all pointers to be declared with __far qualifier? If so, what are the ramifications of that change, presumably some performance hit due to extra code required to use 24 bit pointers?
You are looking for the large memory model. The performance hit is real and I would try to stick with banked.
For task based software one concept is also to assign RPAGE banks to specific tasks and to set RPAGE at every task switch (and never otherwise).
Daniel
CompilerGuru wrote:
DEFAULT_RAM must be placed only into non paged ram in the banked memory model.
so given that we can't use any paged RAM in the allocation scheme for DEFAULT_RAM, i have changed my prm back to
DEFAULT_RAM INTO RAM;
PAGED_RAM INTO RAM_F0, RAM_F1, RAM_F2, RAM_F3, RAM_F4, RAM_F5, RAM_F6, RAM_F7, RAM_F8, RAM_F9, RAM_FA, RAM_FB, RAM_FC, RAM_FD;
which generates the original linker error due to insuffient RAM allocation. Now, if i understand what you're suggesting, i would then have to identify all the data/variables what failed to fit into the 8K and use the #pragma to allocate that data/variables to some RAM page. Subsequently, i would also have to be sure (manually) that any code that declares a pointer to that data includes the __rptr or __far pointer qualifier to ensure the compiler produces the appropriate code to address an object that resides in paged RAM (namely setup the RPAGE register accordingly and use RPAGE+offset global address to access it.)
CompilerGuru wrote:
I don't think that pointer and direct accesses are the "same" problem. For pointers I would hope you get a warning when taking the address of a paged variable and assign it to a non paged pointer.
with regards to this point, note that in both cases we are experiencing the problem because we are using pointers to access the TestParam data. Direct access of this data seems to work. The second method here declares the TestParam object inside the #pragma and other auto generated code produces a pointer (unknowingly without the __rptr qualifier) to access it.
Also note that you do not get a warning when taking the address of a paged variable and assign it to a non paged pointer.
so the dilemma i now face is i have to somehow flag to our code generator which objects require __rptr qualifiers.
CompilerGuru wrote:You are looking for the large memory model. The performance hit is real and I would try to stick with banked.
am i correct in assuming that the large memory model essentially treats all pointers as __far ?
thanks again for our help!
> (namely setup the RPAGE register accordingly and use RPAGE+offset global aaddressA little copy paste bug I think. For the __far pointer case the GPAGE register is used. Or RPAGE accesses are using logical and not global addresses, but its never RPAGE with a global address.
> to access it.)
>Also note that you do not get a warning when taking the address of a paged
>variable and assign it to a non paged pointer.
I don't have a compiler here, but I warning would have been nice from the compiler :smileysad:.
>am i correct in assuming that the large memory model essentially treats all
>pointers as __far ?
Essentially yes. Unqualified pointers (and objects) are accessed using gpage access.
So as if they would have a __far qualifier. There can still be explicitely __near (or __rptr, __eptr,...) qualified pointers which keep their explicit behavior.
Daniel