xref: /aosp_15_r20/external/pigweed/pw_thread_freertos/BUILD.gn (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1# Copyright 2020 The Pigweed Authors
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4# use this file except in compliance with the License. You may obtain a copy of
5# the License at
6#
7#     https://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations under
13# the License.
14
15import("//build_overrides/pigweed.gni")
16
17import("$dir_pigweed/third_party/freertos/freertos.gni")
18import("$dir_pw_build/error.gni")
19import("$dir_pw_build/facade.gni")
20import("$dir_pw_build/module_config.gni")
21import("$dir_pw_build/target_types.gni")
22import("$dir_pw_chrono/backend.gni")
23import("$dir_pw_docgen/docs.gni")
24import("$dir_pw_thread/backend.gni")
25import("$dir_pw_thread_freertos/backend.gni")
26import("$dir_pw_unit_test/test.gni")
27
28declare_args() {
29  # The build target that overrides the default configuration options for this
30  # module. This should point to a source set that provides defines through a
31  # public config (which may -include a file or add defines directly).
32  pw_thread_freertos_CONFIG = pw_build_DEFAULT_MODULE_CONFIG
33}
34
35config("public_include_path") {
36  include_dirs = [ "public" ]
37  visibility = [ ":*" ]
38}
39
40pw_source_set("config") {
41  public = [ "public/pw_thread_freertos/config.h" ]
42  public_configs = [ ":public_include_path" ]
43  public_deps = [
44    "$dir_pw_third_party/freertos",
45    pw_thread_freertos_CONFIG,
46  ]
47}
48
49config("id_public_overrides") {
50  include_dirs = [ "id_public_overrides" ]
51  visibility = [ ":*" ]
52}
53
54# This target provides the backend for pw::Thread::id & pw::this_thread::get_id.
55pw_source_set("id") {
56  public_configs = [
57    ":public_include_path",
58    ":id_public_overrides",
59  ]
60  public_deps = [
61    "$dir_pw_assert",
62    "$dir_pw_interrupt:context",
63    "$dir_pw_third_party/freertos",
64  ]
65  public = [
66    "id_public_overrides/pw_thread_backend/id_inline.h",
67    "id_public_overrides/pw_thread_backend/id_native.h",
68    "public/pw_thread_freertos/id_inline.h",
69    "public/pw_thread_freertos/id_native.h",
70  ]
71  deps = [ "$dir_pw_thread:id.facade" ]
72}
73
74pw_build_assert("check_system_clock_backend") {
75  condition =
76      pw_chrono_SYSTEM_CLOCK_BACKEND == "" ||
77      pw_chrono_SYSTEM_CLOCK_BACKEND == "$dir_pw_chrono_freertos:system_clock"
78  message = "This FreeRTOS backend only works with the FreeRTOS " +
79            "pw::chrono::SystemClock backend " +
80            "(pw_chrono_SYSTEM_CLOCK_BACKEND = " +
81            "\"$dir_pw_chrono_freertos:system_clock\")"
82  visibility = [ ":*" ]
83}
84
85config("sleep_public_overrides") {
86  include_dirs = [ "sleep_public_overrides" ]
87  visibility = [ ":*" ]
88}
89
90# This target provides the backend for pw::this_thread::sleep_{for,until}.
91pw_source_set("sleep") {
92  public_configs = [
93    ":public_include_path",
94    ":sleep_public_overrides",
95  ]
96  public = [
97    "public/pw_thread_freertos/sleep_inline.h",
98    "sleep_public_overrides/pw_thread_backend/sleep_inline.h",
99  ]
100  public_deps = [ "$dir_pw_chrono:system_clock" ]
101  sources = [ "sleep.cc" ]
102  deps = [
103    ":check_system_clock_backend",
104    "$dir_pw_assert",
105    "$dir_pw_chrono_freertos:system_clock",
106    "$dir_pw_third_party/freertos",
107    "$dir_pw_thread:sleep.facade",
108    "$dir_pw_thread:thread",
109  ]
110}
111
112config("thread_public_overrides") {
113  include_dirs = [ "thread_public_overrides" ]
114  visibility = [ ":*" ]
115}
116
117# This target provides the backend for pw::Thread and the headers needed for
118# thread creation.
119pw_source_set("thread") {
120  public_configs = [
121    ":public_include_path",
122    ":thread_public_overrides",
123  ]
124  public_deps = [
125    ":config",
126    ":id",
127    "$dir_pw_assert",
128    "$dir_pw_string",
129    "$dir_pw_third_party/freertos",
130    "$dir_pw_thread:thread.facade",
131    dir_pw_function,
132    dir_pw_span,
133  ]
134  public = [
135    "public/pw_thread_freertos/context.h",
136    "public/pw_thread_freertos/options.h",
137    "public/pw_thread_freertos/thread_inline.h",
138    "public/pw_thread_freertos/thread_native.h",
139    "thread_public_overrides/pw_thread_backend/thread_inline.h",
140    "thread_public_overrides/pw_thread_backend/thread_native.h",
141  ]
142  allow_circular_includes_from = [ "$dir_pw_thread:thread.facade" ]
143  sources = [ "thread.cc" ]
144}
145
146# This target provides the backend for pw::thread::thread_iteration.
147if (pw_thread_freertos_FREERTOS_TSKTCB_BACKEND != "") {
148  pw_source_set("thread_iteration") {
149    public_configs = [ ":thread_public_overrides" ]
150    deps = [
151      ":freertos_tsktcb",
152      "$dir_pw_third_party/freertos",
153      "$dir_pw_thread:thread_info",
154      "$dir_pw_thread:thread_iteration.facade",
155      "$dir_pw_thread_freertos:util",
156      dir_pw_function,
157      dir_pw_span,
158      dir_pw_status,
159    ]
160    sources = [
161      "pw_thread_freertos_private/thread_iteration.h",
162      "thread_iteration.cc",
163    ]
164  }
165}
166
167config("yield_public_overrides") {
168  include_dirs = [ "yield_public_overrides" ]
169  visibility = [ ":*" ]
170}
171
172# This target provides the backend for pw::this_thread::yield.
173pw_source_set("yield") {
174  public_configs = [
175    ":public_include_path",
176    ":yield_public_overrides",
177  ]
178  public = [
179    "public/pw_thread_freertos/yield_inline.h",
180    "yield_public_overrides/pw_thread_backend/yield_inline.h",
181  ]
182  public_deps = [
183    "$dir_pw_assert",
184    "$dir_pw_third_party/freertos",
185    "$dir_pw_thread:thread",
186  ]
187  deps = [ "$dir_pw_thread:yield.facade" ]
188}
189
190pw_source_set("util") {
191  public_configs = [ ":public_include_path" ]
192  public_deps = [
193    "$dir_pw_third_party/freertos",
194    dir_pw_function,
195    dir_pw_span,
196    dir_pw_status,
197  ]
198  public = [ "public/pw_thread_freertos/util.h" ]
199  deps = [ dir_pw_log ]
200  sources = [ "util.cc" ]
201}
202
203# Action to generate `freertos_tsktcb.h` for
204# pw_thread_freertos_FREERTOS_TSKTCB_BACKEND.
205if (dir_pw_third_party_freertos != "") {
206  pw_python_action("generate_freertos_tsktcb") {
207    _out_path = "${target_gen_dir}/public_overrides/pw_thread_freertos_backend/freertos_tsktcb.h"
208    script = "py/pw_thread_freertos/generate_freertos_tsktcb.py"
209    args = [
210      "--freertos-src-dir",
211      rebase_path(dir_pw_third_party_freertos, root_build_dir),
212      "-o",
213      rebase_path(_out_path, root_build_dir),
214    ]
215    outputs = [ _out_path ]
216    visibility = [ ":auto_freertos_tsktcb" ]
217  }
218
219  config("auto_freertos_include_path") {
220    include_dirs = [ "${target_gen_dir}/public_overrides" ]
221    visibility = [ ":auto_freertos_tsktcb" ]
222  }
223
224  # Source set that provides backend for automatically generated
225  # `freertos_tsktcb.h` header.
226  pw_source_set("auto_freertos_tsktcb") {
227    public_configs = [ ":auto_freertos_include_path" ]
228    public = [ "${target_gen_dir}/public_overrides/pw_thread_freertos_backend/freertos_tsktcb.h" ]
229    public_deps = [ "$dir_pw_third_party/freertos" ]
230    deps = [ ":generate_freertos_tsktcb" ]
231    visibility = [ ":freertos_tsktcb" ]
232  }
233}
234
235pw_facade("freertos_tsktcb") {
236  backend = pw_thread_freertos_FREERTOS_TSKTCB_BACKEND
237  public_configs = [ ":public_include_path" ]
238  public = [ "public/pw_thread_freertos/freertos_tsktcb.h" ]
239  public_deps = [ "$dir_pw_third_party/freertos" ]
240}
241
242pw_source_set("snapshot") {
243  public_configs = [ ":public_include_path" ]
244  public_deps = [
245    ":config",
246    "$dir_pw_third_party/freertos",
247    "$dir_pw_thread:protos.pwpb",
248    "$dir_pw_thread:snapshot",
249    dir_pw_function,
250    dir_pw_protobuf,
251    dir_pw_status,
252  ]
253  public = [ "public/pw_thread_freertos/snapshot.h" ]
254  sources = [ "snapshot.cc" ]
255  deps = [
256    ":freertos_tsktcb",
257    ":util",
258    dir_pw_function,
259    dir_pw_log,
260  ]
261}
262
263config("test_thread_context_public_overrides") {
264  include_dirs = [ "test_thread_context_public_overrides" ]
265  visibility = [ ":*" ]
266}
267
268pw_source_set("test_thread_context") {
269  public_configs = [
270    ":public_include_path",
271    ":test_thread_context_public_overrides",
272  ]
273  public_deps = [
274    ":thread",
275    "$dir_pw_thread:test_thread_context.facade",
276  ]
277  public = [
278    "public/pw_thread_freertos/test_thread_context_native.h",
279    "test_thread_context_public_overrides/pw_thread_backend/test_thread_context_native.h",
280  ]
281}
282
283pw_test_group("tests") {
284  tests = [
285    ":dynamic_thread_backend_test",
286    ":static_thread_backend_test",
287  ]
288  if (pw_thread_freertos_FREERTOS_TSKTCB_BACKEND != "") {
289    tests += [ ":thread_iteration_test" ]
290  }
291}
292
293if (pw_thread_freertos_FREERTOS_TSKTCB_BACKEND != "") {
294  pw_test("thread_iteration_test") {
295    enable_if = pw_thread_THREAD_BACKEND == "$dir_pw_thread_freertos:thread" &&
296                pw_thread_THREAD_ITERATION_BACKEND != ""
297    sources = [
298      "pw_thread_freertos_private/thread_iteration.h",
299      "thread_iteration_test.cc",
300    ]
301    deps = [
302      ":freertos_tsktcb",
303      ":static_test_threads",
304      ":thread_iteration",
305      "$dir_pw_bytes",
306      "$dir_pw_span",
307      "$dir_pw_string:builder",
308      "$dir_pw_string:util",
309      "$dir_pw_sync:thread_notification",
310      "$dir_pw_third_party/freertos",
311      "$dir_pw_thread:non_portable_test_thread_options",
312      "$dir_pw_thread:thread",
313      "$dir_pw_thread:thread_info",
314      "$dir_pw_thread:thread_iteration",
315    ]
316  }
317}
318
319pw_source_set("dynamic_test_threads") {
320  public_deps = [ "$dir_pw_thread:non_portable_test_thread_options" ]
321  sources = [ "dynamic_test_threads.cc" ]
322  deps = [
323    "$dir_pw_chrono:system_clock",
324    "$dir_pw_thread:sleep",
325    "$dir_pw_thread:thread",
326  ]
327}
328
329pw_test("dynamic_thread_backend_test") {
330  enable_if = pw_thread_THREAD_BACKEND == "$dir_pw_thread_freertos:thread"
331  deps = [
332    ":dynamic_test_threads",
333    "$dir_pw_thread:thread_facade_test",
334  ]
335
336  # Doesn't work on the Pico yet;
337  # TODO: https://pwbug.dev/325509758 - Doesn't work on the Pico yet; hangs
338  # indefinitely (on join() test).
339  if (pw_build_EXECUTABLE_TARGET_TYPE == "pico_executable") {
340    enable_if = false
341  }
342}
343
344pw_source_set("static_test_threads") {
345  public_deps = [ "$dir_pw_thread:non_portable_test_thread_options" ]
346  sources = [ "static_test_threads.cc" ]
347  deps = [
348    "$dir_pw_chrono:system_clock",
349    "$dir_pw_thread:sleep",
350    "$dir_pw_thread:thread",
351  ]
352}
353
354pw_test("static_thread_backend_test") {
355  enable_if = pw_thread_THREAD_BACKEND == "$dir_pw_thread_freertos:thread"
356  deps = [
357    ":static_test_threads",
358    "$dir_pw_thread:thread_facade_test",
359  ]
360}
361
362pw_doc_group("docs") {
363  sources = [ "docs.rst" ]
364}
365