1.. _bsim boards:
2
3Bsim boards
4###########
5
6**Available bsim boards**
7
8* :ref:`Simulated nRF52833 (nrf52_bsim)<nrf52_bsim>`
9* :ref:`Simulated nRF5340 (nrf5340bsim)<nrf5340bsim>`
10* :ref:`Simulated nRF54L15 (nrf54l15bsim)<nrf54l15bsim>`
11
12.. contents:: Table of contents
13   :depth: 2
14   :backlinks: entry
15   :local:
16
17This page covers the design, architecture and rationale, of the
18nrf5x_bsim boards and other similar bsim boards.
19These boards are postfixed with `_bsim` as they use BabbleSim_
20(shortened bsim), to simulate the radio environment.
21These boards use the `native simulator`_ and the :ref:`POSIX architecture<Posix arch>` to build
22and execute the embedded code natively on Linux.
23
24Particular details on the :ref:`nRF52<nrf52_bsim>`, :ref:`nRF5340<nrf5340bsim>` and
25:ref:`nRF54l15<nrf54l15bsim>` simulation boards, including how to use them,
26can be found in their respective documentation.
27
28.. _BabbleSim:
29   https://BabbleSim.github.io
30
31.. _EDTT:
32   https://github.com/EDTTool/EDTT
33
34.. _Architecture of HW models used for FW development and testing:
35   https://babblesim.github.io/arch_hw_models.html
36
37.. _native simulator:
38   https://github.com/BabbleSim/native_simulator/blob/main/docs/README.md
39
40.. _native simulator design documentation:
41   https://github.com/BabbleSim/native_simulator/blob/main/docs/Design.md
42
43.. _nRF HW models design documentation:
44   https://github.com/BabbleSim/ext_nRF_hw_models/blob/main/docs/README_HW_models.md
45
46
47Overall objective
48*****************
49
50The main purpose of these bsim boards is to be test-benches for
51integration testing of embedded code on workstation/simulation.
52Integration testing in the sense that the code under test will, at the very
53least, run with the Zephyr RTOS just like for any other
54:ref:`POSIX arch based board<posix_arch_rationale>`, but in addition these
55will include some HW models which, to some degree, pretend to be the real
56embedded HW.
57
58These tests are run in workstation, that is, without using real embedded HW.
59The intention being to be able to run tests much faster than real time,
60without the need for real HW, and in a deterministic/reproducible fashion.
61
62Unlike :ref:`native_sim <native_sim>`, bsim boards do not interact directly with any host
63peripherals, and their execution is independent of the host load, or timing.
64
65These boards are also designed to be used as prototyping and development environments,
66which can help developing applications or communication stacks.
67
68.. _bsim_boards_tests:
69
70Different types of tests and how the bsim boards relate to them
71===============================================================
72
73With the POSIX architecture we provided an overall
74:ref:`comparison of what the POSIX arch provides vs other options<posix_arch_compare>`.
75That comparison applies fully to these boards, but in this section we expand
76further on the differences, benefits and drawbacks of different testing
77methodologies normally employed by embedded SW developers and how they relate
78to these boards.
79
80- Unit tests:
81  Typical unit tests frameworks provide unit testing
82  support which covers a different need: testing a component in isolation.
83  Zephyr provides a unit testing target (unit_testing) which is not related to
84  these bsim boards.
85- Integration tests on real HW: Allows testing with the real SW
86  components that may be too dependent on the exact HW particularities, and
87  possibly without any changes compared to the final solution.
88  As such can provide better integration coverage than simulation ins ome cases,
89  but at the expense of slower execution, needing the real HW setups,
90  test in general not being reproducible, and in many cases failures
91  not being easy to debug.
92  They otherwise serve a very similar purpose to simulation integration tests.
93- Integration tests on workstation (what the POSIX arch and these boards enable)
94
95  - Using bsim boards: Allow testing the embedded SW (or a subset), including
96    the OS, models of peripherals etc. By testing them in conjunction,
97    it is possible to test the components interactions and their integration.
98  - Using bsim boards with the BabbleSim Physical layer simulation allows
99    testing how several devices would interact with each other.
100    For ex. how a left and a right earbud synchronize and exchange data and
101    audio over their radio link, and how they interact with a mobile phone.
102  - Using bsim boards, and the `EDTT`_ framework: With the EDTT framework we can
103    test the embedded code under test while controlling the test from external
104    python test scripts. This is supported by compiling the embedded code with
105    an special driver that handles the EDTT communication (its RPC transport)
106    and an embedded application that handles the RPC calls themselves, while
107    the python test scripts provide the test logic.
108  - Using Zephyr's :ref:`native_sim <native_sim>` board: It also allows integration testing of
109    the embedded code, but without any specific HW. In that way, many embedded
110    components which are dependent on the HW would not be suited for testing in
111    that platform. Just like the bsim boards, this Zephyr target board can
112    be used with or without Zephyr's ztest system and twister.
113    The :ref:`native_sim <native_sim>` board shares the :ref:`POSIX architecture<Posix arch>`,
114    and native simulator runner with the bsim boards.
115
116- Zephyr's ztest infrastructure and Zephyr's twister:
117  Based on dedicated embedded test applications build with the code under test.
118  The embedded test application is responsible for driving the tests and check
119  the results on its own, and provide a test result to a PC which directs the
120  test.
121  Originally used as a framework for integration testing on target,
122  with a very dedicated test application,
123  these are fully supported with the bsim boards.
124
125Design
126******
127
128Layering: Zephyr's arch, soc and board layers
129=============================================
130
131The basic architecture layering of these boards is as follows:
132
133- The `native simulator`_ runner is used to execute the code in your host.
134- The architecture, SOC and board components of Zephyr are replaced with
135  simulation specific ones.
136- The architecture (arch) is the Zephyr :ref:`POSIX architecture<Posix arch>`
137  layer.
138  The SOC layer is `inf_clock`. And the board layer is dependent on
139  the specific device we are simulating.
140- The POSIX architecture provides an adaptation from the Zephyr arch API
141  (which handles mostly the thread context switching) to the native simulator
142  CPU thread emulation.
143  See :ref:`POSIX arch architecture<posix_arch_architecture>`
144- The SOC `inf_clock` layer provides an adaptation to the native simulator CPU "simulation"
145  and the handling of control between the "CPU simulation" (Zephyr threads) and the
146  HW models thread ( See `Threading`_ ).
147- The board layer provides all SOC/ IC specific content, including
148  selecting the HW models which are built in the native simulator runner context, IRQ handling,
149  busy wait API (see :ref:`posix_busy_wait<posix_busy_wait>`), and Zephyr's printk backend.
150  Note that in a normal Zephyr target interrupt handling and a custom busy wait
151  would be provided by the SOC layer, but abusing Zephyr's layering, and for the
152  `inf_clock` layer to be generic, these were delegated to the board.
153  The board layer provides other test specific
154  functionality like bs_tests hooks, trace control, etc, and
155  by means of the native simulator, provides the :c:func:`main` entry point for the Linux
156  program, command line argument handling, and the overall time scheduling of
157  the simulated device.
158  Note that the POSIX arch and `inf_clock` soc expect a set of APIs being provided by
159  the board. This includes the busy wait API, a basic tracing API, the interrupt
160  controller and interrupt handling APIs, :c:func:`posix_exit`,
161  and :c:func:`posix_get_hw_cycle` (see :file:`posix_board_if.h` and :file:`posix_soc_if.h`).
162
163.. figure:: layering_natsim.svg
164    :align: center
165    :alt: Zephyr layering in native & bsim builds
166    :figclass: align-center
167
168    Overall architecture in a Zephyr application in an embedded target vs a bsim
169    target
170
171Important limitations and unsupported features
172==============================================
173
174All native and bsim boards share the same set of
175:ref:`important limitations which<posix_arch_limitations>`
176are inherited from the POSIX arch and `inf_clock` design.
177
178Similarly, they inherit the POSIX architecture
179:ref:`unsupported features set <posix_arch_unsupported>`.
180
181.. _Threading:
182
183Threading and overall scheduling of CPU and HW models
184=====================================================
185
186The threading description, as well as the general SOC and board architecture
187introduced in
188:ref:`POSIX arch architecture<posix_arch_architecture>` and on the
189`native simulator design documentation`_ apply to the bsim boards.
190
191Moreover in
192`Architecture of HW models used for FW development and testing`_
193a general introduction to the babblesim HW models and their scheduling are provided.
194
195In case of the nRF bsim boards, more information can be found in the
196`nRF HW models design documentation`_.
197
198Time and the time_machine
199=========================
200
201Simulated time in bsim boards is in principle fully decoupled from
202real wall-clock time. As described in
203:ref:`POSIX arch architecture<posix_arch_architecture>`,
204simulated time is advanced
205as needed to the next scheduled HW event, and does not progress while
206the simulated CPU is executing code.
207
208In general simulation time will pass much faster than real time,
209and the simulation results will not be affected in any way by the
210load of the simulation host or by the process execution being "paused"
211in a debugger or similar.
212
213The native simulator HW scheduler provides the overall HW event time loop
214required by the HW models, which consists of a very simple
215"search for next event", "advance time to next event and execute it" loop,
216together with an API for components that use it to inform about their events
217timers having been updated. Events are defined at design time,
218they are not registered dynamically for simplicity and speed.
219
220Use of babblesim components: tracing, random number generation, logging activity
221================================================================================
222
223The same considerations as for the HW models apply to the bsim boards, see
224`Architecture of HW models used for FW development and testing`_.
225
226The communication between a Zephyr device and other simulated devices is
227handled over the bsim libPhyCom libraries. For the radio activity the figure
228below represents this communication:
229
230
231.. figure:: Zephyr_and_bsim.svg
232    :align: center
233    :alt: Communication between a Zephyr device and other simulated devices
234    :figclass: align-center
235
236    Communication between a Zephyr device and other simulated devices
237
238Test code may also communicate with other devices' test code using the bsim
239backchannels. These provide a direct, reliable pipe between devices which test code
240can use to exchange data.
241
242
243About using Zephyr APIs
244=======================
245
246Note that even though part of the bsim board code is linked with the Zephyr kernel,
247one should in general not call Zephyr APIs from the board code itself.
248In particular, one should not call Zephyr APIs from the original/HW models
249thread as the Zephyr code would be called from the wrong context,
250and will with all likelihood cause all kind of difficult to debug issues.
251
252In general board code should be considered as lower level than the Zephyr OS,
253and not dependent on it.
254For example, board code should not use the printk API as that anyhow would
255result in a call back into the board code (the bsim specific printk backend)
256which relies on the bs_trace API. Instead, for tracing the bs_trace API
257should be used directly.
258The same applies to other Zephyr APIs, including the entropy API, etc.
259
260posix_print and nsi_print backends
261==================================
262
263The bsim board provides a backend for the ``posix_print`` API which is expected by the posix
264ARCH and `inf_clock` code, and for the ``nsi_print`` API expected by the native simulator.
265
266These simply route this API calls into the ``bs_trace`` bsim API.
267Any message printed to these APIs, and by extension by default to Zephyr's ``printk``,
268will be printed to the console (stdout) together with all other device messages.
269
270.. _bsim_boards_bs_tests:
271
272bs_tests
273========
274
275The bsim boards provide also the bs_tests facility.
276
277This allows tests to be defined (registered), and for each of these tests to
278use a number of special test hooks which are present only in these simulated
279targets.
280
281These tests are built together with the embedded SW, and are present in the
282binary but will not be executed by default.
283From the command line the user can query what tests are present, and select
284which test (if any) should be executed. When a test is selected its registered
285callbacks are assigned to the respective hooks.
286
287There is a set of one time hooks at different levels of initialization of the HW
288and Zephyr OS, a hook to process possible command line arguments, and, a hook
289that can be used to sniff or capture interrupts.
290`bs_tests` also provides a hook which will be called from the embedded application
291:c:func:`main`, but this will only work if the main application supports it,
292that is, if the main app is a version for simulation which calls
293:c:func:`bst_main` when running in the bsim board.
294
295Apart from these hooks, the `bs_tests` system provides facilities to build a
296dedicated test "task". This will be executed in the HW models thread context,
297but will have access to all SW variables. This task will be driven with a
298special timer which can be configured to produce either periodic or one time
299ticks. When these ticks occur a registered test tick function will be called.
300This can be used to support the test logic, like run checks or perform actions
301at specific points in time. This can be combined with Babblesim's tb_defs macros
302to build quite complex test tasks which can wait for a given amount of time,
303for conditions to be fulfilled, etc.
304
305Note when writing the tests with `bs_tests` one needs to be aware that other
306bs tests will probably be built with the same application, and that therefore
307the tests should not be registering initialization or callback functions using
308NATIVE_TASKS or Zephyr's PRE/POST kernel driver initialization APIs as this
309will execute even if the test is not selected.
310Instead the equivalent `bs_tests` provided hooks should be used.
311
312Note also that, for AMP targets like the :ref:`nrf5340bsim <nrf5340bsim>`, each embedded MCU has
313its own separate `bs_tests` built with that MCU. You can select if and what test is used
314for each MCU separatedly with the command line options.
315
316Command line argument parsing
317=============================
318
319bsim boards need to handle command line arguments. There are several sets of
320arguments:
321
322- Basic arguments: to enable selecting things like trace verbosity, random seed,
323  simulation device number and simulation id (when connected to a phy), etc.
324  This follow as much as possible the same convention as other bsim
325  devices to ease use for developers.
326- The HW models command line arguments: The HW models will expose which
327  arguments they need to have processed, but the bsim board as actual
328  integrating program ensures they are handled.
329- Test (bs_tests) control: To select a test for each embedded CPU,
330  print which are available, and pass arguments to the tests themselves.
331
332Command line argument parsing is handled by using the bs_cmd_line component
333from Babblesim's base/libUtilv1 library. And basic arguments definitions that
334comply with the expected convention are provided in bs_cmd_line_typical.h.
335
336Other considerations
337====================
338
339- Endianness: Code will be built for the host target architecture, which is
340  typically x86. x86 is little endian, which is typically also the case for the
341  target architecture. If this is not the case, embedded code which works in one
342  may not work in the other due to endianness bugs.
343  Note that Zephyr code is be written to support both big and little endian.
344- WordSize: The bsim targets, as well as normal embedded targets are 32 bit
345  targets. In the case of the bsim targets this is done by explicitly targeting
346  x86 (ILP32 ABI) instead of x86_64. This is done purposefully to provide more
347  accurate structures layout in memory and therefore better reproduce possible
348  issues related to access to structures members or array overflows.
349