API 07: Memory Management¶
📌 After reading this page: You will know how to select the right memory region on XM10 — RAM_D1 / DTCM / Flash NV — based on your use case. ⏱️ Estimated reading time: 15 minutes 🧰 Prerequisites: Static data-structure patterns from Ex.19 Memory Aware Design 🎯 Key APIs:
XM_RAMFUNC/XM_DTCM_VARmacros +XM_UserNV_Read/Write/EraseFlash APIHeader file:
xm_api_memory.h
This API provides access to the various memory regions available on XM10.
Memory Region Overview¶
| Region | Characteristics | Speed | Typical Use |
|---|---|---|---|
| RAM_D1 Workspace | Cacheable, volatile | Fast | Algorithm variables, sensor buffers |
| DTCM | Zero-Wait-State, no DMA | Fastest | Real-time control variables |
| Flash NV | Non-volatile, slow write | Slow | Configuration, calibration data |
Section Placement Macros¶
XM_RAMFUNC¶
Places a function in ITCMRAM for Zero-Wait-State execution.
Ideal for ISRs, control loops, and any function that must execute without branch-prediction penalties.
XM_DTCM_VAR¶
Places a variable in DTCMRAM for Zero-Wait-State access.
Bypasses the D-Cache, guaranteeing deterministic access latency. DMA cannot access DTCM.
RAM_D1 Workspace API¶
XM_GetUserWorkspace()¶
Returns the base address of the RAM_D1 user workspace.
- Cacheable (goes through the D-Cache)
- Lost on power-off
- General-purpose: algorithm variables, sensor data arrays, computation buffers
XM_GetUserWorkspaceSize()¶
Returns the size of the user workspace in bytes.
DTCM API¶
XM_GetUserDTCM()¶
Returns the base address of the DTCM user variable region.
- Zero-Wait-State @ 480 MHz, bypasses the D-Cache
- DMA cannot access this region
- Use when you need a large contiguous block (for individual variables, the
XM_DTCM_VARmacro is more convenient)
XM_GetUserDTCMSize()¶
Returns the size of the DTCM user region in bytes.
Flash User NV (Non-Volatile Storage) API¶
Non-volatile storage that retains data across power cycles.
Uses Flash Bank 2, Sector 7 (128 KB). Minimum guaranteed endurance: 10,000 erase cycles.
XM_UserNV_GetSize()¶
Returns the size of the User NV region in bytes.
XM_UserNV_Read()¶
Reads data from Flash User NV.
| Parameter | Description |
|---|---|
offset |
Byte offset from the start of User NV (0 ~ Size-1) |
data |
Buffer to store the read data |
size |
Number of bytes to read |
| Return value | Meaning |
|---|---|
0 |
Success |
-1 |
Parameter error (offset + size exceeds NV size) |
XM_UserNV_Write()¶
Writes data to Flash User NV.
| Parameter | Description |
|---|---|
offset |
Byte offset from the start of User NV (32-byte alignment recommended) |
data |
Pointer to the data to write |
size |
Number of bytes to write |
| Return value | Meaning |
|---|---|
0 |
Success |
-1 |
Parameter error |
-2 |
Flash programming failure |
Caution: Flash can only be written after an erase — bits can only go from 1 to 0. Call
XM_UserNV_Erase()before writing new data. STM32H7 Flash is programmed in 32-byte (256-bit) units. Frequent writes wear out Flash. The recommended pattern is: read once at boot, write once on shutdown or configuration change.
XM_UserNV_Erase()¶
Erases the entire Flash User NV region (fills with 0xFF).
| Return value | Meaning |
|---|---|
0 |
Success |
-2 |
Flash erase failure |
Erases the full 128 KB sector. Takes approximately 1–2 seconds. Do not call this from a real-time control loop.
XM_UserNV_IsErased()¶
Checks whether the Flash User NV region is blank (entirely 0xFF).
Usage Example¶
// Settings structure definition
typedef struct {
float kp_gain;
float kd_gain;
uint32_t magic; // Validity sentinel
} UserSettings_t;
#define SETTINGS_MAGIC 0xCAFEBEEF
void LoadSettings(UserSettings_t* s) {
XM_UserNV_Read(0, s, sizeof(UserSettings_t));
if (s->magic != SETTINGS_MAGIC) {
// Use default values
s->kp_gain = 4.8f;
s->kd_gain = 0.6f;
s->magic = SETTINGS_MAGIC;
}
}
void SaveSettings(const UserSettings_t* s) {
XM_UserNV_Erase(); // Erase the full sector first (required)
XM_UserNV_Write(0, s, sizeof(UserSettings_t));
}
⚠️ Common Mistakes¶
| Symptom | Cause | Fix |
|---|---|---|
XM_UserNV_Write returns -2 |
Write attempted without erasing first (Flash bits can only go 1 → 0) | Call XM_UserNV_Erase() first |
| Flash wears out quickly | Write called every cycle or every second | Read once at boot; write only on shutdown or configuration change |
| DMA does not work with DTCM variables | DTCM is CPU-only; DMA cannot access it | Move the buffer to RAM_D1 or SRAM |
XM_DTCM_VAR variable contains garbage instead of zero |
DTCM .bss is not zero-initialized in some cases |
Add explicit = 0 initializers or call memset in Control_Setup |
Large array declared inside an XM_RAMFUNC function |
ITCM has a limited size (64 KB) | Keep large data in RAM_D1; place only the function itself in ITCM |
XM_UserNV_Read returns all 0xFF |
Region was erased but never written (erased state = 0xFF) | Check with XM_UserNV_IsErased() first and load defaults if blank |
| Settings structure stored without a magic field | Garbage values mistaken for valid data on first boot | Add a sentinel field such as magic = 0xCAFEBEEF to validate stored data |
Related Examples¶
| Example | Difficulty | Memory Usage |
|---|---|---|
| 16_TinyAI_Sensor_Fusion | Advanced | NN weights (.rodata constant arrays) |
| 19_Memory_Aware_Design | Advanced | Ring buffer + pool allocator (static .bss allocation) |