You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Update architectures and flags for Zephyr guide
- Added back picolibc include dir, added more info
- Add more information on linking customizations
- Change title of IntegrateWithZephyr doc
Copy file name to clipboardExpand all lines: Sources/EmbeddedSwift/Documentation.docc/SDKSupport/IntegrateWithZephyr.md
+95-7Lines changed: 95 additions & 7 deletions
Original file line number
Diff line number
Diff line change
@@ -1,19 +1,22 @@
1
-
# Integrating with Zephyr
1
+
# Zephyr RTOS SDK
2
2
3
3
Integrating Swift with Zephyr RTOS for embedded systems development
4
4
5
+
[Zephyr](https://www.zephyrproject.org/) is an open-source RTOS for embedded systems that is sponsored by the Linux Foundation. Since it depends on CMake primarily for its build system, it can easily be integrated to be used with Embedded Swift.
6
+
5
7
The following document outlines how to setup a Swift to Zephyr project for an emulated ARM Cortex M0, explaining a few key concepts along the way. For a complete working example on real hardware, however, refer to the [nrfx-blink-sdk](https://github.com/swiftlang/swift-embedded-examples/tree/main/nrfx-blink-sdk) project that is compatible with nRF or other boards.
6
8
7
9
> Note: Embedded Swift is experimental. Public releases of Swift do not support Embedded Swift, yet. See <doc:InstallEmbeddedSwift> for details.
8
10
9
-
## Zephyr Target Architecture Compatibility
11
+
## Target Architecture Compatibility
10
12
11
13
Zephyr [supports quite a few target architectures](https://docs.zephyrproject.org/latest/introduction/index.html), but not all are supported by Embedded Swift. Please refer to the following table for an overview of Zephyr-supported architectures that are supported by Swift, along with the correct target triple to use:
There are quite a few other Zephyr flags that must also be imported in order to get Zephyr include paths and flags such `-mcpu`, `-mfloat-abi`, and so on:
168
+
- NOTE: The `-mfloat-abi=soft` flag may need to change to `-mfloat-abi=hard` for ARM CPUs that support hard-float, such as the Cortex-M4F and Cortex-M7. This and the `-fshort-enums` flags are not required for non-ARM architectures such as Intel and RISC-V.
169
+
170
+
There are quite a few other Zephyr flags that can also be imported (optional) in order to get Zephyr include paths and flags such `-mcpu`, `mthumb`, `-mabi`, and so on:
157
171
158
172
```cmake
159
173
# Import TOOLCHAIN_C_FLAGS from Zephyr as -Xcc flags
@@ -289,7 +303,8 @@ manifest:
289
303
- cmsis # required by the ARM port
290
304
```
291
305
292
-
It is recommended to set the `revision` to a tagged version of Zephyr instead of always getting the main revision, which could have changing APIs.
306
+
- It is recommended to set the `revision` to a tagged version of Zephyr instead of always getting the main revision, which could have changing APIs.
307
+
- Also, please note that depending on what architecture you are targeting, you may need to add more/different targets to the `name-allowlist`, which is useful to get needed dependencies when compiling a project from a CI. See the [Zephyr workflow from swift-embedded-examples](https://github.com/swiftlang/swift-embedded-examples/blob/main/.github/workflows/build-zephyr.yml) for an example of setting up a CI for Zephyr.
293
308
294
309
Next, set the `ZEPHYR_BASE` environment variable to tell `west` where the Zephyr workspace is located:
295
310
@@ -335,3 +350,76 @@ ninja: no work to do.
335
350
```
336
351
337
352
The `-r jlink` param is needed for this example to use the J-Link tools instead of using `nrfjprog`, which is the default for this board and also [deprecated](https://www.nordicsemi.com/Products/Development-tools/nRF-Command-Line-Tools).
353
+
354
+
## Customizing the Linker
355
+
356
+
The default linker configuration for building a Zephyr project from CMake works well for simple projects, but it can be customized as needed. The following sections show off some useful ways to customize linking Zephyr projects for Swift.
357
+
358
+
### Stripping Out Unused Sections
359
+
360
+
When compiling Swift to Zephyr projects, you may see some warnings about orphaned sections from the linker, like `.swift_modhash`:
361
+
362
+
```console
363
+
~/zephyr-sdk-0.17.0/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: warning: orphan section `.swift_modhash' from `app/libapp.a(Main.swift.obj)' being placed in section `.swift_modhash'
364
+
[135/135] Linking C executable zephyr/zephyr.elf
365
+
~/zephyr-sdk-0.17.0/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: warning: orphan section `.swift_modhash' from `app/libapp.a(Main.swift.obj)' being placed in section `.swift_modhash
366
+
```
367
+
368
+
These types of warnings can be suppressed by passing a custom linker script to Zephyr that discards the sections, especially if they are not needed. For example, a script called `sections.ld` can be created at the root of the project with the following contents:
369
+
370
+
```ld
371
+
/DISCARD/ : { *(.swift_modhash*) }
372
+
/DISCARD/ : { *(.ARM.attributes*) *(.ARM.exidx) }
373
+
```
374
+
375
+
Then, in `CMakeLists.txt`, add the following line:
376
+
377
+
```cmake
378
+
# Remove unused sections
379
+
zephyr_linker_sources(SECTIONS "sections.ld")
380
+
```
381
+
382
+
This can also help to reduce the size of the output elf/binary since unused sections are stripped out. Be careful what sections you strip out, however, as some sections may be required.
383
+
384
+
### Linking Swift Libraries
385
+
386
+
This example adds the `swiftUnicodeDataTables` library from Swift to be linked into the Zephyr project. This is useful for linking unicode symbols when using strings. See <doc:Strings> for more information on this.
387
+
388
+
In order to add additional linker params, the CMake `target_link_libraries` invocation can be used against `zephyr_pre0` and `zephyr_final`, like this:
389
+
390
+
```cmake
391
+
# The code is using a String as a Dictionary key and thus require linking with libswiftUnicodeDataTables.a
392
+
# We compute the path where this file reside, taking into accout how the toolchain is referenced (Swiftly or TOOLCHAINS env variable).
393
+
find_program(SWIFTLY "swiftly")
394
+
IF(SWIFTLY)
395
+
execute_process(COMMAND swiftly use --print-location OUTPUT_VARIABLE toolchain_path)
Extra code is required to find the right paths where the `swiftUnicodeDataTables.a` file is located, depending on how Swift is installed.
418
+
419
+
When this is built, depending on the target architecture, warnings may then be printed about 32-bit enums, like this:
420
+
421
+
```console
422
+
~/zephyr-sdk-0.17.0/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/12.2.0/../../../../arm-zephyr-eabi/bin/ld.bfd: warning: ~/.local/share/swiftly/toolchains/6.1.0/usr/lib/swift/embedded/armv6m-none-none-eabi/libswiftUnicodeDataTables.a(UnicodeWord.cpp.o) uses 32-bit enums yet the output is to use variable-size enums; use of enum values across objects may fail
423
+
```
424
+
425
+
To suppress these, simply add `-Wl,--no-enum-size-warning` to the `target_link_libraries` invocations.
0 commit comments