nmc-utils  0.1.1
DSP Application as a service

Functions

struct easynmc_handleeasynmc_connect (const char *appid)
size_t easynmc_appdata_size (struct easynmc_handle *h)
int easynmc_appdata_set (struct easynmc_handle *h, void *data, size_t len)
size_t easynmc_appdata_get (struct easynmc_handle *h, void *data, size_t len)
int easynmc_appid_set (struct easynmc_handle *h, char appid[])
const char * easynmc_appid_get (struct easynmc_handle *h)
int easynmc_persist_set (struct easynmc_handle *h, enum easynmc_persist_state status)

Detailed Description

Sometimes you need to keep the DSP core running in background to provide some kind of 'service' to userspace application(s) or run completely independently. Mostly it is needed if userspace applications using this 'service' start and stop often and you don't want to waste time restarting DSP application again and again for some reason.

Please note, that thread creation is a slow process by itself and can be the bottleneck by itself, therefore do not expect the application persistence mechanism to magically boost performance.

If you are using DSP app persistence API the state diagram you've seen in Loading, starting and stopping DSP Applications is a little bit more complex.

dot_nmc-states.png

A DSP application that doesn't have an associated userspace process is in KILLABLE state. If someone needs a free DSP core and easynmc_open() doesn't find any cores in COLD or IDLE states it will search for cores in KILLABLE state, kill the application and return the handle in IDLE state.

You can make your app transition into KILLABLE state by enabling DSP app persistence via easynmc_persist_set(). When enabled, easynmc_close() doesn't kill the application, but leaves it in KILLABLE state.

Running DSP apps are identified via a string of up to 8 characters long including the terminating NULL character. After the application is started its appid can be set and retrieved using easynmc_appid_set() and easynmc_appid_get() calls respectively.

If you want to 'connect' to a running background DSP app you need to know its appid and supply it to easynmc_connect() which attempts to locate the core with the app and returns the handle to it.

Sometimes you need to store useful pieces of data that describe the current state of the aplication e.g. adresses obtained via absfilters during app loading. Starting with libeasynmc version 0.1.1 you can can call easynmc_appdata_set() and easynmc_appdata_get() to get and set your application-specific data respectively.

The appdata buffer is copied by the library to the kernel driver. DSP app termination invalidates the data stored and the DSP application ID.

Function Documentation

size_t easynmc_appdata_get ( struct easynmc_handle h,
void *  data,
size_t  len 
)

Retrieve current application-specific data from kernel. The atmost len bytes of application-specific data is copied to the supplied buffer

Parameters
hThe easynmc handle
datapointer to user buffer
lenThe length of app data in bytes
Returns
The actual number of bytes copied to user buffer

Definition at line 1286 of file easynmc-core.c.

int easynmc_appdata_set ( struct easynmc_handle h,
void *  data,
size_t  len 
)

Setup current application-specific data. Associate some arbitary data with the running easynmc application. The application data is copied internally and can be freed after this call.

Parameters
hThe easynmc handle
Returns
0 if everything went fine

Definition at line 1257 of file easynmc-core.c.

size_t easynmc_appdata_size ( struct easynmc_handle h)

Returns curent appdata size in bytes.

Parameters
hThe easynmc handle
Returns
appdata size in bytes

Definition at line 1217 of file easynmc-core.c.

const char* easynmc_appid_get ( struct easynmc_handle h)

Retrieve tihe current application identifier. The memory for the identifier if manages by the library and should not be freed or altered by the caller.

Parameters
hThe easynmc handle
Returns
application id

Definition at line 1357 of file easynmc-core.c.

References easynmc_handle::appid, easynmc_handle::imem32, and NMC_REG_APPDATA_SIZE.

Referenced by do_dump_core_info().

int easynmc_appid_set ( struct easynmc_handle h,
char  appid[] 
)

Set the current application identifier.

Parameters
hThe easynmc handle
appidpointer to user buffer
Returns
0 if everything went fine

Definition at line 1316 of file easynmc-core.c.

References easynmc_handle::appid, and EASYNMC_APPID_LEN.

struct easynmc_handle* easynmc_connect ( const char *  appid)
read

Connect to a running DSP application via a supplied appid.

This function iterates over available DSP cores and returns the handle to first core that meets the following criteria:

  • It is NOT exclusively used by anyone.
  • It has a matching appid label
  • It is in a KILLABLE state.

This call obtains the exclusive lock on the core. NOTE: This function will NEVER try to connect to any cores in RUNNING state, even if they are not used by anyone. This might happen the userspace application that started the DSP code crashed prior to calling easynmc_close() but after easynmc_persist_set(). If this is the case, connecting to such apps can lead to big problems.

You have to kill these stale DSP apps manually with nmctl or with your own tool.

Parameters
appidApplication identifier
Returns
Handle for the core or NULL if no running, unlocked cores with matching appid found

Definition at line 1189 of file easynmc-core.c.

References easynmc_for_each_core().

int easynmc_persist_set ( struct easynmc_handle h,
enum easynmc_persist_state  status 
)

Enable application persistence. By default, any running nmc application is terminated by the driver when the device is closed. In rare cases where this is not required you can call this function to disable this for the current handle, call this function with EASYNMC_PERSIST_ENABLE. After this call, calling easynmc_close() on the handle will place the core in EASYNMC_CORE_KILLABLE state.

Parameters
hThe easynmc handle
appidpointer to user buffer
Returns
0 if everything went fine

Definition at line 1393 of file easynmc-core.c.

References EASYNMC_PERSIST_ENABLE, easynmc_handle::iofd, and easynmc_handle::persistent.

Referenced by do_start_app(), easynmc_open(), and main().