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 in some 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 128Relationship between Zephyr, the native simulator, the nRF HW models and BabbleSim 129================================================================================== 130 131As shown in the figure below, when you build your embedded application targeting one of Zephyr's 132nrf_bsim targets, you are using the `native simulator`_, which is being built together with and 133expanded by the nRF HW models for that target. 134Your application is first built and linked with the Zephyr kernel and any subsystems and network 135stacks you may have selected, including mostly the same drivers as for the real target. 136The native simulator runner is built together with the HW models which match your desired target. 137And then both the embedded SW and runner are linked together to produce a Linux executable. 138 139.. figure:: components_bsim.svg 140 :align: center 141 :alt: nrf_bsim boards and the native simulator 142 :figclass: align-center 143 144 Relationship between Zephyr, the native simulator, the nRF HW models and BabbleSim. 145 146When you target a multi MCU SOC like the :ref:`nrf5340bsim<nrf5340bsim_multi_mcu_build>`, you can 147use :ref:`sysbuild<sysbuild>` to build an executable, where, for each MCU, its application, Zephyr 148kernel and subsystems are built and linked first, and finally assembled all together with the native 149simulator runner into a single executable. 150 151Layering: Zephyr's arch, soc and board layers 152============================================= 153 154The basic architecture layering of these boards is as follows: 155 156- The `native simulator`_ runner is used to execute the code in your host. 157- The architecture, SOC and board components of Zephyr are replaced with 158 simulation specific ones. 159- The architecture (arch) is the Zephyr :ref:`POSIX architecture<Posix arch>` 160 layer. 161 The SOC layer is ``inf_clock``. And the board layer is dependent on 162 the specific device we are simulating. 163- The POSIX architecture provides an adaptation from the Zephyr arch API 164 (which handles mostly the thread context switching) to the native simulator 165 CPU thread emulation. 166 See :ref:`POSIX arch architecture<posix_arch_architecture>` 167- The SOC ``inf_clock`` layer provides an adaptation to the native simulator CPU "simulation" 168 and the handling of control between the "CPU simulation" (Zephyr threads) and the 169 HW models thread ( See `Threading`_ ). 170- The board layer provides all SOC/ IC specific content, including 171 selecting the HW models which are built in the native simulator runner context, IRQ handling, 172 busy wait API (see :ref:`posix_busy_wait<posix_busy_wait>`), and Zephyr's printk backend. 173 Note that in a normal Zephyr target interrupt handling and a custom busy wait 174 would be provided by the SOC layer, but abusing Zephyr's layering, and for the 175 ``inf_clock`` layer to be generic, these were delegated to the board. 176 The board layer provides other test specific 177 functionality like bs_tests hooks, trace control, etc, and 178 by means of the native simulator, provides the :c:func:`main` entry point for the Linux 179 program, command line argument handling, and the overall time scheduling of 180 the simulated device. 181 Note that the POSIX arch and ``inf_clock`` soc expect a set of APIs being provided by 182 the board. This includes the busy wait API, a basic tracing API, the interrupt 183 controller and interrupt handling APIs, :c:func:`posix_exit`, 184 and :c:func:`posix_get_hw_cycle` (see :file:`posix_board_if.h` and :file:`posix_soc_if.h`). 185 186.. figure:: layering_natsim.svg 187 :align: center 188 :alt: Zephyr layering in native & bsim builds 189 :figclass: align-center 190 191 Overall architecture in a Zephyr application in an embedded target vs a bsim 192 target 193 194Important limitations and unsupported features 195============================================== 196 197All native and bsim boards share the same set of 198:ref:`important limitations which<posix_arch_limitations>` 199are inherited from the POSIX arch and ``inf_clock`` design. 200 201Similarly, they inherit the POSIX architecture 202:ref:`unsupported features set <posix_arch_unsupported>`. 203 204.. _Threading: 205 206Threading and overall scheduling of CPU and HW models 207===================================================== 208 209The threading description, as well as the general SOC and board architecture 210introduced in 211:ref:`POSIX arch architecture<posix_arch_architecture>` and on the 212`native simulator design documentation`_ apply to the bsim boards. 213 214Moreover in 215`Architecture of HW models used for FW development and testing`_ 216a general introduction to the babblesim HW models and their scheduling are provided. 217 218In case of the nRF bsim boards, more information can be found in the 219`nRF HW models design documentation`_. 220 221Time and the time_machine 222========================= 223 224Simulated time in bsim boards is in principle fully decoupled from 225real wall-clock time. As described in 226:ref:`POSIX arch architecture<posix_arch_architecture>`, 227simulated time is advanced 228as needed to the next scheduled HW event, and does not progress while 229the simulated CPU is executing code. 230 231In general simulation time will pass much faster than real time, 232and the simulation results will not be affected in any way by the 233load of the simulation host or by the process execution being "paused" 234in a debugger or similar. 235 236The native simulator HW scheduler provides the overall HW event time loop 237required by the HW models, which consists of a very simple 238"search for next event", "advance time to next event and execute it" loop, 239together with an API for components that use it to inform about their events 240timers having been updated. Events are defined at design time, 241they are not registered dynamically for simplicity and speed. 242 243Use of babblesim components: tracing, random number generation, logging activity 244================================================================================ 245 246The same considerations as for the HW models apply to the bsim boards, see 247`Architecture of HW models used for FW development and testing`_. 248 249The communication between a Zephyr device and other simulated devices is 250handled over the bsim libPhyCom libraries. For the radio activity the figure 251below represents this communication: 252 253 254.. figure:: Zephyr_and_bsim.svg 255 :align: center 256 :alt: Communication between a Zephyr device and other simulated devices 257 :figclass: align-center 258 259 Communication between a Zephyr device and other simulated devices 260 261Test code may also communicate with other devices' test code using the bsim 262backchannels. These provide a direct, reliable pipe between devices which test code 263can use to exchange data. 264 265 266About using Zephyr APIs 267======================= 268 269Note that even though part of the bsim board code is linked with the Zephyr kernel, 270one should in general not call Zephyr APIs from the board code itself. 271In particular, one should not call Zephyr APIs from the original/HW models 272thread as the Zephyr code would be called from the wrong context, 273and will with all likelihood cause all kind of difficult to debug issues. 274 275In general board code should be considered as lower level than the Zephyr OS, 276and not dependent on it. 277For example, board code should not use the printk API as that anyhow would 278result in a call back into the board code (the bsim specific printk backend) 279which relies on the bs_trace API. Instead, for tracing the bs_trace API 280should be used directly. 281The same applies to other Zephyr APIs, including the entropy API, etc. 282 283posix_print and nsi_print backends 284================================== 285 286The bsim board provides a backend for the ``posix_print`` API which is expected by the posix 287ARCH and ``inf_clock`` code, and for the ``nsi_print`` API expected by the native simulator. 288 289These simply route this API calls into the ``bs_trace`` bsim API. 290Any message printed to these APIs, and by extension by default to Zephyr's ``printk``, 291will be printed to the console (stdout) together with all other device messages. 292 293.. _bsim_boards_bs_tests: 294 295bs_tests 296======== 297 298The bsim boards provide also the bs_tests facility. 299 300This allows tests to be defined (registered), and for each of these tests to 301use a number of special test hooks which are present only in these simulated 302targets. 303 304These tests are built together with the embedded SW, and are present in the 305binary but will not be executed by default. 306From the command line the user can query what tests are present, and select 307which test (if any) should be executed. When a test is selected its registered 308callbacks are assigned to the respective hooks. 309 310There is a set of one time hooks at different levels of initialization of the HW 311and Zephyr OS, a hook to process possible command line arguments, and, a hook 312that can be used to sniff or capture interrupts. 313``bs_tests`` also provides a hook which will be called from the embedded application 314:c:func:`main`, but this will only work if the main application supports it, 315that is, if the main app is a version for simulation which calls 316:c:func:`bst_main` when running in the bsim board. 317 318Apart from these hooks, the ``bs_tests`` system provides facilities to build a 319dedicated test "task". This will be executed in the HW models thread context, 320but will have access to all SW variables. This task will be driven with a 321special timer which can be configured to produce either periodic or one time 322ticks. When these ticks occur a registered test tick function will be called. 323This can be used to support the test logic, like run checks or perform actions 324at specific points in time. This can be combined with Babblesim's tb_defs macros 325to build quite complex test tasks which can wait for a given amount of time, 326for conditions to be fulfilled, etc. 327 328Note when writing the tests with ``bs_tests`` one needs to be aware that other 329bs tests will probably be built with the same application, and that therefore 330the tests should not be registering initialization or callback functions using 331NATIVE_TASKS or Zephyr's PRE/POST kernel driver initialization APIs as this 332will execute even if the test is not selected. 333Instead the equivalent ``bs_tests`` provided hooks should be used. 334 335Note also that, for AMP targets like the :ref:`nrf5340bsim <nrf5340bsim>`, each embedded MCU has 336its own separate ``bs_tests`` built with that MCU. You can select if and what test is used 337for each MCU separatedly with the command line options. 338 339Command line argument parsing 340============================= 341 342bsim boards need to handle command line arguments. There are several sets of 343arguments: 344 345- Basic arguments: to enable selecting things like trace verbosity, random seed, 346 simulation device number and simulation id (when connected to a phy), etc. 347 This follow as much as possible the same convention as other bsim 348 devices to ease use for developers. 349- The HW models command line arguments: The HW models will expose which 350 arguments they need to have processed, but the bsim board as actual 351 integrating program ensures they are handled. 352- Test (bs_tests) control: To select a test for each embedded CPU, 353 print which are available, and pass arguments to the tests themselves. 354 355Command line argument parsing is handled by using the bs_cmd_line component 356from Babblesim's base/libUtilv1 library. And basic arguments definitions that 357comply with the expected convention are provided in bs_cmd_line_typical.h. 358 359Other considerations 360==================== 361 362- Endianness: Code will be built for the host target architecture, which is 363 typically x86. x86 is little endian, which is typically also the case for the 364 target architecture. If this is not the case, embedded code which works in one 365 may not work in the other due to endianness bugs. 366 Note that Zephyr code is be written to support both big and little endian. 367- WordSize: The bsim targets, as well as normal embedded targets are 32 bit 368 targets. In the case of the bsim targets this is done by explicitly targeting 369 x86 (ILP32 ABI) instead of x86_64. This is done purposefully to provide more 370 accurate structures layout in memory and therefore better reproduce possible 371 issues related to access to structures members or array overflows. 372