Merge branch 'feature/freeRTOS_make_debug_functions_configurable' into 'master'
FreeRTOS/make Queue Registry and Run Time Stats configurable See merge request !1480
This commit is contained in:
commit
3c33807689
8 changed files with 234 additions and 9 deletions
|
@ -275,6 +275,16 @@ config TIMER_QUEUE_LENGTH
|
||||||
|
|
||||||
For most uses the default value of 10 is OK.
|
For most uses the default value of 10 is OK.
|
||||||
|
|
||||||
|
config FREERTOS_QUEUE_REGISTRY_SIZE
|
||||||
|
int "FreeRTOS queue registry size"
|
||||||
|
range 0 20
|
||||||
|
default 0
|
||||||
|
help
|
||||||
|
FreeRTOS uses the queue registry as a means for kernel aware debuggers to locate queues, semaphores,
|
||||||
|
and mutexes. The registry allows for a textual name to be associated with a queue for easy identification
|
||||||
|
within a debugging GUI. A value of 0 will disable queue registry functionality, and a value larger than 0
|
||||||
|
will specify the number of queues/semaphores/mutexes that the registry can hold.
|
||||||
|
|
||||||
config FREERTOS_USE_TRACE_FACILITY
|
config FREERTOS_USE_TRACE_FACILITY
|
||||||
bool "Enable FreeRTOS trace facility"
|
bool "Enable FreeRTOS trace facility"
|
||||||
default n
|
default n
|
||||||
|
@ -285,13 +295,63 @@ config FREERTOS_USE_TRACE_FACILITY
|
||||||
|
|
||||||
config FREERTOS_USE_STATS_FORMATTING_FUNCTIONS
|
config FREERTOS_USE_STATS_FORMATTING_FUNCTIONS
|
||||||
bool "Enable FreeRTOS stats formatting functions"
|
bool "Enable FreeRTOS stats formatting functions"
|
||||||
depends on FREERTOS_USE_TRACE_FACILITY
|
depends on FREERTOS_USE_TRACE_FACILITY || FREERTOS_GENERATE_RUN_TIME_STATS
|
||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
If enabled, configUSE_STATS_FORMATTING_FUNCTIONS will be defined as 1 in
|
If enabled, configUSE_STATS_FORMATTING_FUNCTIONS will be defined as 1 in
|
||||||
FreeRTOS. This will allow the usage of stats formatting functions such
|
FreeRTOS. This will allow the usage of stats formatting functions such
|
||||||
as vTaskList().
|
as vTaskList().
|
||||||
|
|
||||||
|
config FREERTOS_GENERATE_RUN_TIME_STATS
|
||||||
|
bool "Enable FreeRTOS to collect run time stats"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
If enabled, configGENERATE_RUN_TIME_STATS will be defined as 1 in
|
||||||
|
FreeRTOS. This will allow FreeRTOS to collect information regarding the
|
||||||
|
usage of processor time amongst FreeRTOS tasks. Run time stats are
|
||||||
|
generated using either the ESP Timer or the CPU Clock as the clock
|
||||||
|
source (Note that run time stats are only valid until the clock source
|
||||||
|
overflows). The function vTaskGetRunTimeStats() will also be available
|
||||||
|
if FREERTOS_USE_STATS_FORMATTING_FUNCTIONS and
|
||||||
|
FREERTOS_USE_TRACE_FACILITY are enabled. vTaskGetRunTimeStats() will
|
||||||
|
display the run time of each task as a % of the total run time of all
|
||||||
|
CPUs (task run time / no of CPUs) / (total run time / 100 )
|
||||||
|
|
||||||
|
|
||||||
|
choice FREERTOS_RUN_TIME_STATS_CLK
|
||||||
|
prompt "Choose the clock source for run time stats"
|
||||||
|
depends on FREERTOS_GENERATE_RUN_TIME_STATS
|
||||||
|
default FREERTOS_RUN_TIME_STATS_USING_ESP_TIMER
|
||||||
|
help
|
||||||
|
Choose the clock source for FreeRTOS run time stats. Options are CPU0's
|
||||||
|
CPU Clock or the ESP Timer. Both clock sources are 32 bits. The CPU
|
||||||
|
Clock can run at a higher frequency hence provide a finer resolution
|
||||||
|
but will overflow much quicker. Note that run time stats are only valid
|
||||||
|
until the clock source overflows.
|
||||||
|
|
||||||
|
config FREERTOS_RUN_TIME_STATS_USING_ESP_TIMER
|
||||||
|
bool "Use ESP TIMER for run time stats"
|
||||||
|
help
|
||||||
|
ESP Timer will be used as the clock source for FreeRTOS run time stats.
|
||||||
|
The ESP Timer runs at a frequency of 1MHz regardless of Dynamic
|
||||||
|
Frequency Scaling. Therefore the ESP Timer will overflow in
|
||||||
|
approximately 4290 seconds.
|
||||||
|
|
||||||
|
config FREERTOS_RUN_TIME_STATS_USING_CPU_CLK
|
||||||
|
bool "Use CPU Clock for run time stats"
|
||||||
|
help
|
||||||
|
CPU Clock will be used as the clock source for the generation of run
|
||||||
|
time stats. The CPU Clock has a frequency dependent on
|
||||||
|
ESP32_DEFAULT_CPU_FREQ_MHZ and Dynamic Frequency Scaling (DFS).
|
||||||
|
Therefore the CPU Clock frequency can fluctuate between 80 to 240MHz.
|
||||||
|
Run time stats generated using the CPU Clock represents the number of
|
||||||
|
CPU cycles each task is allocated and DOES NOT reflect the amount of
|
||||||
|
time each task runs for (as CPU clock frequency can change). If the CPU
|
||||||
|
clock consistently runs at the maximum frequency of 240MHz, it will
|
||||||
|
overflow in approximately 17 seconds.
|
||||||
|
|
||||||
|
endchoice
|
||||||
|
|
||||||
menuconfig FREERTOS_DEBUG_INTERNALS
|
menuconfig FREERTOS_DEBUG_INTERNALS
|
||||||
bool "Debug FreeRTOS internals"
|
bool "Debug FreeRTOS internals"
|
||||||
default n
|
default n
|
||||||
|
|
|
@ -219,7 +219,7 @@ int xt_clock_freq(void) __attribute__((deprecated));
|
||||||
#define configBENCHMARK 0 /* Provided by Xtensa port patch */
|
#define configBENCHMARK 0 /* Provided by Xtensa port patch */
|
||||||
#define configUSE_16_BIT_TICKS 0
|
#define configUSE_16_BIT_TICKS 0
|
||||||
#define configIDLE_SHOULD_YIELD 0
|
#define configIDLE_SHOULD_YIELD 0
|
||||||
#define configQUEUE_REGISTRY_SIZE 0
|
#define configQUEUE_REGISTRY_SIZE CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE
|
||||||
|
|
||||||
#define configUSE_MUTEXES 1
|
#define configUSE_MUTEXES 1
|
||||||
#define configUSE_RECURSIVE_MUTEXES 1
|
#define configUSE_RECURSIVE_MUTEXES 1
|
||||||
|
|
|
@ -80,6 +80,7 @@ extern "C" {
|
||||||
#include <xtensa/config/system.h> /* required for XSHAL_CLIB */
|
#include <xtensa/config/system.h> /* required for XSHAL_CLIB */
|
||||||
#include <xtensa/xtruntime.h>
|
#include <xtensa/xtruntime.h>
|
||||||
#include "esp_crosscore_int.h"
|
#include "esp_crosscore_int.h"
|
||||||
|
#include "esp_timer.h" /* required for FreeRTOS run time stats */
|
||||||
|
|
||||||
|
|
||||||
#include <esp_heap_caps.h>
|
#include <esp_heap_caps.h>
|
||||||
|
@ -299,6 +300,15 @@ static inline void uxPortCompareSet(volatile uint32_t *addr, uint32_t compare, u
|
||||||
|
|
||||||
/* Fine resolution time */
|
/* Fine resolution time */
|
||||||
#define portGET_RUN_TIME_COUNTER_VALUE() xthal_get_ccount()
|
#define portGET_RUN_TIME_COUNTER_VALUE() xthal_get_ccount()
|
||||||
|
//ccount or esp_timer are initialized elsewhere
|
||||||
|
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
|
||||||
|
|
||||||
|
#ifdef CONFIG_FREERTOS_RUN_TIME_STATS_USING_ESP_TIMER
|
||||||
|
/* Coarse resolution time (us) */
|
||||||
|
#define portALT_GET_RUN_TIME_COUNTER_VALUE(x) x = (uint32_t)esp_timer_get_time()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Kernel utilities. */
|
/* Kernel utilities. */
|
||||||
void vPortYield( void );
|
void vPortYield( void );
|
||||||
|
|
|
@ -1627,6 +1627,23 @@ BaseType_t xQueueGiveMutexRecursive( QueueHandle_t pxMutex ) PRIVILEGED_FUNCTION
|
||||||
void vQueueUnregisterQueue( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
|
void vQueueUnregisterQueue( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @note This function has been back ported from FreeRTOS v9.0.0
|
||||||
|
*
|
||||||
|
* The queue registry is provided as a means for kernel aware debuggers to
|
||||||
|
* locate queues, semaphores and mutexes. Call pcQueueGetName() to look
|
||||||
|
* up and return the name of a queue in the queue registry from the queue's
|
||||||
|
* handle.
|
||||||
|
*
|
||||||
|
* @param xQueue The handle of the queue the name of which will be returned.
|
||||||
|
* @return If the queue is in the registry then a pointer to the name of the
|
||||||
|
* queue is returned. If the queue is not in the registry then NULL is
|
||||||
|
* returned.
|
||||||
|
*/
|
||||||
|
#if( configQUEUE_REGISTRY_SIZE > 0 )
|
||||||
|
const char *pcQueueGetName( QueueHandle_t xQueue ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generic version of the function used to creaet a queue using dynamic memory
|
* Generic version of the function used to creaet a queue using dynamic memory
|
||||||
* allocation. This is called by other functions and macros that create other
|
* allocation. This is called by other functions and macros that create other
|
||||||
|
|
|
@ -205,6 +205,9 @@ _Static_assert(sizeof(StaticQueue_t) == sizeof(Queue_t), "StaticQueue_t != Queue
|
||||||
array position being vacant. */
|
array position being vacant. */
|
||||||
QueueRegistryItem_t xQueueRegistry[ configQUEUE_REGISTRY_SIZE ];
|
QueueRegistryItem_t xQueueRegistry[ configQUEUE_REGISTRY_SIZE ];
|
||||||
|
|
||||||
|
//Need to add queue registry mutex to protect against simultaneous access
|
||||||
|
static portMUX_TYPE queue_registry_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||||
|
|
||||||
#endif /* configQUEUE_REGISTRY_SIZE */
|
#endif /* configQUEUE_REGISTRY_SIZE */
|
||||||
|
|
||||||
|
|
||||||
|
@ -2316,7 +2319,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
||||||
{
|
{
|
||||||
UBaseType_t ux;
|
UBaseType_t ux;
|
||||||
|
|
||||||
UNTESTED_FUNCTION();
|
portENTER_CRITICAL(&queue_registry_spinlock);
|
||||||
/* See if there is an empty space in the registry. A NULL name denotes
|
/* See if there is an empty space in the registry. A NULL name denotes
|
||||||
a free slot. */
|
a free slot. */
|
||||||
for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ )
|
for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ )
|
||||||
|
@ -2335,6 +2338,38 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
||||||
mtCOVERAGE_TEST_MARKER();
|
mtCOVERAGE_TEST_MARKER();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
portEXIT_CRITICAL(&queue_registry_spinlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* configQUEUE_REGISTRY_SIZE */
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if ( configQUEUE_REGISTRY_SIZE > 0 )
|
||||||
|
|
||||||
|
//This function is backported from FreeRTOS v9.0.0
|
||||||
|
const char *pcQueueGetName( QueueHandle_t xQueue ) /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||||
|
{
|
||||||
|
UBaseType_t ux;
|
||||||
|
const char *pcReturn = NULL; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||||
|
|
||||||
|
portENTER_CRITICAL(&queue_registry_spinlock);
|
||||||
|
/* Note there is nothing here to protect against another task adding or
|
||||||
|
removing entries from the registry while it is being searched. */
|
||||||
|
for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ )
|
||||||
|
{
|
||||||
|
if( xQueueRegistry[ ux ].xHandle == xQueue )
|
||||||
|
{
|
||||||
|
pcReturn = xQueueRegistry[ ux ].pcQueueName;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
portEXIT_CRITICAL(&queue_registry_spinlock);
|
||||||
|
|
||||||
|
return pcReturn;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configQUEUE_REGISTRY_SIZE */
|
#endif /* configQUEUE_REGISTRY_SIZE */
|
||||||
|
@ -2346,6 +2381,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
||||||
{
|
{
|
||||||
UBaseType_t ux;
|
UBaseType_t ux;
|
||||||
|
|
||||||
|
portENTER_CRITICAL(&queue_registry_spinlock);
|
||||||
/* See if the handle of the queue being unregistered in actually in the
|
/* See if the handle of the queue being unregistered in actually in the
|
||||||
registry. */
|
registry. */
|
||||||
for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ )
|
for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ )
|
||||||
|
@ -2361,6 +2397,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
||||||
mtCOVERAGE_TEST_MARKER();
|
mtCOVERAGE_TEST_MARKER();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
portEXIT_CRITICAL(&queue_registry_spinlock);
|
||||||
|
|
||||||
} /*lint !e818 xQueue could not be pointer to const because it is a typedef. */
|
} /*lint !e818 xQueue could not be pointer to const because it is a typedef. */
|
||||||
|
|
||||||
|
|
|
@ -309,7 +309,7 @@ PRIVILEGED_DATA static portMUX_TYPE xTickCountMutex = portMUX_INITIALIZER_UNLOCK
|
||||||
|
|
||||||
#if ( configGENERATE_RUN_TIME_STATS == 1 )
|
#if ( configGENERATE_RUN_TIME_STATS == 1 )
|
||||||
|
|
||||||
PRIVILEGED_DATA static uint32_t ulTaskSwitchedInTime = 0UL; /*< Holds the value of a timer/counter the last time a task was switched in. */
|
PRIVILEGED_DATA static uint32_t ulTaskSwitchedInTime[portNUM_PROCESSORS] = {0U}; /*< Holds the value of a timer/counter the last time a task was switched in on a particular core. */
|
||||||
PRIVILEGED_DATA static uint32_t ulTotalRunTime = 0UL; /*< Holds the total amount of execution time as defined by the run time counter clock. */
|
PRIVILEGED_DATA static uint32_t ulTotalRunTime = 0UL; /*< Holds the total amount of execution time as defined by the run time counter clock. */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -2729,16 +2729,16 @@ void vTaskSwitchContext( void )
|
||||||
against suspect run time stat counter implementations - which
|
against suspect run time stat counter implementations - which
|
||||||
are provided by the application, not the kernel. */
|
are provided by the application, not the kernel. */
|
||||||
taskENTER_CRITICAL_ISR(&xTaskQueueMutex);
|
taskENTER_CRITICAL_ISR(&xTaskQueueMutex);
|
||||||
if( ulTotalRunTime > ulTaskSwitchedInTime )
|
if( ulTotalRunTime > ulTaskSwitchedInTime[ xPortGetCoreID() ] )
|
||||||
{
|
{
|
||||||
pxCurrentTCB[ xPortGetCoreID() ]->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime );
|
pxCurrentTCB[ xPortGetCoreID() ]->ulRunTimeCounter += ( ulTotalRunTime - ulTaskSwitchedInTime[ xPortGetCoreID() ] );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mtCOVERAGE_TEST_MARKER();
|
mtCOVERAGE_TEST_MARKER();
|
||||||
}
|
}
|
||||||
taskEXIT_CRITICAL_ISR(&xTaskQueueMutex);
|
taskEXIT_CRITICAL_ISR(&xTaskQueueMutex);
|
||||||
ulTaskSwitchedInTime = ulTotalRunTime;
|
ulTaskSwitchedInTime[ xPortGetCoreID() ] = ulTotalRunTime;
|
||||||
}
|
}
|
||||||
#endif /* configGENERATE_RUN_TIME_STATS */
|
#endif /* configGENERATE_RUN_TIME_STATS */
|
||||||
|
|
||||||
|
@ -4372,7 +4372,6 @@ For ESP32 FreeRTOS, vTaskExitCritical implements both portEXIT_CRITICAL and port
|
||||||
volatile UBaseType_t uxArraySize, x;
|
volatile UBaseType_t uxArraySize, x;
|
||||||
uint32_t ulTotalTime, ulStatsAsPercentage;
|
uint32_t ulTotalTime, ulStatsAsPercentage;
|
||||||
|
|
||||||
UNTESTED_FUNCTION();
|
|
||||||
#if( configUSE_TRACE_FACILITY != 1 )
|
#if( configUSE_TRACE_FACILITY != 1 )
|
||||||
{
|
{
|
||||||
#error configUSE_TRACE_FACILITY must also be set to 1 in FreeRTOSConfig.h to use vTaskGetRunTimeStats().
|
#error configUSE_TRACE_FACILITY must also be set to 1 in FreeRTOSConfig.h to use vTaskGetRunTimeStats().
|
||||||
|
@ -4433,7 +4432,8 @@ For ESP32 FreeRTOS, vTaskExitCritical implements both portEXIT_CRITICAL and port
|
||||||
/* What percentage of the total run time has the task used?
|
/* What percentage of the total run time has the task used?
|
||||||
This will always be rounded down to the nearest integer.
|
This will always be rounded down to the nearest integer.
|
||||||
ulTotalRunTimeDiv100 has already been divided by 100. */
|
ulTotalRunTimeDiv100 has already been divided by 100. */
|
||||||
ulStatsAsPercentage = pxTaskStatusArray[ x ].ulRunTimeCounter / ulTotalTime;
|
/* Also need to consider total run time of all */
|
||||||
|
ulStatsAsPercentage = (pxTaskStatusArray[ x ].ulRunTimeCounter/portNUM_PROCESSORS)/ ulTotalTime;
|
||||||
|
|
||||||
/* Write the task name to the string, padding with
|
/* Write the task name to the string, padding with
|
||||||
spaces so it can be printed in tabular form more
|
spaces so it can be printed in tabular form more
|
||||||
|
|
100
components/freertos/test/test_freertos_debug_functions.c
Normal file
100
components/freertos/test/test_freertos_debug_functions.c
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
/*
|
||||||
|
* Test FreeRTOS debug functions and utilities.
|
||||||
|
* - Queue registry functions vQueueAddToRegistry(), vQueueUnregisterQueue(),
|
||||||
|
* and pcQueueGetName(backported)
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "freertos/semphr.h"
|
||||||
|
#include "freertos/queue.h"
|
||||||
|
#include "unity.h"
|
||||||
|
|
||||||
|
#if (CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE > 0)
|
||||||
|
#define NO_OF_QUEUES_PER_CORE ((int)((CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE - 3)/portNUM_PROCESSORS)) //Save space for some preallocated tasks
|
||||||
|
#define NO_OF_QUEUES_TOTAL (NO_OF_QUEUES_PER_CORE * portNUM_PROCESSORS)
|
||||||
|
#define QUEUE_NAME_MAX_LENGTH 10
|
||||||
|
|
||||||
|
static SemaphoreHandle_t start_sem = NULL;
|
||||||
|
static SemaphoreHandle_t done_sem = NULL;
|
||||||
|
static char *names[NO_OF_QUEUES_TOTAL];
|
||||||
|
static QueueHandle_t handles[NO_OF_QUEUES_TOTAL];
|
||||||
|
|
||||||
|
void test_queue_registry_task(void *arg)
|
||||||
|
{
|
||||||
|
int core = xPortGetCoreID();
|
||||||
|
int offset = core * NO_OF_QUEUES_PER_CORE;
|
||||||
|
//Create queues and accompanying queue names
|
||||||
|
for(int i = 0; i < NO_OF_QUEUES_PER_CORE; i++){
|
||||||
|
handles[i + offset] = xQueueCreate(1,1); //Create queues
|
||||||
|
names[i + offset] = calloc(QUEUE_NAME_MAX_LENGTH, sizeof(char));
|
||||||
|
sprintf(names[i + offset], "Queue%d%d", core, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
xSemaphoreTake(start_sem, portMAX_DELAY); //Wait for start vQueueAddToRegistry()
|
||||||
|
for(int i = 0; i < NO_OF_QUEUES_PER_CORE; i++){
|
||||||
|
vQueueAddToRegistry(handles[i + offset] , names[i + offset]); //Register queues to queue registry
|
||||||
|
}
|
||||||
|
xSemaphoreGive(done_sem); //Signal that vQueueAddToRegistry() has completed
|
||||||
|
|
||||||
|
vTaskDelay(1);
|
||||||
|
|
||||||
|
xSemaphoreTake(start_sem, portMAX_DELAY); //Wait to start vQueueUnregisterQueue()
|
||||||
|
for(int i = 0; i < NO_OF_QUEUES_PER_CORE; i++){
|
||||||
|
vQueueDelete(handles[i + offset]); //Internally calls vQueueUnregisterQueue
|
||||||
|
}
|
||||||
|
xSemaphoreGive(done_sem); //Signal done
|
||||||
|
|
||||||
|
vTaskDelete(NULL); //Delete self
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Test FreeRTOS Queue Registry", "[freertos]")
|
||||||
|
{
|
||||||
|
//Create synchronization semaphores
|
||||||
|
start_sem = xSemaphoreCreateCounting(portNUM_PROCESSORS, 0);
|
||||||
|
done_sem = xSemaphoreCreateCounting(portNUM_PROCESSORS, 0);
|
||||||
|
for(int i = 0; i < portNUM_PROCESSORS; i++){ //Create tasks to test queue registry
|
||||||
|
xTaskCreatePinnedToCore(test_queue_registry_task, "testing task", 4096, NULL, UNITY_FREERTOS_PRIORITY+1, NULL, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
for(int i = 0; i < portNUM_PROCESSORS; i++){
|
||||||
|
xSemaphoreGive(start_sem); //Trigger start
|
||||||
|
}
|
||||||
|
portENABLE_INTERRUPTS();
|
||||||
|
for(int i = 0; i < portNUM_PROCESSORS; i++){
|
||||||
|
xSemaphoreTake(done_sem, portMAX_DELAY); //Wait for tasks to complete vQueueAddToRegistry
|
||||||
|
}
|
||||||
|
for(int i = 0; i < NO_OF_QUEUES_TOTAL; i++){
|
||||||
|
const char *addr = pcQueueGetName(handles[i]);
|
||||||
|
TEST_ASSERT(addr == names[i]) //Check vQueueAddToRegistry was successful
|
||||||
|
}
|
||||||
|
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
for(int i = 0; i < portNUM_PROCESSORS; i++){
|
||||||
|
xSemaphoreGive(start_sem); //Trigger start
|
||||||
|
}
|
||||||
|
portENABLE_INTERRUPTS();
|
||||||
|
for(int i = 0; i < portNUM_PROCESSORS; i++){
|
||||||
|
xSemaphoreTake(done_sem, portMAX_DELAY); //Wait for tasks to complete vQueueUnregisterQueue
|
||||||
|
}
|
||||||
|
for(int i = 0; i < NO_OF_QUEUES_TOTAL; i++){
|
||||||
|
const char *addr = pcQueueGetName(handles[i]);
|
||||||
|
TEST_ASSERT(addr == NULL) //Check vQueueUnregisterQueue was successful
|
||||||
|
handles[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Cleanup
|
||||||
|
for(int i = 0; i < NO_OF_QUEUES_TOTAL; i++){
|
||||||
|
free(names[i]);
|
||||||
|
names[i] = NULL;
|
||||||
|
}
|
||||||
|
vSemaphoreDelete(start_sem);
|
||||||
|
start_sem = NULL;
|
||||||
|
vSemaphoreDelete(done_sem);
|
||||||
|
done_sem = NULL;
|
||||||
|
}
|
||||||
|
#endif //(CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE > 0)
|
|
@ -20,3 +20,4 @@ CONFIG_SPI_FLASH_ENABLE_COUNTERS=y
|
||||||
CONFIG_ULP_COPROC_ENABLED=y
|
CONFIG_ULP_COPROC_ENABLED=y
|
||||||
CONFIG_TASK_WDT=n
|
CONFIG_TASK_WDT=n
|
||||||
CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS=y
|
CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS=y
|
||||||
|
CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=7
|
||||||
|
|
Loading…
Reference in a new issue