Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for processor affinity to CMSIS-RTOS2 wrapper #93

Merged
merged 1 commit into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions ARM.CMSIS-FreeRTOS.pdsc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<release version="0.0.0">
FreeRTOS 11.0.1
Active development...
- Add support for processor affinity to CMSIS-RTOS2 wrapper
- Add memory allocation configuration options to FreeRTOSConfig.h
- CMSIS-RTOS2 requires CMSIS:OS Tick component
- Drop support for Arm Compiler 5
Expand All @@ -20,7 +21,7 @@

<requirements>
<packages>
<package vendor="ARM" name="CMSIS" version="5.9.0"/>
<package vendor="ARM" name="CMSIS" version="6.0.0-0"/>
</packages>
</requirements>

Expand Down Expand Up @@ -870,7 +871,7 @@

<components>
<!-- CMSIS-RTOS2 FreeRTOS component -->
<component Cclass="CMSIS" Cgroup="RTOS2" Csub="FreeRTOS" Cvariant="Cortex-M" Cversion="11.0.1" Capiversion="2.2.0" condition="CMSIS RTOS2 FreeRTOS CortexM">
<component Cclass="CMSIS" Cgroup="RTOS2" Csub="FreeRTOS" Cvariant="Cortex-M" Cversion="11.0.1" Capiversion="2.3.0" condition="CMSIS RTOS2 FreeRTOS CortexM">
<description>CMSIS-RTOS2 implementation for Cortex-M based on FreeRTOS</description>
<RTE_Components_h>
#define RTE_CMSIS_RTOS2 /* CMSIS-RTOS2 */
Expand All @@ -884,7 +885,7 @@
</files>
</component>

<component Cclass="CMSIS" Cgroup="RTOS2" Csub="FreeRTOS" Cvariant="Cortex-A" Cversion="11.0.1" Capiversion="2.2.0" condition="CMSIS RTOS2 FreeRTOS CortexA">
<component Cclass="CMSIS" Cgroup="RTOS2" Csub="FreeRTOS" Cvariant="Cortex-A" Cversion="11.0.1" Capiversion="2.3.0" condition="CMSIS RTOS2 FreeRTOS CortexA">
<description>CMSIS-RTOS2 implementation for Cortex-A based on FreeRTOS</description>
<RTE_Components_h>
#define RTE_CMSIS_RTOS2 /* CMSIS-RTOS2 */
Expand Down
21 changes: 21 additions & 0 deletions CMSIS/RTOS2/FreeRTOS/Config/ARMCM/FreeRTOSConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,27 @@
#define configMINIMAL_SECURE_STACK_SIZE ((uint32_t)128)
// </h>

// <h> Symmetric Multiprocessing Configuration
// <i> Enable and configure FreeRTOS for Symmetric Multiprocessing (SMP).

// <q>Number of processor cores
// <i> Sets the number of available processor cores.
// <i> Default: 1
#define configNUMBER_OF_CORES 1

// <q>Use processor core affinity
// <i> Enables the control for task to run on specific processor cores.
// <i> Task that has no processor affinity set may run on any available core.
// <i> Default: 0
#define configUSE_CORE_AFFINITY 0

// <q>Use passive idle hook
// <i> Enable callback function call on each idle task iteration.
// <i> Callback function vApplicationPassiveIdleHook implementation is required when idle hook is enabled.
// <i> Default: 0
#define configUSE_PASSIVE_IDLE_HOOK 0
// </h>

//------------- <<< end of configuration section >>> ---------------------------

/* Defines needed by FreeRTOS to implement CMSIS RTOS2 API. Do not change! */
Expand Down
28 changes: 27 additions & 1 deletion CMSIS/RTOS2/FreeRTOS/Include/freertos_os2.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* --------------------------------------------------------------------------
* Copyright (c) 2013-2023 Arm Limited. All rights reserved.
* Copyright (c) 2013-2024 Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
Expand Down Expand Up @@ -110,6 +110,12 @@
#define configUSE_OS2_MUTEX configUSE_MUTEXES
#endif

/*
Option to exclude CMSIS-RTOS2 Processor Affinity API functions from the application image.
*/
#ifndef configUSE_OS2_CPU_AFFINITY
#define configUSE_OS2_CPU_AFFINITY configUSE_CORE_AFFINITY
#endif

/*
CMSIS-RTOS2 FreeRTOS configuration check (FreeRTOSConfig.h).
Expand Down Expand Up @@ -267,6 +273,26 @@
#endif
#endif

#if (configUSE_CORE_AFFINITY == 0)
/*
CMSIS-RTOS2 Processor Affinity API functions require FreeRTOS kernel support for
Symmetric Multiprocessing (SMP). In case if this functionality is not available
and the functions are not used in the application image, compiler will optimize
them away.
Set #define configUSE_CORE_AFFINITY 1 to fix this error.
Note: SMP is only available when #define configNUMBER_OF_CORES > 1

Alternatively, if the application does not use processor affinity functions they
can be excluded from the image code by setting:
#define configUSE_OS2_CPU_AFFINITY 0 (in FreeRTOSConfig.h)
*/

#if (configUSE_OS2_CPU_AFFINITY == 1)
#error "Definitions configNUMBER_OF_CORES and configUSE_CORE_AFFINITY must equal 1 to implement Processor Affinity API."
#endif
#endif


#if (configUSE_COUNTING_SEMAPHORES == 0)
/*
CMSIS-RTOS2 Memory Pool functions use FreeRTOS function xSemaphoreCreateCounting
Expand Down
96 changes: 91 additions & 5 deletions CMSIS/RTOS2/FreeRTOS/Source/cmsis_os2.c
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,9 @@ osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAtt
TaskHandle_t hTask;
UBaseType_t prio;
int32_t mem;
#if (configUSE_OS2_CPU_AFFINITY == 1)
UBaseType_t core_aff = tskNO_AFFINITY;
#endif

hTask = NULL;

Expand Down Expand Up @@ -561,23 +564,62 @@ osThreadId_t osThreadNew (osThreadFunc_t func, void *argument, const osThreadAtt
mem = 0;
}
}

#if (configUSE_OS2_CPU_AFFINITY == 1)
if (attr->affinity_mask != 0U) {
core_aff = attr->affinity_mask;
}
#endif
}
else {
mem = 0;
}

if (mem == 1) {
#if (configSUPPORT_STATIC_ALLOCATION == 1)
hTask = xTaskCreateStatic ((TaskFunction_t)func, name, stack, argument, prio, (StackType_t *)attr->stack_mem,
(StaticTask_t *)attr->cb_mem);
#if (configUSE_OS2_CPU_AFFINITY == 0)
hTask = xTaskCreateStatic ((TaskFunction_t)func,
name,
stack,
argument,
prio,
(StackType_t *)attr->stack_mem,
(StaticTask_t *)attr->cb_mem);
#else
hTask = xTaskCreateStaticAffinitySet ((TaskFunction_t)func,
name,
stack,
argument,
prio,
(StackType_t *)attr->stack_mem,
(StaticTask_t *)attr->cb_mem,
core_aff);
#endif
#endif
}
else {
if (mem == 0) {
#if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
if (xTaskCreate ((TaskFunction_t)func, name, (configSTACK_DEPTH_TYPE)stack, argument, prio, &hTask) != pdPASS) {
hTask = NULL;
}
#if (configUSE_OS2_CPU_AFFINITY == 0)
if (xTaskCreate ((TaskFunction_t )func,
name,
(configSTACK_DEPTH_TYPE)stack,
argument,
prio,
&hTask) != pdPASS) {
hTask = NULL;
}
#else
if (xTaskCreateAffinitySet ((TaskFunction_t )func,
name,
(configSTACK_DEPTH_TYPE)stack,
argument,
prio,
core_aff,
&hTask) != pdPASS) {
hTask = NULL;
}
#endif
#endif
}
}
Expand Down Expand Up @@ -878,6 +920,50 @@ uint32_t osThreadEnumerate (osThreadId_t *thread_array, uint32_t array_items) {
}
#endif /* (configUSE_OS2_THREAD_ENUMERATE == 1) */

#if (configUSE_OS2_CPU_AFFINITY == 1)
/*
Set processor affinity mask of a thread.
*/
osStatus_t osThreadSetAffinityMask (osThreadId_t thread_id, uint32_t affinity_mask) {
TaskHandle_t hTask = (TaskHandle_t)thread_id;
osStatus_t stat;

if (IRQ_Context() != 0U) {
stat = osErrorISR;
}
else if (hTask == NULL) {
stat = osErrorParameter;
VladimirUmek marked this conversation as resolved.
Show resolved Hide resolved
}
else {
stat = osOK;
vTaskCoreAffinitySet (hTask, (UBaseType_t)affinity_mask);
}

/* Return execution status */
return (stat);
}

/*
Get current processor affinity mask of a thread.
*/
uint32_t osThreadGetAffinityMask (osThreadId_t thread_id) {
TaskHandle_t hTask = (TaskHandle_t)thread_id;
UBaseType_t affinity_mask;

if (IRQ_Context() != 0U) {
affinity_mask = 0U;
}
else if (hTask == NULL) {
affinity_mask = 0U;
}
else {
affinity_mask = vTaskCoreAffinityGet (hTask);
}

/* Return current processor affinity mask */
return ((uint32_t)affinity_mask);
}
#endif /* (configUSE_OS2_CPU_AFFINITY == 1) */

/* ==== Thread Flags Functions ==== */

Expand Down
Loading