Skip to content

Commit

Permalink
Merge pull request #1198 from dav-mac/cmsis_rtx_vs
Browse files Browse the repository at this point in the history
Cmsis rtx vs
  • Loading branch information
jasonrandrews authored Aug 30, 2024
2 parents f184f8d + e1d1eb5 commit cb3e5d7
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ minutes_to_complete: 30
who_is_this_for: This is an introductory topic for software developers new to RTOS development.

learning_objectives:
- Implement a basic RTOS-based application
- Understand the basics of RTX-based RTOS application development
- Configure and manage an RTOS project in Keil Studio, including defining the memory map, selecting software components, and setting up debugging configurations for Cortex-M processors
- Create and manage multiple threads within an RTX5 RTOS application

prerequisites:
- Installation of [Arm Keil Studio for VS Code](/install-guides/keilstudio_vs)
Expand Down
33 changes: 25 additions & 8 deletions content/learning-paths/microcontrollers/cmsis_rtx_vs/_review.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,34 @@


review:
- questions:
question: >
Which function is used to invoke an OS thread?
- questions:
- question: >
Which function is used to invoke an OS thread?
answers:
- "osKernelInitialize()"
- "osKernelStart()"
- "osThreadNew()"
- "osKernelInitialize()"
- "osKernelStart()"
- "osThreadNew()"
correct_answer: 3
explanation: >
osThreadNew() is called before osKernelStart() to define the main thread, and then by the main thread to start other threads.
osThreadNew() is called before osKernelStart() to define the main thread, and then by the main thread to start other threads.
- question: >
What is the purpose of the `osKernelStart()` function?
answers:
- "To create the main application thread"
- "To start the RTOS kernel and begins thread switching"
- "To update the system clock"
correct_answer: 2
explanation: >
`osKernelStart()` starts the RTOS kernel and enables thread switching, making it essential for multitasking.
- question: >
What happens if the code execution reaches the infinite while(1) loop in the main function?
answers:
- "All threads are successfully started."
- "Something went wrong, likely with the platform initialization."
- "The RTOS has successfully initialized the kernel."
correct_answer: 2
explanation: >
Reaching the infinite `while(1)` loop in the main function suggests an error occurred during platform initialization.
# ================================================================================
# FIXED, DO NOT MODIFY
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,21 @@ weight: 5 # 1 is first, 2 is second, etc.
# Do not modify these elements
layout: "learningpathall"
---
You are now ready to build and run the application.
You are now ready to build and run your application.

## Build

In the CMSIS Extension view, save all files, and click the hammer icon to build the example.
In the CMSIS Extension view, save all your files. Then, click the hammer icon to build the example.

## Debug

Click the `Debug` icon, or enter the `Run and Debug` extension view.
To start debugging, click the `Debug` icon, or enter the `Run and Debug` extension view.

Select the debug connection previously configured to launch the FVP.
Choose the debug connection you configured earlier to launch the FVP (Fixed Virtual Platform).

Use the controls to step through the code.
Use the debugging controls to step through your code.

Once the OS is initialized, the output from the threads is displayed in the `Debug Console`.
Once the OS is initialized, you will see the output from the threads displayed in the `Debug Console`.

```
[model] hello from thread 1
Expand All @@ -31,10 +31,10 @@ Once the OS is initialized, the output from the threads is displayed in the `Deb
[model] hello from thread 2
...
```
Click `Stop` (`Ctrl`+`F5`) to terminate the debug session.
To end the debug session, click `Stop` or press `Ctrl`+`F5`.

{{% notice Note%}}
For a more feature rich debug environment, it is recommended to use `Arm Keil μVision IDE`.
For a more feature-rich debugging environment, consider using the `Arm Keil μVision IDE`.

See [Build an RTX5 RTOS application with Keil μVision](/learning-paths/microcontrollers/cmsis_rtx/).
For more details, see [Build an RTX5 RTOS application with Keil μVision](/learning-paths/microcontrollers/cmsis_rtx/).
{{% /notice %}}
75 changes: 33 additions & 42 deletions content/learning-paths/microcontrollers/cmsis_rtx_vs/create.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,62 +7,55 @@ weight: 2 # 1 is first, 2 is second, etc.
# Do not modify these elements
layout: "learningpathall"
---
This learning path will introduce the steps to create a basic RTX based RTOS application, making use of the latest features of [CMSIS](https://www.keil.arm.com/cmsis).
This learning path will introduce the steps to create a basic RTX-based RTOS application using the latest features of [CMSIS](https://www.keil.arm.com/cmsis).

For more information on the latest update, see the [CMSIS v6 is here](https://community.arm.com/arm-community-blogs/b/tools-software-ides-blog/posts/cmsis-v6-is-here) blog.

You will use [Keil Studio for VS Code](/install-guides/keilstudio_vs) in this Learning Path.
You will use **[Keil Studio for VS Code](/install-guides/keilstudio_vs)** in this Learning Path.

This Learning Path is written for the supplied (Cortex-M4) Fixed Virtual Platform (FVP), however it could be run on any of the 10000+ devices supported by [CMSIS-Pack](https://www.open-cmsis-pack.org/).
This Learning Path is written for the supplied **Cortex-M4 Fixed Virtual Platform (FVP)**, but you can run it on any of the 10,000+ devices supported by [CMSIS-Pack](https://www.open-cmsis-pack.org/).

{{% notice Note%}}
If using `Arm Keil μVision IDE` (or `Arm Development Studio`) please go to [Build an RTX5 RTOS application with Keil μVision](/learning-paths/microcontrollers/cmsis_rtx/).
If using `Arm Keil μVision IDE` or Arm Development Studio, refer to the [Build an RTX5 RTOS application with Keil μVision](/learning-paths/microcontrollers/cmsis_rtx/) guide.
{{% /notice %}}

## Create a new project (csolution)
## Create a New Project

Keil Studio projects are based on the [CMSIS Solution](https://github.com/Open-CMSIS-Pack/cmsis-toolbox/blob/main/docs/YML-Input-Format.md) standard.

Open the `VS Code` IDE, and select `File` > `New File` from the `File` menu. (`Ctrl`+`Alt`+`Windows`+`N`). You will be prompted for the type of file. Select `New Solution` (`Arm CMSIS Solution`).
1. Open the VS Code IDE, and select `File` > `New File` from the `File` menu. You will be prompted for the type of file. Select `New Solution` (`Arm CMSIS Solution`).
2. The `Create New Solution` window will open. Click the `Target Device` pulldown, and search for `ARMCM4`.
3. From the `Templates, Reference Applications, and Examples` pulldown, select `Blank Solution`.
4. Ensure `Arm Compiler 6` is the selected compiler.
5. Enter an appropriate `Solution Name`. This will define the folder name that the project will be created into. You can also change the folder location if necessary.
6. Click `Create`. You will be prompted to open the solution in the current window, or open a new window.

The `Create New Solution` window will open. Click the `Target Device` pulldown, and search for `ARMCM4`.

From the `Templates, Reference Applications, and Examples` pulldown, select `Blank Solution`.

Ensure `Arm Compiler 6` is the selected compiler.

Enter an appropriate `Solution Name`. This will define the folder name that the project will be created into. You can also change the folder location if necessary.

Click `Create`. You will be prompted to open the solution in the current window, or open a new window.

## Configure solution environment
## Configure the Solution Environment

VS Code allows complete configurability of all aspects of the project.

Locate `vcpkg-configuration.json` within the project. This file defines the components used.
- Locate `vcpkg-configuration.json` within the project. This file defines the components used.
- Right-click on this file, and select `Configure Arm Tools Environment` to open the configuration panel.

Right-click on this file, and select `Configure Arm Tools Environment` to open the configuration panel.
From the dropdown menus, make sure to select the most up-to-date versions of the following:

From the various pull-downs, ensure that the most up to date versions of the following are selected:
- Arm CMSIS-Toolbox
- Arm Compiler for Embedded
- Arm Debugger
- Arm Virtual Hardware for Cortex-M based on Fast Models
- Kitware's CMake tool
- Ninja Build

* Arm CMSIS-Toolbox
* Arm Compiler for Embedded
* Arm Debugger
* Arm Virtual Hardware for Cortex-M based on Fast Models
* Kitware's cmake tool
* Ninja Build
Set all other tools to **None** as they are not needed for this example.

Others can be set as `None` as they are not needed for this example.

If you open `vcpkg-configuration.json` in the text editor you will see these set as selected. Close the file to save.
If you open `vcpkg-configuration.json` in the text editor, you’ll see these selections reflected. Close the file to save your changes.

All necessary components will be downloaded and installed as necessary (if not already installed).

## Configure CMSIS options

Select `CMSIS` from the Extensions icon list. You will see the project structure.
## Configure CMSIS Options

Move cursor over the top-level `Project`, and click on `Manage Software Components`. This is the view to add CMSIS Software Packs to your project.
1. Select **CMSIS** from the Extensions icon list in VS Code. You will see the project structure.
2. Hover over the top-level project and click **Manage Software Components** to add CMSIS Software Packs to your project.

Enable the following components:
* `CMSIS > Core`
Expand All @@ -76,7 +69,7 @@ If prompted in the `Validation` pane, select the latest available version for ea

Close this view to save.

## Define memory map
## Define the Memory Map

Use [scatter-loading](https://developer.arm.com/documentation/101754/latest/armlink-Reference/Scatter-loading-Features/The-scatter-loading-mechanism/Overview-of-scatter-loading) to define the memory map to the linker.

Expand All @@ -102,18 +95,16 @@ LOAD 0x0 0x400000 {
}
```

## Configure debug with the FVP

Select `Run and Debug` from the Extensions icon list.

Click the gear icon to open `launch.json`. This is the file that defines the debug instance.
## Configure Debug with the FVP

Right-click on `launch.json` and select `Open Run and Debug Configuration`.
1. Select `Run and Debug` from the Extensions icon list.
2. Click the gear icon to open `launch.json`. This is the file that defines the debug instance.
3. Right-click on `launch.json` and select `Open Run and Debug Configuration`.

From the `Selected Configuration` pull-down, select `New Configuration` > `Launch FVP`. Edit the `Configuration Name` if desired.

From the `Target` > `Configuration Database Entry` pull-down, select `MPS2_Cortex_M4` > `Cortex-M4`.

Other fields can be left as default. Observe that `launch.json` has been updated.
Leave other fields as default. Observe that `launch.json` has been updated.

Close the file to save.
Close the file to save your configuration.
28 changes: 15 additions & 13 deletions content/learning-paths/microcontrollers/cmsis_rtx_vs/initialize.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
---
# User change
title: "Initialize the operating system"
title: "Initialize the Operating System"

weight: 3 # 1 is first, 2 is second, etc.

# Do not modify these elements
layout: "learningpathall"
---
[Keil RTX5](https://www2.keil.com/mdk5/cmsis/rtx) is quite a feature rich real-time operating system (RTOS). CMSIS and the [CMSIS-RTOS2](https://arm-software.github.io/CMSIS_5/RTOS2/html/index.html) API makes it very easy to work with.
[Keil RTX5](https://www2.keil.com/mdk5/cmsis/rtx) is a feature-rich real-time operating system (RTOS). CMSIS and the [CMSIS-RTOS2](https://arm-software.github.io/CMSIS_5/RTOS2/html/index.html) API makes it easy to work with.

When setting up the project Run-time environment, the appropriate system initialization code (`C Startup`) was added.
When setting up the project's Run-Time Environment, ensure you add the appropriate system initialization code (`C Startup`).

From there, the `RTX5` initialization code is always essentially the same, setting up the `SysTick` timer with the [SystemCoreClockUpdate()](https://www.keil.com/pack/doc/CMSIS/Core/html/group__system__init__gr.html#gae0c36a9591fe6e9c45ecb21a794f0f0f) function, then initializing and starting the RTOS.
Once this is done, the `RTX5` initialization code is typically the same. It involves setting up the `SysTick` timer with the [SystemCoreClockUpdate()](https://www.keil.com/pack/doc/CMSIS/Core/html/group__system__init__gr.html#gae0c36a9591fe6e9c45ecb21a794f0f0f) function, then initializing and starting the RTOS.

## Create main()
## Create `main()`

Return to the `CMSIS` view.

Within the `Source Files` Group, a `main.c` is automatically created. Click on the file to open in text editor.
Within the `Source Files` group, a `main.c` is automatically created. Click on the file to open it in the text editor.

Delete any auto created code therein, and add the following.
Delete any auto-generated code and replace it with the following:

```C
#include "RTE_Components.h"
Expand All @@ -42,16 +42,18 @@ int __attribute__((noreturn)) main (void) {
}
```
## Understanding the code
## Understanding the Code
The function [osKernelStart()](https://arm-software.github.io/CMSIS_6/latest/RTOS2/group__CMSIS__RTOS__KernelCtrl.html#ga9ae2cc00f0d89d7b6a307bba942b5221) should never return.
The function [osKernelStart()](https://arm-software.github.io/CMSIS_6/latest/RTOS2/group__CMSIS__RTOS__KernelCtrl.html#ga9ae2cc00f0d89d7b6a307bba942b5221) is designed to never return.
If your code gets to the infinite `while()` loop, something has gone wrong - most likely with the platform initialization code.
If your code reaches the infinite `while()` loop, something has gone wrong - most likely with the platform initialization code.
All threads use a prototype of the form:
All threads should follow a prototype like this:
```C
void thread(void *);
```
where the argument is passed as the second parameter of the [osThreadNew()](https://arm-software.github.io/CMSIS_6/latest/RTOS2/group__CMSIS__RTOS__ThreadMgmt.html#ga48d68b8666d99d28fa646ee1d2182b8f) function. Use `NULL` if no argument to pass.
The argument for this function is provided as the second parameter of the [osThreadNew()](https://arm-software.github.io/CMSIS_6/latest/RTOS2/group__CMSIS__RTOS__ThreadMgmt.html#ga48d68b8666d99d28fa646ee1d2182b8f) function. Use `NULL` if no argument to pass.

In the above, `app_main` is used as the main application thread, but this naming is arbitrary. From here, you shall spawn all other threads of the RTOS.
In the example above, `app_main` is used as the main application thread, but this naming is arbitrary. From here, you will spawn all other threads in the RTOS.

{{% notice %}} Tip: Naming the main application thread is flexible. Choose a name that clearly reflects its function. {{% /notice %}}
12 changes: 6 additions & 6 deletions content/learning-paths/microcontrollers/cmsis_rtx_vs/threads.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
---
# User change
title: "Create RTOS threads"
title: "Create RTOS Threads"

weight: 4 # 1 is first, 2 is second, etc.

# Do not modify these elements
layout: "learningpathall"
---
Implement the main RTOS thread (`app_main`), whose role is primarily to start and manage the other threads of the system.
In this step, you will implement the main RTOS thread (`app_main`), which is primarily responsible for starting and managing the other threads in the system.

In this example you shall create 3 threads. The number and naming of the threads is arbitrary.
You will create three threads. The number and naming of the threads are flexible, so feel free to adjust as needed.

## Create app_main
## Create `app_main`

Click on the `+` icon within the `Source Files` Group, and add a new file `app_main.c`. Populate with the below.

Expand All @@ -28,9 +28,9 @@ void app_main (void *argument) {
osThreadNew(thread3, NULL, NULL); // Create thread3
}
```
## Create threads
## Create Threads
You can now implement the functionality of the threads themselves. Start with a simple example. Each thread will say hello, and then pause for a period, forever.
Now you can implement the functionality of the threads themselves. Start with a simple example. Each thread will say hello, and then pause for a period, forever.
Click on the `+` icon within the `Source Files` Group, and add a new file `threads.c`. Populate with the contents below.
Expand Down

0 comments on commit cb3e5d7

Please sign in to comment.