The reasons for using a simulator are explained in the main README.
Simulation consists of:
- Firmware (.so file)
- High-level logic is used as-is, without modification for simulation mode. This code is located in the Application/BusinessLogic/ and Application/Device/ folders within the firmware directory.
- The Stub folder replaces low-level classes (Driver folder within the firmware directory).
- device_under_test.py: Loads the firmware .so file and provides a Python API interface.
- simulation.py: Main simulation class. It contains a thread that periodically calls tick from the library, retrieves - internal states like the content of the LCD, and sets external events such as simulating button presses to the firmware. main_window.py: Main window of the application.
- main.py: Provides the graphical interface.
-
Do Not Inherit from Firmware Driver Headers, as they include many HAL dependencies that are difficult to stub and not needed in simulation mode. Instead, use driver interface headers and create stub drivers based on inheritance from those interfaces. The only exception to this rule is the Display driver.
-
No Stubs for Business Logic or Device Layers. A stub in these layers suggests the classes are too tightly coupled with low-level code, indicating a need to refactor the firmware for better separation of concerns.
- Python3
- PyQT6
- C++
- cmake
- Docker