In order to bring consistency in-tree, migrate all samples to the use
the new prefix <zephyr/...>. Note that the conversion has been scripted:
```python
from pathlib import Path
import re
EXTENSIONS = ("c", "h", "cpp", "rst")
for p in Path(".").glob("samples/**/*"):
if not p.is_file() or p.suffix and p.suffix[1:] not in EXTENSIONS:
continue
content = ""
with open(p) as f:
for line in f:
m = re.match(r"^(.*)#include <(.*)>(.*)$", line)
if (m and
not m.group(2).startswith("zephyr/") and
(Path(".") / "include" / "zephyr" / m.group(2)).exists()):
content += (
m.group(1) +
"#include <zephyr/" + m.group(2) +">" +
m.group(3) + "\n"
)
else:
content += line
with open(p, "w") as f:
f.write(content)
```
Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
119 lines
3.3 KiB
C
119 lines
3.3 KiB
C
/*
|
|
* Copyright (c) 2019 Intel Corporation.
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <zephyr/kernel.h>
|
|
#include <zephyr/device.h>
|
|
#include <zephyr/sys/libc-hooks.h>
|
|
#include <zephyr/logging/log.h>
|
|
|
|
#include "app_shared.h"
|
|
#include "app_b.h"
|
|
|
|
LOG_MODULE_REGISTER(app_b);
|
|
|
|
/* Resource pool for allocations made by the kernel on behalf of system
|
|
* calls. Needed for k_queue_alloc_append()
|
|
*/
|
|
K_HEAP_DEFINE(app_b_resource_pool, 256 * 4 + 128);
|
|
|
|
/* Define app_b_partition, where all globals for this app will be routed.
|
|
* The partition starting address and size are populated by build system
|
|
* and linker magic.
|
|
*/
|
|
K_APPMEM_PARTITION_DEFINE(app_b_partition);
|
|
|
|
/* Global data used by application B. By tagging with APP_B_BSS or APP_B_DATA,
|
|
* we ensure all this gets linked into the continuous region denoted by
|
|
* app_b_partition.
|
|
*
|
|
* This is just for demonstration purposes, processor_thread could just as
|
|
* easily put this on its stack.
|
|
*/
|
|
APP_B_BSS unsigned int process_count;
|
|
|
|
static void processor_thread(void *p1, void *p2, void *p3)
|
|
{
|
|
void *payload;
|
|
|
|
ARG_UNUSED(p1);
|
|
ARG_UNUSED(p2);
|
|
ARG_UNUSED(p3);
|
|
|
|
LOG_DBG("processor thread entered");
|
|
|
|
/* Pretend that processor_thread takes some initialization time,
|
|
* meanwhile data coming in from the driver will be buffered in the
|
|
* incoming queue/
|
|
*/
|
|
k_sleep(K_MSEC(400));
|
|
|
|
/* Consume data blobs from shared_queue_incoming.
|
|
* Do some processing, and the put the processed data
|
|
* into shared_queue_outgoing.
|
|
*/
|
|
while (process_count < NUM_LOOPS) {
|
|
payload = k_queue_get(&shared_queue_incoming, K_FOREVER);
|
|
|
|
/* pretend we're doing something complicated and useful
|
|
* to the data, which is untrusted and hence processed in
|
|
* a sandboxed App B
|
|
*/
|
|
LOG_DBG("processing payload #%d", process_count);
|
|
k_busy_wait(100000);
|
|
process_count++;
|
|
LOG_INF("processing payload #%d complete", process_count);
|
|
|
|
/* Stick the now-processed data into the outgoing queue,
|
|
* to be handled by App A's writeback thread.
|
|
*/
|
|
k_queue_alloc_append(&shared_queue_outgoing, payload);
|
|
}
|
|
|
|
LOG_DBG("processor thread exiting");
|
|
}
|
|
|
|
void app_b_entry(void *p1, void *p2, void *p3)
|
|
{
|
|
int ret;
|
|
|
|
/* Much like how we are reusing the main thread as this application's
|
|
* processor thread, we will re-use the default memory domain as the
|
|
* domain for application B.
|
|
*/
|
|
ret = k_mem_domain_add_partition(&k_mem_domain_default,
|
|
&app_b_partition);
|
|
if (ret != 0) {
|
|
LOG_ERR("Failed to add app_b_partition to mem domain (%d)",
|
|
ret);
|
|
k_oops();
|
|
}
|
|
|
|
ret = k_mem_domain_add_partition(&k_mem_domain_default,
|
|
&shared_partition);
|
|
if (ret != 0) {
|
|
LOG_ERR("Failed to add shared_partition to mem domain (%d)",
|
|
ret);
|
|
k_oops();
|
|
}
|
|
|
|
/* Assign a resource pool to serve for kernel-side allocations on
|
|
* behalf of application A. Needed for k_queue_alloc_append().
|
|
*/
|
|
k_thread_heap_assign(k_current_get(), &app_b_resource_pool);
|
|
|
|
/* We are about to drop to user mode and become the monitor thread.
|
|
* Grant ourselves access to the kernel objects we need for
|
|
* the monitor thread to function.
|
|
*
|
|
* In this case, we need access to both shared queue objects. We
|
|
* don't need access to the sample driver, App A handles all that
|
|
* for us.
|
|
*/
|
|
k_thread_access_grant(k_current_get(), &shared_queue_incoming,
|
|
&shared_queue_outgoing);
|
|
|
|
k_thread_user_mode_enter(processor_thread, NULL, NULL, NULL);
|
|
}
|