Skip to content

Commit

Permalink
Incorporate review feedback
Browse files Browse the repository at this point in the history
Signed-off-by: Gaurav Aggarwal <[email protected]>
  • Loading branch information
aggarg committed Oct 11, 2021
1 parent 0dab615 commit b6318c4
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 80 deletions.
50 changes: 25 additions & 25 deletions FreeRTOS/Demo/CORTEX_M0+_RP2040/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# Demos for Raspberry Pi Pico Board

This page documents FreeRTOS demo applications that target
This page documents FreeRTOS demo applications that target the
[Raspberry Pi Pico](https://www.raspberrypi.com/products/raspberry-pi-pico/)
board. The Raspberry Pi Pico board uses [RP2040](https://www.raspberrypi.com/documentation/microcontrollers/rp2040.html#welcome-to-rp2040)
microcontroller from [Raspberry Pi](https://www.raspberrypi.com/) which features
board. The Raspberry Pi Pico board uses the [RP2040](https://www.raspberrypi.com/documentation/microcontrollers/rp2040.html#welcome-to-rp2040)
microcontroller from [Raspberry Pi](https://www.raspberrypi.com/) which features a
Dual-core ARM Cortex M0+ processor.

These demo applications use [GNU ARM Embedded Toolchain](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads)
to build the FreeRTOS Raspberry Pi Pico port. These applications demonstrate the [Symmetric
Multiprocessing (SMP)](https://github.com/FreeRTOS/FreeRTOS-Kernel/tree/smp) support in the FreeRTOS Kernel.
These demo applications use the [GNU ARM Embedded Toolchain](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads)
to build the FreeRTOS Raspberry Pi Pico port. They demonstrate support for [Symmetric
Multiprocessing (SMP)](https://github.com/FreeRTOS/FreeRTOS-Kernel/tree/smp) in the FreeRTOS Kernel.

----

Expand Down Expand Up @@ -44,21 +44,21 @@ The blinky demo uses two tasks and one queue.
* The Queue Send Task:

The queue send task is implemented by the `prvQueueSendTask()` function. The
task sits in a loop sending the value 100 to the queue every 1000 milliseconds
task sits in a loop and sends the value 100 to the queue every 1000 milliseconds
(1 second).

* The Queue Receive Task:

The queue receive task is implemented by the `prvQueueReceiveTask()` function.
The task sits in a loop that blocks on attempts to read from the queue
(no CPU cycles are consumed while the task is blocked), toggling an LED each
(no CPU cycles are consumed while the task is blocked), and toggles an LED each
time the value 100 is received from the queue send task. As the queue send
task writes to the queue every 1000 milliseconds, the queue receive task
unblocks and toggles the LED every 1000 milliseconds.

### Comprehensive Demo
The comprehensive demo implements a comprehensive test and demo application that
demonstrates and/or tests (among other things):
The comprehensive demo implements a comprehensive test and demo application that,
among other things, demonstrates and/or tests:

* [Message buffers](https://www.freertos.org/RTOS-stream-message-buffers.html)
* [Stream buffers](https://www.freertos.org/RTOS-stream-message-buffers.html)
Expand All @@ -70,30 +70,30 @@ demonstrates and/or tests (among other things):
* [Software timers](https://www.freertos.org/RTOS-software-timer.html)

The created tasks are from the set of [standard demo](https://www.freertos.org/a00102.html)
tasks. Standard demo tasks are used by all FreeRTOS port demo applications.
They have no specific functionality, and are created just to demonstrate how to
use the FreeRTOS API, and test the RTOS port.
tasks that are used by all FreeRTOS port demo applications. They have no
specific functionality, but are created just to demonstrate how to use the
FreeRTOS API, and test the RTOS port.

A "check" task is created that periodically inspects the standard demo tasks
(which contain self monitoring code) to ensure all the tasks are functioning
as expected. The check task toggles the LED and each time it executes. This
as expected. The check task toggles the LED each time it executes. This
gives visual feedback of the system health. **If the LED is toggling every 3
seconds, then the check task has not discovered any problems. If the LED is
toggling every 200 milliseconds, then the check task has discovered a problem
in one or more tasks.**

### Multicore Demo
The multicore demo application runs FreeRTOS tasks on one core which interact
The multicore demo application runs FreeRTOS tasks on one core which interacts
with the code running on the other core using Raspberry Pico SDK synchronization
primitives. There are two versions of the same demo - One version runs FreeRTOS
on core 0, the other runs FreeRTOS on core 1.

## Building and Running the RTOS Demo Applications

### Building
1. Setup the Raspberry Pi Pico SDK build environment by following
1. Setup the Raspberry Pi Pico SDK build environment by following the instructions for
[Getting Started With Pico](https://datasheets.raspberrypi.org/pico/getting-started-with-pico.pdf).
Ensure that `PICO_SDK_PATH` is set in your environment or pass it via
Ensure that `PICO_SDK_PATH` is set in your environment, or pass it via
`-DPICO_SDK_PATH=xxx` on the CMake command line.
2. Run the following commands:
```sh
Expand All @@ -118,17 +118,17 @@ Storage Device.
----

## RTOS Configuration and Usage Details
* Configuration items specific to blinky and comprehensive demos are contained in
`FreeRTOS/Demo/CORTEX_M0+_RP2040/Standard/FreeRTOSConfig.h` and the ones specific
to multicore demo are contained in `FreeRTOS/Demo/CORTEX_M0+_RP2040/OnEitherCore/FreeRTOSConfig.h`.
* Configuration items specific to the blinky and comprehensive demos are contained in
`FreeRTOS/Demo/CORTEX_M0+_RP2040/Standard/FreeRTOSConfig.h` and those specific
to the multicore demo are contained in `FreeRTOS/Demo/CORTEX_M0+_RP2040/OnEitherCore/FreeRTOSConfig.h`.
The [constants defined in these files](https://www.freertos.org/a00110.html) can be
edited to suit your application. The following configuration options are
specific to the SMP support in FreeRTOS Kernel:
* `configNUM_CORES` - Set number of cores.
* `configRUN_MULTIPLE_PRIORITIES` - Enable/Disable running multiple priorities tasks simultaneously.
* `configUSE_CORE_AFFINITY` - Enable/Disable setting tasks affinity to cores.
specific to the SMP support in the FreeRTOS Kernel:
* `configNUM_CORES` - Set the number of cores.
* `configRUN_MULTIPLE_PRIORITIES` - Enable/Disable simultaneously running tasks with multiple priorities.
* `configUSE_CORE_AFFINITY` - Enable/Disable setting a task's affinity to certain cores.
* `Source/Portable/MemMang/heap_4.c` is included in the project to provide the
memory allocation required by the RTOS kernel. Please refer to the
[Memory Management](https://www.freertos.org/a00111.html) section of the API
documentation for full information.
documentation for complete information.
* vPortEndScheduler() has not been implemented.
26 changes: 13 additions & 13 deletions FreeRTOS/Demo/XCOREAI_xClang/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ started project and a more comprehensive test and demo application.

### When testingmainBLINKY_DEMO is set to 1
When `testingmainBLINKY_DEMO` is set to 1, the demo application creates
two tasks which toggle 2 on-board LEDs (LED 0 and LED 1) periodically.
two tasks which periodically toggle two on-board LEDs (LED 0 and LED 1).

### When testingmainBLINKY_DEMO is set to 0
When `testingmainBLINKY_DEMO` is set to 0, the demo application implements a
Expand All @@ -50,14 +50,14 @@ comprehensive test and demo that demonstrates and/or tests (among other things):

The created tasks are from the set of [standard demo](https://www.freertos.org/a00102.html)
tasks. Standard demo tasks are used by all FreeRTOS port demo applications. They
have no specific functionality, and are created just to demonstrate how to use
have no specific functionality, and were created simply to demonstrate how to use
the FreeRTOS API, and test the RTOS port.

Two "check" tasks are created that periodically inspect the standard demo tasks
Two "check" tasks are created to periodically inspect the standard demo tasks
(which contain self monitoring code) to ensure all the tasks are functioning as
expected. One check task monitors the demo tasks running on tile 0 and toggles
the LED 0 each time it executes. The other check task monitors the demo tasks
running on tile 1 and toggles the LED 1 each time it executes. This gives visual
LED 0 each time it executes. The other check task monitors the demo tasks
running on tile 1 and toggles LED 1 each time it executes. This gives visual
feedback of the system health. **If both the LEDs toggle every 3 seconds, then the
check tasks have not discovered any problems. If any LED toggles every 200ms,
then the check task has discovered a problem in one or more tasks.**
Expand All @@ -71,7 +71,7 @@ Plug the xTAG programmer into the evaluation board. Ensure both the xTAG and
evaluation board are connected to the computer via USB.

### Toolchain installation
1. Download the XMOS XTC Tools from [here](https://www.xmos.ai/software-tools/).
1. Download the [XMOS XTC Tools](https://www.xmos.ai/software-tools/).
2. Uncompress the archive to your chosen installation directory. The example
below will install to your home directory:
```sh
Expand All @@ -87,12 +87,12 @@ $ source SetEnv
$ xcc --help
```
5. Make the XTAG drivers accessible to all users. This step is only required
once on a given development machine.
to be done once on a given development machine.
```sh
$ cd ~/XMOS/XTC/15.1.0/scripts
$ sudo ./setup_xmos_devices.sh
```
6. check that the XTAG devices are available and accessible:
6. Check that the XTAG devices are available and accessible:
```sh
$ cd ~/XMOS/XTC/15.1.0/scripts
$ ./check_xmos_devices.sh
Expand Down Expand Up @@ -134,12 +134,12 @@ $ make run
`FreeRTOS/Demo/XCOREAI_xClang/RTOSDemo/src/FreeRTOSConfig.h`. The
[constants defined in that file](https://www.freertos.org/a00110.html) can be
edited to suit your application. The following configuration options are
specific to the SMP support in FreeRTOS Kernel:
* `configNUM_CORES` - Set number of cores.
* `configRUN_MULTIPLE_PRIORITIES` - Enable/Disable running multiple priorities tasks simultaneously.
* `configUSE_CORE_AFFINITY` - Enable/Disable setting tasks affinity to cores.
specific to the SMP support in the FreeRTOS Kernel:
* `configNUM_CORES` - Set the number of cores.
* `configRUN_MULTIPLE_PRIORITIES` - Enable/Disable simultaneously running tasks with multiple priorities.
* `configUSE_CORE_AFFINITY` - Enable/Disable setting a task's affinity to certain cores.
* `Source/Portable/MemMang/heap_4.c` is included in the project to provide the
memory allocation required by the RTOS kernel. Please refer to the
[Memory Management](https://www.freertos.org/a00111.html) section of the API
documentation for full information.
documentation for complete information.
* vPortEndScheduler() has not been implemented.
35 changes: 18 additions & 17 deletions Porting-to-FreeRTOS-SMP-Kernel.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
The FreeRTOS API remains mostly same between single core and SMP version except
[these additions](SMP.md). Therefore, an application written for FreeRTOS single
core version should compile with SMP version with minimal to no effort. However,
there may be some functional issues as some assumptions which used to be true
for single core may no longer be true for multi-cores.
The FreeRTOS API remains substantially the same between single core and SMP
versions except for [these additions](SMP.md). Therefore, an application written
for the FreeRTOS single core version should compile with the SMP version with
minimal to no effort. However, there may be some functional issues, as some
assumptions which were true for single core applications may no longer be true
for those on multi-cores.

One such common assumption is that a lower priority task cannot be running while
a higher priority task is running. While this used to be true for single core,
it is no longer true for multi-cores as multiple tasks can be running
simultaneously. If the application relies on relative task priorities to provide
mutual exclusion, it may observe unexpected results in multi-core environment.
The application writer has couple of options to address it:
One such common assumption is that a lower priority task cannot run while a
higher priority task is running. While this was true on a single core, it is no
longer true for multi-cores, as multiple tasks can be running simultaneously. If
the application relies on relative task priorities to provide mutual exclusion,
it may observe unexpected results in a multi-core environment. The application
writer has couple of options to address this:

1. The best option is to update the application to not rely on task priorities
and use synchronization primitives instead.
1. The best option is to update the application so that it does not rely on task
priorities and uses synchronization primitives instead.
2. Another option is to pin all the tasks which must not be running
simultaneously to one core using `vTaskCoreAffinitySet` API.
simultaneously to one core using the `vTaskCoreAffinitySet` API.
3. Another option is to define `configRUN_MULTIPLE_PRIORITIES` to `0` which
ensures that multiple tasks will run simultaneously only if they have same
priority. Note that it may result in under utilization and put some cores to
idle while they could be used to run other low priority tasks.
ensures that multiple tasks will run simultaneously only if they have the
same priority. Note that this may result in under utilization and put some
cores to idle when they could be used to run other low priority tasks.
50 changes: 25 additions & 25 deletions SMP.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# Introduction

[Symmetric Multiprocessing (SMP) support in FreeRTOS Kernel](https://github.com/FreeRTOS/FreeRTOS-Kernel/tree/smp)
enables running multiple tasks simultaneously on multi-core microcontrollers.
enables you to run multiple tasks simultaneously on multi-core microcontrollers.
Mutlti-core microcontrollers contain two or more identical processor cores which
share the same memory. FreeRTOS-SMP kernel utilizes all of those cores to
share the same memory. The FreeRTOS-SMP kernel utilizes all of those cores to
schedule multiple ready tasks simultaneously.

# New APIs

The following new APIs have been added to the FreeRTOS-SMP Kernel:
These additional APIs are available to the FreeRTOS-SMP Kernel:
* [vTaskCoreAffinitySet](#vtaskcoreaffinityset)
* [vTaskCoreAffinityGet](#vtaskcoreaffinityget)
* [vTaskPreemptionDisable](#vtaskpreemptiondisable)
Expand All @@ -22,11 +22,11 @@ void vTaskCoreAffinitySet( const TaskHandle_t xTask, UBaseType_t uxCoreAffinityM
`configUSE_CORE_AFFINITY` must be defined as `1` for this function to be available.
Sets the core affinity mask for a task i.e. the cores on which a task can run.
Sets the core affinity mask for a task, i.e. the cores on which a task can run.
**Parameters:**
`xTask` The handle of the task to set the core affinity mask for. Passing `NULL`
`xTask` The handle of the task that the core affinity mask is for. Passing `NULL`
will set the core affinity mask for the calling task.
`uxCoreAffinityMask` A bitwise value that indicates the cores on which the task
Expand Down Expand Up @@ -64,16 +64,16 @@ UBaseType_t vTaskCoreAffinityGet( const TaskHandle_t xTask );
`configUSE_CORE_AFFINITY` must be defined as `1` for this function to be available.
Gets the core affinity mask for a task i.e. the cores on which a task can run.
Gets the core affinity mask for a task, i.e. the cores on which a task can run.
**Parameters:**
`xTask` The handle of the task to get the core affinity mask for. Passing `NULL`
`xTask` The handle of the task that the core affinity mask is for. Passing `NULL`
will get the core affinity mask for the calling task.
**Returns:**
The core affinity mask which is a bitwise value that indicates the cores on
The core affinity mask, which is a bitwise value that indicates the cores on
which a task can run. Cores are numbered from `0` to `configNUM_CORES - 1`.
For example, if a task can run on core `0` and core `1`, the core affinity mask
is `0x03`.
Expand All @@ -97,7 +97,7 @@ UBaseType_t uxNetworkingCoreAffinityMask;
/* Here is a hypothetical scenario, just for the example. Assume that we
* have 2 cores - Core 0 and core 1. We want to pin the application task to
* the core different than the networking task to ensure that the
* the core that is not the networking task core to ensure that the
* application task does not interfere with networking. */
if( ( uxNetworkingCoreAffinityMask & ( 1 << 0 ) ) != 0 )
{
Expand All @@ -122,8 +122,8 @@ Disables preemption for a task.
**Parameters:**
`xTask` The handle of the task to disable preemption. Passing `NULL` disables
preemption for the calling task.
`xTask` The handle of the task for which preemption will be disabled. Passing
`NULL` disables preemption for the calling task.
**Example Usage:**
Expand Down Expand Up @@ -160,8 +160,8 @@ Enables preemption for a task.
**Parameters:**
`xTask` The handle of the task to enable preemption. Passing `NULL` enables
preemption for the calling task.
`xTask` The handle of the task for which preemption will be enabled. Passing
`NULL` enables preemption for the calling task.
**Example Usage:**
Expand Down Expand Up @@ -192,30 +192,30 @@ void vTaskCode( void *pvParameters )

## Minimal Idle Hook Function
The FreeRTOS-SMP kernel has two type of Idle tasks:
1. Idle Task - There is one usual Idle task which does all the garbage collection.
1. Idle Task - There is the one usual Idle task which does all the garbage collection.
2. Minimal Idle Tasks - There are `configNUM_CORES - 1` Minimal Idle tasks which
are run on idle cores and do nothing.
are run on idle cores and which do nothing.

The minimal idle tasks can optionally call an application defined hook
The minimal idle tasks can optionally call an application-defined hook
(or callback) function - the minimal idle hook. The minimal idle tasks run at
the very lowest priority, so such an idle hook function will only get executed
the very lowest priority, so such an idle hook function will only run
when there are no tasks of higher priority that are able to run.

The minimal idle hook will only get called if `configUSE_MINIMAL_IDLE_HOOK` is
set to `1` within `FreeRTOSConfig.h`. When this is set the application must
set to `1` within `FreeRTOSConfig.h`. When this is set, the application must
provide the hook function with the following prototype:

```c
void vApplicationMinimalIdleHook( void );
```
The minimal idle hook is called repeatedly by call the minimal idle tasks as
long as any of them is running. **It is paramount that the minimal idle hook
unction does not call any API functions that could cause it to block.**
The minimal idle hook is called repeatedly by the minimal idle tasks as
long as any one of them is running. **It is paramount that the minimal idle hook
function does not call any API functions that could cause it to block.**
# New Configuration Options
The following new configuration options have been added to the FreeRTOS-SMP
These additional configuration options are available to the FreeRTOS-SMP
Kernel:
* [configNUM_CORES](#confignumcores)
* [configRUN_MULTIPLE_PRIORITIES](#configrunmultiplepriorities)
Expand All @@ -227,15 +227,15 @@ Sets the number of cores.
## configRUN_MULTIPLE_PRIORITIES
Configures if multiple priorities task can run simultaneously. If
Configures whether tasks with multiple priorities can run simultaneously. If
`configRUN_MULTIPLE_PRIORITIES` is defined as `0`, multiple tasks may run
simultaneously only if they have equal priority. If
`configRUN_MULTIPLE_PRIORITIES` is defined as `1`, multiple tasks with different
priorities may run simultaneously.
## configUSE_CORE_AFFINITY
Enables the application writer to control which cores a task can run on.
Allows the application writer to control which cores a task can run on.
If `configUSE_CORE_AFFINITY` is defined as `1`, `vTaskCoreAffinitySet` can be
used to control which cores a task can run on. `vTaskCoreAffinityGet` can be
used to control which cores a task can run on, and `vTaskCoreAffinityGet` can be
used to query which cores a task can run on.

0 comments on commit b6318c4

Please sign in to comment.