Data Structures | Macros | Typedefs | Variables
NVSCC26XX.h File Reference

Detailed Description

Non-Volatile Storage driver for CC13XX/CC26XX devices.


Interrupt Latency During Flash Operations

When writing or erasing flash, interrupts must be disabled to avoid executing code in flash while the flash is being reprogrammed. This constraint is handled by the driver. Application code does not need to safeguard against this.

Additionally, to avoid extremely large interrupt latencies that would be incurred if entire blocks were written with interrupts disabled, block writes to flash are broken into multiple smaller sizes.

Even with this scheme in place, latencies of roughly 64 microseconds will be incurred while flash is being written to.

A similar caveat applies to flash erase operations. Erasing an entire flash sector (the minimal amount that can be erased at a time) can take roughly 8 milliseconds. This entire operation must be performed with interrupts disabled. Here again, this requirement is met internally by the driver and flash region erases are performed one sector at a time to minimize this significant latency impact.

Care must be taken by the user to not perform flash write or erase operations during latency critical phases of an application. See the NVS_lock() and NVS_unlock() API descriptions for more information.

Maximum flash writes before erase

On CC13XX & CC26XX memory rows can be 128 or 256 bytes in length; refer to the device datasheet for the exact size. A maximum of 83 write operations can be performed on a memory row. Once the limit is reached, the row must be erased before it is written to again.

Note
The 83 write limit persists through device reset & power cycles. If 60 write operations were performed on a memory page & the device is reset; the page can still only be written to 23 more times before it must be erased.

A write "Scoreboard" can be enabled in this driver; the scoreboard keeps track of how many times a page has been written to. It is provided as a debug tool to ensure the 83 write limit is not exceeded. If a page is written to more than 83 times, the NVSCC26XX driver will spin forever. Each byte in the scoreboard corresponds to a memory page in the NVS region. The byte is incremented when the memory is written to & set to 0 when erased.

To enable the "scoreboard" the "NVSCC26XX_INSTRUMENTED" symbol must be defined when the driver is compiled. Three new fields are added to the NVSCC26XX_HWAttrs structure:

When configured correctly, the scoreboard can be viewed in a memory browser.

Note
The scoreboard will only keep track of writes to flash within a NVS region using a NVS driver. Writes performed outside the NVS region or without the NVS driver are untracked.
The scoreboard is in RAM & will be lost on reset or power cycle.

#include <stdint.h>
#include <stdbool.h>

Go to the source code of this file.

Data Structures

struct  NVSCC26XX_HWAttrs
 NVSCC26XX hardware attributes. More...
 
struct  NVSCC26XX_Object
 

Macros

#define NVSCC26XX_STATUS_LOW_VOLTAGE   (NVS_STATUS_RESERVED - 1)
 Error status code returned by NVS_erase(), NVS_write(). More...
 

Typedefs

typedef struct NVSCC26XX_HWAttrs NVSCC26XX_HWAttrs
 NVSCC26XX hardware attributes. More...
 
typedef struct NVSCC26XX_Object NVSCC26XX_Object
 

Variables

const NVS_FxnTable NVSCC26XX_fxnTable
 

Macro Definition Documentation

§ NVSCC26XX_STATUS_LOW_VOLTAGE

#define NVSCC26XX_STATUS_LOW_VOLTAGE   (NVS_STATUS_RESERVED - 1)

Error status code returned by NVS_erase(), NVS_write().

This error status is returned if the system voltage is too low to safely perform the flash operation. Voltage must be 1.5V or greater.

Typedef Documentation

§ NVSCC26XX_HWAttrs

NVSCC26XX hardware attributes.

The NVSCC26XX hardware attributes define hardware specific settings for a NVS driver instance.

Note
Care must be taken to ensure that the linker does not place application content (such as .text or .const) in the flash regions defined by the this hardware attributes structure.

For CCS and IAR tools, defining and reserving flash memory regions can be done entirely within the Board.c file. For GCC, additional content is required in the application's linker script to achieve the same result.

The example below defines a char array flashBuf. Preprocessor logic is used so that this example will work with either the TI, IAR or GCC tools. For the TI and IAR tools, pragmas are used to place flashBuf at the flash location specified by NVSCC26XX_HWAttrs.regionBase.

For the GCC tool, the flashBuf array is placed into a named linker output section, .nvs. This section is defined in the application's linker script. The section placement command is carefully chosen to only RESERVE space for the flashBuf array, and not to actually initialize it during the application load process, thus preserving the content of flash.

Regardless of tool chain, the flashBuf array in the example below is placed at the NVS_REGIONS_BASE address and has an overall size of REGIONSIZE bytes. Theoretically, the memory reserved by flashBuf can be divided into four separate regions, each having a size of SECTORSIZE bytes. Each region must always be aligned to the flash sector size, SECTORSIZE. This example below shows two regions defined.

An array of two NVSCC26XX_HWAttrs structures is defined. Each index of this structure defines a region of on-chip flash memory. Both regions utilize memory reserved by the flashBuf array. The two regions do not overlap or share the same physical memory locations. The two regions do however exist adjacent to each other in physical memory. The first region is defined as starting at the NVS_REGIONS_BASE address and has a size equal to the flash sector size, as defined by SECTORSIZE. The second region is defined as starting at (NVS_REGIONS_BASE + SECTORSIZE), that is, the NVS_REGIONS_BASE address offset by SECTORSIZE bytes. The second region has a size equal to (3 * SECTORSIZE) bytes. These regions together fully occupy REGIONSIZE bytes of physical on-chip flash memory as reserved by the flashBuf array.

#define NVS_REGIONS_BASE 0x1B000
#define SECTORSIZE 0x1000
#define REGIONSIZE (SECTORSIZE * 4)
//
// Reserve flash sectors for NVS driver use
// by placing an uninitialized byte array
// at the desired flash address.
//
#if defined(__TI_COMPILER_VERSION__)
//
// Place uninitialized array at FLASH_REGION_BASE
//
#pragma LOCATION(flashBuf, FLASH_REGION_BASE);
#pragma NOINIT(flashBuf);
char flashBuf[REGIONSIZE];
#elif defined(__IAR_SYSTEMS_ICC__)
//
// Place uninitialized array at FLASH_REGION_BASE
//
__no_init char flashBuf[REGIONSIZE] @ FLASH_REGION_BASE;
#elif defined(__GNUC__)
//
// Place the flash buffers in the .nvs section created in the gcc linker file.
// The .nvs section enforces alignment on a sector boundary but may
// be placed anywhere in flash memory. If desired the .nvs section can be set
// to a fixed address by changing the following in the gcc linker file:
//
// .nvs (FIXED_FLASH_ADDR) (NOLOAD) : AT (FIXED_FLASH_ADDR) {
// *(.nvs)
// } > REGION_TEXT
//
__attribute__ ((section (".nvs")))
char flashBuf[REGIONSIZE];
#endif
NVSCC26XX_HWAttrs nvsCC26XXHWAttrs[2] = {
//
// region 0 is 1 flash sector in length.
//
{
.regionBase = (void *)flashBuf,
.regionSize = SECTORSIZE,
},
//
// region 1 is 3 flash sectors in length.
//
{
.regionBase = (void *)(flashBuf + SECTORSIZE),
.regionSize = SECTORSIZE * 3,
}
};

Example GCC linker script file content. This example places an output section, .nvs, at the memory address 0x1B000. The NOLOAD directive is used so that this memory is not initialized during program load to the target.

MEMORY
{
FLASH (RX) : ORIGIN = 0x00000000, LENGTH = 0x0001ffa8
FLASH_CCFG (RX) : ORIGIN = 0x0001ffa8, LENGTH = 0x00000058
SRAM (RWX) : ORIGIN = 0x20000000, LENGTH = 0x00005000
}
.nvs (0x1b000) (NOLOAD) : AT (0x1b000) {
*(.nvs)
} > REGION_TEXT

If the write "scoreboard" is enabled, three new fields are added to the NVSCC26XX_HWAttrs structure:

  • scoreboard - a buffer provided by the application where each byte represents how many times a page has been written to. It is important that this buffer be large enough such that there is a byte for each page of memory in the NVS region. For example:
    • 64k NVS region
    • 256 byte page size
    • 64k / 256 = 256; the scoreboard buffer must be 256 bytes in length
  • scoreboardSize - number of bytes in the scoreboard.
  • flashPageSize - number of bytes in a flash page (i.e. 128 or 256)

§ NVSCC26XX_Object

Variable Documentation

§ NVSCC26XX_fxnTable

const NVS_FxnTable NVSCC26XX_fxnTable
Copyright 2018, Texas Instruments Incorporated