(sdk-setup)= # SDK Setup and Build Overview This guide covers SDK installation, manual environment setup, and primary workflows using CMake or STM32CubeIDE. The focus is on a **manual, transparent setup** (no helper scripts required on Linux) so you can see exactly which tools are used and which environment variables are expected. For platform architecture, see [platform overview](platform-overview.md). For tutorials, see [HelloWorld tutorial](Tutorials/HelloWorld/ARCHITECTURE.md). ## Prerequisites - Linux/macOS/Windows development machine - CMake 3.21+ (for manual builds) - A build tool: `make` (Unix Makefiles) - Python 3 + pip (for packaging/build utilities) - **ST ARM GCC Toolchain (CRITICAL)**: STM32CubeIDE or STM32CubeCLT version **required**. System `gcc-arm-none-eabi` is often incompatible (newlib syscall stubs such as `_write` can be missing). See [toolchain setup](#toolchain-setup). - **TouchGFX (Windows-only for Designer)**: For GUI development - TouchGFX Designer requires Windows. See [TouchGFX](#touchgfx-require-a-windows-host) below. - USB cable for device flashing - Git for cloning the SDK The rest of this document provides OS-specific, end-to-end setup sections (Linux/Windows) that follow the same flow: **Get required software → Prepare → Clone and setup environment → Copy example and build** (toolchain-setup)= ## Toolchain Setup **CRITICAL**: Use STMicroelectronics GNU Tools for STM32 (from **STM32CubeIDE** or **STM32CubeCLT**). The system `gcc-arm-none-eabi` shipped by many distros (often GCC 13+) is frequently incompatible with this SDK's bare-metal/newlib expectations and may fail with undefined syscall stubs (`_write`, `_close`, etc.). ### Linux Setup #### Get required software - [Git](https://git-scm.com/) (clone + version string generation) - Python 3 + pip (packaging utilities) - CMake 3.21+ - make - **STM32CubeIDE** or **STM32CubeCLT** (provides the **ST** `arm-none-eabi-gcc` toolchain) Install hints (keep it minimal; equivalents work on other distros): ```bash # Ubuntu/Debian sudo apt update sudo apt install -y git python3 python3-pip cmake build-essential ``` #### Prepare ##### Toolchain (CubeIDE/CubeCLT) and PATH 1) Install the ST toolchain (choose one): - **STM32CubeCLT** (CLI-first): ```bash chmod +x ~/Downloads/STM32CubeCLT_Linux64_v1-*.run ~/Downloads/STM32CubeCLT_Linux64_v1-*.run ``` - **STM32CubeIDE** (IDE + toolchain): Download/install from: https://www.st.com/en/development-tools/stm32cubeide.html 2) Ensure the ST toolchain is on your `PATH`. If you installed **CubeCLT**, the toolchain is typically under: ```bash export PATH="$HOME/.local/share/stm32cube/bundles/gnu-tools-for-stm32/*/bin:$PATH" ``` If `arm-none-eabi-gcc` is still not found and you installed **CubeIDE**, add the directory that contains `arm-none-eabi-gcc` to your `PATH` (it is usually a `.../plugins/...gnu-tools-for-stm32.../tools/bin` folder inside the CubeIDE installation). ##### Clone and setup environment ```bash # Clone git clone --recursive https://github.com/UNAWatch/una-sdk.git cd una-sdk # Export environment for the current shell export UNA_SDK="$PWD" # Satisfy python dependencies python3 -m pip install -r "$UNA_SDK/Utilities/Scripts/app_packer/requirements.txt" ``` ##### Verify your environment This SDK expects the toolchain and build tools to be discoverable via `PATH`. ```bash which arm-none-eabi-gcc || true which cmake || true which make || true which python3 || true python3 -m pip --version arm-none-eabi-gcc --version || true cmake --version || true make --version || true ``` If `which arm-none-eabi-gcc` prints nothing, your ST toolchain bin directory is not on `PATH` yet. Add it (see **Prepare** above) and re-open your terminal. #### Copy and Build an Existing Example This section demonstrates how to copy an existing app example (Alarm) and build it without modifications to verify your setup. For creating and customizing a new app by modifying a copy, see "Creating New Apps" below. This uses the same **Alarm CMake** example flow as Windows: **copy project → create build dir → configure → build**. ```bash # Copy entire project for simplicity cp -r "$UNA_SDK/Examples/Apps/Alarm/"* MyAlarm # Create build dir mkdir -p MyAlarm/build # Configure cmake -G "Unix Makefiles" -S MyAlarm/Software/Apps/Alarm-CMake -B MyAlarm/build # Build cmake --build MyAlarm/build ``` #### Optional (Linux) ##### Persist `UNA_SDK` and toolchain `PATH` If you don't want to export variables every time, add them to your shell profile. For bash: ```bash echo 'export UNA_SDK="$HOME/path/to/una-sdk"' >> ~/.bashrc echo 'export PATH="$HOME/.local/share/stm32cube/bundles/gnu-tools-for-stm32/*/bin:$PATH"' >> ~/.bashrc source ~/.bashrc ``` For zsh: ```bash echo 'export UNA_SDK="$HOME/path/to/una-sdk"' >> ~/.zshrc echo 'export PATH="$HOME/.local/share/stm32cube/bundles/gnu-tools-for-stm32/*/bin:$PATH"' >> ~/.zshrc source ~/.zshrc ``` ##### Note about distro `gcc-arm-none-eabi` If you installed `gcc-arm-none-eabi` from your distro repositories and builds fail with missing syscall stubs, switch to the **ST** toolchain from CubeIDE/CubeCLT and ensure its `arm-none-eabi-gcc` is the one found first in `PATH`. ### Windows Setup #### Get required software - [Git](https://git-scm.com/install/windows) - [Python 3](https://www.python.org/downloads/windows/) - Notes: - Enable "Add python.exe to PATH" checkmark - Click "Disable path length limit" after installation - [STM32CubeIDE](https://www.st.com/en/development-tools/stm32cubeide.html#st-get-software) - Provides Toolchain, CMake, Make utilities (*note*: STM32CubeCLT does not includes `make` program, which is required) - [VS Code](https://code.visualstudio.com/download) - IDE #### Prepare ##### Clone and setup environment ```powershell # Clone via SSH git clone --recursive git@github.com:UNAWatch/una-sdk.git # Or use HTTPS git clone --recursive https://github.com/UNAWatch/una-sdk.git # Export environment (persistent) # If you encounter a security error (e.g., running scripts is disabled), run this first: Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process . ./una-sdk/Utilities/Scripts/export-stm32-tools.ps1 # Satisfy python dependencies pip install -r ${env:UNA_SDK}/Utilities/Scripts/app_packer/requirements.txt # If pip fails or dependencies are not found, verify Python is in PATH and restart PowerShell. ``` Reboot your PC or restart PowerShell to apply the environment variables. This ensures all changes take effect and may resolve issues like copy errors in later steps. #### Copy and Build an Existing Example This section demonstrates how to copy an existing app example (Alarm) and build it without modifications to verify your setup. For creating and customizing a new app by modifying a copy, see "Creating New Apps" below. ```powershell # Copy entire project for simplicity # Note: The copied folder will retain original names like Alarm-CMake. Use the original name in commands below (e.g., Alarm-CMake instead of MyAlarm-CMake). # If you get "Container cannot be copied onto existing leaf item" error, restart PowerShell and try again. cp "${env:UNA_SDK}\Examples\Apps\Alarm\*" MyAlarm -Recurse -Force # Create build dir mkdir -p MyAlarm\build # Call CMake cmake -G "Unix Makefiles" -S MyAlarm/Software/Apps/Alarm-CMake -B MyAlarm/build # Build cmake --build MyAlarm/build ``` #### Troubleshooting Windows Setup If you encounter errors like "include could not find requested file: /cmake/una-app.cmake" or "/cmake/una-sdk.cmake", ensure the `UNA_SDK` environment variable is set. Run the export script with dot sourcing to apply it to the current shell: `. ./una-sdk/Utilities/Scripts/export-stm32-tools.ps1`. Reboot your PC or restart PowerShell if issues persist, as environment variables may not apply immediately. If CMake reports "CMAKE_MAKE_PROGRAM is not set", "CMAKE_C_COMPILER not set", or "CMAKE_CXX_COMPILER not set", even after setting environment variables, add the following compiler flags to the CMake command: ```powershell cmake -G "Unix Makefiles" -DCMAKE_SYSTEM_NAME=Generic -DCMAKE_C_COMPILER=arm-none-eabi-gcc -DCMAKE_CXX_COMPILER=arm-none-eabi-g++ -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY -DCMAKE_ASM_COMPILER=arm-none-eabi-gcc -S MyAlarm/Software/Apps/Alarm-CMake -B MyAlarm/build ``` Then proceed with the build step: `cmake --build MyAlarm/build`. ## CMake-Based Workflow Development The CMake workflow is recommended for command-line control and is fully standalone. Apps reference the SDK via `UNA_SDK` and use relative paths for flexibility. ### `Examples/` Project Structure Overview ``` MyApp/ # App root (can be anywhere) ├── Software/ │ ├── Apps/ │ │ ├── MyApp-Service-CubeIDE/ # CubeIDE project with Service │ │ ├── MyApp-GUI-CubeIDE/ # CubeIDE project with GUI │ │ ├── MyApp-CMake/ # CMake project dir │ │ │ ├── CMakeLists.txt │ │ │ ├── MyAppService.ld # Linker script │ │ │ └── syscalls.cpp │ │ └── TouchGFX-GUI/ # For GUI apps │ └── Libs/ │ ├── Header/ # Headers │ └── Sources/ # Sources ├── Resources/ │ ├── icon_30x30.png │ └── icon_60x60.png └── Output/ # Built .uapp files ``` ### CMake Command Explanations The CMake build process is a two-step procedure: 1. **Configuration/Generation**: `cmake -G "Unix Makefiles" -S -B ` generates intermediate build files (e.g., Makefiles) in the specified build directory. This step configures the project, resolves dependencies, sets compilers and paths, and prepares the build environment. Run this for initial setup or when `CMakeLists.txt` changes. 2. **Build/Compilation**: `cmake --build ` (from any directory) or `make` (inside the build directory) compiles the source code using the generated build files. Run this to build or recompile after source file modifications. For a clean rebuild, remove the build directory and repeat both steps: `rm -rf build && cmake -S . -B build && cmake --build build`. If build files are generated in the wrong directory (e.g., root instead of build dir), navigate to the correct build directory and run `make` or `cmake --build .` from there. ### Creating New Apps 1. **Copy CMake Template**: To create a new app, copy an existing one from Examples/Apps (replace with e.g., "Alarm" or "HRMonitor"). There are two ways: an easy way without renaming (no path changes needed) and an optional way to fully rename and reorganize. **Easy Way (No Renaming, Minimal Changes):** ```bash # Copy the entire app folder cp -r "${UNA_SDK}/Examples/Apps/" MyApp # Copy or create icons in MyApp/Resources/ if needed (required: icon_30x30.png, icon_60x60.png) ``` This keeps all original folder and file names. When building, use the original -CMake in commands (e.g., cmake -S MyApp/Software/Apps/-CMake -B MyApp/build). To adapt for your app: - Update APP_NAME and APP_ID in MyApp/Software/Apps/-CMake/CMakeLists.txt (see step 2). - For GUI apps: Open MyApp/Software/Apps/TouchGFX-GUI/GUI.touchgfx in TouchGFX Designer, update project name if desired, and save as MyAppGUI.touchgfx. Other references remain the same. **Optional: Full Rename and Reorganization (Customize Structure):** If you want to match your app name or change folder structure: ```bash # Create custom structure mkdir -p MyApp/Software/Apps/MyApp-CMake MyApp/Software/Libs MyApp/Software/Apps/TouchGFX-GUI MyApp/Resources MyApp/Output # Copy and rename CMake folder contents cp -r "${UNA_SDK}/Examples/Apps//Software/Apps/-CMake/*" MyApp/Software/Apps/MyApp-CMake/ # Rename internal files, e.g.: mv MyApp/Software/Apps/MyApp-CMake/Service.ld MyApp/Software/Apps/MyApp-CMake/MyAppService.ld # Copy libs (or move to custom path and update LIBS_PATH in CMakeLists.txt) cp -r "${UNA_SDK}/Examples/Apps//Software/Libs/*" MyApp/Software/Libs/ # Copy TouchGFX (skip if not GUI; adjust TOUCHGFX_PATH if moved) cp -r "${UNA_SDK}/Examples/Apps//Software/Apps/TouchGFX-GUI/*" MyApp/Software/Apps/TouchGFX-GUI/ # Rename TouchGFX project if desired: mv MyApp/Software/Apps/TouchGFX-GUI/GUI.touchgfx MyApp/Software/Apps/TouchGFX-GUI/MyAppGUI.touchgfx # Copy or create icons in MyApp/Resources/ (adjust RESOURCES_PATH if changed) ``` Note: A clean template is planned for future releases. If reorganizing, update paths in CMakeLists.txt accordingly (see step 2). 2. **Customize CMakeLists.txt** (located at MyApp/Software/Apps/MyApp-CMake/CMakeLists.txt): Update the following variables to customize your app. These are defined in the CMakeLists.txt and control build parameters, paths, and app metadata. Defaults are provided where applicable. - `APP_NAME`: Set to your app's name, e.g., "MyApp". This is used for output filenames and internal references. - `APP_ID`: A unique 16-character uppercase hexadecimal string identifying your app. - Generate locally: - Bash/Linux: python -c 'import hashlib; print(hashlib.md5(b"MyApp").hexdigest().upper()[:16])' - PowerShell/Windows: python -c "import hashlib; print(hashlib.md5(b'MyApp').hexdigest().upper()[:16])" - Alternatively, acquire from the developer portal for published apps as described in [deploy.md](deploy.md). Replace "MyApp" with your app name. See [API reference](api-reference.rst) for details. - `DEV_ID`: Device identifier, typically "UNAWatch". - `APP_TYPE`: App type, e.g., "app". - `APP_AUTOSTART`: "On" or "Off" (default "Off") to enable autostart. - Paths (adjust if reorganizing file structure): - `LIBS_PATH`: Path to libraries, default "../../Libs". - `OUTPUT_PATH`: Path for built files, default "../../../Output". - `RESOURCES_PATH`: Path to resources like icons, default "../../../Resources". - `TOUCHGFX_PATH`: Path to TouchGFX directory for GUI apps, e.g., "../TouchGFX-GUI". - Memory settings (optional, adjust for app needs; defaults in una-app.cmake): - `UNA_APP_SERVICE_STACK_SIZE`: Service stack, default 10*1024. - `UNA_APP_SERVICE_RAM_LENGTH`: Service RAM, default 500K. - `UNA_APP_GUI_STACK_SIZE`: GUI stack, default 10*1024. - `UNA_APP_GUI_RAM_LENGTH`: GUI RAM, default 600K. - Other optional: `BUILD_VERSION` (auto-detected from git or script), `APP_USER_NAME` (defaults to APP_NAME). After updating APP_NAME, rename files like the linker script (e.g., from AlarmService.ld to MyAppService.ld) to match, as CMakeLists.txt references "${APP_NAME}Service.ld". Note: Paths are relative to CMakeLists.txt. You can reorganize folders by updating these paths accordingly. For example, if libs are in a different location, change LIBS_PATH. 3. **Implement Logic**: - Edit `Libs/Sources/` for service code. - For GUI, configure TouchGFX in `TouchGFX-GUI/` (e.g., update `application.config`, generate code via TouchGFX Designer). 4. **Add Resources**: - Place icons in `MyApp/Resources/` (30x30 and 60x60 PNGs required; copy from the original app or create new ones). 5. **Set Environment**: Ensure the `UNA_SDK` environment variable is set, as described in the Linux or Windows setup sections above (e.g., run the export script or export command). If you've just set it, restart your terminal or PowerShell for the changes to take effect. ### Building Apps Manually Navigate to the app's CMake directory: ```bash cd MyApp/Software/Apps/MyApp-CMake # Ensure UNA_SDK and other vars are exported # Configure (creates build dir) cmake -G "Unix Makefiles" -S . -B build # Build cmake --build build # Output: .uapp in Output/ ``` For clean rebuild: `rm -rf build && cmake -S . -B build && cmake --build build`. ## Alternative Workflow: STM32CubeIDE For IDE users, copy CubeIDE projects from Examples. ### Creating New Apps in CubeIDE 1. **Copy Projects**: - Copy from `Examples/Apps/` to `Examples/Apps/` 2. **Customize**: - Edit `.project` and `.cproject`: Replace names/IDs. - Update `Linker.ld`: App name, paths. - Modify `Core/Src/` and `Core/Inc/` for logic. 3. **Import to CubeIDE**: - File > Import > Existing Projects into Workspace > Select copied dirs. - Fix paths in Project Properties > C/C++ Build > Settings. 4. **Build**: - Build service/GUI separately. - Manual merge: Use SDK scripts (e.g., `Utilities/Scripts/app_merging/app_merging.py`) with icons/resources. (touchgfx-require-a-windows-host)= ## TouchGFX (Windows-only for Designer) TouchGFX is a high-performance graphics framework designed for STM32 microcontrollers, enabling rich graphical user interfaces on embedded devices with limited resources. For now this is single supported way to create graphical applications for UNAwatch platform. **Note**: Glances operates without TouchGFX framework, it uses embedded lightweight drawing API which allow to draw simple text and icons in glances menu. ### Installation 1. **Download and Install TouchGFX Designer**: - Create a free account on the [STMicroelectronics website](https://www.st.com). - Download the latest version of TouchGFX from the ST Developer Zone. - Install the TouchGFX Designer tool on your development machine (Windows only). 2. **Framework Integration**: - In the UNA SDK, TouchGFX is pre-integrated in example GUI projects (e.g., `Examples/Apps//Software/Apps/TouchGFX-GUI/`). - For new projects, copy the TouchGFX-GUI directory from an example and ensure the framework libraries are available via the SDK paths. - No separate installation of the framework is needed if using the SDK's bundled version; otherwise, download the TouchGFX framework package from ST. ### Using TouchGFX Designer for Visual Editing - **Launch Designer**: Open TouchGFX Designer and create a new project or open an existing `.touchgfx` configuration file (e.g., `MyAppGUI.touchgfx`). - **Visual Design**: Define display settings, add widgets, organize screens, import assets, and configure interactions. - **Preview and Simulate**: Use the built-in simulator to test the UI before generating code. For comprehensive guidance on TouchGFX Designer usage, code generation, project structure, CMake integration, build configuration, code organization, MVP pattern implementation, and custom GUI development, see the [TouchGFX Port Architecture](TouchGFX-Port-Architecture.md) document. ### Integration with CMake In UNA SDK projects, TouchGFX integrates seamlessly with CMake for building GUI applications. Set `TOUCHGFX_PATH` in `CMakeLists.txt`, include `touchgfx.cmake`, and configure GUI sources. ### Modifying Generated Code Safely - **Avoid Editing Generated Files**: Files in `generated/` are automatically overwritten during code generation. - **Custom Code Locations**: Place custom implementations in `gui/src/` (views, presenters, model). - **Regeneration Workflow**: Design → Generate Code → Implement custom logic in `gui/src/` → Rebuild. ## **Troubleshooting** - **Missing Dependencies**: Ensure all required libraries are linked. - **Path Errors**: Verify `UNA_SDK` and other paths are correctly set. - **Toolchain Issues**: Confirm ARM GCC is properly installed and in PATH. On Windows, run the export script with dot sourcing and reboot if necessary. - **CMake Compiler Errors**: If CMake cannot find compilers (e.g., "CMAKE_C_COMPILER not set"), add `-DCMAKE_SYSTEM_NAME=Generic -DCMAKE_C_COMPILER=arm-none-eabi-gcc -DCMAKE_CXX_COMPILER=arm-none-eabi-g++ -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY -DCMAKE_ASM_COMPILER=arm-none-eabi-gcc` to the cmake command. - **Build Conflicts**: Clean build dirs if errors persist after changes. Use `rm -rf build` (Linux) or `Remove-Item -Recurse build` (PowerShell) and reconfigure.