-
Notifications
You must be signed in to change notification settings - Fork 79
lmdk: How to convert and build loadable modules #488
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,11 +8,86 @@ What is LMDK | |
|
||
LMDK(Loadable Module Development Kit) is a standalone package required to build loadable module. It is independent from SOF FW but contains necessary data structures to interact with it. | ||
|
||
.. code-block:: bash | ||
|
||
$ python scripts/lmdk/libraries_build.py -l dummy -k "/path/to/signing/key.pem" | ||
|
||
Latest headers pack is being deployed with FW and its versioning is keept in sof\src\include\module\module\api_ver.h . Every change in headers must be marked in that header(todo: automation). | ||
Creating deployment header pack is done by calling: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't know what a 'headers pack' means. |
||
|
||
.. code-block:: bash | ||
|
||
$ python scripts/lmdk/header_pack.py | ||
|
||
These headers should be extracted in include directory of lmdk with the same include path as it is in the sof project. | ||
|
||
.. code-block:: cmake | ||
|
||
target_compile_definitions(dummy PRIVATE CONFIG_XTENSA=1 | ||
CONFIG_IPC_MAJOR_4=1 | ||
CONFIG_LIBRARY=1 | ||
XCHAL_HAVE_HIFI3=1 | ||
SOF_MODULE_API_PRIVATE=1) | ||
|
||
set(LMDK_DIR_INCLUDE ../../../lmdk/include) | ||
|
||
target_include_directories(up_down_mixer PRIVATE "${LMDK_DIR_INCLUDE}" | ||
"${LMDK_DIR_INCLUDE}/src/include" | ||
"${LMDK_DIR_INCLUDE}/src/include/sof/audio/module_adapter/iadk" | ||
"${LMDK_DIR_INCLUDE}/posix/include" | ||
"${LMDK_DIR_INCLUDE}/posix/include/sof" | ||
|
||
Good example how to prepare module for using lmdk exported headers is included dummy module. | ||
|
||
How to prepare MODULE to be loadable | ||
************************************ | ||
|
||
Loadable modules are using functions provided by native_system_services which are narrowed to only neccesary and safe functions. For example all dynamic allocations are done on strict size local heap_mem | ||
softwarecki marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what is the definition of 'safe' in this context? |
||
declared in a body of the module. | ||
|
||
.. code-block:: c | ||
|
||
static struct native_system_service_api* system_service; | ||
uint32_t heap_mem[2048] __attribute__((section(".heap_mem"))) __attribute__((aligned(4096))); | ||
|
||
Each module also has to declare as a loadable and has prepared manifest which is specific for each. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. where is that manifest? |
||
|
||
.. code-block:: c | ||
|
||
DECLARE_LOADABLE_MODULE_API_VERSION(dummy); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. avoid this term. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Stub, placeholder, example |
||
|
||
static void* entry_point(void* mod_cfg, void* parent_ppl, void** mod_ptr) | ||
{ | ||
system_service = *(const struct native_system_agent**)mod_ptr; | ||
|
||
return &up_down_mixer_interface; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. haha that's interesting, I was told this component is deprecated... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @plbossart I don't understand, can you elaborate? |
||
} | ||
|
||
__attribute__((section(".module"))) | ||
const struct sof_man_module_manifest dummy_module_manifest = { | ||
.module = { | ||
.name = "DUMMY", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Example_module or something |
||
.uuid = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ?? why can't we use a regular UUID. |
||
.entry_point = (uint32_t)dummyPackageEntryPoint, | ||
.type = { | ||
.load_type = SOF_MAN_MOD_TYPE_MODULE, | ||
.domain_ll = 1 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. are DP modules supported? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @plbossart Native loadable libraries (LMDK) supports DP processing if they provide a processing function based on the sink/source interface. int (*process)(struct processing_module *mod,
struct sof_source **sources, int num_of_sources,
struct sof_sink **sinks, int num_of_sinks); |
||
}, | ||
.affinity_mask = 3, | ||
softwarecki marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
}; | ||
|
||
|
||
|
||
How to build | ||
************ | ||
Designers of lmdk prepared two options of building loadable modules. Using them is depend from needs. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. consider rewording, this does not read well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also explain which one should be use when. You are just listing two solutions without any explanations on pros/cons. |
||
|
||
Using CMake scripts | ||
=================== | ||
To build example loadable library execute: | ||
.. code-block:: bash | ||
|
||
.. code-block:: bash | ||
|
||
$ cd libraries/example | ||
$ mkdir build | ||
|
@@ -21,5 +96,11 @@ To build example loadable library execute: | |
$ cmake -DRIMAGE_COMMAND="/path/to/rimage" -DSIGNING_KEY="/path/to/signing/key.pem" .. | ||
$ cmake --build . | ||
|
||
Here RIMAGE_COMMAND is path to rimage executable binary, SIGNING_KEY is path to | ||
signing key for rimage. `LMDK <https://github.com/thesofproject/sof/pull/7354>` | ||
Using Python scripts | ||
==================== | ||
Building module using python | ||
|
||
.. code-block:: bash | ||
|
||
$ python scripts/lmdk/libraries_build.py -l dummy -k "/path/to/signing/key.pem" | ||
|
Uh oh!
There was an error while loading. Please reload this page.