tin  1.5.9
zephyr.h
Go to the documentation of this file.
1 // Copyright (c) 2026 Tinverse LLC. All rights reserved.
2 // SPDX-License-Identifier: LicenseRef-Tinverse-Commercial
3 
10 
11 #pragma once
12 
13 #include <cstddef>
14 #include <cstdint>
15 #include <utility>
16 
17 #include "tsm/runtime/executor.h"
19 
20 #if defined(__ZEPHYR__)
21 #include <zephyr/kernel.h>
22 
23 namespace tsm::runtime::storage {
24 
32 template<std::size_t Capacity>
33 struct zephyr_msgq
34 {
35  static constexpr std::size_t capacity = Capacity;
36 
37  template<typename Event>
38  class queue
39  {
40  static_assert(Capacity > 0,
41  "tsm: zephyr_msgq requires non-zero capacity");
42 
43  public:
44  using value_type = Event;
45 
46  queue()
47  {
48  k_msgq_init(
49  &queue_, buffer_, sizeof(Event), static_cast<uint32_t>(Capacity));
50  }
51 
52  queue(queue const&) = delete;
53  queue& operator=(queue const&) = delete;
54 
55  [[nodiscard]] bool try_push(Event const& event)
56  {
57  return k_msgq_put(&queue_, &event, K_NO_WAIT) == 0;
58  }
59 
60  [[nodiscard]] bool try_push(Event&& event)
61  {
62  return k_msgq_put(&queue_, &event, K_NO_WAIT) == 0;
63  }
64 
65  [[nodiscard]] bool try_pop(Event& event)
66  {
67  return k_msgq_get(&queue_, &event, K_NO_WAIT) == 0;
68  }
69 
70  [[nodiscard]] bool empty() const
71  {
72  return k_msgq_num_used_get(const_cast<k_msgq*>(&queue_)) == 0U;
73  }
74 
75  [[nodiscard]] bool full() const
76  {
77  return k_msgq_num_free_get(const_cast<k_msgq*>(&queue_)) == 0U;
78  }
79 
80  [[nodiscard]] std::size_t size() const
81  {
82  return k_msgq_num_used_get(const_cast<k_msgq*>(&queue_));
83  }
84 
85  [[nodiscard]] k_msgq* native_handle()
86  {
87  return &queue_;
88  }
89  [[nodiscard]] k_msgq const* native_handle() const
90  {
91  return &queue_;
92  }
93 
94  private:
95  alignas(Event) char buffer_[Capacity * sizeof(Event)]{};
96  k_msgq queue_{};
97  };
98 };
99 
101 template<std::size_t Capacity>
102 struct target_storage<Capacity, zephyr_storage_tag>
103 {
104  using type = zephyr_msgq<Capacity>;
105 };
106 
107 } // namespace tsm::runtime::storage
108 
109 namespace tsm {
110 
111 struct zephyr_tick_source
112 {
113  [[nodiscard]] tsm::tick_rep ticks() const noexcept
114  {
115  return static_cast<tsm::tick_rep>(k_uptime_ticks());
116  }
117 };
118 
123 template<typename... Tasks>
124 class zephyr_task_executor
125 {
126  public:
127  explicit zephyr_task_executor(Tasks&... tasks)
128  : ready_(tasks...)
129  {
130  k_sem_init(&wake_sem_, 0, 1);
131  }
132 
133  void start() {}
134  void stop() {}
135 
136  void wake()
137  {
138  k_sem_give(&wake_sem_);
139  }
140  void wake_from_isr()
141  {
142  wake();
143  }
144 
145  void wait_for_work()
146  {
147  static_cast<void>(k_sem_take(&wake_sem_, K_MSEC(1)));
148  }
149 
150  [[nodiscard]] bool step()
151  {
152  return ready_.step();
153  }
154 
155  std::size_t run_ready()
156  {
157  const auto ran = ready_.run_ready();
158  if (ran == 0U) {
159  // The semaphore is the Zephyr wake primitive; runtime queues still
160  // carry typed tsm events and coroutine wakeups.
161  wait_for_work();
162  }
163  return ran;
164  }
165 
166  std::size_t tick(tsm::tick_rep elapsed_ticks = 1U)
167  {
168  const auto resumed = ready_.tick(elapsed_ticks);
169  if (resumed != 0U) {
170  wake();
171  }
172  return resumed;
173  }
174 
175  std::size_t tick(tsm::tick_count elapsed_ticks)
176  {
177  return tick(elapsed_ticks.count());
178  }
179 
180  void start_all()
181  {
182  ready_.start_all();
183  }
184 
185  template<auto Entry, std::size_t Instance = 0U>
186  [[nodiscard]] spawn_result start()
187  {
188  auto result = ready_.template start<Entry, Instance>();
189  if (result == spawn_result::started) {
190  wake();
191  }
192  return result;
193  }
194 
195  template<auto Entry, typename... Args>
196  [[nodiscard]] spawn_result spawn(Args&&... args)
197  {
198  auto result = ready_.template spawn<Entry>(std::forward<Args>(args)...);
199  if (result == spawn_result::started) {
200  wake();
201  }
202  return result;
203  }
204 
205  [[nodiscard]] runtime::task_spawner<zephyr_task_executor> spawner()
206  {
207  return runtime::task_spawner<zephyr_task_executor>{ *this };
208  }
209 
210  template<auto Entry, std::size_t Instance = 0U>
211  [[nodiscard]] task_status task_status() const
212  {
213  return ready_.template task_status<Entry, Instance>();
214  }
215 
216  template<auto Entry, std::size_t Instance = 0U>
217  [[nodiscard]] task_failure_reason task_failure_reason() const
218  {
219  return ready_.template task_failure_reason<Entry, Instance>();
220  }
221 
222  template<auto Entry, std::size_t Instance = 0U>
223  [[nodiscard]] bool cancel() noexcept
224  {
225  const bool cancelled = ready_.template cancel<Entry, Instance>();
226  if (cancelled) {
227  wake();
228  }
229  return cancelled;
230  }
231 
232  void cancel_all() noexcept
233  {
234  ready_.cancel_all();
235  wake();
236  }
237 
238  private:
239  runtime::cooperative_executor<Tasks...> ready_;
240  k_sem wake_sem_{};
241 };
242 
243 template<typename... Tasks>
244 zephyr_task_executor(Tasks&...) -> zephyr_task_executor<Tasks...>;
245 
246 template<typename... Tasks>
247 using task_executor = zephyr_task_executor<Tasks...>;
248 
249 } // namespace tsm
250 
251 #endif // defined(__ZEPHYR__)
Target-independent executors for tsm runtimes.
Definition: freertos.h:26
task_spawner< Executor > spawner
Definition: executor.h:150
cooperative_executor(Tasks &...) -> cooperative_executor< Tasks... >
Definition: bare_metal.h:20
task_failure_reason
Definition: coroutine.h:170
constexpr tick_count ticks(tick_rep value) noexcept
Definition: ticks.h:85
runtime::storage::target_queue< Capacity > target_storage
Definition: static_ring.h:179
task_status
Definition: coroutine.h:160
bare_metal_task_executor< Tasks... > task_executor
Definition: bare_metal.h:166
spawn_result
Definition: coroutine.h:181
TSM_TICK_REP tick_rep
Definition: ticks.h:35
Fixed-capacity ring queue storage for runtime events.
Strong value type for semantic scheduler ticks.
Definition: ticks.h:54
constexpr tick_rep count() const noexcept
Definition: ticks.h:73