Skip to content

xm_api_memory.h — XM10 Memory Access API

🟢 Rev 2.0 only — This entire header ships only in the XM10 Rev 2.0 SDK. The Rev 1.1 SDK (XM10_SDK/Rev1.1/) does not contain xm_api_memory.h at all, so calling any of the functions below from a Rev 1.1 project will fail at the link stage. To check your board revision, see Board Revision Comparison.


When to use this

Reach for this API when plain global variables (.bss/.data) aren't enough — you need a large buffer, deterministic cache-free access inside a control loop, or values that must survive a power cycle. 07. Memory Management covers the characteristics of each region (speed / volatility / DMA capability) and how to choose between them; this page only covers the signature and parameters of each function.


Function List

Function One-line description
XM_GetUserWorkspace() Returns the base address of the RAM_D1 user workspace
XM_GetUserWorkspaceSize() Returns the size (bytes) of the RAM_D1 workspace
XM_GetUserDTCM() Returns the base address of the DTCM user area
XM_GetUserDTCMSize() Returns the size (bytes) of the DTCM user area
XM_UserNV_GetSize() Returns the size (bytes) of the Flash User NV area
XM_UserNV_Read() Reads data from Flash User NV
XM_UserNV_Write() Writes data to Flash User NV
XM_UserNV_Erase() Erases the entire Flash User NV area
XM_UserNV_IsErased() Checks whether Flash User NV is empty (all 0xFF)

ℹ️ XM_GetUserPSRAM() / XM_GetUserPSRAMSize() from earlier releases have been removed from the public API. For large buffers, use XM_GetUserWorkspace() (RAM_D1, 200KB).

The two macros (XM_RAMFUNC, XM_DTCM_VAR) are covered in Types/Macros.


Function Details

RAM_D1 User Workspace

XM_GetUserWorkspace()

void* XM_GetUserWorkspace(void);

Returns the base address of the user workspace reserved in RAM_D1. This is a cacheable region (goes through D-Cache), so access is fast, but the contents are lost on power-down. It's the first region to reach for general-purpose data: algorithm variables, sensor data arrays, computation buffers.

Parameters: none

Return value

Return Meaning
void* Base address of the contiguous memory block

⚠️ Calling context: Call it from Control_Setup()/Control_Loop(), not from an ISR. The usual pattern is to fetch the pointer once in Control_Setup(), store it in a static/global pointer, and reuse it in Control_Loop().

static float* s_work_buf;

void Control_Setup(void) {
    s_work_buf = (float*)XM_GetUserWorkspace();
}

See also: 07. Memory Management — RAM_D1 Workspace API

XM_GetUserWorkspaceSize()

uint32_t XM_GetUserWorkspaceSize(void);

Returns the total size, in bytes, of the block returned by XM_GetUserWorkspace(). Use it to check bounds when you manually partition the workspace by offset.

Parameters: none · Return value: workspace size (bytes)


DTCM User Area

XM_GetUserDTCM()

void* XM_GetUserDTCM(void);

Returns the base address of the user variable area inside DTCMRAM. It is accessed with zero wait states at 480MHz and bypasses D-Cache, so access latency is deterministic — but it cannot be reached by DMA. If you only need a handful of individual variables, the XM_DTCM_VAR macro is more convenient; use this function when you need a single large contiguous block, such as a LUT.

Parameters: none

Return value

Return Meaning
void* Base address of the DTCM contiguous memory block

⚠️ Calling context: Call it from Control_Setup()/Control_Loop(), not from an ISR. Do not place DMA buffers in this block — the DMA controller cannot access the DTCM address space.

See also: 07. Memory Management — DTCM API

XM_GetUserDTCMSize()

uint32_t XM_GetUserDTCMSize(void);

Returns the total size, in bytes, of the block returned by XM_GetUserDTCM().

Parameters: none · Return value: DTCM user area size (bytes)


Flash User NV (Non-Volatile Storage)

A non-volatile storage area using Flash Bank 2, Sector 7 (128KB). Values survive a power cycle, but the usual Flash constraints still apply (write only possible after erase, finite erase-cycle count).

XM_UserNV_GetSize()

uint32_t XM_UserNV_GetSize(void);

Returns the total size (bytes) of the User NV area.

Parameters: none · Return value: User NV area size (bytes, fixed at 128KB)

XM_UserNV_Read()

int32_t XM_UserNV_Read(uint32_t offset, void *data, uint32_t size);

Reads data from the Flash User NV area into the data buffer.

Parameters

Name Type Description
offset uint32_t Byte offset from the start of User NV (0 ~ Size-1)
data void* Buffer to receive the data read
size uint32_t Number of bytes to read

Return value

Return Meaning
0 Success
-1 Parameter error (offset + size > NV size)

⚠️ Calling context: Call it from Control_Setup()/Control_Loop(), not from an ISR. The usual pattern is to call this once at boot, from Control_Setup().

See also: It's safer to check XM_UserNV_IsErased() first to see whether valid data exists — right after an erase, the whole area is 0xFF.

XM_UserNV_Write()

int32_t XM_UserNV_Write(uint32_t offset, const void *data, uint32_t size);

Writes data to the Flash User NV area.

Parameters

Name Type Description
offset uint32_t Byte offset from the start of User NV (32-byte alignment recommended)
data const void* Pointer to the data to write
size uint32_t Number of bytes to write

Return value

Return Meaning
0 Success
-1 Parameter error
-2 Flash programming failed

⚠️ Calling context: Call it from Control_Setup()/Control_Loop(), not from an ISR. However, the following two constraints must be respected:

  • Flash can only be written after an erase (1→0 only, never 0→1). Call XM_UserNV_Erase() before writing new data.
  • STM32H7 Flash is programmed in 32-byte (256-bit) units; if offset isn't aligned, it is automatically aligned before writing.
  • Frequent writes affect Flash lifetime (minimum 10,000 erase cycles guaranteed). A "read once at boot, write once on setting-change/shutdown" pattern is recommended.
// Ex.36 pattern — define offsets as constants and write per struct field
#define NV_MAGIC          0xCA5E0A01
#define NV_OFFSET_MAGIC   0
#define NV_OFFSET_WEIGHTS 4

XM_UserNV_Erase();
XM_UserNV_Write(NV_OFFSET_MAGIC, &magic, sizeof(magic));
XM_UserNV_Write(NV_OFFSET_WEIGHTS, &s_nn, sizeof(s_nn));

See also: Ex.36 OnDevice Kinesthetic Learning saves trained neural-network weights this way.

XM_UserNV_Erase()

int32_t XM_UserNV_Erase(void);

Erases the entire Flash User NV area (128KB), resetting it to all 0xFF.

Parameters: none

Return value

Return Meaning
0 Success
-2 Flash erase failed

⚠️ Calling context: Erasing the full 128KB sector takes roughly 1–2 seconds — the header explicitly warns "do not call from a real-time control loop." Never call this from inside a 1kHz Control_Loop(); only use it from a one-shot path such as button-event handling or boot-time initialization.

XM_UserNV_IsErased()

bool XM_UserNV_IsErased(void);

Checks whether the entire Flash User NV area is empty (all 0xFF, i.e. right after an erase).

Parameters: none

Return value

Return Meaning
true The entire area is 0xFF (state right after erase)
false Data exists, or the area was partially written

⚠️ Calling context: Call it from Control_Setup()/Control_Loop(), not from an ISR. It's typically used as a guard before XM_UserNV_Read(), to check whether valid data has been stored (a magic-number field checked after reading is another valid approach).


Types/Macros

XM_RAMFUNC

#define XM_RAMFUNC  __attribute__((section(".itcm_text")))

A function attribute macro that places a function in ITCMRAM so it executes with zero wait states. Because it avoids the branch-prediction-miss latency of executing directly from Flash, it's suited to functions whose execution time must be deterministic, such as ISRs and control loops. Startup code automatically handles the Flash → ITCM copy, so no manual copying is required.

Field Description
Applies to An attribute placed before a function declaration
Placement ITCMRAM (.itcm_text section)
Constraint ITCM capacity is limited (64KB) — place only function code here; keep large arrays/buffers in RAM_D1 or another region
XM_RAMFUNC void MyControlLoop(void) {
    // This function runs from ITCMRAM (1-cycle fetch @ 480MHz)
}

XM_DTCM_VAR

#define XM_DTCM_VAR  __attribute__((section(".dtcm_data")))

A variable attribute macro that places a variable in DTCMRAM for zero-wait-state access. Because it bypasses D-Cache, access latency is deterministic, making it suitable for individual variables that need fast, per-variable access — control-algorithm state variables, lookup tables.

Field Description
Applies to An attribute placed before a variable declaration
Placement DTCMRAM (.dtcm_data section)
Constraint Not reachable by DMA — do not use for buffers that need to be filled by DMA
XM_DTCM_VAR static float s_pid_state[6];
XM_DTCM_VAR static float s_lookup_table[256];

See also: If you need one large contiguous block rather than a few variables, use XM_GetUserDTCM().


Internal Only (Do Not Call)

xm_api_memory.h has no functions marked [Internal]/system-only — all 11 functions and 2 macros listed above are public API intended to be called from user code (XM_Apps).