sp500/dsp.h File Reference

sp500/dsp.h File Reference#

Mobilint REGULUS: sp500/dsp.h File Reference
Mobilint REGULUS v4.1
SP500 DSP API
dsp.h File Reference

Mobilint SP500 DSP offload - status codes, lifecycle and shared memory. More...

#include <stdint.h>
#include <stddef.h>

Go to the source code of this file.

Data Structures

struct  sp500_buffer
 A tensor handed to or received from the DSP. More...

Macros

#define SP500_VERSION_MAJOR   1
#define SP500_VERSION_MINOR   0
#define SP500_VERSION_PATCH   0
#define SP500_VERSION_INT
 Header version as one integer: major*10000 + minor*100 + patch.
#define SP500_API
#define SP500_INLINE   static inline
#define SP500_DEFAULT_OPEN_TIMEOUT_MS   10000u
 Default deadline for sp500_dsp_open(), in milliseconds.
#define SP500_DEFAULT_DSP_TIMEOUT_MS   3000u
 Default deadline for a single DSP call, in milliseconds.
#define SP500_ALIGN_DSP   32u
 Smallest alignment the DSP accepts.
#define SP500_ALIGN_NPU   4096u
 Alignment to use for a buffer that the NPU also reads or writes.

Typedefs

typedef int32_t sp500_status
 Result of every sp500 call.

Enumerations

enum  {
  SP500_OK = 0 ,
  SP500_ERR_INVALID_ARG = -1 ,
  SP500_ERR_UNSUPPORTED = -2 ,
  SP500_ERR_BUFFER_TOO_SMALL = -3 ,
  SP500_ERR_NOT_READY = -4 ,
  SP500_ERR_NO_MEMORY = -5 ,
  SP500_ERR_TIMEOUT = -6 ,
  SP500_ERR_DSP = -7 ,
  SP500_ERR_INTERNAL = -8
}
enum  { SP500_BUFFER_SHARED = 1u << 0 }
 sp500_buffer::flags bits. More...

Functions

const char * sp500_status_string (sp500_status status)
 Human-readable name of a status code. Never NULL, never allocates.
uint32_t sp500_version (void)
 Version of the loaded library, encoded like SP500_VERSION_INT.
const char * sp500_version_string (void)
 Version of the loaded library as "major.minor.patch". Never NULL.
sp500_status sp500_dsp_open (uint32_t timeout_ms)
 Attach to the DSP. Must succeed before any other DSP call.
int sp500_dsp_is_open (void)
 Non-blocking: 1 once sp500_dsp_open() has succeeded, 0 otherwise.
void sp500_set_dsp_timeout_ms (uint32_t timeout_ms)
 Raise the deadline applied to every subsequent DSP call.
uint32_t sp500_get_dsp_timeout_ms (void)
 Deadline currently in force, in milliseconds, after clamping.
void sp500_dsp_lock (void)
 Take the one reentrant DSP lock, across threads and across processes.
void sp500_dsp_unlock (void)
 Release one level of the lock taken by sp500_dsp_lock().
void * sp500_shmem_alloc (uint32_t size, uint32_t alignment)
 Allocate inside the DSP shared-memory window.
void sp500_shmem_free (void *ptr)
 Release a buffer from sp500_shmem_alloc(). NULL is ignored.
int sp500_shmem_contains (const void *ptr)
 1 when ptr lies inside the shared-memory window, 0 otherwise.
uint64_t sp500_shmem_phys_addr (const void *ptr)
 Physical address of a shared-memory pointer, for NPU DMA.
sp500_buffer sp500_buffer_none (void)
 An unused buffer, for an optional tensor.
sp500_buffer sp500_buffer_alloc (uint32_t size, uint32_t alignment)
 Allocate a zero-copy buffer in shared memory.
sp500_buffer sp500_buffer_wrap (void *data, uint32_t size)
 Wrap memory you already own. The call stages one copy in each direction; nothing is taken over and nothing needs freeing.
void sp500_buffer_release (sp500_buffer *buffer)
 Release a buffer and reset it to unused.

Detailed Description

Mobilint SP500 DSP offload - status codes, lifecycle and shared memory.

This is the foundation header. sp500/letterbox.h, sp500/log_mel.h and sp500/yolo.h all include it; include the module headers you need.

The only dependencies are <stdint.h> and <stddef.h>. No C++ standard library, no OpenCV, no vendor SDK header, no using directive, and no macro that is not prefixed SP500_.

The binary interface
Everything inside the extern "C" block is the ABI of the shared library:
  • Every function returns sp500_status (an int32_t) or a fixed-width scalar. Enumerations name constants only; what crosses the boundary is int32_t or uint32_t, never an enum type whose width is implementation defined.
  • No struct is passed or returned by value across the boundary. Pointers only.
  • Every struct ends with a reserved array. It must be zero. A later library version may give those words a meaning whose zero value is today's behaviour.
  • Always fill a parameter struct with its *_params_init() function before setting fields. The defaults are not all zero, and a struct you only zeroed carries none of them. An all-zero struct is always rejected, because the fields documented as required are invalid at zero - but if you zero a struct and then set exactly those required fields, the call runs with every remaining option at zero rather than at its default. Initialise first.
  • Nothing throws. Every entry point is an exception firewall.
Threading
Every entry point may be called concurrently from several threads and several processes. A DSP call serialises itself against every other DSP call and every shared-memory allocation, system wide, for the duration of the round trip. Use sp500_dsp_lock() only when a multi-call sequence must be atomic as a whole.
Buffers
Every tensor is a sp500_buffer. A buffer from sp500_buffer_alloc() lives in the shared-memory window the DSP reads directly, so it costs no copy. A buffer from sp500_buffer_wrap() points at memory you already own and is staged through shared memory, which costs one copy in each direction. Prefer the former for anything large, and for anything you also hand to the NPU.

Definition in file dsp.h.

Macro Definition Documentation

◆ SP500_VERSION_MAJOR

#define SP500_VERSION_MAJOR   1

Definition at line 49 of file dsp.h.

◆ SP500_VERSION_MINOR

#define SP500_VERSION_MINOR   0

Definition at line 50 of file dsp.h.

◆ SP500_VERSION_PATCH

#define SP500_VERSION_PATCH   0

Definition at line 51 of file dsp.h.

◆ SP500_VERSION_INT

#define SP500_VERSION_INT
Value:
(((SP500_VERSION_MAJOR) * 10000) + \
((SP500_VERSION_MINOR) * 100) + (SP500_VERSION_PATCH))

Header version as one integer: major*10000 + minor*100 + patch.

Definition at line 54 of file dsp.h.

◆ SP500_API

#define SP500_API

Definition at line 62 of file dsp.h.

◆ SP500_INLINE

#define SP500_INLINE   static inline

Definition at line 69 of file dsp.h.

◆ SP500_DEFAULT_OPEN_TIMEOUT_MS

#define SP500_DEFAULT_OPEN_TIMEOUT_MS   10000u

Default deadline for sp500_dsp_open(), in milliseconds.

Definition at line 115 of file dsp.h.

◆ SP500_DEFAULT_DSP_TIMEOUT_MS

#define SP500_DEFAULT_DSP_TIMEOUT_MS   3000u

Default deadline for a single DSP call, in milliseconds.

Definition at line 118 of file dsp.h.

◆ SP500_ALIGN_DSP

#define SP500_ALIGN_DSP   32u

Smallest alignment the DSP accepts.

Definition at line 192 of file dsp.h.

◆ SP500_ALIGN_NPU

#define SP500_ALIGN_NPU   4096u

Alignment to use for a buffer that the NPU also reads or writes.

Definition at line 195 of file dsp.h.

Typedef Documentation

◆ sp500_status

typedef int32_t sp500_status

Result of every sp500 call.

A typedef over int32_t rather than an enum type, so a code introduced by a later library version is never an out-of-range enum value in your build. Zero is success and every error is negative, so both rc != SP500_OK and rc < 0 are correct tests. Treat an unrecognised negative value as a generic failure.

Definition at line 83 of file dsp.h.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
SP500_OK 0 

completed; output buffers are valid

SP500_ERR_INVALID_ARG -1 

a parameter is missing, out of range, or inconsistent with another

SP500_ERR_UNSUPPORTED -2 

this module cannot run that combination

SP500_ERR_BUFFER_TOO_SMALL -3 

a supplied buffer cannot hold the result

SP500_ERR_NOT_READY -4 

sp500_dsp_open() has not succeeded

SP500_ERR_NO_MEMORY -5 

host or shared-memory allocation failed

SP500_ERR_TIMEOUT -6 

the DSP did not answer within the deadline

SP500_ERR_DSP -7 

the DSP reported a failure

SP500_ERR_INTERNAL -8 

unexpected internal condition

Definition at line 85 of file dsp.h.

◆ anonymous enum

anonymous enum

sp500_buffer::flags bits.

Enumerator
SP500_BUFFER_SHARED 1u << 0 

Set by sp500_buffer_alloc(): the memory is inside the shared-memory window, so the DSP reads and writes it in place with no copy.

Definition at line 244 of file dsp.h.

Function Documentation

◆ sp500_version()

uint32_t sp500_version ( void )

Version of the loaded library, encoded like SP500_VERSION_INT.

Compare against SP500_VERSION_INT at start-up to catch a header/library mismatch before it becomes a silent misinterpretation of a struct.

◆ sp500_dsp_open()

sp500_status sp500_dsp_open ( uint32_t timeout_ms)

Attach to the DSP. Must succeed before any other DSP call.

Attaching waits for the DSP-side firmware to register itself, so it blocks until the DSP is up. timeout_ms bounds that wait; pass 0 for SP500_DEFAULT_OPEN_TIMEOUT_MS. Calling it again after success is a cheap no-op, so it is safe to call from every module of an application.

On success the shared-memory window is also mapped, which is what makes sp500_shmem_contains() and sp500_shmem_phys_addr() usable from an NPU setup path that runs before the first DSP call.

Parameters
timeout_msDeadline in milliseconds, or 0 for the default.
Returns
SP500_OK, SP500_ERR_TIMEOUT if the DSP did not register in time, or SP500_ERR_NOT_READY if the link could not be established.
Note
A timeout leaves one worker thread parked inside the vendor link layer until the DSP appears. Load the DSP firmware before calling, and treat a timeout as a fatal start-up error rather than something to retry in a loop.

◆ sp500_set_dsp_timeout_ms()

void sp500_set_dsp_timeout_ms ( uint32_t timeout_ms)

Raise the deadline applied to every subsequent DSP call.

This is a dead-DSP guard, not a latency budget. It must sit comfortably ABOVE the longest operation you submit; the case to check is a long log-mel clip.

A deadline that expires does not cancel anything: the DSP keeps working on buffers the call has already given up on and released, the late completion desynchronises the single-slot channel, and the next call can return the previous call's result. Recovering from that needs a DSP reload. Because of that, the deadline can only be raised - a value below SP500_DEFAULT_DSP_TIMEOUT_MS is clamped up to it, and sp500_get_dsp_timeout_ms() reports what actually took effect.

Parameters
timeout_msDeadline in milliseconds; 0 restores SP500_DEFAULT_DSP_TIMEOUT_MS, and anything below it is clamped up to it.

◆ sp500_dsp_lock()

void sp500_dsp_lock ( void )

Take the one reentrant DSP lock, across threads and across processes.

Individual calls already lock themselves, so this is only needed to make a multi-step sequence atomic against other threads and other processes - for example allocate, letterbox, read, free. The lock is reentrant, so the per-call lock simply nests inside it.

Every sp500_dsp_lock() must be paired with exactly one sp500_dsp_unlock(). An unbalanced lock stalls the DSP and the shared-memory allocator for every process on the system.

◆ sp500_shmem_alloc()

void * sp500_shmem_alloc ( uint32_t size,
uint32_t alignment )

Allocate inside the DSP shared-memory window.

Parameters
sizeBytes to allocate.
alignmentByte alignment; must be at least SP500_ALIGN_DSP. Use SP500_ALIGN_NPU for buffers the NPU also touches.
Returns
Pointer to the buffer, or NULL if the window is exhausted or the DSP is not open. Release it with sp500_shmem_free().
Note
The window is served by a first-fit allocator with no compaction. Freeing does reclaim, in any order, and the freed span rejoins its neighbors - but allocating and freeing buffers of mixed lifetimes every frame fragments the pool. It then carries roughly a quarter more than your live bytes, and a large request can be refused while smaller gaps go unused. Allocate your working set once and reuse it.
Never hold a shared-memory buffer in a global or static object. It would be released after the link has already been torn down.

◆ sp500_shmem_contains()

int sp500_shmem_contains ( const void * ptr)

1 when ptr lies inside the shared-memory window, 0 otherwise.

Interior pointers count, so this also answers "is this row of my image in shared memory". Never blocks; returns 0 until sp500_dsp_open() has succeeded.

◆ sp500_shmem_phys_addr()

uint64_t sp500_shmem_phys_addr ( const void * ptr)

Physical address of a shared-memory pointer, for NPU DMA.

The window is physically contiguous, so any pointer inside it maps to a fixed physical base plus its offset. Hand the result to the NPU runtime to let it read and write the same buffer the DSP uses, with no copy in between.

Returns
The physical address, or 0 if ptr is not inside the window (including before sp500_dsp_open() has succeeded).

◆ sp500_buffer_none()

sp500_buffer sp500_buffer_none ( void )

An unused buffer, for an optional tensor.

Definition at line 268 of file dsp.h.

◆ sp500_buffer_alloc()

sp500_buffer sp500_buffer_alloc ( uint32_t size,
uint32_t alignment )

Allocate a zero-copy buffer in shared memory.

Parameters
sizeBytes to allocate.
alignmentByte alignment; at least SP500_ALIGN_DSP.
Returns
The buffer, or an unused buffer (data == NULL) if the window is exhausted. Release it with sp500_buffer_release().

Definition at line 286 of file dsp.h.

◆ sp500_buffer_wrap()

sp500_buffer sp500_buffer_wrap ( void * data,
uint32_t size )

Wrap memory you already own. The call stages one copy in each direction; nothing is taken over and nothing needs freeing.

Definition at line 302 of file dsp.h.

◆ sp500_buffer_release()

void sp500_buffer_release ( sp500_buffer * buffer)

Release a buffer and reset it to unused.

Frees the shared-memory allocation of a buffer from sp500_buffer_alloc(); does nothing to a wrapped buffer beyond clearing the handle.

Definition at line 316 of file dsp.h.