Const referencing RL78

    I'm using the R5F100BG MCU which has 128k of flash memory. I'm running into an issue where in Im unable to read any data beyond 64K.
For example

 

In the linker file, I define a location

-Z(CODE)TEST_AREA=[10000-103FF]

 

#pragma segment="TEST_AREA"

#pragma location=" TEST_AREA "

const unsigned char test_array[4] ={0x40,0x41,0x42,0x043};

 

the above code initializes test_array with the values and places it in memory location starting from 0x10000

 

Now, if I try to read the values of the test_array by

 

uint8_t test_value;

test_value= test_array[0];

the test_value always returns 0 instead of 0x40

 

    The manual says that the data in 0x0000 to 0xFFFF is mirrored in 0xF0000 to 0xFFFFF and the values are fetched from the mirrored location.  Is there a way I can disable the mirroring and force IAR compiler to generate code that would read data from the absolute memory location instead of reading data from the mirrored location?

  • Mirroring of the near constant area is a hardware feature of RL78 controllers can not be disabled. If you are using a 16bit access (= near access) always the address area 0xF0000-0xFFFFF is accessed

    For devices with more than 64KB Flash memory you can configure in register PMC which memory area shall be mirrored ( 0 => mirror starts at 0x02000, 1 => mirror starts at 0x12000). Please take care that the setting for near constant area of EWRL78 matches the setting of the PMC register.

    Outside the mirror area you have to define a far constant respectively a far pointer. Far constant data can be located anywhere in the Flash memory and by a far pointer you can read the complete Flash memory.

    Here is an example.

    __far const unsigned char far_test_array[4] ={0x40,0x41,0x42,0x043};

    __near const unsigned char near_test_array[4] ={0x50,0x51,0x52,0x053};


    const unsigned char __far * myFarPtr= &far_test_array[0];

    const unsigned char __near * myNearPtr= &near_test_array[0];


    volatile unsigned char r1,r2;
    void main( void )
    {
      r1 = *myFarPtr;
      r2 = *myNearPtr;

      r1 = far_test_array[3];
      r2 = near_test_array[3];
    }


    If you are using the data model near (which is strongly recommended to get efficient code) the data attribute  __near  can be skipped, because it is the default data attribute.

  • Hi Srivatsav,

    in IAR the default data model is the "NEAR" model. In this model the 64KB memory range of 0xF0000 to 0xFFFFF is accessed with 16-bit pointers.

    In your example the data in 0x10000... is out of reach for the standard data addressing in the NEAR model.

    If you stick to the NEAR model you could use a far pointer to the array:

    const unsigned char __far *fp;  // fp is a pointer to constant values of type unsigned char

    fp = &test_array[0];   // fp points to the first element in test_array

    test_value = *fp;       // reading test_array[0]

    test_value = *(fp + i)  // reading test_array[i]

  • In reply to Rutronik-Ralf:

    Its been a while... This issue is closed... I contacted tech support and they suggested the above two solutions :) ... Thanks guys!