@@ -15,6 +15,17 @@ LOG_MODULE_REGISTER(app);
15
15
16
16
#include <stdlib.h>
17
17
18
+ #ifdef CONFIG_USERSPACE
19
+ K_THREAD_STACK_DEFINE (llext_stack , CONFIG_MAIN_STACK_SIZE );
20
+ struct k_thread llext_thread ;
21
+
22
+ void llext_entry (void * arg0 , void * arg1 , void * arg2 )
23
+ {
24
+ void (* fn )(struct llext_loader * , struct llext * ) = arg0 ;
25
+ fn (arg1 , arg2 );
26
+ }
27
+ #endif /* CONFIG_USERSPACE */
28
+
18
29
static int loader (const struct shell * sh )
19
30
{
20
31
const struct flash_area * fa ;
@@ -95,8 +106,45 @@ static int loader(const struct shell *sh)
95
106
return - ENOENT ;
96
107
}
97
108
109
+ #ifdef CONFIG_USERSPACE
110
+ /*
111
+ * Due to the number of MPU regions on some parts with MPU (USERSPACE)
112
+ * enabled we need to always call into the extension from a new dedicated
113
+ * thread to avoid running out of MPU regions on some parts.
114
+ *
115
+ * This is part dependent behavior and certainly on MMU capable parts
116
+ * this should not be needed! This test however is here to be generic
117
+ * across as many parts as possible.
118
+ */
119
+ struct k_mem_domain domain ;
120
+
121
+ k_mem_domain_init (& domain , 0 , NULL );
122
+
123
+ #ifdef Z_LIBC_PARTITION_EXISTS
124
+ k_mem_domain_add_partition (& domain , & z_libc_partition );
125
+ #endif
126
+
127
+ res = llext_add_domain (ext , & domain );
128
+ if (res == - ENOSPC ) {
129
+ printk ("Too many memory partitions for this particular hardware\n" );
130
+ return -1 ;
131
+ }
132
+
133
+ k_thread_create (& llext_thread , llext_stack ,
134
+ K_THREAD_STACK_SIZEOF (llext_stack ),
135
+ & llext_entry , llext_bootstrap , ext , main_fn ,
136
+ 1 , K_INHERIT_PERMS , K_FOREVER );
137
+
138
+ k_mem_domain_add_thread (& domain , & llext_thread );
139
+
140
+ k_thread_start (& llext_thread );
141
+ k_thread_join (& llext_thread , K_FOREVER );
142
+ #else
143
+
98
144
llext_bootstrap (ext , main_fn , NULL );
99
145
146
+ #endif
147
+
100
148
return 0 ;
101
149
}
102
150
0 commit comments