add tmr demo
This commit is contained in:
parent
f0728a8a5e
commit
a333ed57b3
@ -71,6 +71,8 @@ extern void vAssertCalled( void );
|
|||||||
#define configNUM_TX_DESCRIPTORS 15
|
#define configNUM_TX_DESCRIPTORS 15
|
||||||
#define configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN 2
|
#define configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN 2
|
||||||
|
|
||||||
|
#define configUSE_QUEUE_SETS 1
|
||||||
|
|
||||||
/* Set the following definitions to 1 to include the API function, or zero
|
/* Set the following definitions to 1 to include the API function, or zero
|
||||||
* to exclude the API function. */
|
* to exclude the API function. */
|
||||||
|
|
||||||
|
@ -73,6 +73,11 @@ ifeq ($(BUBBLESORT_DEMO), 1)
|
|||||||
SOURCE_FILES += main_bubblesort.c
|
SOURCE_FILES += main_bubblesort.c
|
||||||
|
|
||||||
CFLAGS := -DmainCREATE_BUBBLESORT_DEMO=1
|
CFLAGS := -DmainCREATE_BUBBLESORT_DEMO=1
|
||||||
|
else
|
||||||
|
ifeq ($(TMR_DEMO), 1)
|
||||||
|
SOURCE_FILES += main_tmr.c
|
||||||
|
|
||||||
|
CFLAGS := -DmainCREATE_TMR_DEMO=1
|
||||||
else
|
else
|
||||||
SOURCE_FILES += main_blinky.c
|
SOURCE_FILES += main_blinky.c
|
||||||
|
|
||||||
@ -81,6 +86,7 @@ endif
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
DEFINES := -DQEMU_SOC_MPS2 -DHEAP3
|
DEFINES := -DQEMU_SOC_MPS2 -DHEAP3
|
||||||
|
|
||||||
|
@ -75,6 +75,10 @@ int main()
|
|||||||
{
|
{
|
||||||
main_bubblesort();
|
main_bubblesort();
|
||||||
}
|
}
|
||||||
|
#elif ( mainCREATE_TMR_DEMO == 1 )
|
||||||
|
{
|
||||||
|
main_tmr();
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
{
|
{
|
||||||
#error "Invalid Selection...\nPlease Select a Demo application from the main command"
|
#error "Invalid Selection...\nPlease Select a Demo application from the main command"
|
||||||
|
237
FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_tmr.c
Normal file
237
FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_tmr.c
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
/*
|
||||||
|
* FreeRTOS V202111.00
|
||||||
|
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
* this software and associated documentation files (the "Software"), to deal in
|
||||||
|
* the Software without restriction, including without limitation the rights to
|
||||||
|
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
* subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in all
|
||||||
|
* copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* https://www.FreeRTOS.org
|
||||||
|
* https://github.com/FreeRTOS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <FreeRTOS.h>
|
||||||
|
#include <task.h>
|
||||||
|
#include <queue.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
/*
|
||||||
|
TMR Demo with retry
|
||||||
|
prvSamplerTask will read 4 Bytes of Input into a buffer, unlocks xMutexInput
|
||||||
|
prvReplicateA and prvReplicateB wait on xMutexInput to average the Inputs and
|
||||||
|
sum up all numbers up to the Input.
|
||||||
|
ReplicateA will fail if mod 11 = 0, but only once
|
||||||
|
ReplicateB will fail if mod 12 = 0
|
||||||
|
ReplicateC also exists and will never fail, does not run by default
|
||||||
|
Each Replicate outputs to it's own queue
|
||||||
|
prvVoterTask will wait on ReplicateA&B
|
||||||
|
If they disagree ReplicateC will be started by mutex.
|
||||||
|
If all the Replicates disagree now the sampler will be engaged once more
|
||||||
|
*/
|
||||||
|
|
||||||
|
__attribute__((noinline)) static void trigger_Qemu_break( void )
|
||||||
|
{
|
||||||
|
puts("Trigger");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Begin Input Stuff
|
||||||
|
volatile unsigned char FUZZ_INPUT[4096] = {33};
|
||||||
|
volatile uint32_t FUZZ_LENGTH = 32;
|
||||||
|
volatile uint32_t FUZZ_POINTER = 0;
|
||||||
|
// Read the Byte of Input, if the Input is exausted trigger the breakpoint instead
|
||||||
|
static unsigned char fuzz_input_next(void) {
|
||||||
|
if (FUZZ_POINTER < FUZZ_LENGTH) {
|
||||||
|
FUZZ_POINTER++;
|
||||||
|
return FUZZ_INPUT[FUZZ_POINTER-1];
|
||||||
|
} else {
|
||||||
|
// Exausted inputs early
|
||||||
|
trigger_Qemu_break();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// End Input Stuff
|
||||||
|
static void prvSamplerTask( void * pvParameters );
|
||||||
|
static void prvReplicaA( void * pvParameters );
|
||||||
|
static void prvReplicaB( void * pvParameters );
|
||||||
|
static void prvReplicaC( void * pvParameters );
|
||||||
|
static void prvVoterTask( void * pvParameters );
|
||||||
|
|
||||||
|
#define mainSAMPLER_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
||||||
|
#define mainVOTER_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
||||||
|
#define mainREPLICA_A_TASK_PRIORITY ( tskIDLE_PRIORITY + 4 )
|
||||||
|
#define mainREPLICA_B_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
|
||||||
|
#define mainREPLICA_C_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
|
||||||
|
#define mainQUEUE_LENGTH ( 1 )
|
||||||
|
#define mainQUEUE_SEND_FREQUENCY_MS ( 10 / portTICK_PERIOD_MS )
|
||||||
|
#define voterMAXRETRIES 1
|
||||||
|
#define WORK_SET_SIZE_POWER 2
|
||||||
|
#define WORK_SET_SIZE 4
|
||||||
|
|
||||||
|
// Handles for direct messages
|
||||||
|
static TaskHandle_t xReplA = NULL;
|
||||||
|
static TaskHandle_t xReplB = NULL;
|
||||||
|
static TaskHandle_t xReplC = NULL;
|
||||||
|
/* The queue used by both tasks. */
|
||||||
|
static QueueHandle_t xQueueOutputA = NULL;
|
||||||
|
static QueueHandle_t xQueueOutputB = NULL;
|
||||||
|
static QueueHandle_t xQueueOutputC = NULL;
|
||||||
|
// static QueueSetHandle_t xQueueSetAB = NULL;
|
||||||
|
|
||||||
|
void main_tmr( void )
|
||||||
|
{
|
||||||
|
/* Create the queues. */
|
||||||
|
xQueueOutputA = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned char ) );
|
||||||
|
xQueueOutputB = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned char ) );
|
||||||
|
xQueueOutputC = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned char ) );
|
||||||
|
// xQueueSetAB = xQueueCreateSet(2);
|
||||||
|
// xQueueAddToSet(xQueueOutputA,xQueueSetAB);
|
||||||
|
// xQueueAddToSet(xQueueOutputB,xQueueSetAB);
|
||||||
|
|
||||||
|
if( xQueueOutputA != NULL && xQueueOutputA != NULL && xQueueOutputC != NULL)
|
||||||
|
{
|
||||||
|
/* Start the two tasks as described in the comments at the top of this
|
||||||
|
* file. */
|
||||||
|
xTaskCreate( prvReplicaA, /* The function that implements the task. */
|
||||||
|
"ReplA", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
|
||||||
|
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
|
||||||
|
NULL, /* The parameter passed to the task - not used in this case. */
|
||||||
|
mainREPLICA_A_TASK_PRIORITY, /* The priority assigned to the task. */
|
||||||
|
&xReplA ); /* The task handle is not required, so NULL is passed. */
|
||||||
|
|
||||||
|
xTaskCreate( prvReplicaB, /* The function that implements the task. */
|
||||||
|
"ReplB", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
|
||||||
|
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
|
||||||
|
NULL, /* The parameter passed to the task - not used in this case. */
|
||||||
|
mainREPLICA_B_TASK_PRIORITY, /* The priority assigned to the task. */
|
||||||
|
&xReplB ); /* The task handle is not required, so NULL is passed. */
|
||||||
|
|
||||||
|
xTaskCreate( prvReplicaC, /* The function that implements the task. */
|
||||||
|
"ReplC", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
|
||||||
|
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
|
||||||
|
NULL, /* The parameter passed to the task - not used in this case. */
|
||||||
|
mainREPLICA_C_TASK_PRIORITY, /* The priority assigned to the task. */
|
||||||
|
&xReplC ); /* The task handle is not required, so NULL is passed. */
|
||||||
|
|
||||||
|
xTaskCreate( prvSamplerTask,
|
||||||
|
"Sample",
|
||||||
|
configMINIMAL_STACK_SIZE,
|
||||||
|
NULL,
|
||||||
|
mainSAMPLER_TASK_PRIORITY,
|
||||||
|
NULL );
|
||||||
|
|
||||||
|
xTaskCreate( prvVoterTask,
|
||||||
|
"Voter",
|
||||||
|
configMINIMAL_STACK_SIZE,
|
||||||
|
NULL,
|
||||||
|
mainVOTER_TASK_PRIORITY,
|
||||||
|
NULL );
|
||||||
|
|
||||||
|
/* Start the tasks and timer running. */
|
||||||
|
vTaskStartScheduler();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If all is well, the scheduler will now be running, and the following
|
||||||
|
* line will never be reached. If the following line does execute, then
|
||||||
|
* there was insufficient FreeRTOS heap memory available for the Idle and/or
|
||||||
|
* timer tasks to be created. See the memory management section on the
|
||||||
|
* FreeRTOS web site for more details on the FreeRTOS heap
|
||||||
|
* http://www.freertos.org/a00111.html. */
|
||||||
|
for( ; ; )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
volatile unsigned char WORK_SET[WORK_SET_SIZE] = {0};
|
||||||
|
static int count_up(unsigned char cinput)
|
||||||
|
{
|
||||||
|
int t = 0;
|
||||||
|
for (int i=1; i<cinput; i++)
|
||||||
|
{
|
||||||
|
t+=i;
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
static unsigned char get_average( void )
|
||||||
|
{
|
||||||
|
int tmp = 0;
|
||||||
|
for (int i=0; i<WORK_SET_SIZE; i++)
|
||||||
|
{tmp+=WORK_SET[i];}
|
||||||
|
return (unsigned char)(tmp>>WORK_SET_SIZE_POWER);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void prvSamplerTask( void * pvParameters )
|
||||||
|
{
|
||||||
|
for (int i=0; i<WORK_SET_SIZE; i++)
|
||||||
|
{WORK_SET[i]=fuzz_input_next();}
|
||||||
|
xTaskNotifyGive(xReplA);
|
||||||
|
xTaskNotifyGive(xReplB);
|
||||||
|
}
|
||||||
|
volatile char A_WILL_FAIL = 1;
|
||||||
|
static void prvReplicaA( void * pvParameters )
|
||||||
|
{
|
||||||
|
ulTaskNotifyTake(pdTRUE,portMAX_DELAY);
|
||||||
|
unsigned char tmp = get_average();
|
||||||
|
if (tmp % 11 == 0 && A_WILL_FAIL)
|
||||||
|
{
|
||||||
|
A_WILL_FAIL--;
|
||||||
|
tmp+=1;
|
||||||
|
}
|
||||||
|
int sum = count_up(tmp);
|
||||||
|
xQueueSend( xQueueOutputA, &sum, portMAX_DELAY );
|
||||||
|
}
|
||||||
|
static void prvReplicaB( void * pvParameters )
|
||||||
|
{
|
||||||
|
ulTaskNotifyTake(pdTRUE,portMAX_DELAY);
|
||||||
|
unsigned char tmp = get_average();
|
||||||
|
if (tmp % 12 == 0)
|
||||||
|
{
|
||||||
|
tmp+=2;
|
||||||
|
}
|
||||||
|
int sum = count_up(tmp);
|
||||||
|
xQueueSend( xQueueOutputB, &sum, portMAX_DELAY );
|
||||||
|
}
|
||||||
|
static void prvReplicaC( void * pvParameters )
|
||||||
|
{
|
||||||
|
ulTaskNotifyTake(pdTRUE,portMAX_DELAY);
|
||||||
|
unsigned char tmp = get_average();
|
||||||
|
int sum = count_up(tmp);
|
||||||
|
xQueueSend( xQueueOutputC, &sum, portMAX_DELAY );
|
||||||
|
}
|
||||||
|
static void prvVoterTask( void * pvParameters )
|
||||||
|
{
|
||||||
|
int retries = voterMAXRETRIES+1;
|
||||||
|
int success = 0;
|
||||||
|
unsigned char ulReceivedA = 0;
|
||||||
|
unsigned char ulReceivedB = 0;
|
||||||
|
unsigned char ulReceivedC = 0;
|
||||||
|
do {
|
||||||
|
retries--;
|
||||||
|
xQueueReceive( xQueueOutputA, &ulReceivedA, portMAX_DELAY );
|
||||||
|
xQueueReceive( xQueueOutputB, &ulReceivedC, portMAX_DELAY );
|
||||||
|
if (ulReceivedA!=ulReceivedB) {
|
||||||
|
xTaskNotifyGive(xReplC);
|
||||||
|
xQueueReceive( xQueueOutputC, &ulReceivedC, portMAX_DELAY );
|
||||||
|
if (ulReceivedA==ulReceivedC || ulReceivedB==ulReceivedC)
|
||||||
|
{
|
||||||
|
success=1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
success=1;
|
||||||
|
}
|
||||||
|
} while (!success && retries>0);
|
||||||
|
// Finisched one TMR Cycle
|
||||||
|
trigger_Qemu_break();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
Loading…
x
Reference in New Issue
Block a user