Skip to content

Commit 85addde

Browse files
Add zephyr template files for use with Zephyr runtime
1 parent 89cacba commit 85addde

7 files changed

Lines changed: 556 additions & 0 deletions

File tree

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/* ----------------------------------------------------------------------
2+
* Project: CMSIS Stream Library
3+
* Title: IdentifiedNode.hpp
4+
* Description: Helper template that exposes identified C++ nodes through C
5+
*
6+
*
7+
* Target Processor: Cortex-M and Cortex-A cores
8+
* --------------------------------------------------------------------
9+
*
10+
* Copyright (C) 2026 ARM Limited or its affiliates. All rights reserved.
11+
*
12+
* SPDX-License-Identifier: Apache-2.0
13+
*
14+
* Licensed under the Apache License, Version 2.0 (the License); you may
15+
* not use this file except in compliance with the License.
16+
* You may obtain a copy of the License at
17+
*
18+
* www.apache.org/licenses/LICENSE-2.0
19+
*
20+
* Unless required by applicable law or agreed to in writing, software
21+
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
22+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23+
* See the License for the specific language governing permissions and
24+
* limitations under the License.
25+
*/
26+
#pragma once
27+
28+
extern "C" {
29+
#include "cstream_node.h"
30+
}
31+
32+
#include "StreamNode.hpp"
33+
34+
#include <type_traits>
35+
36+
/**
37+
* @brief Create a CStreamNode handle for an identified C++ node.
38+
*
39+
* The helper detects supported C++ base classes at compile time and installs
40+
* the matching C interface tables in the returned CStreamNode. Interface
41+
* pointers remain NULL when the node type does not implement the corresponding
42+
* API.
43+
*
44+
* Extend this function with additional interface tables when the application
45+
* adds more C-callable APIs to CStreamNode.
46+
*/
47+
template <typename T>
48+
CStreamNode createStreamNode(T &obj)
49+
{
50+
const StreamNodeInterface *stream_intf_current = nullptr;
51+
const ContextSwitchInterface *context_switch_intf_current = nullptr;
52+
53+
if constexpr (std::is_base_of<arm_cmsis_stream::StreamNode, T>::value)
54+
{
55+
static const StreamNodeInterface stream_intf = {
56+
[](const void *self) -> int {
57+
return static_cast<const T *>(self)->nodeID();
58+
},
59+
[](const void *self) -> int {
60+
return static_cast<const T *>(self)->needsAsynchronousInit();
61+
},
62+
[](void *self, int outputPort, CStreamNode *dst, int dstPort) {
63+
static_cast<T *>(self)->subscribe(
64+
outputPort,
65+
*static_cast<arm_cmsis_stream::StreamNode *>(dst->obj),
66+
dstPort);
67+
},
68+
[](void *self) -> cg_status {
69+
return static_cast<T *>(self)->init();
70+
},
71+
};
72+
stream_intf_current = &stream_intf;
73+
}
74+
75+
if constexpr (std::is_base_of<ContextSwitch, T>::value)
76+
{
77+
static const ContextSwitchInterface context_switch_intf = {
78+
[](void *self) -> int {
79+
return static_cast<T *>(self)->pause();
80+
},
81+
[](void *self) -> int {
82+
return static_cast<T *>(self)->resume();
83+
},
84+
};
85+
context_switch_intf_current = &context_switch_intf;
86+
}
87+
88+
return CStreamNode{&obj, stream_intf_current, context_switch_intf_current};
89+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Zephyr Application Configuration Templates
2+
3+
The files in this folder are examples to copy into a Zephyr application and
4+
customize. They are application-specific glue around the shared Zephyr runtime:
5+
6+
- `app_config.hpp`: generated-scheduler hooks and application logging aliases.
7+
- `cstream_node.h`: C API used to expose identified C++ stream nodes.
8+
- `IdentifiedNode.hpp`: helper that builds `CStreamNode` handles for identified
9+
C++ nodes.
10+
- `stream_init.hpp` and `stream_init.cpp`: example top-level stream startup and
11+
shutdown code for one generated graph.
12+
- `prj.conf`: example Zephyr Kconfig fragment for CMSIS-Stream runtime sizing,
13+
priorities, stacks, pools, and logging.
14+
15+
Unlike the CMSIS-RTOS runtime, Zephyr runtime settings are Kconfig symbols named
16+
`CONFIG_CMSISSTREAM_*`. Put the values from `prj.conf` in the application's
17+
`prj.conf` or an overlay configuration file.
18+
19+
The sample `stream_init.cpp` assumes a generated graph named `hello`, with
20+
`scheduler_hello.h` and `hello_params.h`. Replace those includes, init calls,
21+
parameter assignments, and execution-context entries with the generated files
22+
for the target application.
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#pragma once
2+
3+
/*
4+
* Application configuration for a CMSIS-Stream scheduler on Zephyr.
5+
*
6+
* Generated schedulers include this copied configuration header before
7+
* stream_platform_config.hpp. Use it for scheduler-specific application hooks.
8+
* Shared runtime sizing, thread priorities, stack sizes, pool sections, and
9+
* logging levels are Zephyr Kconfig symbols; see the example prj.conf.
10+
*/
11+
12+
#include <zephyr/kernel.h>
13+
#include <zephyr/logging/log.h>
14+
15+
LOG_MODULE_DECLARE(cmsisstream, CONFIG_CMSISSTREAM_LOG_LEVEL);
16+
17+
extern "C" {
18+
#include "hello_params.h"
19+
}
20+
21+
#include "cg_enums.h"
22+
#include "stream_rtos_events.h"
23+
24+
extern struct k_event cg_streamEvent;
25+
26+
// FIFO buffers are placed in a dedicated section so the linker can apply the
27+
// memory layout selected for the generated graph.
28+
// When memory optimization is used by the Python generator, FIFO memory can be
29+
// shared and must remain aligned to avoid unaligned accesses.
30+
#define CG_BEFORE_BUFFER __aligned(16) __attribute__((section(".bss.stream_fifo")))
31+
32+
#define CMSISSTREAM_LOG_ERR(...) LOG_ERR(__VA_ARGS__)
33+
#define CMSISSTREAM_LOG_DBG(...) LOG_DBG(__VA_ARGS__)
34+
35+
#define CG_BEFORE_NODE_EXECUTION(id) \
36+
{ \
37+
uint32_t res = k_event_wait(&cg_streamEvent, \
38+
STREAM_PAUSE_EVENT | STREAM_DONE_EVENT, \
39+
false, K_NO_WAIT); \
40+
if ((res & STREAM_DONE_EVENT) != 0U) \
41+
{ \
42+
k_event_clear(&cg_streamEvent, STREAM_DONE_EVENT); \
43+
cgStaticError = CG_STOP_SCHEDULER; \
44+
goto errorHandling; \
45+
} \
46+
if ((res & STREAM_PAUSE_EVENT) != 0U) \
47+
{ \
48+
k_event_clear(&cg_streamEvent, STREAM_PAUSE_EVENT); \
49+
cgStaticError = CG_PAUSED_SCHEDULER; \
50+
goto errorHandling; \
51+
} \
52+
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/* ----------------------------------------------------------------------
2+
* Project: CMSIS Stream Library
3+
* Title: cstream_node.h
4+
* Description: C interface used by the runtime to access C++ stream nodes
5+
*
6+
*
7+
* Target Processor: Cortex-M and Cortex-A cores
8+
* --------------------------------------------------------------------
9+
*
10+
* Copyright (C) 2026 ARM Limited or its affiliates. All rights reserved.
11+
*
12+
* SPDX-License-Identifier: Apache-2.0
13+
*
14+
* Licensed under the Apache License, Version 2.0 (the License); you may
15+
* not use this file except in compliance with the License.
16+
* You may obtain a copy of the License at
17+
*
18+
* www.apache.org/licenses/LICENSE-2.0
19+
*
20+
* Unless required by applicable law or agreed to in writing, software
21+
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
22+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23+
* See the License for the specific language governing permissions and
24+
* limitations under the License.
25+
*/
26+
#ifndef C_STREAM_NODE_H
27+
#define C_STREAM_NODE_H
28+
29+
#include "cg_enums.h"
30+
31+
#ifdef __cplusplus
32+
extern "C" {
33+
#endif
34+
35+
struct CStreamNode;
36+
37+
/**
38+
* @brief C-callable view of the standard StreamNode API.
39+
*
40+
* The generated scheduler exposes identified C++ nodes through these function
41+
* pointers so code outside the scheduler can query and initialize them without
42+
* depending on their concrete C++ types.
43+
*/
44+
struct StreamNodeInterface
45+
{
46+
int (*nodeID)(const void *self);
47+
int (*needsAsynchronousInit)(const void *self);
48+
void (*subscribe)(void *self, int outputPort, CStreamNode *dst, int dstPort);
49+
cg_status (*init)(void *self);
50+
};
51+
52+
/**
53+
* @brief Optional C-callable view of the ContextSwitch API.
54+
*
55+
* Nodes implement this interface when they must react to graph pause and
56+
* resume operations. Typical users are hardware-facing nodes and stateful
57+
* nodes that must quiesce or restart cleanly around a context switch.
58+
*/
59+
struct ContextSwitchInterface
60+
{
61+
int (*pause)(void *self);
62+
int (*resume)(void *self);
63+
};
64+
65+
/**
66+
* @brief Opaque handle for an identified C++ stream node.
67+
*
68+
* The generated scheduler creates CStreamNode handles only for nodes marked as
69+
* identified in the Python graph description. If a C++ object does not
70+
* implement an optional interface, the corresponding pointer is NULL.
71+
*/
72+
struct CStreamNode
73+
{
74+
void *obj;
75+
const struct StreamNodeInterface *stream_intf;
76+
const struct ContextSwitchInterface *context_switch_intf;
77+
};
78+
79+
#ifdef __cplusplus
80+
}
81+
#endif
82+
83+
#endif
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Enable CMSIS-Stream Zephyr runtime support.
2+
CONFIG_CMSISSTREAM=y
3+
4+
# Event queue configuration.
5+
CONFIG_CMSISSTREAM_EVENT_QUEUE_LENGTH=20
6+
7+
# Runtime thread configuration.
8+
CONFIG_CMSISSTREAM_EVT_THREAD_STACK_SIZE=4096
9+
CONFIG_CMSISSTREAM_STREAM_THREAD_STACK_SIZE=4096
10+
11+
# Zephyr priorities: lower numerical values are higher priority.
12+
CONFIG_CMSISSTREAM_STREAM_THREAD_PRIORITY=0
13+
CONFIG_CMSISSTREAM_EVT_HIGH_PRIORITY=4
14+
CONFIG_CMSISSTREAM_EVT_NORMAL_PRIORITY=5
15+
CONFIG_CMSISSTREAM_EVT_LOW_PRIORITY=6
16+
17+
# Runtime memory pools.
18+
CONFIG_CMSISSTREAM_NB_MAX_EVENTS=16
19+
CONFIG_CMSISSTREAM_NB_MAX_BUFS=16
20+
CONFIG_CMSISSTREAM_SHARED_OVERHEAD=16
21+
CONFIG_CMSISSTREAM_POOL_SECTION=".bss.evt_pool"
22+
23+
# Event data configuration.
24+
CONFIG_CMSISSTREAM_MAX_NUMBER_EVENT_ARGUMENTS=8
25+
CONFIG_CMSISSTREAM_TENSOR_MAX_DIMENSIONS=3
26+
27+
# Zephyr logging for the cmsisstream module.
28+
CONFIG_LOG=y
29+
CONFIG_CMSISSTREAM_LOG_LEVEL_DBG=y

0 commit comments

Comments
 (0)