This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Execute code from RAM instead of flash in nrf52840 for gcc

in  nRF52840, current consumption can be decreased by executing code from RAM instead of from flash. How is it possible to execute code from RAM? how to executing code from RAM instead of from flash in linker file?
  • Hi,

    You can reference the code in this post. Note that if the function running in RAM calls softdevice functions or other functions located in flash inside, you will not save much current by running code from RAM, as these functions will still be executed from flash.

    Best regards,
    Jørgen

  • As per your suggestion I have made changes for one of the function ACCORDING TO this post. BUT i face same essue that not resolved in post. compiler gives same error

    s/main.c:38:(.data+0x2): relocation truncated to fit: R_ARM_THM_CALL against symbol `ble_init' defined in .text.ble_init section in _build/nrf52840_xxaa_Ble_Interface.c.o

  • This error seems to occur because the RAM function does calls to functions in flash. See this answer from RK. Like I said, you will not gain much in terms of current consumption when doing this with short functions that does call to existing SDK/Softdevice functions. It only makes sense if you have standalone functions doing heavy calculation, keeping the CPU running for long periods of time.

  • There is perhaps a simpler solution which avoids relocating functions into RAM with zero wait state; use the cache instead which executes small groups of instructions with zero wait state as long as other functions outside the range of the cache are not invoked. That includes interrupts, of course, but if rare they only incolve a cache reload.

     // Enable instruction cache (I-Cache) - ensure NVMC is not busy first
     while(NRF_NVMC->READY == 0) ;
     NRF_NVMC->ICACHECNF = 0x101;
     //NRF_NVMC->IHIT
     //NRF_NVMC->IMISS

    The hit/miss tracking/diagnostic counters are non-resettable, but useful for occasional trace to see how effective the cache is in a specific test (I tried everything to reset them, but nothing worked); enable just before testing a function helps

      NRF_LOG_INFO("Cache Enabled 0x%08X 0x%08X 0x%08X 0x%08X", NRF_NVMC->ICACHECNF, NRF_NVMC->IHIT, NRF_NVMC->IMISS, NRF_NVMC->CONFIG);
      NRF_LOG_FLUSH();

    And a description of how the cache works:

    // 11.6 Cache
    // An instruction cache (I-Cache) can be enabled for the ICODE bus in the NVMC.
    // See the Memory map in Memory map on page 24 for the location of Flash.
    // A cache hit is an instruction fetch from the cache, and it has a 0 wait-state delay. The number of wait-states
    // for a cache miss, where the instruction is not available in the cache and needs to be fetched from Flash,
    // depends on the processor frequency and is shown in CPU on page 21
    // Enabling the cache can increase CPU performance and reduce power consumption by reducing the number
    // of wait cycles and the number of flash accesses. This will depend on the cache hit rate. Cache will use some
    // current when enabled. If the reduction in average current due to reduced flash accesses is larger than the
    // cache power requirement, the average current to execute the program code will reduce.
    // When disabled, the cache does not use current and does not retain its content.
    // It is possible to enable cache profiling to analyze the performance of the cache using the
    // ICACHECNF register. When profiling is enabled, the IHIT and IMISS registers are incremented for every
    // instruction cache hit or miss respectively. The hit and miss profiling registers do not wrap around after
    // reaching the maximum value.
    

Related