Browse Source

Upgraded cmake-tutorial to v2024.01

- Simplified tutorial on README.md
- Converted examples to their interactive counterparts
- Added version example
- Added cmake-tutorial wiki entries
pull/38/head v2024.01
Felipe Torrezan 9 months ago
parent
commit
473986b602
No known key found for this signature in database GPG Key ID: 84AA4B457EA04B17
  1. 23
      .github/workflows/issues.yml
  2. 2
      LICENSE
  3. 347
      README.md
  4. 30
      examples/430/iar-cspy-430.cmake
  5. 43
      examples/430/mix-c-asm/CMakeLists.txt
  6. 23
      examples/430/mix-c-asm/main.c
  7. 33
      examples/430/mix-c-asm/mixLanguages.mac
  8. 28
      examples/430/mix-c-asm/mynum.asm
  9. 4
      examples/430/mix-c-asm/mynum.h
  10. 18
      examples/430/using-libs/CMakeLists.txt
  11. 40
      examples/430/using-libs/app/CMakeLists.txt
  12. 29
      examples/430/using-libs/app/main.c
  13. 51
      examples/430/using-libs/app/myProgram.mac
  14. 17
      examples/430/using-libs/lib/CMakeLists.txt
  15. 5
      examples/430/using-libs/lib/add.c
  16. 5
      examples/430/using-libs/lib/mul.c
  17. 6
      examples/430/using-libs/lib/myMath.h
  18. 5
      examples/430/using-libs/lib/sub.c
  19. 30
      examples/8051/iar-cspy-8051.cmake
  20. 57
      examples/8051/mix-c-asm/CMakeLists.txt
  21. 23
      examples/8051/mix-c-asm/main.c
  22. 33
      examples/8051/mix-c-asm/mixLanguages.mac
  23. 20
      examples/8051/mix-c-asm/mynum.asm
  24. 4
      examples/8051/mix-c-asm/mynum.h
  25. 18
      examples/8051/using-libs/CMakeLists.txt
  26. 50
      examples/8051/using-libs/app/CMakeLists.txt
  27. 29
      examples/8051/using-libs/app/main.c
  28. 51
      examples/8051/using-libs/app/myProgram.mac
  29. 17
      examples/8051/using-libs/lib/CMakeLists.txt
  30. 5
      examples/8051/using-libs/lib/add.c
  31. 5
      examples/8051/using-libs/lib/mul.c
  32. 6
      examples/8051/using-libs/lib/myMath.h
  33. 5
      examples/8051/using-libs/lib/sub.c
  34. 3
      examples/README.md
  35. 17
      examples/arm/hello-world/CMakeLists.txt
  36. 10
      examples/arm/hello-world/main.c
  37. 48
      examples/arm/iar-cspy-arm.cmake
  38. 16
      examples/arm/iar-functions.cmake
  39. 39
      examples/arm/mix-c-asm/CMakeLists.txt
  40. 23
      examples/arm/mix-c-asm/main.c
  41. 33
      examples/arm/mix-c-asm/mixLanguages.mac
  42. 18
      examples/arm/mix-c-asm/mynum.asm
  43. 4
      examples/arm/mix-c-asm/mynum.h
  44. 18
      examples/arm/using-libs/CMakeLists.txt
  45. 42
      examples/arm/using-libs/app/CMakeLists.txt
  46. 29
      examples/arm/using-libs/app/main.c
  47. 51
      examples/arm/using-libs/app/myProgram.mac
  48. 16
      examples/arm/using-libs/lib/CMakeLists.txt
  49. 5
      examples/arm/using-libs/lib/add.c
  50. 5
      examples/arm/using-libs/lib/mul.c
  51. 6
      examples/arm/using-libs/lib/myMath.h
  52. 5
      examples/arm/using-libs/lib/sub.c
  53. 25
      examples/avr/iar-cspy-avr.cmake
  54. 40
      examples/avr/mix-c-asm/CMakeLists.txt
  55. 23
      examples/avr/mix-c-asm/main.c
  56. 33
      examples/avr/mix-c-asm/mixLanguages.mac
  57. 15
      examples/avr/mix-c-asm/mynum.asm
  58. 4
      examples/avr/mix-c-asm/mynum.h
  59. 18
      examples/avr/using-libs/CMakeLists.txt
  60. 31
      examples/avr/using-libs/app/CMakeLists.txt
  61. 29
      examples/avr/using-libs/app/main.c
  62. 51
      examples/avr/using-libs/app/myProgram.mac
  63. 17
      examples/avr/using-libs/lib/CMakeLists.txt
  64. 5
      examples/avr/using-libs/lib/add.c
  65. 5
      examples/avr/using-libs/lib/mul.c
  66. 6
      examples/avr/using-libs/lib/myMath.h
  67. 5
      examples/avr/using-libs/lib/sub.c
  68. 51
      examples/iar-toolchain.cmake
  69. 32
      examples/libs/CMakeLists.txt
  70. 8
      examples/libs/lib/CMakeLists.txt
  71. 8
      examples/libs/lib/inc/crc32.h
  72. 33
      examples/libs/lib/src/crc32.c
  73. 10
      examples/libs/main.c
  74. 28
      examples/mix/CMakeLists.txt
  75. 4
      examples/mix/fun.h
  76. 43
      examples/mix/fun.s
  77. 7
      examples/mix/main.c
  78. 28
      examples/rh850/iar-cspy-rh850.cmake
  79. 16
      examples/rh850/iar-functions.cmake
  80. 43
      examples/rh850/mix-c-asm/CMakeLists.txt
  81. 23
      examples/rh850/mix-c-asm/main.c
  82. 33
      examples/rh850/mix-c-asm/mixLanguages.mac
  83. 19
      examples/rh850/mix-c-asm/mynum.asm
  84. 4
      examples/rh850/mix-c-asm/mynum.h
  85. 18
      examples/rh850/using-libs/CMakeLists.txt
  86. 42
      examples/rh850/using-libs/app/CMakeLists.txt
  87. 29
      examples/rh850/using-libs/app/main.c
  88. 51
      examples/rh850/using-libs/app/myProgram.mac
  89. 16
      examples/rh850/using-libs/lib/CMakeLists.txt
  90. 5
      examples/rh850/using-libs/lib/add.c
  91. 5
      examples/rh850/using-libs/lib/mul.c
  92. 6
      examples/rh850/using-libs/lib/myMath.h
  93. 5
      examples/rh850/using-libs/lib/sub.c
  94. 25
      examples/riscv/iar-cspy-riscv.cmake
  95. 16
      examples/riscv/iar-functions.cmake
  96. 41
      examples/riscv/mix-c-asm/CMakeLists.txt
  97. 23
      examples/riscv/mix-c-asm/main.c
  98. 33
      examples/riscv/mix-c-asm/mixLanguages.mac
  99. 16
      examples/riscv/mix-c-asm/mynum.asm
  100. 4
      examples/riscv/mix-c-asm/mynum.h

23
.github/workflows/issues.yml

@ -1,23 +0,0 @@
name: Close inactive issues
on:
schedule:
- cron: "30 17 * * *"
jobs:
close-issues:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v3
with:
days-before-issue-stale: 30
days-before-issue-close: 14
stale-issue-label: "stale"
stale-issue-message: "This issue is stale because it has been open for 30 days with no activity. If there is no further activity, the ticket will be automatically closed in 14 days."
close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale."
days-before-pr-stale: -1
days-before-pr-close: -1
repo-token: ${{ secrets.GITHUB_TOKEN }}

2
LICENSE

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2020-2021 IAR Systems AB
Copyright (c) 2020-2024 IAR Systems AB
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

347
README.md

@ -1,234 +1,167 @@
# Tutorial <br>Building and testing with the IAR tools in CMake
# Building CMake projects with IAR
[CMake][url-cm-home] is an open-source, cross-platform family of tools maintained and supported by [Kitware][url-cm-kitware]. CMake is used to control the software compilation process - using simple configuration files - to generate native build scripts for a selected build system, like ninja, make, etc. For detailed documentation, visit the [CMake Documentation Page][url-cm-docs].
This tutorial serves as a very basic-level guide to using CMake together with the __IAR C/C++ compilers__ to cross-compile embedded software applications for the supported target architectures.
CMake is an open-source, cross-platform family of tools maintained and supported by Kitware. Among its many features, it essentially provides [Makefile Generators](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id11) and [Ninja Generators](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#id12) which compose scripts for cross-compiling C/C++ embedded software projects based on one or more `CMakeLists.txt` configuration files.
This tutorial offers a short introduction for those seeking information on how to start using the IAR C/C++ Compiler together with CMake from the command line. While this guide is based on the IAR Build Tools for Arm version 9.50.1 on Linux, it should work with other supported IAR products with no or minimal changes.
## Prerequisites
This tutorial assumes that:
Before you begin, you will need to download and install the IAR product, CMake and then clone this repository.
1) Download, install and activate[^1] your IAR product
* You are familiar with using the IAR and Kitware tools on the command line.
| __Product__ | __Evaluation__ | __IAR Customers (login required)__ |
| - | - | - |
| IAR Build Tools | [Contact us](https://iar.com/about/contact) | [for Arm](https://updates.iar.com/?product=BXARM) (or for others[^2]) |
| IAR Embedded Workbench | [Download](https://iar.com/downloads) | [for Arm](https://updates.iar.com/?product=EWARM) (or for others[^2]) |
2) Download and install [CMake](https://github.com/Kitware/CMake/releases/latest).
* This repository is cloned to the development computer (it can also be downloaded as a zip archive by clicking the __Code__ button).
3) Clone this repository to your computer. For more information, see ["Cloning a repository"](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository).
* The required tools are already installed on the system, according to the table below:
## Building a Basic CMake Project
The most basic CMake project is an executable built from a single source code file. For simple projects like this, a `CMakeLists.txt` file with about half dozen of commands is all that is required.
| __Tool__ | __Windows-based systems__ | __Linux-based systems__ |
|-----------------------------------------|---------------------------------------------------------------------------------------------------|--------------------------------------------------------------------|
| IAR C/C++ Compiler for... | `Arm`, `RISC-V`, `RL78`, `RX`, `RH850`,<br>`8051`, `AVR`, `MSP430`, `STM8` or `V850` | `Arm`, `AVR`, `RISC-V`, `RL78`, `RX` or `RH850` |
| [CMake 3.23+](https://cmake.org) | Download and install the [latest][url-cmake-dl] for `-windows-x86_x64.msi` | Use the [Kitware APT repository](https://apt.kitware.com/) or,<br> if suitable, the distribution-provided package |
| [Ninja 1.10+](https://ninja-build.org) | Download the latest [ninja-win.zip][url-ninja-dl] and extract "ninja.exe" to a directory belonging to the `PATH` environment variable (like `C:\Windows\`) | Usually, the distribution-provided package should be enough |
Any project's topmost `CMakeLists.txt` must start by specifying a minimum CMake version using the [`cmake_minimum_required()`][url-help-cmake_minimum_required] command. This establishes policy settings and ensures that CMake functions used in the project are run with a compatible version of CMake.
>:warning: Before being able to start using CMake, make sure the compiler license is activated. Refer to your product's documentation for details.
To start a project, use the [`project()`][url-help-project] command to set the project name. This call is required with every project and should be called soon after [`cmake_minimum_required()`][url-help-cmake_minimum_required]. This command can also be used to specify other project level information such as the language(s) used or its version number.
>:penguin: Recent **Linux distributions** offer relatively up-to-date packages for `cmake` and `ninja`. Once installed, these executables are normally found on the default search path, so that both can be executed directly from anywhere in the system. You can follow the official [Kitware's APT repository](https://apt.kitware.com/) instructions so you can use it with your package manager to stay always up-to-date.
>
>:thought_balloon: On **Windows-based systems**, the `cmake-<version>-windows-x86_x64.msi` installer wizard will offer you the choice of _adding the CMake directory to the system PATH for all users_ so that CMake can be executed from anywhere in your system. For the `ninja.exe` executable from the [`ninja-win.zip`](https://github.com/ninja-build/ninja/releases/latest) binary distribution archive, you can extract it to the CMake's `bin` directory inside its installation directory, or any other potential directory belonging to the `PATH` environment variable (like `C:\Windows\`). The same recommendation applies for when using CMake with alternative generators. For example, when using `cmake -G "Unix Makefiles"`, instead of `ninja.exe` you will need to use `make.exe` to build. In such a scenario, if the `make.exe` program cannot be found, CMake will fail immediately when you try to run the toolchain configuration step, returning with a fatal error message (for example, "`CMAKE_MAKE_PROGRAM not found`").
Use the [`add_executable()`][url-help-add_executable] command to tell CMake to create an executable using the specified source code files.
Then use [`target_sources()`][url-help-target_sources] to list the source files required to build the target.
## Building Projects
To use CMake to build a project developed with an IAR compiler, you need at least:
* A toolchain file
* A `CMakeLists.txt` file
* The application source code
Use [`target_compile_options()`][url-help-target_compile_options] for setting up the compiler options to build the target.
### Configuring the toolchain file
By default, CMake uses what it assumes to be the host platform's default compiler. When the application targets an embedded platform (known as cross-compiling), a toolchain file `<toolchain-file>.cmake` can be used to specify the intended toolchain's location to its compiler and assembler. This section provides a simple generic template for the __IAR C/C++ compilers__.
And finally, set your target's linker options with [`target_link_options()`][url-help-target_link_options]:
In the [`examples/iar-toolchain.cmake`](examples/iar-toolchain.cmake) file:
* Set the `TOOLKIT` variable to the compiler's target architecture.
```cmake
# Action: Set the TOOLKIT variable
# Examples: arm, riscv, rh850, rl78, rx, stm8, 430, 8051, avr or v850
# Alternative: override the default TOOLKIT (/path/to/installation/<arch>)
set(TOOLKIT arm)
# set the minimum required version of CMake to be 3.20
cmake_minimum_required(VERSION 3.20)
# set the project name
project(Tutorial)
# add the executable target
add_executable(tutorial)
# target sources
target_sources(tutorial PRIVATE tutorial.c)
# compiler options
target_compile_options(tutorial PRIVATE --cpu=cortex-m4)
# linker options
target_link_options(tutorial PRIVATE --semihosting)
```
>:bulb: The default toolchain file will search for an available compiler on the default installation paths. You can also use the `TOOLKIT` variable to set a specific installation directory (for example, `C:/IAR/EWARM/N.nn`).
### A minimal project
A CMake project is defined by one or more `CMakeLists.txt` file(s). This is how a simple `hello-world` project can be configured for the Arm target architecture:
* Change the directory to the `hello-world` project:
### Enabling the IAR Compiler
CMake uses the host platform's default compiler. When cross-compiling embedded applications, the compiler must be set manually via [`CMAKE_<lang>_COMPILER`](https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER.html) variables for each supported language. Additionally, it is possible to specify a build tool via [`CMAKE_MAKE_PROGRAM`]():
| Variable | Description | Examples |
| - | - | - |
| `CMAKE_C_COMPILER` | Must point to the C Compiler executable | `"C:/Program Files/..../arm/bin/iccarm.exe"`<br>`"/opt/iarsystems/bxarm/arm/bin/iccarm"` |
| `CMAKE_CXX_COMPILER` | Must point to the C++ Compiler executable | `"C:/Program Files/..../arm/bin/iccarm.exe"`<br>`"/opt/iarsystems/bxarm/arm/bin/iccarm"` |
| `CMAKE_ASM_COMPILER` | Must point to the Assembler executable | `"C:/Program Files/..../arm/bin/iasmarm.exe"`<br>`"/opt/iarsystems/bxarm/arm/bin/iasmarm"` |
| `CMAKE_MAKE_PROGRAM` | Must point to the build tool executable | `"C:/Program Files/..../common/bin/ninja.exe"`<br>`"/opt/iarsystems/bxarm/common/bin/ninja"` |
CMake reads these variables from
- a separate file called "toolchain file" (for example by invoking `cmake` with [`--toolchain /path/to/bxarm.cmake`](tutorial/bxarm.cmake)) -or-
- invoking `cmake` with `-DCMAKE_<lang>_COMPILER=...` on the command line, during the configuration phase -or-
- the user/system environment variables [`CC`](https://cmake.org/cmake/help/latest/envvar/CC.html), [`CXX`](https://cmake.org/cmake/help/latest/envvar/CXX.html) and [`ASM`](https://cmake.org/cmake/help/latest/envvar/ASM.html) which can be used to override the platform's default compiler.
- the IAR Embedded Workbench IDE 9.3 or later, shipped with IAR products starting from the IAR Embedded Workbench for Arm 9.50, where the available IAR toolchain environment is automatically set for CMake projects.
### Configure and Build
We are ready to build our first project! Run CMake to configure the project and then build it with your chosen build tool.
- Before starting to use CMake, make sure your compiler is working and does not run into any [license issues](#issues). Example (for Arm):
```
cd /path/to/cmake-tutorial/examples/arm/hello-world
/path/to/iccarm --version
```
* Verify the contents of the `CMakeLists.txt` file:
- From the terminal, navigate to the [tutorial](tutorial) directory and create a build directory:
```
mkdir build
```
https://github.com/IARSystems/cmake-tutorial/blob/985f597765bd1186867b4157af3d1afde6531943/examples/arm/hello-world/CMakeLists.txt#L1-L16
- Next, navigate to that build directory and run CMake to configure the project and generate a native build system using the compiler specified in the `bxarm.cmake` toolchain file (if needed, edit the supplied toolchain file to match your tool):
```
cd build
cmake .. -G Ninja --toolchain ../bxarm.cmake
```
> :bulb: Adjust the target compiling/linking options for architectures other than __arm__.
* Verify the contents of the `main.c` source file:
https://github.com/IARSystems/cmake-tutorial/blob/985f597765bd1186867b4157af3d1afde6531943/examples/arm/hello-world/main.c#L1-L9
### Configuring the build system generator
Once you have created the minimal project with a suitable toolchain file, invoke CMake to configure the build environment for cross-compiling, choosing the _build system generator_ and _toolchain file_ to use for the project.
In this example, take advantage of the `"Ninja Multi-Config"` generator option. This option can be used to generate build configurations for "Debug" and "Release" purposes. The general recommendation when using CMake is to perform an "out-of-source" build, which means creating a subdirectory for the output files.
* Use the following command to generate the scripts for the build system inside the `_builds` subdirectory:
```
cmake -B_builds -G "Ninja Multi-Config" --toolchain /path/to/iar-toolchain.cmake
```
>:bulb: The `cmake --help` command provides more information.
<details><summary><b>Expected output example</b> (click to expand):</summary>
>```
>-- The C compiler identification is IAR ARM N.nn
>-- Detecting C compiler ABI info
>-- Detecting C compiler ABI info - done
>-- Check for working C compiler: /path/to/toolkit_dir/bin/iccarm.exe - skipped
>-- Detecting C compile features
>-- Detecting C compile features - done
>-- Configuring done
>-- Generating done
>-- Build files have been written to: /path/to/cmake-tutorial/examples/arm/hello-world/_builds
>```
</details>
>:warning: If by mistake the configuration step fails (for example, because of using the wrong option, the wrong selection, etc.), you might have to remove the `_builds` subdirectory before you try again. This helps CMake to avoid potential cache misses interference during the new attempt.
### Building the project
* Once the `_builds` tree is configured, use CMake with the `--build` flag to build the project:
```
cmake --build _builds
```
>:bulb: The `cmake --help` command provides more information.
<details><summary><b>Expected output example</b> (click to unfold):</summary>
>```
>[2/2] Linking C executable Debug\hello-world.elf
>```
</details>
In the minimal example, we had an initial overview of what you need to bootstrap a CMake project for a simple executable file. Targets created from actual embedded software projects will typically require preprocessor symbols, compiler options, linker options and extended options. Additional project examples for the target architectures supported by CMake are provided as reference in the "[Examples](#examples)" section of this tutorial.
## Examples
Now that you know how to use CMake to _configure_ and _build_ embedded projects developed with the IAR tools, you can start to explore how projects can be configured in greater detail.
In this section you will find descriptions for the provided [examples](examples). Each __architecture__ (__`<arch>`__) subdirectory contains multiple examples.
Optionally, each example's `CMakeLists.txt` file for target architectures contains the line `include(/path/to/iar-cspy-<arch>.cmake)` at the end, as an example that illustrates how to use CTest to invoke the __IAR C-SPY command line utility__ ([`cspybat.exe`][url-iar-docs-cspybat]) to perform automated tests using [macros][url-iar-docs-macros].
### Example 1 - Mixing C and assembler source code
The `examples/<arch>/mix-c-asm` example project demonstrates the basic concepts of building a single executable file (`mixLanguages`) using __C__ and __assembler__ source code.
It also shows how to use `target_compile_definitions()` to set preprocessor symbols that can be used in the target source code.
### Example 2 - Creating and using libraries
The `examples/<arch>/using-libs` example project demonstrates some advanced features and building one executable file (`myProgram`) linked with a static library file (`myMath`) using __C__ source code.
The top-level directory contains a `CMakeLists.txt` file that will add the `lib` and the `app` subdirectories, each one containing its own `CMakeLists.txt`.
The `myMath` library file is located in the `lib` subdirectory. The library contains functions that take two integer parameters to perform basic arithmetic on, returning another integer as the result.
The `myProgram` executable file is located in the `app` subdirectory. The application performs arithmetic operations using the functions in the `myMath` library.
It also shows:
* How to use `set_target_properties()` to propagate configuration details across the target options.
* How to set `target_link_options()` to create a map file of the executable file.
* How to use `add_custom_command()` for generating `.bin`/`.hex`/`.srec` output using the `ielftool` utility.
### Testing the examples
CTest is an extension of CMake that can help you perform automated tests. With CTest, you can execute the target application directly on your host PC, evaluating its exit code.
When cross-compiling, it is not possible to execute the target application directly on your host PC. However, you can execute the target application using the __IAR C-SPY Debugger__ and, for example, a custom function that wraps the required parameters (for example, `iar_cspy_add_test()`). A module named `iar-cspy-<arch>.cmake` is included in the `CMakeLists.txt` files for target architectures and illustrates the concept.
>:warning: This section requires the __IAR C-SPY command line utility__ (`cspybat.exe`), which is installed with __IAR Embedded Workbench__.
* Test the desired project example (*built with debug information*) by executing:
```
ctest --test-dir _builds --build-config Debug --output-on-failure --timeout 10
```
>:bulb: The `ctest --help` command provides more information.
<details><summary>Expected output - <b>Example 1</b> (click to unfold):</summary>
>```
>Internal ctest changing into directory: C:/path/to/cmake-tutorial/examples/<arch>/mix-c-asm/_builds
>Test project C:/path/to/cmake-tutorial/examples/<arch>/mix-c-asm/_builds
> Start 1: test_mynum
>1/1 Test #1: test_mynum ....................... Passed 0.20 sec
>
>100% tests passed, 0 tests failed out of 1
>
>Total Test time (real) = 0.25 sec
>```
</details>
<details><summary>Expected output - <b>Example 2</b> (click to unfold):</summary>
>```
>Internal ctest changing into directory: C:/path/to/cmake-tutorial/examples/<arch>/using-libs/_builds
>Test project C:/path/to/cmake-tutorial/examples/<arch>/using-libs/_builds
> Start 1: test_add
>1/3 Test #1: test_add ......................... Passed 0.44 sec
> Start 2: test_sub
>2/3 Test #2: test_sub .........................***Failed Required regular expression not found. Regex=[PASS] 0.44 sec
>-- app debug output begin --
>40 + 2 = 42
>-- C-SPY TEST:test_sub. Expected: 38 Result: FAIL
>40 - 2 = 39
>40 * 2 = 80
>-- app debug output end --
>
> Start 3: test_mul
>3/3 Test #3: test_mul ......................... Passed 0.44 sec
>
>67% tests passed, 1 tests failed out of 3
>
>Total Test time (real) = 1.34 sec
>
>The following tests FAILED:
> 2 - test_sub (Failed)
>Errors while running CTest
>```
</details>
## Debugging
When target applications are built with _debug information_, they can be debugged with the __IAR C-SPY Debugger__, directly in the __IAR Embedded Workbench__ IDE.
The [Debugging an Externally Built Executable file][url-iar-docs-ext-elf] Technical Note has instructions for setting up a __debug-only__ project.
## Issues
Did you find an issue or do you have a question related to the __cmake-tutorial__ tutorial?
- Visit the [cmake-tutorial wiki](https://github.com/IARSystems/cmake-tutorial/wiki).
- Check the public issue tracker for [earlier issues][url-repo-issue-old].
- If you are reporting a [new][url-repo-issue-new] issue, please describe it in detail.
- Then call CMake for building the executable using the build system:
```
cmake --build .
```
## Run
Let's test the application. To run the executable you will need the non-interactive[^3] command line interface for the IAR C-SPY Debugger (`cspybat`) with the proper drivers for the desired target. Amongst the many ways of accomplishing this, let's take advantage of the `add_test()` for testing the application in a Arm Cortex-M4 simulated target.
In this example we will use Arm. To do so, we need to change the Tutorial's `CMakeLists.txt`:
- Firstly add [`enable_testing()`](https://cmake.org/cmake/help/latest/command/enable_testing.html#command:enable_testing) to enable testing:
```cmake
enable_testing()
```
- Then use [`add_test()`](https://cmake.org/cmake/help/latest/command/add_test.html#add-test) to encapsulate the command line `cspybat` needs. In the example below, the parameters are adjusted for simulating a generic Arm Cortex-M4 target environment:
```cmake
add_test(NAME tutorialTest
COMMAND /opt/iarsystems/bxarm/common/bin/CSpyBat
# C-SPY drivers for the Arm simulator via command line interface
/opt/iarsystems/bxarm/arm/bin/libarmPROC.so
/opt/iarsystems/bxarm/arm/bin/libarmSIM2.so
--plugin=/opt/iarsystems/bxarm/arm/bin/libarmLibsupportUniversal.so
# The target executable (built with debug information)
--debug_file=$<TARGET_FILE:tutorial>
# C-SPY driver options
--backend
--cpu=cortex-m4
--semihosting)
```
- Now use the [`PASS_REGULAR_EXPRESSION`](https://cmake.org/cmake/help/latest/prop_test/PASS_REGULAR_EXPRESSION.html#prop_test:PASS_REGULAR_EXPRESSION) test property to validate if the program emits the expected string to the standard output (`stdout`). In this case, verifying that the usage message is printed when an incorrect number of arguments is provided.
```cmake
set_tests_properties(tutorialTest PROPERTIES PASS_REGULAR_EXPRESSION "Hello world!")
```
- Since `CMakeLists.txt` was modified, the build system needs to be reconfigured:
```
cmake --build .
```
- And finally we call CMake's [`ctest`](https://cmake.org/cmake/help/latest/manual/ctest.1.html#manual:ctest(1)) which subsequently will execute `Tutorial.elf` using the IAR C-SPY Debugger for Arm:
```
ctest
```
## Conclusion
This tutorial provides information on how to start building embedded software projects and, also, on how to perform automated tests when using the IAR tools with CMake. When you have understood the core ideas presented here, a world of possibilities opens up. Such a setup might be useful depending on your organization's needs, and can be used as a starting point for particular customizations.
And this is what you need to know to start using CMake with the IAR tools from the command line. Proceed to the [wiki](https://github.com/IARSystems/cmake-tutorial/wiki) for more information.
## Issues
Use the [CMake Issue Tracker](https://gitlab.kitware.com/cmake/cmake/-/issues/) to report CMake-related software defects.
For questions/suggestions specifically related to this tutorial:
- Try the [wiki][url-repo-wiki].
- Check for [earlier issues][url-repo-issue-old] in the issue tracker.
- If nothing helps, create a [new issue][url-repo-issue-new], describing in detail.
Do not use the issue tracker if you need technical support. The issue tracker **is not a support forum**:
- If you run into license issues, refer to [IAR Customer Care](https://iar.com/knowledge/support/licensing-faq/).
- If you run into tools issues, contact [IAR Tech Support](https://iar.com/knowledge/support/request-technical-support/).
[^1]: For more information, see the "Installation and Licensing" guide for your product. If you do not have a license, [contact us](https://iar.com/about/contact).
[^2]: CMake has built-in IAR C/C++ Compiler support for the following non-Arm architectures: 8051, AVR, MSP430, RH850, RISC-V, RL78, RX, STM8 and V850.
[^3]: For interactively debugging of executable files (`*.elf`) using the C-SPY Debugger from the IAR Embedded Workbench IDE, read [this technical note][url-iar-docs-ext-elf].
<!-- links -->
[url-repo-home]: https://github.com/IARSystems/cmake-tutorial
[url-repo-issue-new]: https://github.com/IARSystems/cmake-tutorial/issues/new
[url-repo-issue-old]: https://github.com/IARSystems/cmake-tutorial/issues?q=is%3Aissue+is%3Aopen%7Cclosed
[url-iar-docs-macros]: https://wwwfiles.iar.com/arm/webic/doc/EWARM_DebuggingGuide.ENU.pdf#page=417
[url-iar-docs-cspybat]: https://wwwfiles.iar.com/arm/webic/doc/EWARM_DebuggingGuide.ENU.pdf#page=503
[url-repo-wiki]: https://github.com/IARSystems/cmake-tutorial/wiki
[url-repo-issue-new]: https://github.com/IARSystems/cmake-tutorial/issues/new
[url-repo-issue-old]: https://github.com/IARSystems/cmake-tutorial/issues?q=is%3Aissue+is%3Aopen%7Cclosed
[url-help-cmake_minimum_required]: https://cmake.org/cmake/help/latest/command/cmake_minimum_required.html#command:cmake_minimum_required
[url-help-project]: https://cmake.org/cmake/help/latest/command/project.html#command:project
[url-help-add_executable]: https://cmake.org/cmake/help/latest/command/add_executable.html#command:add_executable
[url-help-target_sources]: https://cmake.org/cmake/help/latest/command/target_sources.html#target-sources
[url-help-target_compile_options]: https://cmake.org/cmake/help/latest/command/target_compile_options.html#target-compile-options
[url-help-target_link_options]: https://cmake.org/cmake/help/latest/command/target_link_options.html#target-link-options
[url-iar-docs-ext-elf]: https://www.iar.com/knowledge/support/technical-notes/debugger/debugging-an-externally-built-executable-file/
[url-cmake-dl]: https://github.com/kitware/cmake/releases/latest
[url-ninja-dl]: https://github.com/ninja-build/ninja/releases/latest
[url-gh-docs-notify]: https://docs.github.com/en/github/managing-subscriptions-and-notifications-on-github/setting-up-notifications/about-notifications
[url-cm-home]: https://cmake.org
[url-cm-docs]: https://cmake.org/documentation
[url-cm-docs-genex]: https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html
[url-cm-docs-ctest]: https://cmake.org/cmake/help/latest/manual/ctest.1.html
[url-cm-wiki]: https://gitlab.kitware.com/cmake/community/-/wikis/home
[url-cm-kitware]: https://kitware.com

30
examples/430/iar-cspy-430.cmake

@ -1,30 +0,0 @@
# Example for creating a test for CTest
# to execute the `IAR C-SPY Command-line Utility (cspybat.exe)`
function(iar_cspy_add_test TARGET TEST_NAME EXPECTED_OUTPUT)
# Add a test for CTest
add_test(NAME ${TEST_NAME}
COMMAND ${TOOLKIT_DIR}/../common/bin/cspybat --silent
# C-SPY drivers
"${TOOLKIT_DIR}/bin/${CMAKE_SYSTEM_PROCESSOR}proc.dll"
"${TOOLKIT_DIR}/bin/${CMAKE_SYSTEM_PROCESSOR}sim.dll"
"--plugin=${TOOLKIT_DIR}/bin/${CMAKE_SYSTEM_PROCESSOR}bat.dll"
--debug_file=$<TARGET_FILE:${TARGET}>
# C-SPY macros settings
"--macro=${CMAKE_CURRENT_SOURCE_DIR}/${TARGET}.mac"
"--macro_param=testName=\"${TEST_NAME}\""
"--macro_param=testExpected=${EXPECTED_OUTPUT}"
# C-SPY backend setup
--backend
-p $<IF:$<BOOL:$<TARGET_PROPERTY:${TARGET},DDF>>,$<TARGET_PROPERTY:${TARGET},DDF>,${TOOLKIT_DIR}/config/debugger/msp430f149.ddf>
--hwmul_base=0x130
--hardware_multiplier=16
--hwmult_type=1
--iv_base=0xFFE0
--odd_word_check
--derivativeSim=MSP430F149
-d sim )
# Set the test to interpret a C-SPY's message containing `PASS`
set_tests_properties(${TEST_NAME} PROPERTIES PASS_REGULAR_EXPRESSION "PASS")
endfunction()

43
examples/430/mix-c-asm/CMakeLists.txt

@ -1,43 +0,0 @@
cmake_minimum_required(VERSION 3.22)
# Set the project name, [description] and [version],
# while enabling its required languages
project(Example1
DESCRIPTION "Mixing C and Assembly"
VERSION 1.0.0
LANGUAGES C ASM )
# Fallback option for generators other than `Ninja Multi-Config`
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug)
endif()
# Enable CTest
enable_testing()
# Add the executable for the "mixLanguages" target
add_executable(mixLanguages
# Source files
main.c
mynum.asm )
# Set a preprocessor symbol, usable from "mixLanguages" target
target_compile_definitions(mixLanguages PUBLIC USE_ASM=1)
# Set the compiler flags for the "mixLanguages" target
target_compile_options(mixLanguages PRIVATE
$<$<COMPILE_LANGUAGE:C>:--multiplier=16 --dlib_config ${TOOLKIT_DIR}/lib/dlib/dl430fn.h>
-D__MSP430F149__ )
# Set the linker options for the "mixLanguages" target
target_link_options(mixLanguages PRIVATE
-f ${TOOLKIT_DIR}/config/linker/lnk430f149.xcl
${TOOLKIT_DIR}/lib/dlib/dl430fn.r43
# The `SHELL:` prefix prevents option de-duplication
"SHELL:-D_DATA16_HEAP_SIZE=50"
"SHELL:-D_STACK_SIZE=50"
"SHELL:-D_DATA20_HEAP_SIZE=50" )
# Optional: test the project with C-SPY
include(../iar-cspy-430.cmake)
iar_cspy_add_test(mixLanguages test_mynum 42)

23
examples/430/mix-c-asm/main.c

@ -1,23 +0,0 @@
#include <stdio.h>
#include "mynum.h"
int answer;
int main(void)
{
#if USE_ASM
answer = mynum();
#else
answer = 10;
#endif
/* NDEBUG is set automatically for when
bulding with -DCMAKE_BUILD_TYPE=Release */
#ifndef NDEBUG
printf("-- app debug output begin --\n");
printf("mixLanguages v%d.%d.%d\n", 1, 0, 0);
printf("The answer is: %d.\n",answer);
printf("-- app debug output end --\n");
#endif
return 0;
}

33
examples/430/mix-c-asm/mixLanguages.mac

@ -1,33 +0,0 @@
__param testName;
__param testExpected;
__var _breakID;
__var _result;
execUserSetup()
{
__message "C-SPY TEST: started...";
__message "C-SPY TEST: When the `answer` variable is read, `checkanswer()` will execute.";
_breakID = __setSimBreak("answer", "R", "checkAnswer()");
}
Done()
{
__message "-- C-SPY TEST: Done()";
if (_result == testExpected)
{
__message "-- C-SPY TEST:", testName, ". Result: PASS";
} else {
__message "-- C-SPY TEST:", testName, ". Expected: ", testExpected, " Result: FAIL";
}
}
checkAnswer()
{
__message "-- C-SPY TEST: checkAnswer()";
if (testName == "test_mynum")
{
_result = answer;
Done();
}
}

28
examples/430/mix-c-asm/mynum.asm

@ -1,28 +0,0 @@
RSEG CSTACK:DATA:SORT:NOROOT(0)
EXTERN ?longjmp_r4
EXTERN ?longjmp_r5
EXTERN ?setjmp_r4
EXTERN ?setjmp_r5
PUBWEAK ?setjmp_save_r4
PUBWEAK ?setjmp_save_r5
PUBLIC mynum
RSEG `CODE`:CODE:REORDER:NOROOT(1)
mynum:
MOV.W #0x2A, R12
RET
RSEG `CODE`:CODE:REORDER:NOROOT(1)
?setjmp_save_r4:
REQUIRE ?setjmp_r4
REQUIRE ?longjmp_r4
RSEG `CODE`:CODE:REORDER:NOROOT(1)
?setjmp_save_r5:
REQUIRE ?setjmp_r5
REQUIRE ?longjmp_r5
END

4
examples/430/mix-c-asm/mynum.h

@ -1,4 +0,0 @@
#ifndef MYNUM_H
#define MYNUM_H
extern int mynum();
#endif

18
examples/430/using-libs/CMakeLists.txt

@ -1,18 +0,0 @@
cmake_minimum_required (VERSION 3.22)
project (Example2
DESCRIPTION "Creating and using libraries"
VERSION 1.0.0
LANGUAGES C )
# Fallback option for generators other than `Ninja Multi-Config`
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug)
endif()
# Enable CTest
enable_testing()
# Recurse into the "lib" and "app" subdirectiories
add_subdirectory(lib)
add_subdirectory(app)

40
examples/430/using-libs/app/CMakeLists.txt

@ -1,40 +0,0 @@
# Add the executable for the "myProgram" target,
# specifying its source files
add_executable (myProgram
# Source files
main.c )
# Set the properties for the "myProgram" target
set_target_properties(myProgram PROPERTIES
XCL "${TOOLKIT_DIR}/config/linker/lnk430f149.xcl"
# C-SPY-related properties
DDF "${TOOLKIT_DIR}/config/debugger/msp430f149.ddf" )
# Set the compiler flags for the target
target_compile_options(myProgram PRIVATE
$<$<COMPILE_LANGUAGE:C>:--multiplier=16 --double=32 --dlib_config ${TOOLKIT_DIR}/lib/dlib/dl430fn.h>
-D__MSP430F149__ )
# Set the linker flags for the target
target_link_options(myProgram PRIVATE
-s __program_start
# Create a map file from the target's UBROF
-l $<TARGET_PROPERTY:NAME>.map
# The `SHELL:` prefix prevents option de-duplication
"SHELL:-D_DATA16_HEAP_SIZE=50"
"SHELL:-D_STACK_SIZE=50"
"SHELL:-D_DATA20_HEAP_SIZE=50"
# Set the linker script
-f $<TARGET_PROPERTY:XCL>
# The `SHELL:` prefix prevents option de-duplication
"SHELL:-f ${TOOLKIT_DIR}/config/linker/multiplier.xcl"
-rt ${TOOLKIT_DIR}/lib/dlib/dl430fn.r43 )
# Link "myProgram" against the "myMath" library
target_link_libraries(myProgram LINK_PUBLIC myMath)
# Optional: test the project with C-SPY
include(../../iar-cspy-430.cmake)
iar_cspy_add_test(myProgram test_add 42)
iar_cspy_add_test(myProgram test_sub 38)
iar_cspy_add_test(myProgram test_mul 80)

29
examples/430/using-libs/app/main.c

@ -1,29 +0,0 @@
#ifndef NDEBUG
#include <stdio.h>
#endif
#include <stdlib.h>
#include "myMath.h"
int a = 40, b = 2;
int addResult;
int subResult;
int mulResult;
int main(void)
{
addResult = add(a, b);
subResult = sub(a, b);
mulResult = mul(a, b);
/* In CMake, the NDEBUG preprocessor symbol
is set automatically when the build configuration is set for Release */
#ifndef NDEBUG
printf("-- app debug output begin --\n");
printf("%d + %d = %d\n", a, b, addResult);
printf("%d - %d = %d\n", a, b, subResult);
printf("%d * %d = %d\n", a, b, mulResult);
printf("-- app debug output end --\n");
#endif
return 0;
}

51
examples/430/using-libs/app/myProgram.mac

@ -1,51 +0,0 @@
__param testName;
__param testExpected;
__var _breakID;
__var _result;
execUserSetup()
{
/* Set up immediate breakpoints. */
_breakID = __setSimBreak("addResult", "R", "addAccess()");
_breakID = __setSimBreak("subResult", "R", "subAccess()");
_breakID = __setSimBreak("mulResult", "R", "mulAccess()");
}
Done()
{
if (_result == testExpected)
{
__message "-- C-SPY TEST:", testName, ". Result: PASS";
} else {
__message "-- C-SPY TEST:", testName, ". Expected: ", testExpected, " Result: FAIL";
}
}
addAccess()
{
if (testName == "test_add")
{
_result = addResult;
Done();
}
}
subAccess()
{
if (testName == "test_sub")
{
_result = subResult;
Done();
}
}
mulAccess()
{
if (testName == "test_mul")
{
_result = mulResult;
Done();
}
}

17
examples/430/using-libs/lib/CMakeLists.txt

@ -1,17 +0,0 @@
# The top-level CMakeLists.txt add this subdirectory
# This CMakeLists.txt builds the target "myMath" library
add_library(myMath
add.c
sub.c
mul.c )
# Set the compiler flags for the "myMath" target
target_compile_options(myMath PUBLIC
$<$<COMPILE_LANGUAGE:C>:--multiplier=16 --double=32 --dlib_config ${TOOLKIT_DIR}/lib/dlib/dl430fn.h>
-D__MSP430F149__ )
# Define headers for the target
# PUBLIC headers are used for building the library
# PRIVATE sources, only used in this target
target_include_directories(myMath
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/.> )

5
examples/430/using-libs/lib/add.c

@ -1,5 +0,0 @@
#include "myMath.h"
int add(int a, int b) {
return a + b;
}

5
examples/430/using-libs/lib/mul.c

@ -1,5 +0,0 @@
#include "myMath.h"
int mul(int a, int b) {
return a * b;
}

6
examples/430/using-libs/lib/myMath.h

@ -1,6 +0,0 @@
#ifndef MY_MATH_H
#define MY_MATH_H
int add(int a, int b);
int sub(int a, int b);
int mul(int a, int b);
#endif

5
examples/430/using-libs/lib/sub.c

@ -1,5 +0,0 @@
#include "myMath.h"
int sub(int a, int b) {
return a - --b; /* bug */
}

30
examples/8051/iar-cspy-8051.cmake

@ -1,30 +0,0 @@
# Example for creating a test for CTest
# to execute the `IAR C-SPY Command-line Utility (cspybat.exe)`
function(iar_cspy_add_test TARGET TEST_NAME EXPECTED_OUTPUT)
# Add a test for CTest
add_test(NAME ${TEST_NAME}
COMMAND ${TOOLKIT_DIR}/../common/bin/cspybat --silent
# C-SPY drivers
"${TOOLKIT_DIR}/bin/${CMAKE_SYSTEM_PROCESSOR}proc.dll"
"${TOOLKIT_DIR}/bin/${CMAKE_SYSTEM_PROCESSOR}sim.dll"
"--plugin=${TOOLKIT_DIR}/bin/${CMAKE_SYSTEM_PROCESSOR}bat.dll"
--debug_file=$<TARGET_FILE:${TARGET}>
# C-SPY macros settings
"--macro=${CMAKE_CURRENT_SOURCE_DIR}/${TARGET}.mac"
"--macro_param=testName=\"${TEST_NAME}\""
"--macro_param=testExpected=${EXPECTED_OUTPUT}"
# C-SPY backend setup
--backend
--proc_core=plain
--proc_code_model=near
--proc_nr_virtual_regs 8
--proc_pdata_bank_reg_addr 0xA0
--proc_dptr_nr_of=1
--proc_data_model=small
-p $<IF:$<BOOL:$<TARGET_PROPERTY:${TARGET},DDF>>,$<TARGET_PROPERTY:${TARGET},DDF>,${TOOLKIT_DIR}/config/devices/_generic/io8051.ddf>
--proc_driver sim )
# Set the test to interpret a C-SPY's message containing `PASS`
set_tests_properties(${TEST_NAME} PROPERTIES PASS_REGULAR_EXPRESSION "PASS")
endfunction()

57
examples/8051/mix-c-asm/CMakeLists.txt

@ -1,57 +0,0 @@
cmake_minimum_required(VERSION 3.22)
# Set the project name, [description] and [version],
# while enabling its required languages
project(Example1
DESCRIPTION "Mixing C and Assembly"
VERSION 1.0.0
LANGUAGES C ASM )
# Fallback option for generators other than `Ninja Multi-Config`
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug)
endif()
# Enable CTest
enable_testing()
# Add the executable for the "mixLanguages" target
add_executable(mixLanguages
# Source files
main.c
mynum.asm )
# Set a preprocessor symbol, usable from "mixLanguages" target
target_compile_definitions(mixLanguages PUBLIC USE_ASM=1)
# Set compile options for the target
target_compile_options(mixLanguages PRIVATE
$<$<COMPILE_LANGUAGE:C>:--core=plain --dptr=16,1 --data_model=large --code_model=near --calling_convention=xdata_reentrant --place_constants=data --nr_virtual_regs 8 --dlib --dlib_config ${TOOLKIT_DIR}/lib/dlib/dl8051Normal.h>
$<$<COMPILE_LANGUAGE:ASM>:-v0 -D__CORE__=1 -D__CODE_MODEL__=1 -D__DATA_MODEL__=1 -D__CALLING_CONVENTION__=2 -D__NUMBER_OF_DPTRS__=1> )
# Set the link options for the target
target_link_options(mixLanguages PRIVATE
-rt
-f ${TOOLKIT_DIR}/config/devices/_generic/lnk51ew_8051.xcl
${TOOLKIT_DIR}/lib/dlib/dl-pli-nlxd-1e16x01n.r51
# The `SHELL:` prefix prevents option de-duplication
"SHELL:-D_NR_OF_BANKS=0"
"SHELL:-D_CODEBANK_END=0"
"SHELL:-D_CODEBANK_START=0"
"SHELL:-D_NR_OF_VIRTUAL_REGISTERS=8"
"SHELL:-D?PBANK=0xA0"
"SHELL:-D_IDATA_STACK_SIZE=0x40"
"SHELL:-D?ESP=0"
"SHELL:-D?ESP_MASK=0"
"SHELL:-D_EXTENDED_STACK_START=0"
"SHELL:-D_EXTENDED_STACK_SIZE=0"
"SHELL:-D_PDATA_STACK_SIZE=0x80"
"SHELL:-D_XDATA_STACK_SIZE=0xEFF"
"SHELL:-D_XDATA_HEAP_SIZE=0xFF"
"SHELL:-D_FAR_HEAP_SIZE=0xFFF"
"SHELL:-D_HUGE_HEAP_SIZE=0xFFF"
"SHELL:-D_FAR22_HEAP_SIZE=0xFFF" )
# Optional: test the project with CTest and IAR C-SPY
include(../iar-cspy-8051.cmake)
iar_cspy_add_test(mixLanguages test_mynum 42)

23
examples/8051/mix-c-asm/main.c

@ -1,23 +0,0 @@
#include <stdio.h>
#include "mynum.h"
int answer;
int main(void)
{
#if USE_ASM
answer = mynum();
#else
answer = 10;
#endif
/* NDEBUG is set automatically for when
bulding with -DCMAKE_BUILD_TYPE=Release */
#ifndef NDEBUG
printf("-- app debug output begin --\n");
printf("mixLanguages v%d.%d.%d\n", 1, 0, 0);
printf("The answer is: %d.\n",answer);
printf("-- app debug output end --\n");
#endif
return 0;
}

33
examples/8051/mix-c-asm/mixLanguages.mac

@ -1,33 +0,0 @@
__param testName;
__param testExpected;
__var _breakID;
__var _result;
execUserSetup()
{
__message "C-SPY TEST: started...";
__message "C-SPY TEST: When the `answer` variable is read, `checkanswer()` will execute.";
_breakID = __setSimBreak("answer", "R", "checkAnswer()");
}
Done()
{
__message "-- C-SPY TEST: Done()";
if (_result == testExpected)
{
__message "-- C-SPY TEST:", testName, ". Result: PASS";
} else {
__message "-- C-SPY TEST:", testName, ". Expected: ", testExpected, " Result: FAIL";
}
}
checkAnswer()
{
__message "-- C-SPY TEST: checkAnswer()";
if (testName == "test_mynum")
{
_result = answer;
Done();
}
}

20
examples/8051/mix-c-asm/mynum.asm

@ -1,20 +0,0 @@
NAME mynum
RSEG DOVERLAY:DATA:NOROOT(0)
RSEG IOVERLAY:IDATA:NOROOT(0)
RSEG ISTACK:IDATA:NOROOT(0)
RSEG PSTACK:XDATA:NOROOT(0)
RSEG XSTACK:XDATA:NOROOT(0)
PUBLIC mynum
RSEG NEAR_CODE:CODE:NOROOT(0)
mynum:
CODE
; Saved register size: 0
; Auto size: 0
MOV R2,#0x2A
MOV R3,#0x0
RET
END

4
examples/8051/mix-c-asm/mynum.h

@ -1,4 +0,0 @@
#ifndef MYNUM_H
#define MYNUM_H
extern int mynum();
#endif

18
examples/8051/using-libs/CMakeLists.txt

@ -1,18 +0,0 @@
cmake_minimum_required (VERSION 3.22)
project (Example2
DESCRIPTION "Creating and using libraries"
VERSION 1.0.0
LANGUAGES C )
# Fallback option for generators other than `Ninja Multi-Config`
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug)
endif()
# Enable CTest
enable_testing()
# Recurse into the "lib" and "app" subdirectiories
add_subdirectory(lib)
add_subdirectory(app)

50
examples/8051/using-libs/app/CMakeLists.txt

@ -1,50 +0,0 @@
# Add the executable for the "myProgram" target,
# specifying its source files
add_executable (myProgram
# Source files
main.c )
# Set the properties for the "myProgram" target
set_target_properties(myProgram PROPERTIES
XCL "${TOOLKIT_DIR}/config/devices/_generic/lnk51ew_8051.xcl"
# C-SPY-related properties
DDF "${TOOLKIT_DIR}/config/devices/_generic/io8051.ddf" )
# Set the compiler flags for the "myProgram" target
target_compile_options(myProgram PRIVATE
$<$<COMPILE_LANGUAGE:C>:--core=plain --dptr=16,1 --data_model=large --code_model=near --calling_convention=xdata_reentrant --place_constants=data --nr_virtual_regs 8 --dlib --dlib_config ${TOOLKIT_DIR}/lib/dlib/dl8051Normal.h> )
# Set the linker flags for the target
target_link_options(myProgram PRIVATE
-rt
# Set the linker script
-f $<TARGET_PROPERTY:XCL>
${TOOLKIT_DIR}/lib/dlib/dl-pli-nlxd-1e16x01n.r51
# Create a map file from the target's UBROF
-l $<TARGET_PROPERTY:NAME>.map
# The `SHELL:` prefix prevents option de-duplication
"SHELL:-D_NR_OF_BANKS=0"
"SHELL:-D_CODEBANK_END=0"
"SHELL:-D_CODEBANK_START=0"
"SHELL:-D_NR_OF_VIRTUAL_REGISTERS=8"
"SHELL:-D?PBANK=0xA0"
"SHELL:-D_IDATA_STACK_SIZE=0x40"
"SHELL:-D?ESP=0"
"SHELL:-D?ESP_MASK=0"
"SHELL:-D_EXTENDED_STACK_START=0"
"SHELL:-D_EXTENDED_STACK_SIZE=0"
"SHELL:-D_PDATA_STACK_SIZE=0x80"
"SHELL:-D_XDATA_STACK_SIZE=0xEFF"
"SHELL:-D_XDATA_HEAP_SIZE=0xFF"
"SHELL:-D_FAR_HEAP_SIZE=0xFFF"
"SHELL:-D_HUGE_HEAP_SIZE=0xFFF"
"SHELL:-D_FAR22_HEAP_SIZE=0xFFF" )
# Link "myProgram" against the "myMath" library
target_link_libraries(myProgram LINK_PUBLIC myMath)
# Optional: test the project with CTest and IAR C-SPY
include(../../iar-cspy-8051.cmake)
iar_cspy_add_test(myProgram test_add 42)
iar_cspy_add_test(myProgram test_sub 38)
iar_cspy_add_test(myProgram test_mul 80)

29
examples/8051/using-libs/app/main.c

@ -1,29 +0,0 @@
#ifndef NDEBUG
#include <stdio.h>
#endif
#include <stdlib.h>
#include "myMath.h"
int a = 40, b = 2;
int addResult;
int subResult;
int mulResult;
int main(void)
{
addResult = add(a, b);
subResult = sub(a, b);
mulResult = mul(a, b);
/* In CMake, the NDEBUG preprocessor symbol
is set automatically when the build configuration is set for Release */
#ifndef NDEBUG
printf("-- app debug output begin --\n");
printf("%d + %d = %d\n", a, b, addResult);
printf("%d - %d = %d\n", a, b, subResult);
printf("%d * %d = %d\n", a, b, mulResult);
printf("-- app debug output end --\n");
#endif
return 0;
}

51
examples/8051/using-libs/app/myProgram.mac

@ -1,51 +0,0 @@
__param testName;
__param testExpected;
__var _breakID;
__var _result;
execUserSetup()
{
/* Set up immediate breakpoints. */
_breakID = __setSimBreak("addResult", "R", "addAccess()");
_breakID = __setSimBreak("subResult", "R", "subAccess()");
_breakID = __setSimBreak("mulResult", "R", "mulAccess()");
}
Done()
{
if (_result == testExpected)
{
__message "-- C-SPY TEST:", testName, ". Result: PASS";
} else {
__message "-- C-SPY TEST:", testName, ". Expected: ", testExpected, " Result: FAIL";
}
}
addAccess()
{
if (testName == "test_add")
{
_result = addResult;
Done();
}
}
subAccess()
{
if (testName == "test_sub")
{
_result = subResult;
Done();
}
}
mulAccess()
{
if (testName == "test_mul")
{
_result = mulResult;
Done();
}
}

17
examples/8051/using-libs/lib/CMakeLists.txt

@ -1,17 +0,0 @@
# The top-level CMakeLists.txt add this subdirectory
# This CMakeLists.txt builds the target "myMath" library
add_library(myMath
add.c
sub.c
mul.c )
# Set the compiler flags for the "myMath" target
target_compile_options(myMath PUBLIC
$<$<COMPILE_LANGUAGE:C>:--core=plain --dptr=16,1 --data_model=large --code_model=near --calling_convention=xdata_reentrant --place_constants=data --nr_virtual_regs 8 --dlib --dlib_config ${TOOLKIT_DIR}/lib/dlib/dl8051Normal.h>
$<$<COMPILE_LANGUAGE:ASM>:-v0 -D__CORE__=1 -D__CODE_MODEL__=1 -D__DATA_MODEL__=1 -D__CALLING_CONVENTION__=2 -D__NUMBER_OF_DPTRS__=1>)
# Define headers for the target
# PUBLIC headers are used for building the library
# PRIVATE sources, only used in this target
target_include_directories(myMath
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/.> )

5
examples/8051/using-libs/lib/add.c

@ -1,5 +0,0 @@
#include "myMath.h"
int add(int a, int b) {
return a + b;
}

5
examples/8051/using-libs/lib/mul.c

@ -1,5 +0,0 @@
#include "myMath.h"
int mul(int a, int b) {
return a * b;
}

6
examples/8051/using-libs/lib/myMath.h

@ -1,6 +0,0 @@
#ifndef MY_MATH_H
#define MY_MATH_H
int add(int a, int b);
int sub(int a, int b);
int mul(int a, int b);
#endif

5
examples/8051/using-libs/lib/sub.c

@ -1,5 +0,0 @@
#include "myMath.h"
int sub(int a, int b) {
return a - --b; /* bug */
}

3
examples/README.md

@ -0,0 +1,3 @@
# Interactive examples
Visit the [wiki](https://github.com/iarsystems/cmake-tutorial/wiki) for details and answers.

17
examples/arm/hello-world/CMakeLists.txt

@ -1,17 +0,0 @@
# CMake requires to set its minimum required version
cmake_minimum_required(VERSION 3.23)
# Set the project name, enabling its required languages (e.g. ASM, C and/or CXX)
project(simpleProject LANGUAGES C)
# Add a executable target named "hello-world"
add_executable(hello-world
# Target sources
main.c)
# Set the target's compiler options
target_compile_options(hello-world PRIVATE --cpu=Cortex-M4 --fpu=VFPv4_sp --dlib_config normal)
# Set the target's linker options
target_link_options(hello-world PRIVATE --semihosting --config ${TOOLKIT_DIR}/config/linker/ST/stm32f407xG.icf)

10
examples/arm/hello-world/main.c

@ -1,10 +0,0 @@
#include <intrinsics.h>
#include <stdio.h>
void main() {
while (1) {
printf("Hello world!\n");
__no_operation();
}
}

48
examples/arm/iar-cspy-arm.cmake

@ -1,48 +0,0 @@
# Example for creating a test for CTest
# to execute the `IAR C-SPY Command-line Utility (cspybat.exe)`
function(iar_cspy_add_test TARGET TEST_NAME EXPECTED_OUTPUT)
find_program(CSPY_BAT
NAMES cspybat CSpyBat
PATHS ${TOOLKIT_DIR}/../common
PATH_SUFFIXES bin)
# Check if C-SPY is being run from BX
if(WIN32)
set(libPREFIX "")
set(libPROCsuffix proc.dll)
set(libSIM2suffix sim2.dll)
set(libBATsuffix bat.dll)
else()
set(libPREFIX lib)
set(libPROCsuffix PROC.so)
set(libSIM2suffix SIM2.so)
set(libBATsuffix Bat.so)
endif()
# Add a test for CTest
add_test(NAME ${TEST_NAME}
COMMAND ${CSPY_BAT} --silent
# C-SPY drivers
"${TOOLKIT_DIR}/bin/${libPREFIX}${CMAKE_SYSTEM_PROCESSOR}${libPROCsuffix}"
"${TOOLKIT_DIR}/bin/${libPREFIX}${CMAKE_SYSTEM_PROCESSOR}${libSIM2suffix}"
"--plugin=${TOOLKIT_DIR}/bin/${libPREFIX}${CMAKE_SYSTEM_PROCESSOR}${libBATsuffix}"
--debug_file=$<TARGET_FILE:${TARGET}>
$<IF:$<BOOL:$<TARGET_PROPERTY:${TARGET},DMAC>>,--device_macro=$<TARGET_PROPERTY:${TARGET},DMAC>,>
# C-SPY macros settings
"--macro=${CMAKE_CURRENT_SOURCE_DIR}/${TARGET}.mac"
"--macro_param=testName=\"${TEST_NAME}\""
"--macro_param=testExpected=${EXPECTED_OUTPUT}"
# C-SPY backend setup
--backend
--cpu=$<IF:$<BOOL:$<TARGET_PROPERTY:${TARGET},CPU>>,$<TARGET_PROPERTY:${TARGET},CPU>,Cortex-M3>
--fpu=$<IF:$<BOOL:$<TARGET_PROPERTY:${TARGET},FPU>>,$<TARGET_PROPERTY:${TARGET},FPU>,None>
$<IF:$<BOOL:$<TARGET_PROPERTY:${TARGET},DEVICE>>,--device=$<TARGET_PROPERTY:${TARGET},DEVICE>,>
--semihosting
--endian=little
$<IF:$<BOOL:$<TARGET_PROPERTY:${TARGET},DDF>>,-p,>
$<IF:$<BOOL:$<TARGET_PROPERTY:${TARGET},DDF>>,$<TARGET_PROPERTY:${TARGET},DDF>,> )
# Set the test to interpret a C-SPY's message containing `PASS`
set_tests_properties(${TEST_NAME} PROPERTIES PASS_REGULAR_EXPRESSION "PASS")
endfunction()

16
examples/arm/iar-functions.cmake

@ -1,16 +0,0 @@
# CMake functions for the IAR Build Tools
# Convert the ELF output to .hex
function(iar_elf_tool_hex TARGET)
add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_IAR_ELFTOOL} --silent --ihex $<TARGET_FILE:${TARGET}> $<IF:$<BOOL:$<TARGET_PROPERTY:${TARGET},OUTPUT_NAME>>,$<TARGET_PROPERTY:${TARGET},OUTPUT_NAME>,$<TARGET_PROPERTY:${TARGET},NAME>>.hex)
endfunction()
# Convert the ELF output to .srec
function(iar_elf_tool_srec TARGET)
add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_IAR_ELFTOOL} --silent --srec $<TARGET_FILE:${TARGET}> $<IF:$<BOOL:$<TARGET_PROPERTY:${TARGET},OUTPUT_NAME>>,$<TARGET_PROPERTY:${TARGET},OUTPUT_NAME>,$<TARGET_PROPERTY:${TARGET},NAME>>.srec)
endfunction()
# Convert the ELF output to .bin
function(iar_elf_tool_bin TARGET)
add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_IAR_ELFTOOL} --silent --bin $<TARGET_FILE:${TARGET}> $<IF:$<BOOL:$<TARGET_PROPERTY:${TARGET},OUTPUT_NAME>>,$<TARGET_PROPERTY:${TARGET},OUTPUT_NAME>,$<TARGET_PROPERTY:${TARGET},NAME>>.bin)
endfunction()

39
examples/arm/mix-c-asm/CMakeLists.txt

@ -1,39 +0,0 @@
cmake_minimum_required(VERSION 3.22)
# Set the project name, [description] and [version],
# while enabling its required languages
project(Example1
DESCRIPTION "Mixing C and Assembly"
VERSION 1.0.0
LANGUAGES C ASM )
# Fallback option for generators other than `Ninja Multi-Config`
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug)
endif()
# Enable CTest
enable_testing()
# Add the executable for the "mixLanguages" target
add_executable(mixLanguages
# Source files
main.c
mynum.asm )
# Set a preprocessor symbol, usable from "mixLanguages" target
target_compile_definitions(mixLanguages PUBLIC USE_ASM=1)
# Set compile options for the target
target_compile_options(mixLanguages PRIVATE
$<$<COMPILE_LANGUAGE:C>:--dlib_config normal>
--cpu Cortex-M3 )
# Set the link options for the target
target_link_options(mixLanguages PRIVATE
$<$<CONFIG:Debug>:--semihosting --redirect ___write=___write_buffered>
--config ${TOOLKIT_DIR}/config/generic.icf )
# Optional: test the project with CTest and IAR C-SPY
include(../iar-cspy-arm.cmake)
iar_cspy_add_test(mixLanguages test_mynum 42)

23
examples/arm/mix-c-asm/main.c

@ -1,23 +0,0 @@
#include <stdio.h>
#include "mynum.h"
int answer;
int main(void)
{
#if USE_ASM
answer = mynum();
#else
answer = 10;
#endif
/* NDEBUG is set automatically for when
bulding with -DCMAKE_BUILD_TYPE=Release */
#ifndef NDEBUG
printf("-- app debug output begin --\n");
printf("mixLanguages v%d.%d.%d\n", 1, 0, 0);
printf("The answer is: %d.\n",answer);
printf("-- app debug output end --\n");
#endif
return 0;
}

33
examples/arm/mix-c-asm/mixLanguages.mac

@ -1,33 +0,0 @@
__param testName;
__param testExpected;
__var _breakID;
__var _result;
execUserSetup()
{
__message "C-SPY TEST: started...";
__message "C-SPY TEST: When the `answer` variable is read, `checkAnswer()` will execute.";
_breakID = __setSimBreak("answer", "R", "checkAnswer()");
}
Done()
{
__message "-- C-SPY TEST: Done()";
if (_result == testExpected)
{
__message "-- C-SPY TEST:", testName, ". Result: PASS";
} else {
__message "-- C-SPY TEST:", testName, ". Expected: ", testExpected, " Result: FAIL";
}
}
checkAnswer()
{
__message "-- C-SPY TEST: checkAnswer()";
if (testName == "test_mynum")
{
_result = answer;
Done();
}
}

18
examples/arm/mix-c-asm/mynum.asm

@ -1,18 +0,0 @@
#define SHT_PROGBITS 0x1
PUBLIC mynum
SECTION `.text`:CODE:NOROOT(1)
THUMB
mynum:
MOVS R0,#+0x2A
BX LR ;; return
SECTION `.iar_vfe_header`:DATA:NOALLOC:NOROOT(2)
SECTION_TYPE SHT_PROGBITS, 0
DATA
DC32 0
END

4
examples/arm/mix-c-asm/mynum.h

@ -1,4 +0,0 @@
#ifndef MYNUM_H
#define MYNUM_H
extern int mynum();
#endif

18
examples/arm/using-libs/CMakeLists.txt

@ -1,18 +0,0 @@
cmake_minimum_required (VERSION 3.22)
project (Example2
DESCRIPTION "Creating and using libraries"
VERSION 1.0.0
LANGUAGES C )
# Fallback option for generators other than `Ninja Multi-Config`
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug)
endif()
# Enable CTest
enable_testing()
# Recurse into the "lib" and "app" subdirectiories
add_subdirectory(lib)
add_subdirectory(app)

42
examples/arm/using-libs/app/CMakeLists.txt

@ -1,42 +0,0 @@
# Add the executable for the "myProgram" target,
# specifying its source files
add_executable (myProgram
# Source files
main.c )
# Set the properties for the "myProgram" target
set_target_properties(myProgram PROPERTIES
DEVICE STM32F407VG
CPU Cortex-M4
FPU VFPv4_sp
ICF "${TOOLKIT_DIR}/config/linker/ST/stm32f407xG.icf"
# C-SPY-related properties
DDF "${TOOLKIT_DIR}/config/debugger/ST/STM32F407VG.ddf"
DMAC "${TOOLKIT_DIR}/config/debugger/ST/STM32F4xx.dmac" )
# Set compile options for the target
target_compile_options(myProgram PRIVATE
$<$<COMPILE_LANGUAGE:C,CXX>:--dlib_config normal>
--cpu $<TARGET_PROPERTY:CPU> --fpu $<TARGET_PROPERTY:FPU> )
# Set the link options for the target
target_link_options(myProgram PRIVATE
# Genex evaluates if we are using the `Debug` configuration
$<$<CONFIG:Debug>:--semihosting --redirect ___write=___write_buffered>
# Create a map file from the target's ELF
--map $<TARGET_PROPERTY:NAME>.map
# Set the linker script
--config $<TARGET_PROPERTY:ICF> )
# Link "myProgram" against the "myMath" library
target_link_libraries(myProgram LINK_PUBLIC myMath)
# Optional: convert the output to .hex format
include(../../iar-functions.cmake)
iar_elf_tool_hex(myProgram)
# Optional: test the project with CTest and IAR C-SPY
include(../../iar-cspy-arm.cmake)
iar_cspy_add_test(myProgram test_add 42)
iar_cspy_add_test(myProgram test_sub 38)
iar_cspy_add_test(myProgram test_mul 80)

29
examples/arm/using-libs/app/main.c

@ -1,29 +0,0 @@
#ifndef NDEBUG
#include <stdio.h>
#endif
#include <stdlib.h>
#include "myMath.h"
int a = 40, b = 2;
int addResult;
int subResult;
int mulResult;
int main(void)
{
addResult = add(a, b);
subResult = sub(a, b);
mulResult = mul(a, b);
/* In CMake, the NDEBUG preprocessor symbol
is set automatically when the build configuration is set for Release */
#ifndef NDEBUG
printf("-- app debug output begin --\n");
printf("%d + %d = %d\n", a, b, addResult);
printf("%d - %d = %d\n", a, b, subResult);
printf("%d * %d = %d\n", a, b, mulResult);
printf("-- app debug output end --\n");
#endif
return 0;
}

51
examples/arm/using-libs/app/myProgram.mac

@ -1,51 +0,0 @@
__param testName;
__param testExpected;
__var _breakID;
__var _result;
execUserSetup()
{
/* Set up immediate breakpoints. */
_breakID = __setSimBreak("addResult", "R", "addAccess()");
_breakID = __setSimBreak("subResult", "R", "subAccess()");
_breakID = __setSimBreak("mulResult", "R", "mulAccess()");
}
Done()
{
if (_result == testExpected)
{
__message "-- C-SPY TEST:", testName, ". Result: PASS";
} else {
__message "-- C-SPY TEST:", testName, ". Expected: ", testExpected, " Result: FAIL";
}
}
addAccess()
{
if (testName == "test_add")
{
_result = addResult;
Done();
}
}
subAccess()
{
if (testName == "test_sub")
{
_result = subResult;
Done();
}
}
mulAccess()
{
if (testName == "test_mul")
{
_result = mulResult;
Done();
}
}

16
examples/arm/using-libs/lib/CMakeLists.txt

@ -1,16 +0,0 @@
# The top-level CMakeLists.txt add this subdirectory
# This CMakeLists.txt builds the target "myMath" library
add_library(myMath
add.c
sub.c
mul.c )
# Set the compiler flags for the "myMath" target
target_compile_options(myMath PUBLIC
$<$<COMPILE_LANGUAGE:C>:--cpu Cortex-M4 --dlib_config normal> )
# Define headers for the target
# PUBLIC headers are used for building the library
# PRIVATE sources, only used in this target
target_include_directories(myMath
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/.> )

5
examples/arm/using-libs/lib/add.c

@ -1,5 +0,0 @@
#include "myMath.h"
int add(int a, int b) {
return a + b;
}

5
examples/arm/using-libs/lib/mul.c

@ -1,5 +0,0 @@
#include "myMath.h"
int mul(int a, int b) {
return a * b;
}

6
examples/arm/using-libs/lib/myMath.h

@ -1,6 +0,0 @@
#ifndef MY_MATH_H
#define MY_MATH_H
int add(int a, int b);
int sub(int a, int b);
int mul(int a, int b);
#endif

5
examples/arm/using-libs/lib/sub.c

@ -1,5 +0,0 @@
#include "myMath.h"
int sub(int a, int b) {
return a - --b; /* bug */
}

25
examples/avr/iar-cspy-avr.cmake

@ -1,25 +0,0 @@
# Example for creating a test for CTest
# to execute the `IAR C-SPY Command-line Utility (cspybat.exe)`
function(iar_cspy_add_test TARGET TEST_NAME EXPECTED_OUTPUT)
# Add a test for CTest
add_test(NAME ${TEST_NAME}
COMMAND ${TOOLKIT_DIR}/../common/bin/cspybat --silent
# C-SPY drivers
"${TOOLKIT_DIR}/bin/${CMAKE_SYSTEM_PROCESSOR}proc.dll"
"${TOOLKIT_DIR}/bin/${CMAKE_SYSTEM_PROCESSOR}sim.dll"
"--plugin=${TOOLKIT_DIR}/bin/${CMAKE_SYSTEM_PROCESSOR}libsupportbat.dll"
--debug_file=$<TARGET_FILE:${TARGET}>
# C-SPY macros settings
"--macro=${CMAKE_CURRENT_SOURCE_DIR}/${TARGET}.mac"
"--macro_param=testName=\"${TEST_NAME}\""
"--macro_param=testExpected=${EXPECTED_OUTPUT}"
# C-SPY backend setup
--backend
-v3
--enhanced_core
--disable_internal_eeprom )
# Set the test to interpret a C-SPY's message containing `PASS`
set_tests_properties(${TEST_NAME} PROPERTIES PASS_REGULAR_EXPRESSION "PASS")
endfunction()

40
examples/avr/mix-c-asm/CMakeLists.txt

@ -1,40 +0,0 @@
cmake_minimum_required(VERSION 3.22)
# Set the project name, [description] and [version],
# while enabling its required languages
project(Example1
DESCRIPTION "Mixing C and Assembly"
VERSION 1.0.0
LANGUAGES C ASM )
# Fallback option for generators other than `Ninja Multi-Config`
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug)
endif()
# Enable CTest
enable_testing()
# Add the executable for the "mixLanguages" target
add_executable(mixLanguages
# Source files
main.c
mynum.asm )
# Set a preprocessor symbol, usable from "mixLanguages" target
target_compile_definitions(mixLanguages PUBLIC USE_ASM=1)
# Set compile options for the target
target_compile_options(mixLanguages PRIVATE
$<$<COMPILE_LANGUAGE:C>:--enhanced_core -ms -y --initializers_in_flash --dlib --dlib_config ${TOOLKIT_DIR}/lib/dlib/dlAVR-3s-ec_mul-n.h>
$<$<COMPILE_LANGUAGE:ASM>:-u_enhancedCore>
-v3 )
# Set the link options for the target
target_link_options(mixLanguages PRIVATE
-rt ${TOOLKIT_DIR}/lib/dlib/dlAVR-3s-ec_mul-n.r90
-f ${TOOLKIT_DIR}/src/template/lnk3s.xcl )
# Optional: test the project with CTest and IAR C-SPY
include(../iar-cspy-avr.cmake)
iar_cspy_add_test(mixLanguages test_mynum 42)

23
examples/avr/mix-c-asm/main.c

@ -1,23 +0,0 @@
#include <stdio.h>
#include "mynum.h"
int answer;
int main(void)
{
#if USE_ASM
answer = mynum();
#else
answer = 10;
#endif
/* NDEBUG is set automatically for when
bulding with -DCMAKE_BUILD_TYPE=Release */
#ifndef NDEBUG
printf("-- app debug output begin --\n");
printf("mixLanguages v%d.%d.%d\n", 1, 0, 0);
printf("The answer is: %d.\n",answer);
printf("-- app debug output end --\n");
#endif
return 0;
}

33
examples/avr/mix-c-asm/mixLanguages.mac

@ -1,33 +0,0 @@
__param testName;
__param testExpected;
__var _breakID;
__var _result;
execUserSetup()
{
__message "C-SPY TEST: started...";
__message "C-SPY TEST: When the `answer` variable is read, `checkanswer()` will execute.";
_breakID = __setSimBreak("answer", "R", "checkAnswer()");
}
Done()
{
__message "-- C-SPY TEST: Done()";
if (_result == testExpected)
{
__message "-- C-SPY TEST:", testName, ". Result: PASS";
} else {
__message "-- C-SPY TEST:", testName, ". Expected: ", testExpected, " Result: FAIL";
}
}
checkAnswer()
{
__message "-- C-SPY TEST: checkAnswer()";
if (testName == "test_mynum")
{
_result = answer;
Done();
}
}

15
examples/avr/mix-c-asm/mynum.asm

@ -1,15 +0,0 @@
NAME mynum
RSEG CSTACK:DATA:NOROOT(0)
RSEG RSTACK:DATA:NOROOT(0)
PUBLIC mynum
RSEG CODE:CODE:NOROOT(1)
mynum:
LDI R16, 42
LDI R17, 0
RET
END

4
examples/avr/mix-c-asm/mynum.h

@ -1,4 +0,0 @@
#ifndef MYNUM_H
#define MYNUM_H
extern int mynum();
#endif

18
examples/avr/using-libs/CMakeLists.txt

@ -1,18 +0,0 @@
cmake_minimum_required (VERSION 3.22)
project (Example2
DESCRIPTION "Creating and using libraries"
VERSION 1.0.0
LANGUAGES C )
# Fallback option for generators other than `Ninja Multi-Config`
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug)
endif()
# Enable CTest
enable_testing()
# Recurse into the "lib" and "app" subdirectiories
add_subdirectory(lib)
add_subdirectory(app)

31
examples/avr/using-libs/app/CMakeLists.txt

@ -1,31 +0,0 @@
# Add the executable for the "myProgram" target,
# specifying its source files
add_executable (myProgram
# Source files
main.c )
# Set the properties for the "myProgram" target
set_target_properties(myProgram PROPERTIES
XCL "${TOOLKIT_DIR}/src/template/lnk3s.xcl" )
# Set compile options for the target
target_compile_options(myProgram PRIVATE
$<$<COMPILE_LANGUAGE:C>:--enhanced_core -ms -y --initializers_in_flash --dlib --dlib_config ${TOOLKIT_DIR}/lib/dlib/dlAVR-3s-ec_mul-n.h>
-v3 )
# Set the linker flags for the target
target_link_options(myProgram PRIVATE
-rt ${TOOLKIT_DIR}/lib/dlib/dlAVR-3s-ec_mul-n.r90
# Set the linker script
-f $<TARGET_PROPERTY:XCL>
# Create a map file from the target's UBROF
-l $<TARGET_PROPERTY:NAME>.map )
# Link "myProgram" against the "myMath" library
target_link_libraries(myProgram LINK_PUBLIC myMath)
# Optional: test the project with CTest and IAR C-SPY
include(../../iar-cspy-avr.cmake)
iar_cspy_add_test(myProgram test_add 42)
iar_cspy_add_test(myProgram test_sub 38)
iar_cspy_add_test(myProgram test_mul 80)

29
examples/avr/using-libs/app/main.c

@ -1,29 +0,0 @@
#ifndef NDEBUG
#include <stdio.h>
#endif
#include <stdlib.h>
#include "myMath.h"
int a = 40, b = 2;
int addResult;
int subResult;
int mulResult;
int main(void)
{
addResult = add(a, b);
subResult = sub(a, b);
mulResult = mul(a, b);
/* In CMake, the NDEBUG preprocessor symbol
is set automatically when the build configuration is set for Release */
#ifndef NDEBUG
printf("-- app debug output begin --\n");
printf("%d + %d = %d\n", a, b, addResult);
printf("%d - %d = %d\n", a, b, subResult);
printf("%d * %d = %d\n", a, b, mulResult);
printf("-- app debug output end --\n");
#endif
return 0;
}

51
examples/avr/using-libs/app/myProgram.mac

@ -1,51 +0,0 @@
__param testName;
__param testExpected;
__var _breakID;
__var _result;
execUserSetup()
{
/* Set up immediate breakpoints. */
_breakID = __setSimBreak("addResult", "R", "addAccess()");
_breakID = __setSimBreak("subResult", "R", "subAccess()");
_breakID = __setSimBreak("mulResult", "R", "mulAccess()");
}
Done()
{
if (_result == testExpected)
{
__message "-- C-SPY TEST:", testName, ". Result: PASS";
} else {
__message "-- C-SPY TEST:", testName, ". Expected: ", testExpected, " Result: FAIL";
}
}
addAccess()
{
if (testName == "test_add")
{
_result = addResult;
Done();
}
}
subAccess()
{
if (testName == "test_sub")
{
_result = subResult;
Done();
}
}
mulAccess()
{
if (testName == "test_mul")
{
_result = mulResult;
Done();
}
}

17
examples/avr/using-libs/lib/CMakeLists.txt

@ -1,17 +0,0 @@
# The top-level CMakeLists.txt add this subdirectory
# This CMakeLists.txt builds the target "myMath" library
add_library(myMath
add.c
sub.c
mul.c )
# Set the compiler flags for the "myMath" target
target_compile_options(myMath PUBLIC
$<$<COMPILE_LANGUAGE:C>:--enhanced_core -ms -y --initializers_in_flash --dlib --dlib_config ${TOOLKIT_DIR}/lib/dlib/dlAVR-3s-ec_mul-n.h>
-v3 )
# Define headers for the target
# PUBLIC headers are used for building the library
# PRIVATE sources, only used in this target
target_include_directories(myMath
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/.> )

5
examples/avr/using-libs/lib/add.c

@ -1,5 +0,0 @@
#include "myMath.h"
int add(int a, int b) {
return a + b;
}

5
examples/avr/using-libs/lib/mul.c

@ -1,5 +0,0 @@
#include "myMath.h"
int mul(int a, int b) {
return a * b;
}

6
examples/avr/using-libs/lib/myMath.h

@ -1,6 +0,0 @@
#ifndef MY_MATH_H
#define MY_MATH_H
int add(int a, int b);
int sub(int a, int b);
int mul(int a, int b);
#endif

5
examples/avr/using-libs/lib/sub.c

@ -1,5 +0,0 @@
#include "myMath.h"
int sub(int a, int b) {
return a - --b; /* bug */
}

51
examples/iar-toolchain.cmake

@ -1,51 +0,0 @@
# Toolchain File for the IAR C/C++ Compiler
# Action: Set the `TOOLKIT` variable
# Examples: arm, riscv, rh850, rl78, rx, stm8, 430, 8051, avr or v850
# Alternative: override the default TOOLKIT_DIR (/path/to/installation/<arch>)
set(TOOLKIT arm)
# Get the toolchain target from the TOOLKIT
get_filename_component(CMAKE_SYSTEM_PROCESSOR ${TOOLKIT} NAME)
# Set CMake for cross-compiling
set(CMAKE_SYSTEM_NAME Generic)
# IAR C Compiler
find_program(CMAKE_C_COMPILER
NAMES icc${CMAKE_SYSTEM_PROCESSOR}
PATHS ${TOOLKIT}
"$ENV{ProgramFiles}/IAR Systems/*"
"$ENV{ProgramFiles\(x86\)}/IAR Systems/*"
/opt/iarsystems/bx${CMAKE_SYSTEM_PROCESSOR}
PATH_SUFFIXES bin ${CMAKE_SYSTEM_PROCESSOR}/bin
REQUIRED )
# IAR C++ Compiler
find_program(CMAKE_CXX_COMPILER
NAMES icc${CMAKE_SYSTEM_PROCESSOR}
PATHS ${TOOLKIT}
"$ENV{PROGRAMFILES}/IAR Systems/*"
"$ENV{ProgramFiles\(x86\)}/IAR Systems/*"
/opt/iarsystems/bx${CMAKE_SYSTEM_PROCESSOR}
PATH_SUFFIXES bin ${CMAKE_SYSTEM_PROCESSOR}/bin
REQUIRED )
# IAR Assembler
find_program(CMAKE_ASM_COMPILER
NAMES iasm${CMAKE_SYSTEM_PROCESSOR} a${CMAKE_SYSTEM_PROCESSOR}
PATHS ${TOOLKIT}
"$ENV{PROGRAMFILES}/IAR Systems/*"
"$ENV{ProgramFiles\(x86\)}/IAR Systems/*"
/opt/iarsystems/bx${CMAKE_SYSTEM_PROCESSOR}
PATH_SUFFIXES bin ${CMAKE_SYSTEM_PROCESSOR}/bin
REQUIRED )
# Avoids running the linker during try_compile()
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
# Set the TOOLKIT_DIR variable for the CMakeLists
get_filename_component(BIN_DIR ${CMAKE_C_COMPILER} DIRECTORY)
get_filename_component(TOOLKIT_DIR ${BIN_DIR} PATH)
unset(BIN_DIR)

32
examples/libs/CMakeLists.txt

@ -0,0 +1,32 @@
cmake_minimum_required(VERSION 3.20)
project(Libs LANGUAGES C)
add_executable(libs)
target_sources(libs PRIVATE main.c)
# TODO 4: Add the `lib` subdirectory (contains the `lib` target)
add_subdirectory()
# TODO 5: Link the `lib` against `libs`
target_link_libraries()
target_link_options(libs PRIVATE --semihosting)
enable_testing()
add_test(NAME libs-test
COMMAND /opt/iarsystems/bxarm/common/bin/CSpyBat
# C-SPY drivers for the Arm simulator via command line interface
/opt/iarsystems/bxarm/arm/bin/libarmPROC.so
/opt/iarsystems/bxarm/arm/bin/libarmSIM2.so
--plugin=/opt/iarsystems/bxarm/arm/bin/libarmLibsupportUniversal.so
# The target executable (built with debug information)
--debug_file=$<TARGET_FILE:libs>
# C-SPY driver options
--backend
--cpu=cortex-m4
--semihosting)
set_tests_properties(libs-test PROPERTIES PASS_REGULAR_EXPRESSION "2843410253")

8
examples/libs/lib/CMakeLists.txt

@ -0,0 +1,8 @@
# TODO 1: Add a library target named `lib`
add_library()
# TODO 2: Configure the `lib` target sources
target_sources()
# TODO 3: Using the `PUBLIC` scope, expose the `lib` headers (inc) to other targets
target_include_directories()

8
examples/libs/lib/inc/crc32.h

@ -0,0 +1,8 @@
#ifndef _FAST_CRC32_H_
#define _FAST_CRC32_H_
#include <stdint.h>
uint32_t Fast_CRC32(uint32_t crc, uint32_t const* data, uint32_t words);
#endif /* _FAST_CRC32_H_ */

33
examples/libs/lib/src/crc32.c

@ -0,0 +1,33 @@
#include <stdint.h>
#include "crc32.h"
#define CRC32_POLY 0x04C11DB7
/**
* @brief Fast CRC32 software implementation
* @retval CRC32 equivalent to STM32F407 HW-CRC
*/
uint32_t Fast_CRC32(uint32_t crc, uint32_t const* data, uint32_t words)
{
const uint32_t crc32NibbleLUT[16] = {
0x00000000,CRC32_POLY,0x09823B6E,0x0D4326D9,
0x130476DC,0x17C56B6B,0x1A864DB2,0x1E475005,
0x2608EDB8,0x22C9F00F,0x2F8AD6D6,0x2B4BCB61,
0x350C9B64,0x31CD86D3,0x3C8EA00A,0x384FBDBD, };
while (words--)
{
crc = crc ^ *data++;
/* 8 rounds * 4-bit(nibble) = 32 bit(word) */
crc = (crc << 4) ^ crc32NibbleLUT[crc >> 28];
crc = (crc << 4) ^ crc32NibbleLUT[crc >> 28];
crc = (crc << 4) ^ crc32NibbleLUT[crc >> 28];
crc = (crc << 4) ^ crc32NibbleLUT[crc >> 28];
crc = (crc << 4) ^ crc32NibbleLUT[crc >> 28];
crc = (crc << 4) ^ crc32NibbleLUT[crc >> 28];
crc = (crc << 4) ^ crc32NibbleLUT[crc >> 28];
crc = (crc << 4) ^ crc32NibbleLUT[crc >> 28];
}
return crc;
}

10
examples/libs/main.c

@ -0,0 +1,10 @@
#include <stdio.h>
#include "crc32.h"
__root const uint32_t data[4] = { 0x00010203, 0x04050607, 0x08090A0B, 0x0C0D0E0F };
void main() {
uint32_t const * p = data;
printf("%u\n",Fast_CRC32(0xFFFFFFFF, p, 4));
}

28
examples/mix/CMakeLists.txt

@ -0,0 +1,28 @@
cmake_minimum_required(VERSION 3.20)
# TODO 1: Enable Assembly (ASM) for the project
project(Mix LANGUAGES C)
add_executable(mix)
# TODO 2: Add `fun.s` source to the `mix` target
target_sources(mix PRIVATE main.c)
target_link_options(mix PRIVATE --semihosting)
enable_testing()
add_test(NAME mix-test
COMMAND /opt/iarsystems/bxarm/common/bin/CSpyBat
# C-SPY drivers for the Arm simulator via command line interface
/opt/iarsystems/bxarm/arm/bin/libarmPROC.so
/opt/iarsystems/bxarm/arm/bin/libarmSIM2.so
--plugin=/opt/iarsystems/bxarm/arm/bin/libarmLibsupportUniversal.so
# The target executable (built with debug information)
--debug_file=$<TARGET_FILE:mix>
# C-SPY driver options
--backend
--cpu=cortex-m4
--semihosting)
set_tests_properties(mix-test PROPERTIES PASS_REGULAR_EXPRESSION "42")

4
examples/mix/fun.h

@ -0,0 +1,4 @@
#ifndef FUN_H
#define FUN_H
extern int fun();
#endif

43
examples/mix/fun.s

@ -0,0 +1,43 @@
/* This Assembly source file implements
fun() for multiple target architectures */
NAME fun
PUBLIC _fun
PUBLIC fun
#if defined(__IASMARM__)
SECTION `.text`:CODE:NOROOT(1)
THUMB
#elif defined(__IASMAVR__)
RSEG CODE:CODE:NOROOT(1)
#elif defined(__IASMRISCV__)
SECTION `.text`:CODE:REORDER:NOROOT(2)
CODE
#elif defined(__IASMRL78__) || defined(__IASMRX__)
SECTION `.text`:CODE:NOROOT(0)
CODE
#endif
_fun:
fun:
#if defined(__IASMARM__)
MOVS R0, #+0x2A
BX LR
#elif defined(__IASMAVR__)
LDI R16, 42
LDI R17, 0
RET
#elif defined(__IASMRISCV__)
LI12 A0, 0x2A
RET
#elif defined(__IASMRL78__)
MOVW AX, #0x2A
RET
#elif defined(__IASMRX__)
MOV.L #0x2A, R1
RTS
#endif
END

7
examples/mix/main.c

@ -0,0 +1,7 @@
#include <stdio.h>
#include "fun.h"
void main() {
printf("%d\n", fun());
}

28
examples/rh850/iar-cspy-rh850.cmake

@ -1,28 +0,0 @@
# Example for creating a test for CTest
# to execute the `IAR C-SPY Command-line Utility (cspybat.exe)`
function(iar_cspy_add_test TARGET TEST_NAME EXPECTED_OUTPUT)
# Add a test for CTest
add_test(NAME ${TEST_NAME}
COMMAND ${TOOLKIT_DIR}/../common/bin/cspybat --silent
# C-SPY drivers
"${TOOLKIT_DIR}/bin/${CMAKE_SYSTEM_PROCESSOR}proc.dll"
"${TOOLKIT_DIR}/bin/${CMAKE_SYSTEM_PROCESSOR}sim.dll"
"--plugin=${TOOLKIT_DIR}/bin/${CMAKE_SYSTEM_PROCESSOR}bat.dll"
--debug_file=$<TARGET_FILE:${TARGET}>
# C-SPY macros settings
"--macro=${CMAKE_CURRENT_SOURCE_DIR}/${TARGET}.mac"
"--macro_param=testName=\"${TEST_NAME}\""
"--macro_param=testExpected=${EXPECTED_OUTPUT}"
# C-SPY backend setup
--backend
-p $<IF:$<BOOL:$<TARGET_PROPERTY:${TARGET},DDF>>,$<TARGET_PROPERTY:${TARGET},DDF>,${TOOLKIT_DIR}/config/debugger/ior7f701401.ddf>
--core=$<IF:$<BOOL:$<TARGET_PROPERTY:${TARGET},CPU>>,$<TARGET_PROPERTY:${TARGET},CPU>,g3m>
--fpu double
--double=64
-d sim
--multicore_nr_of_cores=1 )
# Set the test to interpret a C-SPY's message containing `PASS`
set_tests_properties(${TEST_NAME} PROPERTIES PASS_REGULAR_EXPRESSION "PASS")
endfunction()

16
examples/rh850/iar-functions.cmake

@ -1,16 +0,0 @@
# CMake functions for the IAR Build Tools
# Convert the ELF output to .hex
function(iar_elf_tool_hex TARGET)
add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_IAR_ELFTOOL} --silent --ihex $<TARGET_FILE:${TARGET}> $<IF:$<BOOL:$<TARGET_PROPERTY:${TARGET},OUTPUT_NAME>>,$<TARGET_PROPERTY:${TARGET},OUTPUT_NAME>,$<TARGET_PROPERTY:${TARGET},NAME>>.hex)
endfunction()
# Convert the ELF output to .srec
function(iar_elf_tool_srec TARGET)
add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_IAR_ELFTOOL} --silent --srec $<TARGET_FILE:${TARGET}> $<IF:$<BOOL:$<TARGET_PROPERTY:${TARGET},OUTPUT_NAME>>,$<TARGET_PROPERTY:${TARGET},OUTPUT_NAME>,$<TARGET_PROPERTY:${TARGET},NAME>>.srec)
endfunction()
# Convert the ELF output to .bin
function(iar_elf_tool_bin TARGET)
add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_IAR_ELFTOOL} --silent --bin $<TARGET_FILE:${TARGET}> $<IF:$<BOOL:$<TARGET_PROPERTY:${TARGET},OUTPUT_NAME>>,$<TARGET_PROPERTY:${TARGET},OUTPUT_NAME>,$<TARGET_PROPERTY:${TARGET},NAME>>.bin)
endfunction()

43
examples/rh850/mix-c-asm/CMakeLists.txt

@ -1,43 +0,0 @@
cmake_minimum_required(VERSION 3.22)
# Set the project name, [description] and [version],
# while enabling its required languages
project(Example1
DESCRIPTION "Mixing C and Assembly"
VERSION 1.0.0
LANGUAGES C ASM )
# Fallback option for generators other than `Ninja Multi-Config`
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug)
endif()
# Enable CTest
enable_testing()
# Add the executable for the "mixLanguages" target
add_executable(mixLanguages
# Source files
main.c
mynum.asm )
# Set a preprocessor symbol, usable from "mixLanguages" target
target_compile_definitions(mixLanguages PUBLIC USE_ASM=1)
# Set compile options for the target
target_compile_options(mixLanguages PRIVATE
$<$<COMPILE_LANGUAGE:C>:--lock_global_pointer_regs=0 --dlib_config ${TOOLKIT_DIR}/lib/DLib_Config_Normal.h>
--core g3m --fpu=double --double=64 --data_model medium )
# Set the link options for the target
target_link_options(mixLanguages PRIVATE
$<$<CONFIG:Debug>:--debug_lib --redirect ___write=___write_buffered>
--config ${TOOLKIT_DIR}/config/lnkr7f701401.icf
# The `SHELL:` prefix prevents option de-duplication
"SHELL:--config_def CSTACK_SIZE=0x1000"
"SHELL:--config_def HEAP_SIZE=0x1000"
"SHELL:--config_def _SELF_SIZE=0x20000" )
# Optional: test the project with CTest and IAR C-SPY
include(../iar-cspy-rh850.cmake)
iar_cspy_add_test(mixLanguages test_mynum 42)

23
examples/rh850/mix-c-asm/main.c

@ -1,23 +0,0 @@
#include <stdio.h>
#include "mynum.h"
int answer;
int main(void)
{
#if USE_ASM
answer = mynum();
#else
answer = 10;
#endif
/* NDEBUG is set automatically for when
bulding with -DCMAKE_BUILD_TYPE=Release */
#ifndef NDEBUG
printf("-- app debug output begin --\n");
printf("mixLanguages v%d.%d.%d\n", 1, 0, 0);
printf("The answer is: %d.\n",answer);
printf("-- app debug output end --\n");
#endif
return 0;
}

33
examples/rh850/mix-c-asm/mixLanguages.mac

@ -1,33 +0,0 @@
__param testName;
__param testExpected;
__var _breakID;
__var _result;
execUserSetup()
{
__message "C-SPY TEST: started...";
__message "C-SPY TEST: When the `answer` variable is read, `checkanswer()` will execute.";
_breakID = __setSimBreak("answer", "R", "checkAnswer()");
}
Done()
{
__message "-- C-SPY TEST: Done()";
if (_result == testExpected)
{
__message "-- C-SPY TEST:", testName, ". Result: PASS";
} else {
__message "-- C-SPY TEST:", testName, ". Expected: ", testExpected, " Result: FAIL";
}
}
checkAnswer()
{
__message "-- C-SPY TEST: checkAnswer()";
if (testName == "test_mynum")
{
_result = answer;
Done();
}
}

19
examples/rh850/mix-c-asm/mynum.asm

@ -1,19 +0,0 @@
NAME mynum
#define SHT_PROGBITS 0x1
PUBLIC _mynum
SECTION `.text`:CODE:NOROOT(2)
CODE
_mynum:
MOV 42,r10
JMP [lp]
SECTION `.iar_vfe_header`:DATA:NOALLOC:NOROOT(2)
SECTION_TYPE SHT_PROGBITS, 0
DATA
DC32 0
END

4
examples/rh850/mix-c-asm/mynum.h

@ -1,4 +0,0 @@
#ifndef MYNUM_H
#define MYNUM_H
extern int mynum();
#endif

18
examples/rh850/using-libs/CMakeLists.txt

@ -1,18 +0,0 @@
cmake_minimum_required (VERSION 3.22)
project (Example2
DESCRIPTION "Creating and using libraries"
VERSION 1.0.0
LANGUAGES C )
# Fallback option for generators other than `Ninja Multi-Config`
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug)
endif()
# Enable CTest
enable_testing()
# Recurse into the "lib" and "app" subdirectiories
add_subdirectory(lib)
add_subdirectory(app)

42
examples/rh850/using-libs/app/CMakeLists.txt

@ -1,42 +0,0 @@
# Add the executable for the "myProgram" target,
# specifying its source files
add_executable (myProgram
# Source files
main.c )
# Set the properties for the "myProgram" target
set_target_properties(myProgram PROPERTIES
CPU g3m
ICF "${TOOLKIT_DIR}/config/lnkr7f701401.icf"
# C-SPY-related properties
DDF "${TOOLKIT_DIR}/config/debugger/ior7f701401.ddf" )
# Set compile options for the target
target_compile_options(myProgram PRIVATE
$<$<COMPILE_LANGUAGE:C,CXX>:--lock_global_pointer_regs=0 --dlib_config ${TOOLKIT_DIR}/lib/DLib_Config_Normal.h>
--core $<TARGET_PROPERTY:CPU> --fpu=double --double=64 --data_model medium )
# Set the link options for the target
target_link_options(myProgram PRIVATE
$<$<CONFIG:Debug>:--debug_lib --redirect ___write=___write_buffered>
# Create a map file from the target's ELF
--map $<TARGET_PROPERTY:NAME>.map
# The `SHELL:` prefix prevents option de-duplication
"SHELL:--config_def CSTACK_SIZE=0x1000"
"SHELL:--config_def HEAP_SIZE=0x1000"
"SHELL:--config_def _SELF_SIZE=0x20000"
# Set the linker script
--config $<TARGET_PROPERTY:ICF> )
# Link "myProgram" against the "myMath" library
target_link_libraries(myProgram LINK_PUBLIC myMath)
# Optional: convert the output to .hex format
include(../../iar-functions.cmake)
iar_elf_tool_hex(myProgram)
# Optional: test the project with CTest and IAR C-SPY
include(../../iar-cspy-rh850.cmake)
iar_cspy_add_test(myProgram test_add 42)
iar_cspy_add_test(myProgram test_sub 38)
iar_cspy_add_test(myProgram test_mul 80)

29
examples/rh850/using-libs/app/main.c

@ -1,29 +0,0 @@
#ifndef NDEBUG
#include <stdio.h>
#endif
#include <stdlib.h>
#include "myMath.h"
int a = 40, b = 2;
int addResult;
int subResult;
int mulResult;
int main(void)
{
addResult = add(a, b);
subResult = sub(a, b);
mulResult = mul(a, b);
/* In CMake, the NDEBUG preprocessor symbol
is set automatically when the build configuration is set for Release */
#ifndef NDEBUG
printf("-- app debug output begin --\n");
printf("%d + %d = %d\n", a, b, addResult);
printf("%d - %d = %d\n", a, b, subResult);
printf("%d * %d = %d\n", a, b, mulResult);
printf("-- app debug output end --\n");
#endif
return 0;
}

51
examples/rh850/using-libs/app/myProgram.mac

@ -1,51 +0,0 @@
__param testName;
__param testExpected;
__var _breakID;
__var _result;
execUserSetup()
{
/* Set up immediate breakpoints. */
_breakID = __setSimBreak("addResult", "R", "addAccess()");
_breakID = __setSimBreak("subResult", "R", "subAccess()");
_breakID = __setSimBreak("mulResult", "R", "mulAccess()");
}
Done()
{
if (_result == testExpected)
{
__message "-- C-SPY TEST:", testName, ". Result: PASS";
} else {
__message "-- C-SPY TEST:", testName, ". Expected: ", testExpected, " Result: FAIL";
}
}
addAccess()
{
if (testName == "test_add")
{
_result = addResult;
Done();
}
}
subAccess()
{
if (testName == "test_sub")
{
_result = subResult;
Done();
}
}
mulAccess()
{
if (testName == "test_mul")
{
_result = mulResult;
Done();
}
}

16
examples/rh850/using-libs/lib/CMakeLists.txt

@ -1,16 +0,0 @@
# The top-level CMakeLists.txt add this subdirectory
# This CMakeLists.txt builds the target "myMath" library
add_library(myMath
add.c
sub.c
mul.c )
# Set the compiler flags for the "myMath" target
target_compile_options(myMath PUBLIC
$<$<COMPILE_LANGUAGE:C>:--core g3m --double=64 --data_model medium --dlib_config ${TOOLKIT_DIR}/lib/DLib_Config_Normal.h> )
# Define headers for the target
# PUBLIC headers are used for building the library
# PRIVATE sources, only used in this target
target_include_directories(myMath
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/.> )

5
examples/rh850/using-libs/lib/add.c

@ -1,5 +0,0 @@
#include "myMath.h"
int add(int a, int b) {
return a + b;
}

5
examples/rh850/using-libs/lib/mul.c

@ -1,5 +0,0 @@
#include "myMath.h"
int mul(int a, int b) {
return a * b;
}

6
examples/rh850/using-libs/lib/myMath.h

@ -1,6 +0,0 @@
#ifndef MY_MATH_H
#define MY_MATH_H
int add(int a, int b);
int sub(int a, int b);
int mul(int a, int b);
#endif

5
examples/rh850/using-libs/lib/sub.c

@ -1,5 +0,0 @@
#include "myMath.h"
int sub(int a, int b) {
return a - --b; /* bug */
}

25
examples/riscv/iar-cspy-riscv.cmake

@ -1,25 +0,0 @@
# Example for creating a test for CTest
# to execute the `IAR C-SPY Command-line Utility (cspybat.exe)`
function(iar_cspy_add_test TARGET TEST_NAME EXPECTED_OUTPUT)
# Add a test for CTest
add_test(NAME ${TEST_NAME}
COMMAND ${TOOLKIT_DIR}/../common/bin/cspybat --silent
# C-SPY drivers
"${TOOLKIT_DIR}/bin/${CMAKE_SYSTEM_PROCESSOR}proc.dll"
"${TOOLKIT_DIR}/bin/${CMAKE_SYSTEM_PROCESSOR}sim.dll"
"--plugin=${TOOLKIT_DIR}/bin/${CMAKE_SYSTEM_PROCESSOR}bat.dll"
--debug_file=$<TARGET_FILE:${TARGET}>
# C-SPY macros settings
"--macro=${CMAKE_CURRENT_SOURCE_DIR}/${TARGET}.mac"
"--macro_param=testName=\"${TEST_NAME}\""
"--macro_param=testExpected=${EXPECTED_OUTPUT}"
# C-SPY backend setup
--backend
-p $<IF:$<BOOL:$<TARGET_PROPERTY:${TARGET},DDF>>,$<TARGET_PROPERTY:${TARGET},DDF>,${TOOLKIT_DIR}/config/debugger/ioriscv.ddf>
--core=$<IF:$<BOOL:$<TARGET_PROPERTY:${TARGET},CPU>>,$<TARGET_PROPERTY:${TARGET},CPU>,RV32IMAC>
-d sim )
# Set the test to interpret a C-SPY's message containing `PASS`
set_tests_properties(${TEST_NAME} PROPERTIES PASS_REGULAR_EXPRESSION "PASS")
endfunction()

16
examples/riscv/iar-functions.cmake

@ -1,16 +0,0 @@
# CMake functions for the IAR Build Tools
# Convert the ELF output to .hex
function(iar_elf_tool_hex TARGET)
add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_IAR_ELFTOOL} --silent --ihex $<TARGET_FILE:${TARGET}> $<IF:$<BOOL:$<TARGET_PROPERTY:${TARGET},OUTPUT_NAME>>,$<TARGET_PROPERTY:${TARGET},OUTPUT_NAME>,$<TARGET_PROPERTY:${TARGET},NAME>>.hex)
endfunction()
# Convert the ELF output to .srec
function(iar_elf_tool_srec TARGET)
add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_IAR_ELFTOOL} --silent --srec $<TARGET_FILE:${TARGET}> $<IF:$<BOOL:$<TARGET_PROPERTY:${TARGET},OUTPUT_NAME>>,$<TARGET_PROPERTY:${TARGET},OUTPUT_NAME>,$<TARGET_PROPERTY:${TARGET},NAME>>.srec)
endfunction()
# Convert the ELF output to .bin
function(iar_elf_tool_bin TARGET)
add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${CMAKE_IAR_ELFTOOL} --silent --bin $<TARGET_FILE:${TARGET}> $<IF:$<BOOL:$<TARGET_PROPERTY:${TARGET},OUTPUT_NAME>>,$<TARGET_PROPERTY:${TARGET},OUTPUT_NAME>,$<TARGET_PROPERTY:${TARGET},NAME>>.bin)
endfunction()

41
examples/riscv/mix-c-asm/CMakeLists.txt

@ -1,41 +0,0 @@
cmake_minimum_required(VERSION 3.22)
# Set the project name, [description] and [version],
# while enabling its required languages
project(Example1
DESCRIPTION "Mixing C and Assembly"
VERSION 1.0.0
LANGUAGES C ASM )
# Fallback option for generators other than `Ninja Multi-Config`
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug)
endif()
# Enable CTest
enable_testing()
# Add the executable for the "mixLanguages" target
add_executable(mixLanguages
# Source files
main.c
mynum.asm )
# Set a preprocessor symbol, usable from the "mixLanguages" target
target_compile_definitions(mixLanguages PUBLIC USE_ASM=1)
# Set compile options for the target
target_compile_options(mixLanguages PRIVATE
$<$<COMPILE_LANGUAGE:C>:--dlib_config normal>
--core=RV32IMAFDC )
# Set the link options for the target
target_link_options(mixLanguages PRIVATE
$<$<CONFIG:Debug>:--debug_lib --redirect ___write=___write_buffered>
# The `SHELL:` prefix prevents option de-duplication
"SHELL:--config_def CSTACK_SIZE=0x1000"
"SHELL:--config_def HEAP_SIZE=0x1000" )
# Optional: test the project with CTest and IAR C-SPY
include(../iar-cspy-riscv.cmake)
iar_cspy_add_test(mixLanguages test_mynum 42)

23
examples/riscv/mix-c-asm/main.c

@ -1,23 +0,0 @@
#include <stdio.h>
#include "mynum.h"
int answer;
int main(void)
{
#if USE_ASM
answer = mynum();
#else
answer = 10;
#endif
/* NDEBUG is set automatically for when
bulding with -DCMAKE_BUILD_TYPE=Release */
#ifndef NDEBUG
printf("-- app debug output begin --\n");
printf("mixLanguages v%d.%d.%d\n", 1, 0, 0);
printf("The answer is: %d.\n",answer);
printf("-- app debug output end --\n");
#endif
return 0;
}

33
examples/riscv/mix-c-asm/mixLanguages.mac

@ -1,33 +0,0 @@
__param testName;
__param testExpected;
__var _breakID;
__var _result;
execUserSetup()
{
__message "C-SPY TEST: started...";
__message "C-SPY TEST: When the `answer` variable is read, `checkanswer()` will execute.";
_breakID = __setSimBreak("answer", "R", "checkAnswer()");
}
Done()
{
__message "-- C-SPY TEST: Done()";
if (_result == testExpected)
{
__message "-- C-SPY TEST:", testName, ". Result: PASS";
} else {
__message "-- C-SPY TEST:", testName, ". Expected: ", testExpected, " Result: FAIL";
}
}
checkAnswer()
{
__message "-- C-SPY TEST: checkAnswer()";
if (testName == "test_mynum")
{
_result = answer;
Done();
}
}

16
examples/riscv/mix-c-asm/mynum.asm

@ -1,16 +0,0 @@
#define SHT_PROGBITS 0x1
PUBLIC mynum
SECTION `.text`:CODE:REORDER:NOROOT(2)
CODE
mynum:
li12 a0, 0x2A
ret
SECTION `.iar_vfe_header`:DATA:NOALLOC:NOROOT(2)
SECTION_TYPE SHT_PROGBITS, 0
DATA
DC32 0
END

4
examples/riscv/mix-c-asm/mynum.h

@ -1,4 +0,0 @@
#ifndef MYNUM_H
#define MYNUM_H
extern int mynum();
#endif

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save