|
Name |
|
Date |
Size |
#Lines |
LOC |
| .. | | - | - |
| app/ | | 04-Jan-2025 | - | 497 | 372 |
| ext1/ | | 04-Jan-2025 | - | 76 | 49 |
| ext2/ | | 04-Jan-2025 | - | 64 | 42 |
| ext3/ | | 04-Jan-2025 | - | 107 | 70 |
| k-ext1/ | | 04-Jan-2025 | - | 106 | 69 |
| README.rst | D | 04-Jan-2025 | 4.5 KiB | 138 | 102 |
README.rst
1.. zephyr:code-sample:: llext-edk
2 :name: Linkable loadable extensions EDK
3 :relevant-api: llext_apis
4
5 Enable linkable loadable extension development outside the Zephyr tree using
6 LLEXT EDK (Extension Development Kit).
7
8Overview
9********
10
11This sample demonstrates how to use the Zephyr LLEXT EDK (Extension Development
12Kit). It is composed of one Zephyr application, which provides APIs for the
13extensions that it loads. The provided API is a simple publish/subscribe system,
14based on :ref:`Zbus <zbus>`, which extensions use to communicate with each other.
15
16The application is composed of a subscriber thread, which listens for events
17published and republishes them via Zbus to the extensions that are
18subscribers. There are four extensions, which are loaded by the application and
19run in different contexts. Extensions ``ext1``, ``ext2`` and ``ext3`` run in
20userspace, each demonstrating different application and Zephyr API usage, such as
21semaphores, spawning threads to listen for events or simply publishing or
22subscribing to events. Extension ``kext1`` runs in a kernel thread, albeit similar
23to ``ext3``.
24
25The application also creates different memory domains for each extension, thus
26providing some level of isolation - although the kernel one still has access
27to all of Zephyr kernel.
28
29Note that the kernel extension is only available when the EDK is built with
30the :kconfig:option:`CONFIG_LLEXT_EDK_USERSPACE_ONLY` option disabled.
31
32
33The application is built using the Zephyr build system. The EDK is built using
34the Zephyr build system as well, via ``llext-edk`` target. The EDK is then
35extracted and the extensions are built using CMake.
36
37Finally, the way the application loads the extensions is by including them
38during build time, which is not really practical. This sample is about the EDK
39providing the ability to build extensions independently from the application.
40One could build the extensions in different directories, not related to the
41Zephyr application - even on different machines, using only the EDK. At the
42limit, one could even imagine a scenario where the extensions are built by
43different teams, using the EDK provided by the application developer.
44
45Building the EDK
46****************
47
48To build the EDK, use the ``llext-edk`` target. For example:
49
50.. zephyr-app-commands::
51 :zephyr-app: samples/subsys/llext/edk/app
52 :board: qemu_cortex_r5
53 :goals: build llext-edk
54 :west-args: -p=always
55 :compact:
56
57Copy the EDK to some place and extract it:
58
59.. code-block:: console
60
61 mkdir /tmp/edk
62 cp build/zephyr/llext-edk.tar.xz /tmp/edk
63 cd /tmp/edk
64 tar -xf llext-edk.tar.xz
65
66Then set ``LLEXT_EDK_INSTALL_DIR`` to the extracted directory:
67
68.. code-block:: console
69
70 export LLEXT_EDK_INSTALL_DIR=/tmp/edk/llext-edk
71
72This variable is used by the extensions to find the EDK.
73
74Building the extensions
75***********************
76
77The :envvar:`ZEPHYR_SDK_INSTALL_DIR` environment variable is used by the
78extensions to find the Zephyr SDK, so you need to ensure it's properly set:
79
80.. code-block:: console
81
82 export ZEPHYR_SDK_INSTALL_DIR=</path/to/zephyr-sdk>
83
84To build the extensions, in the ``ext1``, ``ext2``, ``ext3`` and ``kext1``
85directories:
86
87.. code-block:: console
88
89 cmake -B build
90 make -C build
91
92Alternatively, you can set the ``LLEXT_EDK_INSTALL_DIR`` directly in the
93CMake invocation:
94
95.. code-block:: console
96
97 cmake -B build -DLLEXT_EDK_INSTALL_DIR=/tmp/edk/llext-edk
98 make -C build
99
100Building the application
101************************
102
103Now, build the application, including the extensions, and run it:
104
105.. zephyr-app-commands::
106 :zephyr-app: samples/subsys/llext/edk/app
107 :board: qemu_cortex_r5
108 :goals: build run
109 :west-args: -p=always
110 :compact:
111
112You should see something like:
113
114.. code-block:: console
115
116 [app]Subscriber thread [0x20b28] started.
117 [app]Loading extension [kext1].
118 [app]Thread 0x20840 created to run extension [kext1], at privileged mode.
119 [k-ext1]Waiting sem
120 [app]Thread [0x222a0] registered event [0x223c0]
121 [k-ext1]Waiting event
122 [app]Loading extension [ext1].
123 [app]Thread 0x20a30 created to run extension [ext1], at userspace.
124 [app]Thread [0x20a30] registered event [0x26060]
125 [ext1]Waiting event
126 [app]Loading extension [ext2].
127 [app]Thread 0x20938 created to run extension [ext2], at userspace.
128 [ext2]Publishing tick
129 [app][subscriber_thread]Got channel tick_chan
130 [ext1]Got event, reading channel
131 [ext1]Read val: 0
132 [ext1]Waiting event
133 [k-ext1]Got event, giving sem
134 [k-ext1]Got sem, reading channel
135 [k-ext1]Read val: 0
136 [k-ext1]Waiting sem
137 (...)
138