STM32WBA AMM Allocation Failures: Separate Reserved Quotas from Shared-Pool Capacity

An STM32WBA allocation can fail even while another client has unused reserved capacity. The Advanced Memory Manager first decides whether this caller may consume the requested amount. Only an admitted request reaches the underlying Basic Memory Manager. A global free-memory total does not answer that first question.

This analysis pins STM32CubeWBA v1.10.0’s AMM implementation at commit e455b860ceb52aaa0332a98f1e7a10bbd7014fc9. ST’s Memory Management guide supplies the reservation model and integration context. The exact admission comparison and header charge below follow the pinned C source, rather than an approximate interpretation of the guide.

Treat a reservation as an accounting entitlement

AMM gives each configured virtual-memory ID a nominal reserved amount. The remaining pool provides shared capacity for additional demand. An ID can exceed its reservation when shared capacity permits; the reservation is not a hard maximum.

Conversely, an ID cannot consume another ID’s remaining reservation merely because those bytes are currently unused. That restriction explains an allocation refusal before the physical allocator searches for a block. AMM’s virtual memories are software accounting identities, not MMU mappings or hardware isolation boundaries.

Keep the configured reservation, current occupation and shared occupation in separate columns. The occupation includes AMM’s allocation header, so a payload-only ledger gradually disagrees with the implementation even if every release is correct.

Reconstruct the admission expression

For a valid configured ID, define the following source-derived names in 32-bit words. These equations describe normal valid accounting state; they are not replacement allocator code.

shared_available = AmmPoolSize - AmmOccupiedSharedPoolSize
                   - AmmRequiredVirtualMemorySize
self_available = max(RequiredSize - OccupiedSize, 0)
admit only if BufferSize < shared_available + self_available
BMM request = BufferSize + 1

The implementation calculates the own-reservation remainder only when occupation is below the configured requirement. The final comparison is strictly less than. The one-word VIRTUAL_MEMORY_HEADER_SIZE is then added to the BMM request and to successful occupation accounting.

For a request using AMM_NO_VIRTUAL_ID, there is no own-reservation term. Only shared allowance participates. Neither branch adds the unused reservation of some other ID.

A failed admission produces AMM_ERROR_BAD_ALLOCATION_SIZE on these capacity branches. If admission succeeds but BMM returns a null pointer, the result is AMM_ERROR_ALLOCATION_FAILED. Preserve that distinction in diagnostics; the same broad user-facing message can otherwise hide two different decisions.

Compare two IDs against the same ledger

Consider independent paper cases starting from 16 words of shared allowance. ID A has no remaining reservation; ID B has 64 reserved words remaining. Both ask for a 32-word payload.

For A, 32 < 16 + 0 is false. AMM refuses the request before calling BMM. B’s unused reservation is irrelevant to that decision.

For B, 32 < 16 + 64 is true. AMM asks BMM for 33 words, including its header. If that physical allocation succeeds, B’s occupation rises by 33 words and its remaining reservation falls to 31 words. This request stays within B’s reservation, so it consumes none of the 16-word shared allowance.

Two IDs share 16 available words, but only B has 64 remaining reserved words; a 32-word payload fails for A and reaches BMM for B.
Original source-derived AMM ledger. All amounts are 32-bit words; admitted requests can still fail physical allocation.

Now reset the model and test A at the boundary. A 16-word payload fails 16 < 16; a 15-word payload passes 15 < 16 and requests 16 words from BMM. If successful, the latter consumes all 16 shared words. The strict comparison and header must be considered together; changing the comparison in a spreadsheet to less-than-or-equal overstates admissible payload.

These are accounting deductions, not executed allocation results. In particular, B passing admission is not evidence that a suitable physical block exists.

Keep physical geometry as the second gate

AMM initialization allocates its virtual-memory information records through BMM and accounts for that management space. The guide’s pool-sizing expression includes those records, the sum of reservations and the intended shared allowance. Use the actual build’s AMM_VIRTUAL_INFO_ELEMENT_SIZE, rather than guessing the structure size.

BMM remains responsible for providing the requested physical allocation. ST requires support for merging adjacent freed blocks, but coalescing cannot merge across a still-live allocation. Alignment, allocator overhead and block geometry therefore remain relevant after AMM admission.

The AMM interface expresses sizes in 32-bit words. A byte-oriented BMM wrapper must perform the documented unit conversion. Check both layers’ overhead separately instead of treating AMM’s one-word header as every allocator’s total metadata cost.

Size nominal service and burst demand separately

Choose each reservation from that client’s required nominal live allocation set, including AMM headers. Size shared allowance for the permitted overlap of extra demand. Do not silently count an idle client’s reservation as burst capacity available to every other client.

When a request fails, record the ID, payload words, own remainder, shared allowance, admission outcome and BMM outcome where reached. A retry callback offers another opportunity to request; it is not an allocated buffer or a fairness guarantee. Increasing retry frequency cannot change a permanently insufficient entitlement.

No allocator execution, firmware build or latency measurement was performed. The review output is a two-stage failure classification and a reproducible per-ID ledger. It explains whether the product must revise its reservation/shared-capacity policy or investigate the physical allocator after admission. Those decisions remain distinct even when both failures eventually appear as a missing buffer.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *