# Overview

<Add project overview here>

# Getting started

## Development with devcontainer in visual studio code
### Devcontainer
1. Install Visual Studio Code Dev Containers.
2. Install docker engine [https://docs.docker.com/get-docker/](https://docs.docker.com/get-docker/)
3. Development environment is defined as docker image defined inside .devcontainer directory so no additional installations are required (It is also used by CI so you use is what CI use).

### Linux (debian/ubuntu) issues: docker compose is not installed by default
docker-compose is not installed by default with docker engine so below might be required

```bash
#!/bin/bash

sudo apt install docker-compose
```

### Windows 11 issues: Usb is not available in container
If you use windows and would like to have device access. You would be forced to forward them. It can be done via usbip tool (usb over ip). So

1. Put your Docker Desktop into WSL2 mode (Best during installation, in version v4.18 it is default option).
2. Change default Docker desktop WSL image to UbuntuDistribution (default one is not debian based and will NOT work with usbip instructions). Best  way is to switch it from docker desktop GUI
    1. Go to DockerDesktopTrayIcon (right click) -> Setting -> Resources -> WSL Integration
    2. Find option described as *Enable integration with additional distros* And mark ubuntu 22.04 option
3. Change default WSL image to Ubuntu 22.04
    ```powershell
    wsl -l -v                      # check the names
    wsl --set-default Ubuntu-22.04 # set default distribution
    ```
4. Install usbip on windows and inside WSL Ubuntu-22.04
5. Attach device
    ```
    usbipd list                   # print all usb devices
    usbipd wsl attach --busid 4-2	# attach device 4-2 to docker run env
    ```

### Sources
1. [https://learn.microsoft.com/en-us/windows/wsl/connect-usb](https://learn.microsoft.com/en-us/windows/wsl/connect-usb)
2. [https://github.com/dorssel/usbipd-win](https://github.com/dorssel/usbipd-win)
3. [https://devblogs.microsoft.com/commandline/connecting-usb-devices-to-wsl/](https://devblogs.microsoft.com/commandline/connecting-usb-devices-to-wsl/)


## Configuration of conan
Project relies on internal conan package repository. Compilation work only when you configure credentials.
Add to `.devcontainer/.env` variables with conan credentials. (File might not exist as it is ignored by git - it contains local settings of developer machine):

```bash
CONAN_LOGIN_USERNAME="<gitlab_user>"            # Usually three letters
CONAN_PASSWORD="<gitlab_personal_access_token>" # Access token generated in gitlab  gui EditProfile -> Access Tokens
```

Remember that changing .env file **REQUIRE REBUILD OF DEVCONTAINER**.
Variables should be visible inside containers.

```bash
#!/bin/bash
printenv | grep CONAN # In case of correct config this should print your user and password as system variables
```

## Work with project (compilation)

### Scargo flow (local development)
```bash
#!/bin/bash
scargo clean;                 # Clean build directory.
scargo update;                # GENERATE files using toml file as instruction (scargo is code generator). IT IS REQUIRED AFTER CHANGES IN *.toml FILE
scargo build --profile Debug; # Compile project with debug profile
scargo test -v;               # Run tests with verbose output
```

### Scargo full flow (tools and checks)
```bash
#!/bin/bash
scargo clean;                 # Clean build directory.
scargo update;                # GENERATE files using toml file as instruction (scargo is code generator). IT IS REQUIRED AFTER CHANGES IN scargo.toml FILE
scargo test -v;               # Run tests with verbose output
scargo build --profile Debug; # Compile project with debug profile
scargo check --clang-format;  # Check sources with clang format (autoformatter)
scargo check --cppcheck;      # Check sources with cppcheck (static analysis)
scargo check --clang-tidy;    # Check sources with clang format (naming convention and light static analysis)
scargo check --todo;          # Check for todo comments
scargo check --cyclomatic;    # Calculate cyclomatic complexity
scargo check --pragma;        # Check for existence of pragma directive in headers
scargo check --copyright;     # Check for existence of copyright in files
scargo fix --clang-format;    # Run automate clang formatting for files with issues
scargo fix --copyright;       # Add copyright notice at start of source files (if missing)
scargo fix --pragma;          # Add pragma directive in headers if missing
scargo doc;                   # Generate documentation
scargo publish;               # Publish conan package to artifacts repository
scargo flash;                 # Flash microcontroller board
```

### Other scargo commands (not mandatory for all projects)

```bash
#!/bin/bash
scargo gen #Generate certificate and other artifacts for chosen targets
```


{% if project.target.family == "esp32" %}
# ESP32 configure
At the beginning of a project is strongly recommended to configure the project using `idf.py menuconfig`
In the console please run `idf.py menuconfig` and configure at least the following options:
- Bootloader config -> Bootloader Optimization Level ...  (O2 is recommended)
- Serial Flasher Config -> Flash Size ... (e.g. for wroom is 4MB)
- Partition Table -> Partition Table ... -> Custom Partition Table CSV


# Recomended source code directory structure

The folder structure of the source code reflects the layered solution architecture. There are four layers available:
* application
* middleware
* library
* BSP

It is assumed that any software in given layer should not depend on any upper layer. It is advised that each particular layer should depend only on the direct layer below.

There can be some exceptions but they should be explicitly stated in the software architecture document. By default all layers can use standard C and C++ libraries, RTOS specific libraries and logging.

`/<root>/main`
  - root folder for sources

`/<root>/main/apps`
  - application layer - main tasks of the application
  - main business logic of the application
  - this folder should not depend on any platform specific libraries and components

`/<root>/main/middleware`
  - middleware layer
  - components to be used by application layer in order to provide required functionality
  - this folder should not depend on any platform specific libraries

`/<root>/libs`
  - libraries and utilities to be used by upper layers (mainly middleware)
  - in the main library folder - there are no libraries dependent on any platform
  - as an exception some libraries (e.g., logging) may be used by all layers

`/<root>/libs/_platform`
  - libraries which are platform dependent - i.e., they depend on specific hardware or platform specific SDKs (e.g. ESP-IDF)

`/<root>/bsp`
  - board support package - libraries and other stuff strictly related to the HW board
  - drivers for peripherals
  - linker scripts
  - etc.

*Note*
In order to integrate platform independent libraries with the dependent ones it is suggested to provide platform independent interface libraries with the specific implementation ones. It is up to the main cmake file and main() function (i.e., app_main() on freertos) to integrate everything together.

## Simulation with qemu
To use qemu, a single image with all partitions is needed. You can generate it with the following command:

`scargo gen -b`

or it can be generated based on data from build/flasher_args.json but spiffs partition needs to be added manually to the file.

`esptool.py --chip esp32 merge_bin --fill-flash-size 4MB -o build/flash_image.bin @flash_args`

Then run qemu simulation:

`qemu-system-xtensa -nographic -machine esp32 -drive file=build/flash_image.bin,if=mtd,format=raw`

Stop qemu using `pkill qemu` command in the terminal

## Working directly with IDF

(0) idf.py fullclean

1. idf.py all
2. idf.py flash
3. idf.py monitor

idf.py clean
idf.py build
or
idf.py app
idf.py app-flash

idf.py menuconfig

## Create fs and manage image

Create image:
`scargo gen --fs`
or
`$IDF_PATH/components/spiffs/spiffsgen.py 24576 main/fs build/spiffs.bin`

Write to partition 'spiffs' the contents of a file named 'spiffs.bin':
`scargo flash --fs`
or
`parttool.py write_partition --partition-name=spiffs --input "build/spiffs.bin"`

Erase partition with name 'storage':
`parttool.py erase_partition --partition-name=spiffs`

Read partition with type 'data' and subtype 'spiffs' and save to file 'spiffs.bin':
`parttool.py read_partition --partition-type=data --partition-subtype=spiffs --output "build/spiff.bin"`

Print the size of the default boot partition:
`parttool.py get_partition_info --partition-boot-default --info size`

## Potential issues

idf.py set-target esp32c3 - set up esp32 uC target example with esp32c3


## Debug

### debug in the console

idf.py flash monitor openocd gdbgui

### debug in vsc

- run `idf.py openocd` or `openocd -c \"set ESP_RTOS none\" -f board/esp32-wrover-kit-3.3v.cfg`
- run debug in vscode

{% elif project.target.family == "stm32" %}
# STM32 configure
The model of the microcontroller is taken from the model set in scargo.toml file e.g.:
`[stm32] -> chip = "STM32L496AGI6"`
Please change is according to your needs.

Some of the external dependencies such as CMSIS or HAL are added to the project configuration by default. They will be managed by cmake.
We call stm32-cmake functions for fetch content. Please check the stm32-cmake project to get knowledge of how to use HAL and CMSIS dependencies (https://github.com/ObKo/stm32-cmake#hal)

## Debug

### debug in the console

openocd gdb

### debug in vsc

- run debug in vscode
{% endif %}