add new watersv2 variant, make interrupts configurable
This commit is contained in:
parent
8bf6ccf6ee
commit
0c130a3f96
@ -94,6 +94,11 @@ ifeq ($(WATERS_DEMO), 1)
|
||||
|
||||
CFLAGS := -DmainCREATE_WATERS_DEMO=1
|
||||
else
|
||||
ifeq ($(WATERSV2_DEMO), 1)
|
||||
SOURCE_FILES += main_watersv2.c
|
||||
|
||||
CFLAGS := -DmainCREATE_WATERS_DEMO=1
|
||||
else
|
||||
ifeq ($(BRANCHLESS_DEMO), 1)
|
||||
SOURCE_FILES += main_micro_branchless.c
|
||||
|
||||
@ -123,6 +128,11 @@ endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(INTERRUPT_ACTIVATION), 1)
|
||||
CFLAGS += -D INTERRUPT_ACTIVATION=1
|
||||
endif
|
||||
|
||||
DEFINES := -DQEMU_SOC_MPS2 -DHEAP3
|
||||
|
||||
|
@ -351,9 +351,12 @@ static void prvTask397( void * pvParameters ) {
|
||||
xTaskNotify(xTask90, DEBUG_VAL(x & 0x1, 0), eSetValueWithOverwrite);
|
||||
// 3 different activation strategies -------------
|
||||
// activate sporadically from interrupts
|
||||
#ifdef INTERRUPT_ACTIVATION
|
||||
ulTaskNotifyTake(pdTRUE,portMAX_DELAY);
|
||||
#else
|
||||
// activate with worst possible frequency (700us, but tick resolution is too low)
|
||||
// vTaskDelayUntil( &xLastWakeTime, xFrequency );
|
||||
vTaskDelayUntil( &xLastWakeTime, xFrequency );
|
||||
#endif
|
||||
// wait pseudo random many ticks
|
||||
// vTaskDelayUntil( &xLastWakeTime, CLAMP(RNG, 1, 100) / portTICK_PERIOD_MS );
|
||||
}
|
||||
@ -377,7 +380,7 @@ static void prvTask90( void * pvParameters ) {
|
||||
torun = CLAMP(x, 0, 20045);
|
||||
}
|
||||
WCET_CLAMP(torun, 0, 20045, TASK_90_MESSAGE)
|
||||
xTaskNotify(xTask1107, DEBUG_VAL(x % 4, 0), eSetValueWithOverwrite);
|
||||
xTaskNotify(xTask1107, DEBUG_VAL(x % 4, 0), eSetValueWithOverwrite);
|
||||
// ---------------------------------------------
|
||||
vTaskDelayUntil( &xLastWakeTime, xFrequency );}
|
||||
}
|
||||
@ -469,7 +472,7 @@ static void prvTask1129( void * pvParameters ) {
|
||||
torun = 80000 + x;
|
||||
}
|
||||
WCET_CLAMP(torun, 0, 145040, TASK_1129_MESSAGE)
|
||||
xTaskNotify(xTask416, do_short_run, eSetValueWithOverwrite);
|
||||
xTaskNotify(xTask416, do_short_run, eSetValueWithOverwrite);
|
||||
// ---------------------------------------------
|
||||
vTaskDelayUntil( &xLastWakeTime, xFrequency );}
|
||||
}
|
||||
|
559
FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_watersv2.c
Normal file
559
FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_watersv2.c
Normal file
@ -0,0 +1,559 @@
|
||||
/*
|
||||
* 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>
|
||||
#include <semphr.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
|
||||
*/
|
||||
|
||||
#define GLOBAL_WCET_MULT 16 // Multiplier to increase all waiting periods to make the schedule more tight an force preemptions
|
||||
#include "arbitrary_loads.c"
|
||||
|
||||
__attribute__((noinline)) static void trigger_Qemu_break( void )
|
||||
{
|
||||
puts("Trigger");
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
// if this macro is set, the code will be modified to produce the worst case
|
||||
#define DEBUG_WCET(A) {A}
|
||||
|
||||
// #define WCET_END(A)
|
||||
#define WCET_END(A) {A}
|
||||
|
||||
#ifdef DEBUG_WCET
|
||||
#define DEBUG_VAL(X,D) (D)
|
||||
// #define WCET_CLAMP(X, LB, UB, LABEL) PRINT_TIME(UB,LABEL)
|
||||
#define WCET_CLAMP(X, LB, UB, LABEL) PRINT_TIME(CLAMP(X,LB,UB),LABEL)
|
||||
#else
|
||||
#define DEBUG_VAL(X,D) (X)
|
||||
#define WCET_CLAMP(X, LB, UB, LABEL) PRINT_TIME(CLAMP(X,LB,UB),LABEL)
|
||||
#define DEBUG_WCET(A)
|
||||
#endif
|
||||
|
||||
// #define INTERRUPT_ACTIVATION 1
|
||||
|
||||
// Begin Input Stuff
|
||||
volatile unsigned char FUZZ_INPUT[4096] = {0xa,0xb,0xc,0xd,0xe,0xf};
|
||||
volatile uint32_t FUZZ_LENGTH = 4096;
|
||||
volatile uint32_t FUZZ_POINTER = 0;
|
||||
// Read the Byte of Input, if the Input is exausted trigger the breakpoint instead
|
||||
static unsigned char fuzz_char_next(void) {
|
||||
// printf("Get next Input from %lx \n",FUZZ_INPUT);
|
||||
if (FUZZ_POINTER < FUZZ_LENGTH) {
|
||||
FUZZ_POINTER++;
|
||||
// printf("Input no. %d %x\n",FUZZ_POINTER-1,FUZZ_INPUT[FUZZ_POINTER-1]);
|
||||
return FUZZ_INPUT[FUZZ_POINTER-1];
|
||||
} else {
|
||||
// puts("End of Input");
|
||||
// Exausted inputs early
|
||||
trigger_Qemu_break();
|
||||
}
|
||||
}
|
||||
static uint16_t fuzz_short_next(void) {
|
||||
unsigned char field[2];
|
||||
field[0]=fuzz_char_next();
|
||||
field[1]=fuzz_char_next();
|
||||
uint16_t* sf = (uint16_t*) field;
|
||||
return *sf;
|
||||
}
|
||||
static uint32_t fuzz_long_next(void) {
|
||||
unsigned char field[4];
|
||||
field[0]=fuzz_char_next();
|
||||
field[1]=fuzz_char_next();
|
||||
field[2]=fuzz_char_next();
|
||||
field[3]=fuzz_char_next();
|
||||
uint32_t* sf = (uint32_t*) field;
|
||||
return *sf;
|
||||
}
|
||||
// End Input Stuff
|
||||
static void prvTask31( void * pvParameters );
|
||||
static void prvTask78( void * pvParameters );
|
||||
static void prvTask90( void * pvParameters );
|
||||
static void prvTask397( void * pvParameters );
|
||||
static void prvTask400( void * pvParameters );
|
||||
static void prvTask416( void * pvParameters );
|
||||
static void prvTask579( void * pvParameters );
|
||||
static void prvTask1009( void * pvParameters );
|
||||
static void prvTask1107( void * pvParameters );
|
||||
static void prvTask1129( void * pvParameters );
|
||||
|
||||
// Priorities using rate-monotonic scheduling
|
||||
// ties are decided favoring short wcets
|
||||
// Chain1: 579 -> 1009 -> 1129 -> 416
|
||||
// 10ms 10ms 10ms 10ms
|
||||
// Chain2: 31 -> 78 -> 400
|
||||
// 100ms 10ms 2ms
|
||||
// Chain3: 397 -> 90 -> 1107
|
||||
// spor 2ms 50ms
|
||||
// cross-chain effect ideas:
|
||||
|
||||
// RM + sort by chains
|
||||
#define mainTASK_31_PRIO ( tskIDLE_PRIORITY + 1 )
|
||||
#define mainTASK_78_PRIO ( tskIDLE_PRIORITY + 5 )
|
||||
#define mainTASK_90_PRIO ( tskIDLE_PRIORITY + 8 )
|
||||
#define mainTASK_397_PRIO ( tskIDLE_PRIORITY + 10 )
|
||||
#define mainTASK_400_PRIO ( tskIDLE_PRIORITY + 9 )
|
||||
#define mainTASK_416_PRIO ( tskIDLE_PRIORITY + 5 )
|
||||
#define mainTASK_579_PRIO ( tskIDLE_PRIORITY + 5 )
|
||||
#define mainTASK_1009_PRIO ( tskIDLE_PRIORITY + 5 )
|
||||
#define mainTASK_1107_PRIO ( tskIDLE_PRIORITY + 2 )
|
||||
#define mainTASK_1129_PRIO ( tskIDLE_PRIORITY + 5 )
|
||||
|
||||
// RM with pref for short
|
||||
// #define mainTASK_31_PRIO ( tskIDLE_PRIORITY + 1 )
|
||||
// #define mainTASK_78_PRIO ( tskIDLE_PRIORITY + 5 )
|
||||
// #define mainTASK_90_PRIO ( tskIDLE_PRIORITY + 8 )
|
||||
// #define mainTASK_397_PRIO ( tskIDLE_PRIORITY + 10 )
|
||||
// #define mainTASK_400_PRIO ( tskIDLE_PRIORITY + 9 )
|
||||
// #define mainTASK_416_PRIO ( tskIDLE_PRIORITY + 4 )
|
||||
// #define mainTASK_579_PRIO ( tskIDLE_PRIORITY + 7 )
|
||||
// #define mainTASK_1009_PRIO ( tskIDLE_PRIORITY + 6 )
|
||||
// #define mainTASK_1107_PRIO ( tskIDLE_PRIORITY + 2 )
|
||||
// #define mainTASK_1129_PRIO ( tskIDLE_PRIORITY + 3 )
|
||||
|
||||
// Same Prio
|
||||
// #define mainTASK_31_PRIO ( tskIDLE_PRIORITY + 1 )
|
||||
// #define mainTASK_78_PRIO ( tskIDLE_PRIORITY + 7 )
|
||||
// #define mainTASK_90_PRIO ( tskIDLE_PRIORITY + 8 )
|
||||
// #define mainTASK_397_PRIO ( tskIDLE_PRIORITY + 10 )
|
||||
// #define mainTASK_400_PRIO ( tskIDLE_PRIORITY + 9 )
|
||||
// #define mainTASK_416_PRIO ( tskIDLE_PRIORITY + 7 )
|
||||
// #define mainTASK_579_PRIO ( tskIDLE_PRIORITY + 7 )
|
||||
// #define mainTASK_1009_PRIO ( tskIDLE_PRIORITY + 7 )
|
||||
// #define mainTASK_1107_PRIO ( tskIDLE_PRIORITY + 2 )
|
||||
// #define mainTASK_1129_PRIO ( tskIDLE_PRIORITY + 7 )
|
||||
|
||||
#define TASK_31_MESSAGE "01"
|
||||
#define TASK_78_MESSAGE "05"
|
||||
#define TASK_90_MESSAGE "08"
|
||||
#define TASK_397_MESSAGE "10"
|
||||
#define TASK_400_MESSAGE "09"
|
||||
#define TASK_416_MESSAGE "03"
|
||||
#define TASK_579_MESSAGE "07"
|
||||
#define TASK_1009_MESSAGE "06"
|
||||
#define TASK_1107_MESSAGE "02"
|
||||
#define TASK_1129_MESSAGE "04"
|
||||
|
||||
// Handles for direct messages
|
||||
static TaskHandle_t xTask31 = NULL;
|
||||
static TaskHandle_t xTask78 = NULL;
|
||||
static TaskHandle_t xTask90 = NULL;
|
||||
static TaskHandle_t xTask397 = NULL;
|
||||
static TaskHandle_t xTask400 = NULL;
|
||||
static TaskHandle_t xTask416 = NULL;
|
||||
static TaskHandle_t xTask579 = NULL;
|
||||
static TaskHandle_t xTask1009 = NULL;
|
||||
static TaskHandle_t xTask1107 = NULL;
|
||||
static TaskHandle_t xTask1129 = NULL;
|
||||
|
||||
static SemaphoreHandle_t xSemaphoreSpor;
|
||||
|
||||
void main_waters( void )
|
||||
{
|
||||
xSemaphoreSpor = xSemaphoreCreateBinary();
|
||||
xSemaphoreGive(xSemaphoreSpor);
|
||||
// puts("Main function");
|
||||
/* Start the two tasks as described in the comments at the top of this
|
||||
* file. */
|
||||
xTaskCreate( prvTask31, /* The function that implements the task. */
|
||||
"31", /* 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. */
|
||||
mainTASK_31_PRIO, /* The priority assigned to the task. */
|
||||
&xTask31 ); /* The task handle is not required, so NULL is passed. */
|
||||
|
||||
xTaskCreate( prvTask78, /* The function that implements the task. */
|
||||
"78", /* 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. */
|
||||
mainTASK_78_PRIO, /* The priority assigned to the task. */
|
||||
&xTask78 ); /* The task handle is not required, so NULL is passed. */
|
||||
|
||||
xTaskCreate( prvTask90,
|
||||
"90",
|
||||
configMINIMAL_STACK_SIZE,
|
||||
NULL,
|
||||
mainTASK_90_PRIO,
|
||||
&xTask90 );
|
||||
|
||||
// This task is supposed to be sporadic
|
||||
xTaskCreate( prvTask397,
|
||||
"397",
|
||||
configMINIMAL_STACK_SIZE,
|
||||
NULL,
|
||||
mainTASK_397_PRIO,
|
||||
&xTask397 );
|
||||
|
||||
xTaskCreate( prvTask400,
|
||||
"400",
|
||||
configMINIMAL_STACK_SIZE,
|
||||
NULL,
|
||||
mainTASK_400_PRIO,
|
||||
&xTask400 );
|
||||
|
||||
xTaskCreate( prvTask416,
|
||||
"416",
|
||||
configMINIMAL_STACK_SIZE,
|
||||
NULL,
|
||||
mainTASK_416_PRIO,
|
||||
&xTask416 );
|
||||
|
||||
xTaskCreate( prvTask579,
|
||||
"579",
|
||||
configMINIMAL_STACK_SIZE,
|
||||
NULL,
|
||||
mainTASK_579_PRIO,
|
||||
&xTask579 );
|
||||
|
||||
xTaskCreate( prvTask1009,
|
||||
"1009",
|
||||
configMINIMAL_STACK_SIZE,
|
||||
NULL,
|
||||
mainTASK_1009_PRIO,
|
||||
&xTask1009 );
|
||||
|
||||
xTaskCreate( prvTask1107,
|
||||
"1107",
|
||||
configMINIMAL_STACK_SIZE,
|
||||
NULL,
|
||||
mainTASK_1107_PRIO,
|
||||
&xTask1107 );
|
||||
|
||||
xTaskCreate( prvTask1129,
|
||||
"1129",
|
||||
configMINIMAL_STACK_SIZE,
|
||||
NULL,
|
||||
mainTASK_1129_PRIO,
|
||||
&xTask1129 );
|
||||
|
||||
|
||||
/* Start the tasks and timer running. */
|
||||
// puts("Start scheduler");
|
||||
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( ; ; )
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
// Chain2: 31 -> 78 -> 400
|
||||
static void prvTask31( void * pvParameters ) {
|
||||
TickType_t xLastWakeTime = xTaskGetTickCount();
|
||||
const TickType_t xFrequency = 100 / portTICK_PERIOD_MS;
|
||||
// int period_counter = 2;
|
||||
for( ;; ){
|
||||
// WCET_END({if (--period_counter==0) {puts("End");}}) // Debugging
|
||||
// Actions --------------------------------------
|
||||
// Exectime: f(x) = x
|
||||
// Output: g(x) = x % 2
|
||||
volatile uint16_t x = fuzz_short_next();
|
||||
DEBUG_WCET(x=48940;)
|
||||
WCET_CLAMP(x, 0, 48940, TASK_31_MESSAGE)
|
||||
// WCET_END({trigger_Qemu_break();})
|
||||
xTaskNotify(xTask78, DEBUG_VAL(1 + x % 2, 1+1), eSetValueWithOverwrite);
|
||||
// ---------------------------------------------
|
||||
vTaskDelayUntil( &xLastWakeTime, xFrequency );}// Wait for the next cycle.
|
||||
}
|
||||
|
||||
// Chain2: 31 -> 78 -> 400
|
||||
static void prvTask78( void * pvParameters ) {
|
||||
TickType_t xLastWakeTime = xTaskGetTickCount();
|
||||
const TickType_t xFrequency = 10 / portTICK_PERIOD_MS;
|
||||
for( ;; ){
|
||||
// Actions --------------------------------------
|
||||
// Exectime: f(x,y) = c + y*20000 + rng(x)*50000
|
||||
// Output: g(x,y) = y * (x % 4)
|
||||
uint16_t x = fuzz_short_next();
|
||||
int y = ulTaskNotifyTake(pdTRUE, 0);
|
||||
volatile int torun = 6035;
|
||||
if (y > 1) {
|
||||
torun += 20000;
|
||||
}
|
||||
if (DEBUG_VAL(CHANCE_1_IN_POWOF2(x, 5), 1)) {
|
||||
torun += 50000;
|
||||
}
|
||||
WCET_CLAMP(torun, 0, 76035, TASK_78_MESSAGE)
|
||||
if (y--) {
|
||||
xTaskNotify(xTask400, DEBUG_VAL(1 + y * (x % 4), 1+2), eSetValueWithOverwrite);
|
||||
}
|
||||
// ---------------------------------------------
|
||||
vTaskDelayUntil( &xLastWakeTime, xFrequency );}
|
||||
}
|
||||
|
||||
// Chain2: 31 -> 78 -> 400
|
||||
static void prvTask400( void * pvParameters ) {
|
||||
TickType_t xLastWakeTime = xTaskGetTickCount();
|
||||
const TickType_t xFrequency = 2 / portTICK_PERIOD_MS;
|
||||
for( ;; ){
|
||||
// Actions --------------------------------------
|
||||
// Exectime: f(x,y) = rng(x)*y*c or (rng(x) % 1000)
|
||||
uint32_t x = fuzz_long_next();
|
||||
int y = ulTaskNotifyTake(pdTRUE, 0);
|
||||
volatile int torun = 0;
|
||||
if (y == 3 && DEBUG_VAL(CHANCE_1_IN_POWOF2(x, 2), 1)) {
|
||||
torun = 1765;
|
||||
} else {
|
||||
torun = RNG_FROM(x) % 1000;
|
||||
DEBUG_WCET(torun=999;)
|
||||
}
|
||||
WCET_CLAMP(torun, 0, 1765, TASK_400_MESSAGE)
|
||||
if (y) {
|
||||
WCET_END({trigger_Qemu_break();})
|
||||
}
|
||||
// ---------------------------------------------
|
||||
vTaskDelayUntil( &xLastWakeTime, xFrequency );}
|
||||
}
|
||||
|
||||
//==================================================================
|
||||
|
||||
// Chain3: 397 -> 90 -> 1107
|
||||
static void prvTask397( void * pvParameters ) {
|
||||
TickType_t xLastWakeTime = xTaskGetTickCount();
|
||||
const TickType_t xFrequency = 1 / portTICK_PERIOD_MS;
|
||||
for( ;; ){
|
||||
// 3 different activation strategies -------------
|
||||
// activate sporadically from interrupts
|
||||
#ifdef INTERRUPT_ACTIVATION
|
||||
ulTaskNotifyTake(pdTRUE,portMAX_DELAY);
|
||||
#else
|
||||
// activate with worst possible frequency (700us, but tick resolution is too low)
|
||||
vTaskDelayUntil( &xLastWakeTime, xFrequency );
|
||||
#endif
|
||||
// wait pseudo random many ticks
|
||||
// vTaskDelayUntil( &xLastWakeTime, CLAMP(RNG, 1, 100) / portTICK_PERIOD_MS );
|
||||
// -----------------------------------------------
|
||||
// Exectime: f(x) = x
|
||||
// Output: g(x) = x % 2
|
||||
volatile uint16_t x = fuzz_short_next();
|
||||
DEBUG_WCET(x=5830;)
|
||||
WCET_CLAMP(x, 0, 5830, TASK_397_MESSAGE);
|
||||
if (CHANCE_1_IN_POWOF2(x, 2)) {
|
||||
if (xSemaphoreTake(xSemaphoreSpor, 0)) {
|
||||
xTaskNotify(xTask579, DEBUG_VAL(1 + x & 0x1, 1), eSetValueWithOverwrite);
|
||||
xSemaphoreGive(xSemaphoreSpor);
|
||||
}
|
||||
} else {
|
||||
xTaskNotify(xTask90, DEBUG_VAL(1 + x & 0x1, 1), eSetValueWithOverwrite);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Chain3: 397 -> 90 -> 1107
|
||||
static void prvTask90( void * pvParameters ) {
|
||||
TickType_t xLastWakeTime = xTaskGetTickCount();
|
||||
const TickType_t xFrequency = 2 / portTICK_PERIOD_MS;
|
||||
for( ;; ){
|
||||
// Actions --------------------------------------
|
||||
// Exectime: f(x) = c + x
|
||||
// Output: g(x) = x % 4
|
||||
int y = ulTaskNotifyTake(pdTRUE, 0);
|
||||
volatile uint16_t x = fuzz_short_next();
|
||||
DEBUG_WCET(x=20048;)
|
||||
int torun = 0;
|
||||
if (y == 2) {
|
||||
torun = CLAMP(x, 5000, 10000);
|
||||
} else {
|
||||
torun = CLAMP(x, 0, 20045);
|
||||
}
|
||||
WCET_CLAMP(torun, 0, 20045, TASK_90_MESSAGE)
|
||||
if (y) {
|
||||
xTaskNotify(xTask1107, DEBUG_VAL(x % 4, 0), eSetValueWithOverwrite);
|
||||
}
|
||||
// ---------------------------------------------
|
||||
vTaskDelayUntil( &xLastWakeTime, xFrequency );}
|
||||
}
|
||||
|
||||
// Chain3: 397 -> 90 -> 1107
|
||||
static void prvTask1107( void * pvParameters ) {
|
||||
TickType_t xLastWakeTime = xTaskGetTickCount();
|
||||
const TickType_t xFrequency = 50 / portTICK_PERIOD_MS;
|
||||
for( ;; ){
|
||||
// Actions --------------------------------------
|
||||
// Exectime: f(x) = c - x*y
|
||||
volatile uint16_t x = fuzz_short_next();
|
||||
DEBUG_WCET(x=0;)
|
||||
int y = ulTaskNotifyTake(pdTRUE, 0);
|
||||
int torun = 76865-((int)x)*y;
|
||||
WCET_CLAMP(torun, 10000, 76865, TASK_1107_MESSAGE)
|
||||
// ---------------------------------------------
|
||||
vTaskDelayUntil( &xLastWakeTime, xFrequency );}
|
||||
}
|
||||
|
||||
//==================================================================
|
||||
|
||||
static int sem_at_579 = 0;
|
||||
// Chain1: 579 -> 1009 -> 1129 -> 416
|
||||
static void prvTask579( void * pvParameters ) {
|
||||
// int period = 5;
|
||||
TickType_t xLastWakeTime = xTaskGetTickCount();
|
||||
const TickType_t xFrequency = 10 / portTICK_PERIOD_MS;
|
||||
for( ;; ){
|
||||
// if (--period==0) {puts("End");} // Debugging Marker
|
||||
// Actions --------------------------------------
|
||||
// Exectime: f(x) = x>>8 & 0x0fff
|
||||
// Output: g(x) = x % 8
|
||||
int y = ulTaskNotifyTake(pdTRUE, 0);
|
||||
if (y && !sem_at_579) {
|
||||
sem_at_579 = xSemaphoreTake(xSemaphoreSpor, portMAX_DELAY);
|
||||
}
|
||||
uint32_t x = fuzz_long_next();
|
||||
volatile int torun = (x>>8) & 0x0fff;
|
||||
DEBUG_WCET(torun = 0x0fff;)
|
||||
WCET_CLAMP(torun, 500, 2460, TASK_579_MESSAGE)
|
||||
if (y && sem_at_579) {
|
||||
xTaskNotify(xTask1009, DEBUG_VAL(1 + x % 8, 1), eSetValueWithOverwrite);
|
||||
}
|
||||
if (sem_at_579) {
|
||||
int val = ulTaskNotifyTakeIndexed(1, pdTRUE, xFrequency); // wait for the chain to finish
|
||||
if (val == 1337) {
|
||||
sem_at_579 = xSemaphoreGive(xSemaphoreSpor);
|
||||
}
|
||||
}
|
||||
// ---------------------------------------------
|
||||
vTaskDelayUntil( &xLastWakeTime, xFrequency );}
|
||||
}
|
||||
|
||||
// Chain1: 579 -> 1009 -> 1129 -> 416
|
||||
static void prvTask1009( void * pvParameters ) {
|
||||
TickType_t xLastWakeTime = xTaskGetTickCount();
|
||||
const TickType_t xFrequency = 10 / portTICK_PERIOD_MS;
|
||||
for( ;; ){
|
||||
// Actions --------------------------------------
|
||||
// Exectime: f(x,y) = if x%8 == y ? 40000+x : x (<40k)
|
||||
// Output: g(x) = x % 8 == y
|
||||
uint16_t x = fuzz_short_next();
|
||||
int y = ulTaskNotifyTake(pdTRUE, 0);
|
||||
volatile int torun = 0;
|
||||
if (x % 8 == (y-1)) {
|
||||
torun = 40000 + x;
|
||||
} else {
|
||||
torun = CLAMP(x, 0, 40000);
|
||||
}
|
||||
DEBUG_WCET(torun = 51485;)
|
||||
WCET_CLAMP(torun, 0, 51485, TASK_1009_MESSAGE)
|
||||
if (y--) {
|
||||
xTaskNotify(xTask1129, DEBUG_VAL(1 + x % 8 == y, 2), eSetValueWithOverwrite);
|
||||
}
|
||||
// ---------------------------------------------
|
||||
vTaskDelayUntil( &xLastWakeTime, xFrequency );}
|
||||
}
|
||||
|
||||
// Chain1: 579 -> 1009 -> 1129 -> 416
|
||||
static void prvTask1129( void * pvParameters ) {
|
||||
int period_counter = 2;
|
||||
TickType_t xLastWakeTime = xTaskGetTickCount();
|
||||
const TickType_t xFrequency = 10 / portTICK_PERIOD_MS;
|
||||
for( ;; ){
|
||||
// if (--period_counter==0) {puts("End");}
|
||||
// Actions --------------------------------------
|
||||
// Exectime: f(x,y) = if y && rng(x) ? c1+x : c2+x
|
||||
// Output: g(x) = y && rng(x)
|
||||
// longmax - shortmax: 39505
|
||||
// most likely long case, which causes a short case in next task
|
||||
volatile uint32_t x = (uint32_t)fuzz_short_next();
|
||||
int y = ulTaskNotifyTake(pdTRUE, 0);
|
||||
DEBUG_WCET(
|
||||
static char flag=0;
|
||||
if (flag++ == 0 | flag == 5 | flag == 8 | flag == 9) {x = 65529;}
|
||||
else {x = 0xffff;}
|
||||
)
|
||||
volatile int do_short_run = (y-1 + CHANCE_1_IN_POWOF2(x, 5)) == 1; // XOR
|
||||
int torun = 0;
|
||||
if (do_short_run > 0) {
|
||||
torun = 40000 + x;
|
||||
} else {
|
||||
torun = 80000 + x;
|
||||
}
|
||||
WCET_CLAMP(torun, 0, 145040, TASK_1129_MESSAGE)
|
||||
if (y--) {
|
||||
xTaskNotify(xTask416, do_short_run, eSetValueWithOverwrite);
|
||||
}
|
||||
// ---------------------------------------------
|
||||
vTaskDelayUntil( &xLastWakeTime, xFrequency );}
|
||||
}
|
||||
|
||||
// Chain1: 579 -> 1009 -> 1129 -> 416
|
||||
static void prvTask416( void * pvParameters ) {
|
||||
TickType_t xLastWakeTime = xTaskGetTickCount();
|
||||
const TickType_t xFrequency = 10 / portTICK_PERIOD_MS;
|
||||
for( ;; ){
|
||||
// Actions --------------------------------------
|
||||
// Exectime: f(x,y) = if y ? c1+2*x : c2-x
|
||||
// longmax - shortmax: 76955
|
||||
volatile uint32_t x = (uint32_t)fuzz_short_next();
|
||||
int y = ulTaskNotifyTake(pdTRUE, 0);
|
||||
volatile int torun = 0;
|
||||
if (y-1) {
|
||||
DEBUG_WCET(x=0xffff;)
|
||||
torun = x*3;
|
||||
} else {
|
||||
DEBUG_WCET(x=0;)
|
||||
torun = 50000 - CLAMP_CEILING(x, 50000);
|
||||
}
|
||||
WCET_CLAMP(torun, 10000, 126955, TASK_416_MESSAGE)
|
||||
if (y--) {
|
||||
xTaskNotifyIndexed(xTask579, 1, 1337, eSetValueWithOverwrite);
|
||||
}
|
||||
// ---------------------------------------------
|
||||
vTaskDelayUntil( &xLastWakeTime, xFrequency );}
|
||||
}
|
||||
|
||||
void vWatersIdleFunction() {
|
||||
for (int i; i<1000; i++) {
|
||||
puts("0 ");
|
||||
}
|
||||
}
|
||||
|
||||
void isr_starter( void )
|
||||
{
|
||||
puts("Interrupt");
|
||||
if (xTask397) {
|
||||
vTaskNotifyGiveFromISR(xTask397, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
Loading…
x
Reference in New Issue
Block a user