Using the Cache as RAM

The cache can be disabled temporarily or permanently and used as RAM in stead. When the cache is disabled, the device runs at reduced speed. This increases the device power consumption. If you want to use the cache as cache and temporarily disable it for extra RAM at runtime, jump ahead to the Dynamic GPRAM section. If you want to configure the cache to be used as RAM from the outset, see the Configure the Cache as GPRAM section.

Configure the Cache as GPRAM

If your application needs more memory, or if you need more space in SRAM, the cache can be re-purposed as RAM. This will allow the linker to store parts of the compiled application in this section of the RAM. This section will be referred to as the general purpose RAM (GPRAM). This will cause the program to run at a slightly reduced speed, and it will increase the device power consumption in sleep. This is because the GPRAM, contrary to a cache, will have to be powered even when the device is sleeping. The current consumption in standby mode with and without cache retained is listed in the CC2640R2 datasheet.

With the cache re-purposed as RAM, the program will run at a slightly decreased speed. This will cause the device to spend more time when active, which again will give a higher power consumption. How this will affect the device power consumption will depend on application. For some applications the added power consumption will be very small, but for processing intensive application it will be slightly higher. Please verify your application current consumption by using the method described in the Measuring CC13xx and CC26xx current consumption (SWRA478).

In order to enable using the cache as RAM, two things need to be done. Firstly, the program must be told to retain the cache/GPRAM when it’s being used. Secondly, the linker must be told to allocate the memory region used as cache to GPRAM, and what parts of code to store in the GPRAM. This is done in the linker command/configuration file. The syntax for the linker command/configuration file is slightly different in CCS and IAR. To read more about the CCS linker command file, see the article Linker Command File Primer. To read more about the IAR linker, see IAR C/C++ Development Guide.

If you want to use the cache as RAM in a project, follow these steps:

Note

The steps will be different for CCS users and IAR users. The steps will also differ depending on what example project your project is based on. For the example projects found in the BLE5-Stack folder, only step 1-5 will be required.

1. In the syscfg file, go to TI DevicesDevice Configuration and select Disable Flash Cache

  1. In main(), add the following code:
Retain cache in sleep.
#ifdef CACHE_AS_RAM
// retain cache during standby
Power_setConstraint(PowerCC26XX_SB_VIMS_CACHE_RETAIN);
Power_setConstraint(PowerCC26XX_NEED_FLASH_IN_IDLE);
#else
// Enable iCache pre-fetching
VIMSConfigure(VIMS_BASE, TRUE, TRUE);
// Enable cache
VIMSModeSet(VIMS_BASE, VIMS_MODE_ENABLED);
#endif //CACHE_AS_RAM

Important

Please make sure your program is not using VIMS while using cache as RAM.

In the same file, include the following files:

/* Power Driver */
#include <ti/drivers/Power.h>
#include <ti/drivers/power/PowerCC26XX.h>
/* Header files required to enable instruction fetch cache */
#include <ti/devices/cc26x0r2/inc/hw_memmap.h>
#include <ti/devices/cc26x0r2/driverlib/vims.h>
  1. Go to the compiler predefines and add CACHE_AS_RAM.

4. The GPRAM memory area must be defined in the linker command file. This syntax is different for the CCS and IAR linker. IAR specific instructions will follow the CCS specific instructions.

In CCS, the linker command file ends with .cmd (e.g. cc13x2_cc26x2_app.cmd).

Under Memory Sizes, add defines for GPRAM start and length.
  /*******************************************************************************
   * Memory Sizes
   */
  #define FLASH_BASE   0x00000000
  #define GPRAM_BASE   0x11000000
  #define RAM_BASE     0x20000000
  #define ROM_BASE     0x10000000

  #define FLASH_SIZE   0x00058000
  #define GPRAM_SIZE   0x00002000
  #define RAM_SIZE     0x00014000
  #define ROM_SIZE     0x00040000
Add GPRAM under Memory Definitions.
  /*******************************************************************************
   * GPRAM
   */

  #ifdef CACHE_AS_RAM
    #define GPRAM_START GPRAM_BASE
    #define GPRAM_END   (GPRAM_START + GPRAM_SIZE - 1)
  #endif /* CACHE_AS_RAM */
In MEMORY{}, allocate room for GPRAM.
    #ifdef CACHE_AS_RAM
      GPRAM(RWX) : origin = GPRAM_START, length = GPRAM_SIZE
    #endif /* CACHE_AS_RAM */
In SECTIONS{}, move .bss from SRAM to GPRAM.
  GROUP > SRAM
  {
    .data
    #ifndef CACHE_AS_RAM
    .bss
    #endif /* CACHE_AS_RAM */
    .vtable
    .vtable_ram
    vtable_ram
    .sysmem
    .nonretenvar

  } LOAD_END(heapStart)

  .stack            :   >  SRAM (HIGH) LOAD_START(heapEnd)

  #ifdef CACHE_AS_RAM
  .bss :
  {
    *(.bss)
  } > GPRAM
  #endif /* CACHE_AS_RAM */

Rebuild your application. This will move .bss from SRAM to GPRAM and place the auto-heap size start after. Other objects can also be moved. See Using the AUX RAM as RAM for an example of this.

. In IAR, the linker configuration file ends with .icf (e.g. cc26xx_app.icf).

Add defines for GPRAM start and length under Memory Definitions.
  //////////////////////////////////////////////////////////////////////////////
  // GPRAM
  //
  if ( isdefinedsymbol(CACHE_AS_RAM) )
  {
    define symbol GPRAM_START           = 0x11000000;
    define symbol GPRAM_SIZE            = 0x2000;
    define symbol GPRAM_END             = GPRAM_START + GPRAM_SIZE;
  }
Under Memory Regions, allocate room for GPRAM.
  if ( isdefinedsymbol(CACHE_AS_RAM) )
  {
    define region GPRAM               = mem:[from GPRAM_START to GPRAM_END];
  }
Under Memory Placement, move .bss from SRAM to GPRAM.
  if ( isdefinedsymbol(CACHE_AS_RAM) )
  {
    // GPRAM
    define block GPDATA { section .bss };
    place in GPRAM { block GPDATA } except { object ll.o };
  }

Rebuild your application. This will move .bss from SRAM to GPRAM. Other objects can also be moved. See Using the AUX RAM as RAM for an example of this.

Dynamic GPRAM

In this mode, the cache will be used as RAM only when we need it. At all other times, the cache will operate as normal. When the cache is disabled and the memory is used as RAM, the current consumption will increase as described in the Configure the Cache as GPRAM section. When the cache is not configured as RAM but runs as usual, the power consumption is not increased.

An example use-case is a device that sometimes receives or sends a data stream with a high throughput. When the device is not streaming, it can use the cache as usual. When the device receives the signal to start streaming, the device disables the cache and uses the GPRAM to store a buffer for the stream. When the device receives the command to stop streaming, the memory is freed and the cache is re-enabled.