SDK CMake User Guide

This guide provides comprehensive information on how to use the HPM SDK’s CMake extensions for building embedded applications. It focuses on workflow, best practices, and practical examples rather than API reference (which is covered in cmake_intro).

Overview

This section provides a high-level introduction to the HPM SDK CMake build system and its key concepts.

Design Philosophy and Architecture

Design Philosophy of SDK CMake Build System

The HPM SDK CMake build system is designed with a fundamental principle: decoupling user applications from the underlying SDK. This design philosophy addresses several key challenges in embedded development:

1. SDK Version Independence

  • Users can switch between different SDK versions within the same major version by simply changing the SDK_BASE path

  • No need to modify application code when switching SDK versions

  • Maintains application compatibility across SDK updates

2. Reduced Communication Overhead in Team Development

  • Multiple developers can collaborate on applications based on the same SDK version

  • Only application-related data needs to be exchanged, not the entire SDK

  • Eliminates the need to share large SDK repositories between team members

  • Reduces version synchronization issues and merge conflicts

3. Complete Decoupling Through Custom Board Support

  • Users can define custom board configurations without modifying SDK core files

  • Applications become completely independent of SDK internals

  • Enables rapid prototyping and customization for specific hardware requirements

  • Improves development efficiency by isolating application logic from SDK complexity

4. Modular Architecture Benefits

  • Clear separation of concerns between application and SDK layers

  • Easier maintenance and debugging of application-specific issues

  • Simplified dependency management and build configuration

  • Enhanced portability across different development environments

5. Cross-Platform Build System

  • Windows, macOS, and Linux Support: Full compatibility across major operating systems

  • Unified Build Commands: Same CMake commands work identically on all platforms

  • Automatic Toolchain Detection: Automatically detects and configures platform-specific toolchains

  • IDE Integration: Generates platform-appropriate project files for various IDEs

  • Path Handling: Automatic path conversion between different operating system conventions

  • Dependency Resolution: Platform-agnostic dependency management and resolution

6. SOC-Agnostic Application Development

  • Dependency Abstraction: Build system shields users from complex SOC-specific dependency details

  • Unified API Interface: Consistent development experience across different HPM SOC families

  • Automatic Configuration: SOC-specific settings, memory layouts, and peripheral configurations are handled automatically

  • Focus on Application Logic: Developers can concentrate on application development without worrying about underlying SOC complexities

Architecture Overview

hpm_sdk’s build system creates a layered architecture that separates user applicat with rom SDK internals while maintaincodeflexibility through custom board support:

┌─────────────────────────────────────────────────────────────────┐
│                    User Application Layer                       │
│  ┌─────────────────┐  ┌─────────────────┐  ┌──────────────────┐ │
│  │   Application   │  │   Application   │  │   Application    │ │
│  │   Source Code   │  │   Configuration │  │   Build Files    │ │
│  │   (main.c, etc) │  │   (app.yaml)    │  │ (CMakeLists.txt) │ │
│  └─────────────────┘  └─────────────────┘  └──────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
                                 │
                                 │ depends on
                                 ▼
┌──────────────────────────────────────────────────────────────────┐
│                  Custom Board Configuration                      │
│  ┌─────────────────┐  ┌─────────────────┐  ┌───────────────────┐ │
│  │   Board YAML    │  │   Custom Board  │  │   Board-Specific  │ │
│  │  Configuration  │  │   Definitions   │  │   Pin Mappings    │ │
│  │   (board.yaml)  │  │(board.h/board.c)│  │(pinmux.h/pinmux.c)│ │
│  └─────────────────┘  └─────────────────┘  └───────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
                                 │
                                 │ references
                                 ▼
┌────────────────────────────────────────────────────────────────┐
│                        SDK Core Layer                          │
│  ┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐ │
│  │      SOC        │  │     Drivers     │  │   Middleware    │ │
│  │  Definitions    │  │   (GPIO, UART,  │  │  (FreeRTOS,     │ │
│  │ (registers,     │  │   SPI, I2C,     │  │   USB, etc.)    │ │
│  │  memory map)    │  │   etc.)         │  │                 │ │
│  └─────────────────┘  └─────────────────┘  └─────────────────┘ │
│  ┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐ │
│  │    CMake        │  │   Toolchain     │  │     IDE         │ │
│  │   Build System  │  │  Integration    │  │  Integration    │ │
│  │  (localization, │  │ (GCC, SEGGER,   │  │ (SES, IAR)      │ │
│  │   optimization) │  │  Andes, etc.)   │  │                 │ │
│  └─────────────────┘  └─────────────────┘  └─────────────────┘ │
└────────────────────────────────────────────────────────────────┘

SDK Version Flexibility:

The same application can work with different SDK versions by simply changing the HPM_SDK_BASE path:

Application A (main.c, app.yaml, CMakeLists.txt)
├── SDK Version 1.0.0 (HPM_SDK_BASE=/path/to/sdk_v1.0.0)
├── SDK Version 1.1.0 (HPM_SDK_BASE=/path/to/sdk_v1.1.0)
├── SDK Version 1.2.0 (HPM_SDK_BASE=/path/to/sdk_v1.2.0)
└── Custom SDK Build  (HPM_SDK_BASE=/path/to/custom_sdk)

Application B (main.c, app.yaml, CMakeLists.txt)
├── SDK Version 1.0.0 (HPM_SDK_BASE=/path/to/sdk_v1.0.0)
├── SDK Version 1.1.0 (HPM_SDK_BASE=/path/to/sdk_v1.1.0)
└── SDK Version 1.2.0 (HPM_SDK_BASE=/path/to/sdk_v1.2.0)

Key Benefits of This Architecture:

  • Separation of Concerns: User applications are completely independent of SDK internals

  • Custom Board Support: Users can define custom boards without modifying SDK core files

  • Version Flexibility: Easy switching between SDK versions by changing HPM_SDK_BASE

  • Team Collaboration: Share only application and board files, not the entire SDK

  • Maintainability: Clear boundaries make debugging and maintenance easier

Build System Overview:

The SDK build system is a comprehensive solution that integrates multiple components to provide a seamless development experience. It combines CMake-based project management with automated toolchain detection, intelligent dependency resolution, and cross-platform compatibility. The system is designed to handle the complexity of embedded development while maintaining simplicity for application developers.

Core Components:

The build system handles:

  • Toolchain Management: Automatic detection and configuration of supported toolchains

  • Board Configuration: Board-specific settings and peripheral configurations

  • Component Integration: Modular component system for drivers and middleware

  • Multi-core Support: Support for dual-core applications with linked projects

  • IDE Integration: Generation of project files for various IDEs

  • Build Optimization: Configurable build types and optimization levels

Basic Workflow

Setting Up Your Project

  1. Create Project Structure

    my_project/
    ├── CMakeLists.txt
    ├── app.yaml
    └── src/
        └── main.c
    
  2. Configure CMakeLists.txt

    cmake_minimum_required(VERSION 3.13)
    
    # Find and configure the HPM SDK
    find_package(hpm-sdk REQUIRED HINTS $ENV{HPM_SDK_BASE})
    
    # Define your project
    project(my_application)
    
    # Add source files
    sdk_app_src(src/main.c)
    
    # Generate IDE projects (optional)
    generate_ide_projects()
    
  3. Configure app.yaml

    debug:
      ses:
        auto_start_gdb_server: true
        gdb_server_port: 3333
    

Building Your Project

Basic Build Commands:

# Configure and build
cmake -B build -S . -DBOARD=hpm6750evkmini
cmake --build build

# Or in one step
cmake -B build -S . -DBOARD=hpm6750evkmini && cmake --build build

Build Configuration:

The SDK uses two different build type concepts:

  1. CMAKE_BUILD_TYPE - Compilation optimization level:

    • debug: Debug build with symbols and minimal optimization

    • release: Release build with full optimization

  2. HPM_BUILD_TYPE - Linker configuration for memory layout:

    • ram: Build for RAM execution (default)

    • flash_xip: Build for flash execution with XIP

    • flash_sdram_xip: Build for flash execution with SDRAM XIP

    • flash_hybrid_xip: Build for hybrid execution (code in ram-mapped flash content, data in RAM)

    • sec_core_img: Build for secondary core image

Setting Build Types:

  1. Compilation Type (CMAKE_BUILD_TYPE):

    # Debug compilation
    cmake -B build -S . -DBOARD=hpm6750evkmini -DCMAKE_BUILD_TYPE=debug
    
    # Release compilation
    cmake -B build -S . -DBOARD=hpm6750evkmini -DCMAKE_BUILD_TYPE=release
    
  2. Linker Type (HPM_BUILD_TYPE):

    In CMakeLists.txt (Recommended for project-specific builds):

    cmake_minimum_required(VERSION 3.13)
    
    # Set linker configuration for this project
    set(HPM_BUILD_TYPE "flash_xip")
    
    find_package(hpm-sdk REQUIRED HINTS $ENV{HPM_SDK_BASE})
    project(my_application)
    
    sdk_app_src(src/main.c)
    generate_ide_projects()
    

    Via Command Line (Override CMakeLists.txt setting):

    # Flash XIP execution
    cmake -B build -S . -DBOARD=hpm6750evkmini -DHPM_BUILD_TYPE=flash_xip
    
  3. Combined Example:

    # Release compilation with flash XIP execution
    cmake -B build -S . -DBOARD=hpm6750evkmini -DCMAKE_BUILD_TYPE=release -DHPM_BUILD_TYPE=flash_xip
    

Advanced Configuration

Customize Output File Names

Output File Name (APP_NAME):

The APP_NAME variable controls the output file names. If not specified, it defaults to “demo”. The output file names are:

  • ${APP_NAME}.elf - Executable file

  • ${APP_NAME}.bin - Binary file for flashing

  • ${APP_NAME}.map - Memory map file

  • ${APP_NAME}.asm - Assembly listing

In CMakeLists.txt:

cmake_minimum_required(VERSION 3.13)

# Set custom application name
set(APP_NAME "my_custom_app")

find_package(hpm-sdk REQUIRED HINTS $ENV{HPM_SDK_BASE})
project(my_application)

sdk_app_src(src/main.c)
generate_ide_projects()

Via Command Line:

# Set custom application name
cmake -B build -S . -DBOARD=hpm6750evkmini -DAPP_NAME=my_custom_app

Output Files:

The APP_NAME affects the following output files:

  • ${APP_NAME}.elf - Executable file

  • ${APP_NAME}.bin - Binary file for flashing

  • ${APP_NAME}.map - Memory map file

  • ${APP_NAME}.asm - Assembly listing

Combined Advanced Example:

# Release compilation with flash XIP execution and custom app name
cmake -B build -S . -DBOARD=hpm6750evkmini -DCMAKE_BUILD_TYPE=release -DHPM_BUILD_TYPE=flash_xip -DAPP_NAME=my_custom_app

Segger Embedded Studio (SES) Advanced Customization

The SDK provides extensive customization options for Segger Embedded Studio projects through CMake variables and specialized functions.

Toolchain and Compiler Variants:

# In your CMakeLists.txt file:

# Set toolchain variant (Standard, Andes)
set(SES_TOOLCHAIN_VARIANT "Standard")

# Configure compiler variant (gcc, SEGGER)
set(SES_COMPILER_VARIANT "gcc")

# Set assembler variant (gcc, SEGGER)
set(SES_ASSEMBLER_VARIANT "SEGGER")

# Configure linker variant (gnu, SEGGER)
set(SES_LINKER_VARIANT "SEGGER")

Library I/O Configuration:

# Set library I/O type for SES
sdk_ses_opt_lib_io_type(STD)  # Options: STD, SEGGER, Custom

Advanced Compilation Control:

# Set SES-specific compile options
sdk_ses_compile_options(-O2 -g -Wall)

# Set SES-specific compile definitions
sdk_ses_compile_definitions(-DDEBUG -DVERSION=1)

# Link SES-specific libraries
sdk_ses_link_libraries(libm libc)

Per-File Optimization Control:

# Set optimization level for specific files
sdk_ses_set_optimization_level("src/critical.c" "Level 2 for speed")
sdk_ses_set_optimization_level("src/debug.c" "None")

# Configuration-specific optimization
sdk_ses_set_optimization_level_debug("src/test.c" "Level 1")
sdk_ses_set_optimization_level_release("src/test.c" "Level 3 for more speed")

Section Placement Control:

# Control section placement for specific files
sdk_ses_set_code_placement("src/vector.c" "vector_section")
sdk_ses_set_data_placement("src/constants.c" "const_section")
sdk_ses_set_isr_placement("src/interrupts.c" "isr_section")

# Configuration-specific section placement
sdk_ses_set_code_placement_debug("src/debug.c" "debug_code")
sdk_ses_set_code_placement_release("src/debug.c" "release_code")

Linker and Memory Configuration:

# Set SES-specific linker options
sdk_ses_ld_options(-Wl,--start-group -Wl,--end-group)

# Link SES-specific input libraries
sdk_ses_ld_lib(custom_lib.a)

# Configure memory layout
set(SES_MEMORY_LAYOUT "Custom")

Debug and Target Configuration:

# Configure debug target connection
set(SES_DEBUG_TARGET_CONNECTION "GDB Server")  # Options: GDB Server, J-Link

# GDB Server configuration
set(SES_GDB_SERVER_TYPE "Custom")
set(SES_GDB_SERVER_COMMAND "openocd")
set(SES_GDB_SERVER_ARGS "-f board/hpm6750evkmini.cfg")
set(SES_GDB_SERVER_PORT "3333")

# J-Link configuration
set(SES_JLINK_SPEED "4000")
set(SES_JLINK_DEVICE "HPM6750xVMx")

Build Configuration:

# Set SES build configuration
set(SES_BUILD_CONFIGURATION "Release")  # Options: Debug, Release, RelWithDebInfo

# Configure optimization level
set(SES_OPTIMIZATION_LEVEL "2")  # 0=None, 1=Basic, 2=Full, 3=Size

# Set warning level
set(SES_WARNING_LEVEL "All")  # Options: None, Basic, All, Extra

Command Line Configuration:

# Configure SES via command line
cmake -B build -S . -DBOARD=hpm6750evkmini \
      -DSES_TOOLCHAIN_VARIANT="Standard" \
      -DSES_COMPILER_VARIANT="gcc" \
      -DSES_ASSEMBLER_VARIANT="SEGGER" \
      -DSES_LINKER_VARIANT="SEGGER" \
      -DSES_DEBUG_TARGET_CONNECTION="GDB Server" \
      -DSES_GDB_SERVER_COMMAND="openocd" \
      -DSES_GDB_SERVER_ARGS="-f board/hpm6750evkmini.cfg"

Generated SES Project Structure:

After building, the following SES project files will be generated:

build/segger_embedded_studio/
├── ${CMAKE_PROJECT_NAME}.emProject          # Main project file
└── ${CMAKE_PROJECT_NAME}.emSession          # Session configuration

Integration with app.yaml:

You can also configure some SES debug settings in your app.yaml file:

# app.yaml
debug:
  ses:
    auto_start_gdb_server: true      # Auto-start GDB server (Yes/No)
    gdb_server_port: 3333           # GDB server port number
    gdb_server_reset_command: "reset halt"  # GDB server reset command

Note: Only these three SES debug settings are supported in app.yaml. For other SES configurations (toolchain variants, compiler options, section placement, etc.), you must use CMake variables and functions as described above.

Advanced SES Functions Reference:

The SDK provides several specialized functions for SES customization:

# Set SES project options
sdk_ses_options("LIBRARY_IO_TYPE=STD")
sdk_ses_options("debug_target_connection=GDB Server")
sdk_ses_options("linker_printf_fp_enabled=1")
sdk_ses_options("linker_scanf_fp_enabled=1")
sdk_ses_options("linker_printf_fmt_level=F4000"

Debug Connection Types:
- "GDB Server", "J-Link# Note: If using Andes extensions or DSP features, you MUST use Andes toolchain
Andes")

# When using Andes toolchain, the following variants are automatically set:
# - ES_COMPILER_VARIANT defauls to "gcc"
# - SES_ASSEMBLER_VARIANT defults to "gcc"
# - SES_LINKER_VARIANT defaults to "gnu"

# Aes toolchain is required for:
# - Andes RISC-V extensions (custom instructions)
# - DSP features and optimizations
# - Andes-specific compiler gnu - Standard GNU GCC toolchain
- - Andes RISC-V toolchain (required for Andes extensions and DSP features))Important Note about sdk_ses_options():**

The sdk_ses_options() function accepts key-value pairs that will be saved to the SES project file (.emProject). To discover available configuration options:

  1. Generate the SES project using the SDK

  2. Open the project in Segger Embedded Studio

  3. Modify settings in the SES GUI interface (Project Options, Build Options, etc.)

  4. Save the project - this will update the .emProject file

  5. Examine the `.emProject` file to see the key-value pairs that were saved

This way you can identify which configuration options are available and their valid values for use with sdk_ses_options().

SDK Localization

The SDK provides a localization mechanism designed to address two specific needs:

  1. SES Project Settings Persistence: Enable users to save and transfer SES project settings that cannot be preserved in the CMake build system

  2. Project Simplification for Version Control: Allow users to create minimal, self-contained projects for efficient version management

Localization Process:

The localization process creates a self-contained project by copying only the necessary SDK files:

  1. Dependency Analysis: Analyzes your project’s build dependencies

  2. File Collection: Identifies required SOC, board, middleware, and source files

  3. Copy Operation: Copies necessary files to a local directory

  4. Path Updates: Updates project files to use local paths

Using LOCALIZE_SDK with Ninja:

# Localize the SDK using ninja
ninja -C build localize_sdk

# Unlocalize the SDK (restore original paths)
ninja -C build unlocalize_sdk

# Force localization (overwrite existing localized files)
ninja -C build localize_sdk -- -f

Localization Directory Structure:

After localization, a new directory structure is created:

your_project/
├── CMakeLists.txt                    # Original project file
├── CMakeLists.txt.localized.bak      # Backup of original file
├── src/                              # Your source files
├── hpm_sdk_localized/                # Localized SDK files
│   ├── soc/                          # Required SOC files
│   ├── boards/                       # Required board files
│   ├── middleware/                   # Required middleware files
│   └── cmake/                        # Required CMake files
└── build/                            # Build directory

Key Benefits:

  • SES Settings Persistence: Preserve SES project configurations that CMake cannot maintain

  • Minimal Version Control: Include only essential SDK files in your repository

  • Self-contained Projects: Build projects without external SDK dependencies

  • Easier Distribution: Share projects with others without SDK installation requirements

Use Cases:

  • SES Project Customization: When you need to preserve complex SES project settings

  • Version Control Optimization: Create minimal repositories with only necessary SDK components

  • Project Distribution: Share self-contained projects with team members or external users

  • Build Environment Consistency: Ensure consistent builds across different development environments

Multi-core Applications

For dual-core applications, the SDK supports linked projects through a hierarchical directory structure that reflects the multi-core architecture:

  1. Multi-core Project Organization

    Directory Structure Philosophy:

    The multi-core project structure is designed to:

    • Separate Core Responsibilities: Each core has its own directory with independent build configuration

    • Maintain Build Independence: Each core can be built independently or as part of the complete system

    • Support Different Build Types: Core0 typically runs the main application, while Core1 runs specialized tasks

    • Enable Parallel Development: Teams can work on different cores simultaneously

    Standard Directory Layout:

    multicore_app/
    ├── core0/                    # Primary core (main application)
    │   ├── CMakeLists.txt       # Core0 build configuration
    │   ├── app.yaml             # Core0 application configuration
    │   ├── src/                 # Core0 source files
    │   │   ├── main.c           # Core0 main entry point
    │   │   ├── app_init.c       # Core0 initialization
    │   │   └── sec_core_img.c   # Generated Core1 image (auto-generated)
    │   └── include/             # Core0 header files
    │       └── app_config.h
    ├── core1/                    # Secondary core (specialized tasks)
    │   ├── CMakeLists.txt       # Core1 build configuration
    │   ├── src/                 # Core1 source files
    │   │   ├── demo.c           # Core1 main entry point
    │   │   └── core1_task.c     # Core1 specific tasks
    │   └── include/             # Core1 header files
    │       └── core1_config.h
    ├── shared/                   # Shared resources (optional)
    │   ├── include/             # Shared header files
    │   │   ├── common.h         # Common definitions
    │   │   └── ipc.h            # Inter-processor communication
    │   └── src/                 # Shared source files
    │       └── ipc_common.c
    └── README.md                 # Project documentation
    

    Multi-core Application Architecture:

    From Image Perspective:

    The multi-core application works by converting Core1’s binary into a C array that is embedded within Core0’s project:

    • Core1 Binary Generation: Core1 is compiled as a standalone binary with sec_core_img build type

    • Binary to C Array Conversion: The Core1 binary is converted to a C array format using specialized tools

    • Embedding Process: The C array is written to sec_core_img.c and included in Core0’s source files

    • Single ELF Generation: Core0 is compiled with the embedded Core1 image, resulting in a single ELF file containing both cores

    From Runtime Perspective:

    At runtime, Core0 manages the Core1 execution lifecycle:

    • Image Loading: Core0 copies the Core1 image from the embedded C array to the memory location specified in the linker script

    • Entry Point Update: Core0 updates Core1’s entry point to point to the correct memory location

    • Core1 Release: Core0 releases Core1 from reset, allowing it to execute its code independently

    • Independent Execution: Both cores now run independently, with Core0 managing the system and Core1 handling specialized tasks

  2. Multi-core Program Organization

    Core Roles and Responsibilities:

    • Core0 (Primary Core):

      • Runs the main application logic

      • Handles system initialization and configuration

      • Manages the secondary core lifecycle

      • Contains the generated secondary core image

      • Typically uses flash_xip build type

    • Core1 (Secondary Core):

      • Runs specialized tasks (real-time processing, communication, etc.)

      • Operates independently after initialization

      • Communicates with Core0 through IPC mechanisms

      • Uses sec_core_img build type to generate a binary image

    Build Process Flow:

    1. Core1 Compilation: Core1 is compiled first as a standalone binary

    2. Binary to C Array: Core1 binary is converted to a C array format

    3. File Generation: The C array is written to sec_core_img.c in Core0’s source directory

    4. Core0 Compilation: Core0 is compiled with the embedded Core1 image

    5. Final Binary: Single binary containing both cores

  3. Core0 Configuration

    Core0 CMakeLists.txt:

    cmake_minimum_required(VERSION 3.13)
    
    # Set linker configuration for flash XIP (recommended for primary core)
    set(HPM_BUILD_TYPE "flash_xip")
    
    # Set custom application name (optional)
    set(APP_NAME "multicore_demo")
    
    find_package(hpm-sdk REQUIRED HINTS $ENV{HPM_SDK_BASE})
    project(multicore_core0)
    
    # Add Core0 source files
    sdk_app_src(
        src/main.c
        src/app_init.c
        src/sec_core_img.c # it will be auto-generated by build system
    )
    
    # Add header file directories
    sdk_app_inc(include)
    
    # Generate IDE projects
    generate_ide_projects()
    

    Core0 app.yaml:

    linked_project:
      project_name: multicore_app/core1
      project_path: ../core1
      build_type: sec_core_img
    
  4. Core1 Configuration (CMakeLists.txt)

    Key Configuration Elements:

    cmake_minimum_required(VERSION 3.13)
    
    # Essential for secondary core image generation
    set(HPM_BUILD_TYPE "sec_core_img")
    
    # Specify where the generated C array file will be placed
    # This file contains Core1's binary as a C array for embedding in Core0
    set(SEC_CORE_IMG_C_ARRAY_OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/../core0/src/sec_core_img.c)
    
    find_package(hpm-sdk REQUIRED HINTS $ENV{HPM_SDK_BASE})
    project(multicore_core1)
    
    # Add Core1 source files
    sdk_app_src(src/demo.c)
    
    # Generate IDE projects (optional for Core1)
    generate_ide_projects()
    

    Configuration Explanation:

    • `HPM_BUILD_TYPE=”sec_core_img”`: Tells the build system to compile Core1 as a secondary core image

    • `SEC_CORE_IMG_C_ARRAY_OUTPUT`: Specifies where the converted C array file will be placed

    • Relative Path: Uses ../core0/src/ to place the file in Core0’s source directory

    • File Naming: Conventionally named sec_core_img.c for clarity

  5. Building Multi-core Applications

    Complete Build Process:

    # Navigate to Core0 directory (main application)
    cd core0
    
    # Build both cores (Core1 image + Core0 with embedded Core1)
    cmake -B build -S . -DBOARD=hpm6750evkmini
    cmake --build build
    

    Build Output Structure:

    core0/
    ├── src/
    │   ├── main.c                   # Core0 main source
    │   └── sec_core_img.c           # Core1 binary converted to C array (generated)
    └── build/
        ├── output/
        │   ├── ${APP_NAME}.elf      # Final binary with both cores (default: demo.elf)
        │   ├── ${APP_NAME}.bin      # Binary format for flashing (default: demo.bin)
        │   ├── ${APP_NAME}.map      # Memory map file (default: demo.map)
        │   └── ${APP_NAME}.asm      # Assembly listing (default: demo.asm)
        ├── segger_embedded_studio/  # Segger IDE project files
        └── iar_embedded_workbench/  # IAR IDE project files
    

    Build Process Details:

    The sec_core_img.c file is generated through the following process:

    1. Core1 Compilation: Core1 is compiled as a standalone binary

    2. Binary Conversion: The Core1 binary is converted to a C array format

    3. File Generation: The C array is written to sec_core_img.c in Core0’s src/ directory

    4. Core0 Compilation: Core0 is compiled with the embedded Core1 image from sec_core_img.c

    Individual Core Development:

    # Build Core0 only (Core1 generates empty placeholder)
    cmake -B build -S . -DBOARD=hpm6750evkmini -DDISABLE_LINKED_PROJECT_BUILD=ON
    cmake --build build
    
    # Build Core1 standalone (for testing)
    cd ../core1
    cmake -B build -S . -DBOARD=hpm6750evkmini -DHPM_BUILD_TYPE=sec_core_img
    cmake --build build
    
  1. Linked Project Build Control

    The DISABLE_LINKED_PROJECT_BUILD option provides flexibility in multi-core development:

    Purpose:

    • Avoid Build Failures: Prevents linked project compilation failures from causing the current project build to fail

    • Development Workflow: Allows developers to focus on one core while the other core is still under development

    • Incremental Development: Enables building and testing individual cores independently

    How it Works:

    When DISABLE_LINKED_PROJECT_BUILD=ON, the build system:

    • Skips the actual compilation of the linked project

    • Extracts the output file path from the linked project’s CMakeLists.txt

    • Generates a placeholder file with C error macro at that location

    • Continues with the current project build

    Placeholder File Details:

    The generated placeholder file contains:

    • A warning comment explaining that this is an automatically generated file

    • A C preprocessor #error directive that will cause compilation to fail

    • Clear instructions on how to obtain the actual file

    This ensures that:

    • Users cannot accidentally use the placeholder file in their builds

    • Clear error messages guide users to complete the linked project build

    • The build system can continue without the actual linked project output

    Use Cases:

    • Core Development: When developing core1, you can build core0 without waiting for core1 to be complete

    • Debugging: Focus on debugging one core while the other is temporarily broken

    • CI/CD: In automated builds where linked projects might not be available

    • Testing: Test individual core functionality independently

    Example Workflow:

    # Normal build (both cores)
    cmake -B build -S . -DBOARD=hpm6750evkmini
    cmake --build build
    
    # Build core0 only (core1 generates placeholder file with error macro)
    cmake -B build -S . -DBOARD=hpm6750evkmini -DDISABLE_LINKED_PROJECT_BUILD=ON
    cmake --build build
    
    # Later, when core1 is ready, build normally
    cmake -B build -S . -DBOARD=hpm6750evkmini
    cmake --build build
    

    Example Placeholder File Content:

    When DISABLE_LINKED_PROJECT_BUILD=ON is used, the generated placeholder file will contain:

    /*
     * WARNING: This file is automatically generated by build_linked_project.py
     * This is NOT the actual SEC_CORE_IMG file!
     *
     * To get the actual SEC_CORE_IMG, you need to complete the compilation
     * of the linked project by setting build_linked=true
     */
    
    #error "SEC_CORE_IMG not available. Please compile the linked project to generate the actual SEC_CORE_IMG file."
    

Custom Board Configuration

For custom boards or development kits:

  1. Create Board Directory

    boards/
    └── my_custom_board/
       ├── my_custom_board.yaml
       └── my_custom_board.cfg
    

    Important: The directory name, YAML file name, and CFG file name must all be exactly the same (e.g., my_custom_board). Any mismatch will cause the build system to fail to locate your custom board configuration.

  2. Board YAML Configuration

    The board YAML file defines the hardware configuration and build settings:

    board:
        soc: HPM6750                    # the name of SOC used on this board
        device: HPM6750xVMx             # device name used for jlink connection
        openocd-soc: hpm6750-dual-core  # used for openocd soc config file name: hpm6750-dual-core.cfg
        openocd-probe: ft2232           # used for openocd probe config file name: ft2232.cfg
        on-board-ram:
          type: sdram
          size: 16M                     # the size of on-board ram will be used in linker script as external ram size
          width: 16bit
        on-board-flash:
          type: qspi-nor-flash
          size: 8M                      # the size of on-board flash which will be used in linker script
        # Optional: SDK dependency maintenance (not required for custom boards)
        feature:
          - board_audio_in # PDM
          - board_audio_out # DAO
          - board_gpt_pin
          - board_motor_control
          - board_gpio_led
          - board_gpio_key
          - board_pwm_rgb_led
          - board_puart_pin
        # Optional: SDK dependency maintenance (not required for custom boards)
        excluded_samples:
          - samples/motor_ctrl/bldc_hfi
          - samples/trace_recorder/rtthread-nano
    

    Note: Both feature and excluded_samples fields are used by the SDK for dependency maintenance and are not required for custom board configurations. The feature field specifies board-specific hardware features for sample application compatibility, while excluded_samples specifies which sample applications should not be built for this board due to hardware limitations or compatibility issues.

  3. Using Custom Board

    When using a custom board, you need to specify the BOARD_SEARCH_PATH to tell CMake where to find your custom board configuration:

    # Specify the path to your custom board directory
    cmake -B build -S . -DBOARD=my_custom_board -DBOARD_SEARCH_PATH=/path/to/your/boards
    

    Example:

    If your custom board is located at /home/user/my_boards/my_custom_board/, use:

    cmake -B build -S . -DBOARD=my_custom_board -DBOARD_SEARCH_PATH=/home/user/my_boards
    

Component Management

The SDK uses a component-based architecture:

Available Components:

  • Drivers: gpio, uart, spi, i2c, adc, pwm, etc.

  • Middleware: freertos, lwip, fatfs, etc.

  • Components: ppi, plb, i2c, spi, i2s_over_spi, pmbus, smbus, serial_nor, uart_lin, dma_mgr, tsw_phy, touch, sccb, segment_led, panel, log, jpeg, ipc_event_mgr, enet_phy, eeprom_emulation, debug_console, codec, camera, usb, etc.

  • Utilities: sbrk, ffssi, swap, crc32, size_utils, etc.

Adding Components:

Components are reusable software modules that provide specific functionality. They are located in the components/ directory and include:

  • Communication: i2c, spi, uart_lin, smbus, pmbus, serial_nor

  • Display & Interface: panel, segment_led, camera, codec

  • System Services: dma_mgr, ipc_event_mgr, log, debug_console

  • Specialized Hardware: tsw_phy, enet_phy, eeprom_emulation

  • Protocol Support: ppi, plb, i2s_over_spi, sccb, touch, jpeg

Utilities:

The utils/ directory contains utility functions and tools:

  • Memory Management: sbrk (dynamic memory allocation)

  • Data Processing: swap (byte order conversion), crc32 (checksum calculation)

  • File System: ffssi (flash file system)

  • Build Tools: size_utils (binary size analysis)

These utilities are automatically available when using the SDK and don’t need to be explicitly added to dependencies.

Build Optimization

Optimization Levels:

# Debug build (default)
cmake -B build -S . -DBOARD=hpm6750evkmini -DCMAKE_BUILD_TYPE=debug

# Release build
cmake -B build -S . -DBOARD=hpm6750evkmini -DCMAKE_BUILD_TYPE=release

Custom Compiler Flags:

# Using SDK CMake extensions
sdk_compile_options("-O2")
sdk_compile_definitions("NDEBUG=1")

Compiler Flags Configuration

The SDK provides CMake functions to set compiler flags in a cross-platform way:

Setting Compiler Options:

cmake_minimum_required(VERSION 3.13)

find_package(hpm-sdk REQUIRED HINTS $ENV{HPM_SDK_BASE})
project(my_application)

# Add compiler options for all toolchains
sdk_compile_options("-O2")
sdk_compile_options("-DNDEBUG")
sdk_compile_options("-Wall")

# Add conditional compiler options
sdk_compile_options_ifdef(CONFIG_DEBUG "-g")
sdk_compile_options_ifdef(CONFIG_RELEASE "-O3")

sdk_app_src(src/main.c)
generate_ide_projects()

Setting Compiler Definitions:

# Add compiler definitions for all toolchains
sdk_compile_definitions("DEBUG_MODE=1")
sdk_compile_definitions("VERSION_MAJOR=1")
sdk_compile_definitions("VERSION_MINOR=0")

# Add conditional compiler definitions
sdk_compile_definitions_ifdef(CONFIG_FEATURE_X "FEATURE_X_ENABLED=1")
sdk_compile_definitions_ifndef(CONFIG_FEATURE_Y "FEATURE_Y_DISABLED=1")

Available Functions:

  • sdk_compile_options(OPTIONS…): Add compiler options for all toolchains

  • sdk_compile_options_ifdef(CONDITION OPTIONS…): Add compiler options if condition is defined

  • sdk_compile_options_ifndef(CONDITION OPTIONS…): Add compiler options if condition is not defined

  • sdk_compile_definitions(DEFINITIONS…): Add compiler definitions for all toolchains

  • sdk_compile_definitions_ifdef(CONDITION DEFINITIONS…): Add compiler definitions if condition is defined

  • sdk_compile_definitions_ifndef(CONDITION DEFINITIONS…): Add compiler definitions if condition is not defined

Example with Conditional Compilation:

cmake_minimum_required(VERSION 3.13)

find_package(hpm-sdk REQUIRED HINTS $ENV{HPM_SDK_BASE})
project(my_application)

# Set optimization level based on build type
if(CMAKE_BUILD_TYPE STREQUAL "release")
    sdk_compile_options("-O3")
    sdk_compile_definitions("NDEBUG=1")
else()
    sdk_compile_options("-O0", "-g")
    sdk_compile_definitions("DEBUG=1")
endif()

# Add feature-specific flags
sdk_compile_definitions_ifdef(CONFIG_USB "USB_ENABLED=1")
sdk_compile_definitions_ifdef(CONFIG_NETWORK "NETWORK_ENABLED=1")

Using EXTRA Flags:

The SDK also supports additional compiler, linker, and assembler flags through CMake variables:

# Set extra C compiler flags
set(EXTRA_C_FLAGS "-fstack-protector-strong -fno-strict-aliasing")

# Set extra linker flags
set(EXTRA_LD_FLAGS "-Wl,--gc-sections -Wl,--as-needed")

# Set extra assembler flags
set(EXTRA_AS_FLAGS "-Wa,--no-warn")

# Set extra linker symbols
set(EXTRA_LD_SYMBOLS "--defsym=__heap_size__=0x8000")

Memory Configuration:

The SDK provides built-in support for configuring heap and stack sizes through CMake variables:

# In your project's CMakeLists.txt file:

# Set heap size (default: 0x4000 = 16KB)
set(HEAP_SIZE 0x8000)  # 32KB heap

# Set stack size (default: 0x4000 = 16KB)
set(STACK_SIZE 0x2000)  # 8KB stack

Default Values and How It Works:

The SDK automatically sets these variables if not specified:

  • HEAP_SIZE: Defaults to 0x4000 (16KB) - Segger default heap size

  • STACK_SIZE: Defaults to 0x4000 (16KB) - Segger default stack size

The SDK automatically converts these CMake variables into linker symbols: - HEAP_SIZE_heap_size symbol in linker script - STACK_SIZE_stack_size symbol in linker script

Size Format Support:

You can specify sizes in different formats:

# Hexadecimal (recommended)
set(HEAP_SIZE 0x8000)

# Decimal
set(HEAP_SIZE 32768)

# With K/M suffix
set(HEAP_SIZE 32K)
set(HEAP_SIZE 1M)

RISC-V Architecture Configuration:

Configure RISC-V architecture and ABI settings:

# In your project's CMakeLists.txt file:

# Set RISC-V architecture (default: rv32imac)
set(RV_ARCH "rv32imac_zicsr_zifencei")

# Set RISC-V ABI (default: ilp32)
set(RV_ABI "ilp32")

Default Values and How It Works:

The SDK automatically sets these variables if not specified:

  • RV_ARCH: Defaults to rv32imac (32-bit RISC-V with integer multiply/divide, atomic, and compressed instructions)

  • RV_ABI: Defaults to ilp32 (32-bit integer, long, and pointer)

The SDK automatically appends required extensions:

  • CSR Support: Automatically adds _zicsr if not present and needed

  • Fence.i Support: Automatically adds _zifencei if not present and needed

Common RV_ARCH Values:

# Basic 32-bit RISC-V
set(RV_ARCH "rv32imac")

# With floating point support
set(RV_ARCH "rv32imafc")

# With vector support
set(RV_ARCH "rv32imafdcv")

# Custom extensions
set(RV_ARCH "rv32imac_zicsr_zifencei_zba_zbb")

Common RV_ABI Values:

# 32-bit integer, long, and pointer (most common)
set(RV_ABI "ilp32")

# 32-bit integer, 64-bit long, 32-bit pointer
set(RV_ABI "ilp32f")

# 32-bit integer, 64-bit long, 32-bit pointer with float
set(RV_ABI "ilp32d")

Command Line Usage:

# Pass extra flags via command line
cmake -B build -S . -DBOARD=hpm6750evkmini -DEXTRA_C_FLAGS="-fstack-protector-strong" -DEXTRA_LD_FLAGS="-Wl,--gc-sections" -DEXTRA_AS_FLAGS="-Wa,--no-warn" -DEXTRA_LD_SYMBOLS="--defsym=__heap_size__=0x8000"

# Configure memory sizes via command line
cmake -B build -S . -DBOARD=hpm6750evkmini -DHEAP_SIZE=0x8000 -DSTACK_SIZE=0x2000

# Configure RISC-V architecture and ABI via command line
cmake -B build -S . -DBOARD=hpm6750evkmini -DRV_ARCH="rv32imac_zicsr_zifencei" -DRV_ABI="ilp32"

Nano Specs Configuration:

The HPM_SDK_LD_NO_NANO_SPECS variable controls whether to use the nano.specs linker specification file, which provides optimized implementations of standard library functions for embedded systems.

Default Behavior:

By default, the SDK automatically includes nano.specs for GCC toolchain builds, which provides:

  • Optimized printf/scanf: Smaller, faster implementations of printf and scanf functions

  • Reduced memory footprint: Uses less RAM and flash compared to full standard library

  • Float support: Enables floating-point support for printf and scanf operations

Disabling Nano Specs:

To disable nano.specs and use the full standard library implementations:

# In your CMakeLists.txt file:

# Disable nano.specs (use full standard library)
set(HPM_SDK_LD_NO_NANO_SPECS 1)

When to Disable Nano Specs:

  • Full printf/scanf functionality: When you need complete printf/scanf features not available in nano.specs

  • Custom library implementations: When using custom or third-party standard library implementations

  • Debugging purposes: When you need full standard library debugging capabilities

  • Specialized applications: For applications that require specific standard library behavior

Example Usage:

cmake_minimum_required(VERSION 3.13)

# Disable nano.specs for this project
set(HPM_SDK_LD_NO_NANO_SPECS 1)

find_package(hpm-sdk REQUIRED HINTS $ENV{HPM_SDK_BASE})
project(my_application)

sdk_app_src(src/main.c)
generate_ide_projects()

Command Line Usage:

# Disable nano.specs via command line
cmake -B build -S . -DBOARD=hpm6750evkmini -DHPM_SDK_LD_NO_NANO_SPECS=1

Custom Target Triplet Configuration:

The CUSTOM_TARGET_TRIPLET variable allows you to override the default target triplet used by the SDK’s cross-compilation toolchain. This is useful when you have a toolchain with a different naming convention than the SDK’s default.

Default Behavior:

By default, the SDK uses riscv32-unknown-elf as the target triplet, which means:

  • Architecture: RISC-V 32-bit

  • Vendor: unknown (generic)

  • Operating System: elf (bare metal/embedded)

Using Custom Target Triplet:

To use a different target triplet (e.g., for different toolchain installations):

# In your CMakeLists.txt file:

# Set custom target triplet
set(CUSTOM_TARGET_TRIPLET "riscv32-elf")

Common Target Triplet Formats:

# Standard RISC-V bare metal (default)
set(CUSTOM_TARGET_TRIPLET "riscv32-unknown-elf")

How It Works:

When you set CUSTOM_TARGET_TRIPLET, the SDK uses this value to construct the cross-compilation toolchain prefix instead of the default riscv32-unknown-elf:

  • Compiler: ${CUSTOM_TARGET_TRIPLET}-gcc

  • Linker: ${CUSTOM_TARGET_TRIPLET}-ld

  • Binutils: ${CUSTOM_TARGET_TRIPLET}-objcopy, ${CUSTOM_TARGET_TRIPLET}-objdump, etc.

Example Usage:

cmake_minimum_required(VERSION 3.13)

# Set custom target triplet for specific toolchain
set(CUSTOM_TARGET_TRIPLET "riscv32-elf")

find_package(hpm-sdk REQUIRED HINTS $ENV{HPM_SDK_BASE})
project(my_application)

sdk_app_src(src/main.c)
generate_ide_projects()

Command Line Usage:

# Set custom target triplet via command line
cmake -B build -S . -DBOARD=hpm6750evkmini -DCUSTOM_TARGET_TRIPLET="riscv32-hpmicro-elf"

Toolchain Compatibility:

The target triplet must match your installed toolchain. Common scenarios:

  • Standard RISC-V GCC: Use riscv32-unknown-elf

  • Vendor-specific toolchain: Use vendor-specific triplet

  • Custom toolchain: Use the prefix format of your custom toolchain

Verification:

To verify your toolchain uses the correct target triplet:

# Check if the toolchain exists
ls $GNURISCV_TOOLCHAIN_PATH/bin/

# Look for files matching your CUSTOM_TARGET_TRIPLET
# Example: if CUSTOM_TARGET_TRIPLET="riscv32-elf"
# Look for: riscv32-elf-gcc, riscv32-elf-ld, etc.

IDE Integration

The SDK supports multiple IDEs through the generate_ide_projects() function in CMakeLists.txt:

CMakeLists.txt Configuration:

cmake_minimum_required(VERSION 3.13)

find_package(hpm-sdk REQUIRED HINTS $ENV{HPM_SDK_BASE})
project(my_application)

sdk_app_src(src/main.c)

# Generate IDE projects for all supported IDEs
generate_ide_projects()

Build and Generate Projects:

# Configure and build the project
cmake -B build -S . -DBOARD=hpm6750evkmini
cmake --build build

Generated IDE Projects:

After building, the following IDE project files will be generated in the build directory:

  • Segger Embedded Studio: build/segger_embedded_studio/

  • IAR Embedded Workbench: build/iar_embedded_workbench/

Opening in IDEs:

  • Segger Embedded Studio: Open the .emProject file in the segger directory

  • IAR Embedded Workbench: Open the .ewp file in the iar directory

Best Practices

Project Organization

  1. Use Clear Directory Structure

    project/
    ├── CMakeLists.txt          # Main build configuration
    ├── app.yaml               # Application configuration
    ├── src/                   # Source files
    │   ├── main.c
    │   └── app/
    ├── include/               # Header files
    │   └── app/
    ├── config/                # Configuration files
    └── docs/                  # Documentation
    
  2. Modular Source Organization

       # CMakeLists.txt
    sdk_app_src(
       src/main.c
       src/app/gpio_handler.c
       src/app/uart_handler.c
    )
    
    sdk_app_inc(include/app)
    

Configuration Management

Environment-specific Configurations

# Development
cmake -B build -S . -DBOARD=hpm6750evkmini -DCMAKE_BUILD_TYPE=debug

# Production
cmake -B build -S . -DBOARD=hpm6750evkmini -DCMAKE_BUILD_TYPE=release

Debugging

  1. Enable Debug Information

    cmake -B build -S . -DBOARD=hpm6750evkmini -DCMAKE_BUILD_TYPE=debug
    
  2. Use IDE Debugging

    • Open generated IDE project

    • Set breakpoints

    • Start debugging session

Performance Optimization

Choose Appropriate Build Type

# For development
cmake -B build -S . -DCMAKE_BUILD_TYPE=debug

# For production
cmake -B build -S . -DCMAKE_BUILD_TYPE=release

Troubleshooting

Common Issues and Solutions

Build Fails with “Board not found”

First, check these fundamental issues:

# 1. Verify board path is correct
ls boards/ | grep your_board_name

# 2. Verify board YAML file exists and name is correct
ls boards/your_board_name/your_board_name.yaml

# 3. Check if board name matches exactly (case-sensitive)
cmake -B build -S . -DBOARD=your_board_name

There are two scenarios to consider:

Scenario 1: Using Standard SDK Boards

# Check available boards in SDK
ls boards/

# Use correct board name from SDK
cmake -B build -S . -DBOARD=hpm6750evkmini

Scenario 2: Using Custom Boards

# Ensure custom board directory structure is correct
# Directory name must match YAML and CFG file names exactly
ls /path/to/your/custom/boards/

# Specify BOARD_SEARCH_PATH to locate custom board
cmake -B build -S . -DBOARD=my_custom_board -DBOARD_SEARCH_PATH=/path/to/your/custom/boards

Missing Toolchain

# Set toolchain path
export PATH=$PATH:/path/to/toolchain/bin

# Or specify in CMake
cmake -B build -S . -DBOARD=hpm6750evkmini -DTOOLCHAIN_PATH=/path/to/toolchain

Multi-core Build Issues

By default, multi-core Core0 projects depend on successful compilation of Core1 projects using GNU GCC. However, GNU GCC on Windows cannot handle long file paths, which may cause Core1 project compilation to fail, leading to Core0 build failure.

# Check linked project configuration
# Ensure SEC_CORE_IMG_C_ARRAY_OUTPUT is set correctly
# Use DISABLE_LINKED_PROJECT_BUILD to bypass Core1 compilation on Windows
cmake -B build -S . -DBOARD=hpm6750evkmini -DDISABLE_LINKED_PROJECT_BUILD=ON

IDE Project Generation Fails

# Use supported generator
cmake -B build -S . -DBOARD=hpm6750evkmini -G "Unix Makefiles"

Debugging Build Issues

  1. Enable Verbose Output

    cmake -B build -S . -DBOARD=hpm6750evkmini --debug-output
    cmake --build build --verbose
    
  2. Check CMake Cache

    cat build/CMakeCache.txt | grep -i board
    cat build/CMakeCache.txt | grep -i toolchain
    
  3. Validate Configuration

    cmake -B build -S . -DBOARD=hpm6750evkmini -L
    

Examples

Basic GPIO Application

Project Structure:

gpio_example/
├── CMakeLists.txt
└── src/
   └── main.c

CMakeLists.txt:

cmake_minimum_required(VERSION 3.13)

find_package(hpm-sdk REQUIRED HINTS $ENV{HPM_SDK_BASE})
project(gpio_example)

sdk_app_src(src/main.c)
generate_ide_projects()

main.c:

#include "board.h"
#include "hpm_gpio_drv.h"

int main(void)
{
   /* Initialize GPIO */
   gpio_set_pin_output(HPM_GPIO0, GPIO_DI_GPIOA, 0);

   while (1) {
      /* Toggle LED */
      gpio_toggle_pin(HPM_GPIO0, GPIO_DI_GPIOA, 0);
      board_delay_ms(500);
   }
}

Build Command:

cmake -B build -S . -DBOARD=hpm6750evkmini
cmake --build build

UART Communication Example

main.c:

#include "board.h"
#include "hpm_uart_drv.h"

int main(void)
{
   uart_config_t config;
   uart_default_config(HPM_UART0, &config);
   config.baudrate = 115200;
   uart_init(HPM_UART0, &config);

   while (1) {
      uart_send_byte(HPM_UART0, 'H');
      board_delay_ms(1000);
   }
}

Multi-core Example

Core0 (app.yaml):

linked_project:
   project_name: multicore_example/core1
   project_path: ../core1
   build_type: sec_core_img

Core1 (CMakeLists.txt):

cmake_minimum_required(VERSION 3.13)
set(HPM_BUILD_TYPE "sec_core_img")
set(SEC_CORE_IMG_C_ARRAY_OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/../core0/src/sec_core_img.c)

find_package(hpm-sdk REQUIRED HINTS $ENV{HPM_SDK_BASE})
project(multicore_core1)

sdk_app_src(src/core1_main.c)

Build Command:

cd core0
cmake -B build -S . -DBOARD=hpm6750evkmini
cmake --build build

Conclusion

The HPM SDK CMake build system provides a powerful and flexible foundation for embedded application development. By following the workflows and best practices outlined in this guide, you can:

  • Accelerate Development: Use pre-configured components and board support

  • Ensure Consistency: Standardized build process across projects

  • Simplify Debugging: Integrated IDE support and debugging tools

  • Optimize Performance: Configurable build types and optimization levels

  • Support Multi-core: Seamless dual-core application development

For detailed API reference, see cmake_intro. For additional examples and advanced usage, refer to the samples directory in the SDK.