STM32N6 NPU Deployment — Politecnico di Milano  1.0
Documentation for Neural Network Deployment on STM32N6 NPU - Politecnico di Milano 2024-2025
external_memory_mgt Namespace Reference

Functions

None update_activation_c_code (str c_project_path, str path_network_c_info, int available_AXIRAM, cfg=None, Dict custom_objects=None)
 

Function Documentation

◆ update_activation_c_code()

None external_memory_mgt.update_activation_c_code ( str  c_project_path,
str  path_network_c_info,
int  available_AXIRAM,
  cfg = None,
Dict   custom_objects = None 
)
@brief Patches generated C firmware files to configure activation buffer placement.

@details
This function performs **surgical modification of generated C source files**
to ensure that neural network activation buffers, camera capture buffers, and
rescaled image buffers are placed in the correct memory sections (AXIRAM or SDRAM)
at link time.

The function modifies three C files:

**1. `main.h` — Camera resolution configuration**
Patches `#define CAMERA_RESOLUTION`, `#define CAM_RES_WIDTH`, and
`#define CAM_RES_HEIGHT` based on the model's input shape and the
preprocessing aspect ratio mode from the Hydra configuration.

Resolution selection logic:
| Mode | Network ≤ QVGA (320×240) | Network ≤ VGA (640×480) |
|------|--------------------------|-------------------------|
| crop | CAMERA_R320x240, QVGA_HEIGHT | CAMERA_R640x480, VGA_HEIGHT |
| padding | CAMERA_R320x240, QVGA_WIDTH | CAMERA_R640x480, VGA_WIDTH |
| fit | CAMERA_R320x240, QVGA_WxH | CAMERA_R640x480, VGA_WxH |

**2. `main.c` — Activation buffer declarations**
Replaces the generated code block between
`/*** @GENERATED CODE START - DO NOT TOUCH@ ***/` markers with
explicit buffer declarations using GCC section attributes:

@code{.c}
// Example output for a model with 2 activation pools:
__attribute__((section(".NN_Activation_Buffer_AXIRAM")))
__attribute__ ((aligned (32)))
static uint8_t NN_Activation_Buffer_AXIRAM[AI_ACTIVATION_1_SIZE_BYTES + 32 - (AI_ACTIVATION_1_SIZE_BYTES%32)];

__attribute__((section(".NN_Activation_Buffer_npuRAM4")))
__attribute__ ((aligned (32)))
static uint8_t NN_Activation_Buffer_npuRAM4[AI_ACTIVATION_2_SIZE_BYTES + 32 - (AI_ACTIVATION_2_SIZE_BYTES%32)];

ai_handle NN_Activation_Buffer[AI_ACTIVATION_BUFFERS_COUNT] = {
    NN_Activation_Buffer_AXIRAM, NN_Activation_Buffer_npuRAM4,
};
@endcode

Buffer assignment strategy:
- Buffers are sorted smallest-to-largest
- Each buffer is assigned to AXIRAM if space remains, SDRAM otherwise
- The 32-byte alignment padding ensures efficient cache line usage

The CapturedImage_Buffer and RescaledImage_Buffer are also assigned
to AXIRAM or SDRAM based on remaining available space after activations.

**3. `ai_interface.h` — Input buffer index**
Patches the `AI_NETWORK_INPUTS_IN_ACTIVATIONS_INDEX` and
`AI_NETWORK_INPUTS_IN_ACTIVATIONS_SIZE` macros, which tell the firmware
which activation buffer pool contains the model's input tensor.

@param c_project_path       Root path of the STM32CubeIDE C project.
                            Expected structure:
                            @code
                            c_project_path/
                            └── Application/STM32H747I-DISCO/
                                ├── Inc/CM7/main.h
                                ├── Inc/CM7/ai_interface.h
                                └── Src/CM7/main.c
                            @endcode
@param path_network_c_info  Path to `network_c_info.json` generated by
                            ST Edge AI Core. Contains the list of memory pools
                            with their names, rights (ACC_READ/ACC_WRITE),
                            and used_size_bytes.
@param available_AXIRAM     Available AXIRAM in bytes after subtracting
                            the ST AI runtime library footprint.
@param cfg                  Hydra DictConfig containing:
                            - cfg.preprocessing.resizing.aspect_ratio
                            - cfg.general.model_path
@param custom_objects       Custom Keras objects dictionary for model loading
                            (passed to get_model_name_and_its_input_shape).

@return None — all modifications are performed in place on the C source files.

@note Files are modified using a **write-then-rename** pattern for atomicity:
      a `_modify.c` / `_modify.h` temporary file is written, then
      `os.replace()` atomically replaces the original.

@warning This function directly modifies generated firmware source files.
         Any manual edits inside the `@GENERATED CODE START/STOP` blocks
         will be overwritten on the next deployment run.

@note This function is designed for **STM32H747I-DISCO** targets.
      For STM32N6570-DK (used in this project), the Neural-ART toolchain
      handles memory placement differently — this function is not called
      during STM32N6 deployment.

Definition at line 46 of file external_memory_mgt.py.

Referenced by common_deploy.stm32ai_deploy().

Here is the caller graph for this function: