From 39d2851bcc8ea903579c74aa2d7c00231bd37ca3 Mon Sep 17 00:00:00 2001 From: Alwin Berger Date: Wed, 12 Feb 2025 17:01:08 +0100 Subject: [PATCH] unify input handling, data dependencies for copter --- .../Demo/CORTEX_M3_MPS2_QEMU_GCC/Makefile | 13 +- .../CORTEX_M3_MPS2_QEMU_GCC/copter_input.c | 10 +- .../Demo/CORTEX_M3_MPS2_QEMU_GCC/fuzzhelper.c | 140 +++++++ .../CORTEX_M3_MPS2_QEMU_GCC/main_copter.c | 124 ++---- .../CORTEX_M3_MPS2_QEMU_GCC/main_release.c | 135 ++---- .../CORTEX_M3_MPS2_QEMU_GCC/main_waters.c | 384 +++++++----------- 6 files changed, 377 insertions(+), 429 deletions(-) create mode 100644 FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/fuzzhelper.c diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/Makefile b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/Makefile index cd36ffa8..e80848e9 100644 --- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/Makefile +++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/Makefile @@ -178,18 +178,19 @@ endif endif endif -ifeq ($(FUZZ_BYTES), 1) - CFLAGS += -D FUZZ_BYTES=1 +ifeq ($(IGNORE_BYTES), 1) + CFLAGS += -D IGNORE_BYTES=1 endif -ifeq ($(FUZZ_INT_ACTIVATION), 1) - CFLAGS += -D FUZZ_INT_ACTIVATION=1 +ifeq ($(IGNORE_INTERRUPTS), 1) + CFLAGS += -D IGNORE_INTERRUPTS=1 endif ifeq ($(PARTITION_INPUT), 1) CFLAGS += -D PARTITION_INPUT=1 endif -ifeq ($(DELETE_RNG_STATE), 1) - CFLAGS += -D DELETE_RNG_STATE=1 +ifeq ($(IGNORE_INTERNAL_STATE), 1) + CFLAGS += -D IGNORE_INTERNAL_STATE=1 endif +CFLAGS += $(SPECIAL_CFLAGS) DEFINES := -DQEMU_SOC_MPS2 -DHEAP3 diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/copter_input.c b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/copter_input.c index 5a273fa2..8d533151 100644 --- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/copter_input.c +++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/copter_input.c @@ -61,16 +61,16 @@ unsigned char max_input_for_seed_after(int seed, int iter, unsigned char goal) { unsigned char FUZZ_INPUT[MAX_INPUT_BYTES] = {0}; size_t INPUT_POINTER = 0; -size_t INPUT_POINTERS[NUM_TASKS] = {0}; +size_t INPUT_CURSORS[NUM_TASKS] = {0}; static unsigned char fuzz_char_next(int tasknum) { - if (INPUT_POINTERS[tasknum] == 0) { - INPUT_POINTERS[tasknum] = tasknum * (MAX_INPUT_BYTES / NUM_TASKS); + if (INPUT_CURSORS[tasknum] == 0) { + INPUT_CURSORS[tasknum] = tasknum * (MAX_INPUT_BYTES / NUM_TASKS); } - if (INPUT_POINTERS[tasknum] >= (tasknum+1) * (MAX_INPUT_BYTES / NUM_TASKS)) { + if (INPUT_CURSORS[tasknum] >= (tasknum+1) * (MAX_INPUT_BYTES / NUM_TASKS)) { exit(1); } - return FUZZ_INPUT[INPUT_POINTERS[tasknum]++]; + return FUZZ_INPUT[INPUT_CURSORS[tasknum]++]; } volatile int RNG_STATES[NUM_TASKS] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14}; diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/fuzzhelper.c b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/fuzzhelper.c new file mode 100644 index 00000000..b1109522 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/fuzzhelper.c @@ -0,0 +1,140 @@ +#ifndef __FUZZHELPER_C__ +#define __FUZZHELPER_C__ +#include "arbitrary_loads.c" +#include + +// #define IGNORE_BYTES +// #define IGNORE_INTERRUPTS +// #define IGNORE_INTERNAL_STATE + +/* Defaults */ +#ifndef NUM_TASKS + #define NUM_TASKS 16 +#endif +#ifndef MAX_INPUT_BYTES + #define MAX_INPUT_BYTES 4096 +#endif +#ifndef NUM_OUTPUT_BITS + #define NUM_OUTPUT_BITS 3 +#endif +#define OUTPUT_BITS(X) (X & ((1 << NUM_OUTPUT_BITS) - 1)) + +// Breakpoint when done +__attribute__((noinline)) static void trigger_Qemu_break( void ) +{ + puts("Trigger"); + while (1) { + } +} + +// Signal job response +__attribute__((noinline)) static void trigger_job_done( void ) +{ + puts("Job Done"); +} + +// Begin Input Stuff +volatile uint8_t FUZZ_INPUT[MAX_INPUT_BYTES] = {}; +volatile uint32_t INPUT_CURSORS[NUM_TASKS] = {}; +volatile uint32_t FUZZ_LENGTH = MAX_INPUT_BYTES;// ignored + +volatile uint32_t LAST_INPUTS[NUM_TASKS] = {}; // record the last input per job +#define TASK_LAST_INPUT LAST_INPUTS[task_id] + +// Read the Byte of Input, if the Input is exausted trigger the breakpoint instead +static uint8_t fuzz_char_next(int tasknum) { +#ifdef IGNORE_BYTES + return LAST_INPUTS[NUM_TASKS]=255; +#endif +#ifdef PARTITION_INPUT + if (INPUT_CURSORS[tasknum] == 0) { + // Initial setup + INPUT_CURSORS[tasknum] = tasknum * (MAX_INPUT_BYTES / NUM_TASKS); + } + if (INPUT_CURSORS[tasknum] >= (tasknum+1) * (MAX_INPUT_BYTES / NUM_TASKS)) { + trigger_Qemu_break(); + } + return LAST_INPUTS[NUM_TASKS]=FUZZ_INPUT[INPUT_CURSORS[tasknum]++]; +#else + if (INPUT_CURSORS[0] < FUZZ_LENGTH) { + INPUT_CURSORS[0]++; + return LAST_INPUTS[NUM_TASKS]=FUZZ_INPUT[INPUT_CURSORS[0]-1]; + } else { + // Exausted inputs early + trigger_Qemu_break(); + } +#endif +} +static uint16_t fuzz_short_next(int tasknum) { + uint8_t field[2]; + field[0]=fuzz_char_next(tasknum); + field[1]=fuzz_char_next(tasknum); + uint16_t* sf = (uint16_t*) field; + return LAST_INPUTS[NUM_TASKS]=*sf; +} +static uint32_t fuzz_long_next(int tasknum) { + uint8_t field[4]; + field[0]=fuzz_char_next(tasknum); + field[1]=fuzz_char_next(tasknum); + field[2]=fuzz_char_next(tasknum); + field[3]=fuzz_char_next(tasknum); + uint32_t* sf = (uint32_t*) field; + return LAST_INPUTS[NUM_TASKS]=*sf; +} +#define INPUT_CHAR_NEXT rng_char_next(task_id) +#define INPUT_SHORT_NEXT rng_short_next(task_id) +#define INPUT_LONG_NEXT rng_long_next(task_id) + +// Randomization +volatile uint32_t RNG_STATES[NUM_TASKS] = {}; +#define TASK_RNG_STATE RNG_STATES[task_id] + +static uint8_t rng_char_next(int tasknum) { + #ifdef IGNORE_BYTES + return 0xFF; + #endif + RNG_STATES[tasknum] = RNG_FROM(RNG_STATES[tasknum]); + uint8_t i = fuzz_char_next(tasknum); + uint8_t val = RNG_STATES[tasknum] ^ (uint32_t)i; + return val; +} +static uint16_t rng_short_next(int tasknum) { + #ifdef IGNORE_BYTES + return 0xFFFF; + #endif + RNG_STATES[tasknum] = RNG_FROM(RNG_STATES[tasknum]); + uint16_t i = fuzz_short_next(tasknum); + uint16_t val = RNG_STATES[tasknum] ^ (uint32_t)i; + return val; +} +static uint32_t rng_long_next(int tasknum) { + #ifdef IGNORE_BYTES + return 0xFFFFFFFF; + #endif + RNG_STATES[tasknum] = RNG_FROM(RNG_STATES[tasknum]); + uint32_t i = fuzz_long_next(tasknum); + uint32_t val = RNG_STATES[tasknum] ^ (uint32_t)i; + return val; +} +static uint32_t rng_roll(int tasknum) { + RNG_STATES[tasknum] = RNG_FROM(RNG_STATES[tasknum]); + return RNG_STATES[tasknum]; +} + +#ifdef IGNORE_INTERNAL_STATE + #define RNG_RESET {RNG_STATES[task_id] = task_id;} +#else + #define RNG_RESET {} +#endif + +#define RNG_CHAR_NEXT rng_char_next(task_id) +#define RNG_SHORT_NEXT rng_short_next(task_id) +#define RNG_LONG_NEXT rng_long_next(task_id) +#define RNG_ROLL rng_roll(task_id) + + +// End Input Stuff + + + +#endif \ No newline at end of file diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_copter.c b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_copter.c index 3f48774e..94080593 100644 --- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_copter.c +++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_copter.c @@ -7,78 +7,30 @@ #define GLOBAL_WCET_MULT \ 1 // Multiplier to increase all waiting periods to make the schedule more // tight and force preemptions -#include "arbitrary_loads.c" +#define NUM_TASKS 15 +#include "fuzzhelper.c" #ifdef INSERT_WC #include "wcinput.h" #endif -#define NUM_TASKS 15 -#define MAX_INPUT_BYTES 4096 -volatile unsigned char FUZZ_INPUT[MAX_INPUT_BYTES] = {}; -volatile int INPUT_POINTERS[NUM_TASKS] = {}; -volatile uint32_t FUZZ_LENGTH = MAX_INPUT_BYTES;// ignored - -#ifdef DELETE_RNG_STATE -#define RNG_RESET {RNG_STATES[task_id] = task_id;} -#else -#define RNG_RESET {} -#endif - -__attribute__((noinline)) static void trigger_Qemu_break( void ) -{ - puts("Trigger"); - while (1) { - } -} -__attribute__((noinline)) static void trigger_job_done( void ) -{ - puts("Job Done"); -} - -static unsigned char fuzz_char_next(int tasknum) { -#ifdef PARTITION_INPUT - if (INPUT_POINTERS[tasknum] == 0) { - INPUT_POINTERS[tasknum] = tasknum * (MAX_INPUT_BYTES / NUM_TASKS); - } - if (INPUT_POINTERS[tasknum] >= (tasknum+1) * (MAX_INPUT_BYTES / NUM_TASKS)) { - trigger_Qemu_break(); - } - return FUZZ_INPUT[INPUT_POINTERS[tasknum]++]; -#else - // printf("Get next Input from %lx \n",FUZZ_INPUT); - if (INPUT_POINTERS[0] < FUZZ_LENGTH) { - INPUT_POINTERS[0]++; - // printf("Input no. %d %x\n",FUZZ_POINTER-1,FUZZ_INPUT[FUZZ_POINTER-1]); - return FUZZ_INPUT[INPUT_POINTERS[0]-1]; - } else { - // puts("End of Input"); - // Exausted inputs early - trigger_Qemu_break(); - } -#endif -} - -volatile int RNG_STATES[NUM_TASKS] = {}; -static unsigned char next(int tasknum) { - #ifndef FUZZ_BYTES - return 255; - #endif - RNG_STATES[tasknum] = RNG_FROM(RNG_STATES[tasknum]); - unsigned char i = fuzz_char_next(tasknum); - unsigned char val = RNG_STATES[tasknum] ^ (int)i; - return val; -} - // #define SHORT_CALC 50 // #define LONG_CALC 200 -#ifdef FUZZ_BYTES -#define SHORT_CALC (15+next(task_id)%35) -#define LONG_CALC (50+next(task_id)%150) +#ifdef IGNORE_BYTES + #define SHORT_CALC (50) + #define LONG_CALC (200) + #define MAKE_OUTPUT (0) #else -#define SHORT_CALC (50) -#define LONG_CALC (200) + #define SHORT_CALC (15+RNG_CHAR_NEXT%35) + #define LONG_CALC (50+RNG_CHAR_NEXT%150) + #define MAKE_OUTPUT (OUTPUT_BITS(TASK_LAST_INPUT^RNG_ROLL)) +#endif + +#ifdef COPTER_DATAFLOW + #define STATE_PLUS_DATA(X) {TASK_RNG_STATE+=(X);} +#else + #define STATE_PLUS_DATA(X) {} #endif #define HYPER_PERIOD 9 @@ -236,9 +188,9 @@ static void prv_SignalGatherInitiateTask(void *pvParameters) { xSemaphoreTake(xSemaphore_SPIBus, portMAX_DELAY); WASTE_USEC(LONG_CALC); if ((round % 2) == 0) { - xTaskNotify(xTask_SignalGatherTimeoutTask, 0, eNoAction); + xTaskNotify(xTask_SignalGatherTimeoutTask, MAKE_OUTPUT, eSetValueWithOverwrite); } else { - xTaskNotify(xTask_SignalGatherFinishedTask, 0, eNoAction); + xTaskNotify(xTask_SignalGatherFinishedTask, MAKE_OUTPUT, eSetValueWithOverwrite); } round++; WASTE_USEC(LONG_CALC); @@ -254,11 +206,12 @@ static void prv_SignalGatherFinishedTask(void *pvParameters) { trigger_job_done(); do { RNG_RESET - ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + unsigned long int y = ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + STATE_PLUS_DATA(y) // introduce a data dependency WASTE_USEC(LONG_CALC); - xTaskNotify(xTask_SignalProcessingAttitudeTask, 0, eNoAction); + xTaskNotify(xTask_SignalProcessingAttitudeTask, MAKE_OUTPUT, eSetValueWithOverwrite); WASTE_USEC(LONG_CALC); - xTaskNotify(xTask_SignalProcessingActuateTask, 0, eNoAction); + xTaskNotify(xTask_SignalProcessingActuateTask, MAKE_OUTPUT, eSetValueWithOverwrite); WASTE_USEC(LONG_CALC); trigger_job_done(); } while (1); @@ -269,13 +222,14 @@ static void prv_SignalGatherTimeoutTask(void *pvParameters) { trigger_job_done(); do { RNG_RESET - ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + unsigned long int y = ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + STATE_PLUS_DATA(y) // introduce a data dependency WASTE_USEC(LONG_CALC); xSemaphoreTake(xSemaphore_SPIBus, portMAX_DELAY); WASTE_USEC(LONG_CALC); xSemaphoreGive(xSemaphore_SPIBus); WASTE_USEC(LONG_CALC); - xTaskNotify(xTask_SignalGatherFinishedTask, 0, eNoAction); + xTaskNotify(xTask_SignalGatherFinishedTask, MAKE_OUTPUT, eSetValueWithOverwrite); trigger_job_done(); } while (1); } @@ -287,7 +241,8 @@ static void prv_SignalProcessingActuateTask(void *pvParameters) { trigger_job_done(); do { RNG_RESET - ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + unsigned long int y = ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + STATE_PLUS_DATA(y) // introduce a data dependency WASTE_USEC(LONG_CALC); trigger_job_done(); } while (1); @@ -298,9 +253,9 @@ static void prv_SignalProcessingAttitudeTask(void *pvParameters) { trigger_job_done(); do { RNG_RESET - ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + unsigned long int y = ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + STATE_PLUS_DATA(y) // introduce a data dependency WASTE_USEC(LONG_CALC); - // timing_end(0); trigger_job_done(); } while (1); } @@ -313,9 +268,9 @@ static void prv_FlightControlTask(void *pvParameters) { RNG_RESET // timing_start(1 | TIMING_POINT_IS_HIGHEST_PRIO); WASTE_USEC(LONG_CALC); - xTaskNotify(xTask_FlightControlAttitudeTask, 0, eNoAction); - xTaskNotify(xTask_FlightControlActuateTask, 0, eNoAction); - xTaskNotify(xTask_MavlinkSendTask, 0, eNoAction); + xTaskNotify(xTask_FlightControlAttitudeTask, 0, eSetValueWithOverwrite); + xTaskNotify(xTask_FlightControlActuateTask, 0, eSetValueWithOverwrite); + xTaskNotify(xTask_MavlinkSendTask, 0, eSetValueWithOverwrite); WASTE_USEC(LONG_CALC); trigger_job_done(); xTaskDelayUntil( &xLastWakeTime, xFrequency ); @@ -327,7 +282,8 @@ static void prv_FlightControlAttitudeTask(void *pvParameters) { trigger_job_done(); do { RNG_RESET - ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + unsigned long int y = ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + STATE_PLUS_DATA(y) // introduce a data dependency WASTE_USEC(LONG_CALC); trigger_job_done(); } while (1); @@ -338,7 +294,8 @@ static void prv_FlightControlActuateTask(void *pvParameters) { trigger_job_done(); do { RNG_RESET - ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + unsigned long int y = ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + STATE_PLUS_DATA(y) // introduce a data dependency WASTE_USEC(LONG_CALC); trigger_job_done(); } while (1); @@ -349,7 +306,8 @@ static void prv_MavlinkSendTask(void *pvParameters) { trigger_job_done(); do { RNG_RESET - ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + unsigned long int y = ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + STATE_PLUS_DATA(y) // introduce a data dependency WASTE_USEC(LONG_CALC); xSemaphoreTake(xSemaphore_SPIBus, portMAX_DELAY); WASTE_USEC(SHORT_CALC); @@ -363,18 +321,18 @@ static void prv_MavlinkSendTask(void *pvParameters) { static void prv_CopterControlTask(void *pvParameters) { const int task_id = 9; - #ifndef FUZZ_INT_ACTIVATION TickType_t xLastWakeTime = initial_release_time; const TickType_t xFrequency = 5 / portTICK_PERIOD_MS; - #endif trigger_job_done(); do { RNG_RESET - #ifdef FUZZ_INT_ACTIVATION - ulTaskNotifyTake(pdTRUE, portMAX_DELAY); + #ifndef IGNORE_INTERRUPTS + unsigned long int y = ulTaskNotifyTake(pdTRUE, portMAX_DELAY); #else xTaskDelayUntil( &xLastWakeTime, xFrequency ); + unsigned long int y = ulTaskNotifyTake(pdTRUE, 0); #endif + STATE_PLUS_DATA(y) // introduce a data dependency WASTE_USEC(LONG_CALC); vTaskSuspendAll(); WASTE_USEC(SHORT_CALC); diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_release.c b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_release.c index 7e53e24d..cb79b7e3 100644 --- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_release.c +++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_release.c @@ -29,108 +29,26 @@ #include #include #include -/* -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 20 // Multiplier to increase all waiting periods to make the schedule more tight an force preemptions -#include "arbitrary_loads.c" +#include "fuzzhelper.c" -__attribute__((noinline)) static void trigger_Qemu_break( void ) -{ - puts("Trigger"); - while (1) { - } -} +#define DO_TIME(X,Y) WASTE_USEC((X)) -__attribute__((noinline)) static void trigger_job_done( void ) -{ - puts("Job Done"); - // trigger_Qemu_break(); -} -// 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} - -#define DO_TIME(X, Y) WASTE_USEC((X)) - -#ifndef FUZZ_BYTES -// Produce the worst case, ignore input -#define DEBUG_WCET(A) {A} -#endif - -#ifdef DEBUG_WCET +#ifdef INSERT_WC #define DEBUG_VAL(X,D) (D) - #define WCET_CLAMP(X, LB, UB, LABEL) DO_TIME(UB,LABEL) + #define WCET_CLAMP(X, LB, UB, LABEL) WASTE_NSEC(UB) #else #define DEBUG_VAL(X,D) (X) - #define WCET_CLAMP(X, LB, UB, LABEL) DO_TIME(CLAMP(X,LB,UB),LABEL) - #define DEBUG_WCET(A) + #define WCET_CLAMP(X, LB, UB, LABEL) WASTE_NSEC(CLAMP(X,LB,UB)) #endif -// 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 prvTask1( void * pvParameters ); static void prvTask2( void * pvParameters ); static void prvTask3( void * pvParameters ); static void prvTask4( void * pvParameters ); static void prvTask5( 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_1_PRIO ( tskIDLE_PRIORITY + 1 ) #define mainTASK_2_PRIO ( tskIDLE_PRIORITY + 2 ) #define mainTASK_3_PRIO ( tskIDLE_PRIORITY + 3 ) @@ -235,25 +153,29 @@ void main_release( void ) } static void prvTask1( void * pvParameters ) { + const int task_id = 0; TickType_t xLastWakeTime = initial_release_time; const TickType_t xFrequency = 100 / portTICK_PERIOD_MS; for( ;; ){ + RNG_RESET // Actions -------------------------------------- - volatile uint16_t x = fuzz_short_next(); + volatile uint16_t x = RNG_SHORT_NEXT; WCET_CLAMP(x, 8000, 10000, TASK_1_MESSAGE) xTaskNotify(xTask2, DEBUG_VAL(x % 2, 1), eSetValueWithOverwrite); // --------------------------------------------- trigger_job_done(); - trigger_Qemu_break(); + // trigger_Qemu_break(); xTaskDelayUntil( &xLastWakeTime, xFrequency );}// Wait for the next cycle. } static void prvTask2( void * pvParameters ) { + const int task_id = 1; TickType_t xLastWakeTime = initial_release_time; const TickType_t xFrequency = 50 / portTICK_PERIOD_MS; for( ;; ){ + RNG_RESET // Actions -------------------------------------- - uint16_t x = fuzz_short_next(); + uint16_t x = RNG_SHORT_NEXT; DO_TIME(1000, TASK_2_MESSAGE) xSemaphoreTake(xMutex, portMAX_DELAY); volatile int torun = 2000; @@ -268,14 +190,21 @@ static void prvTask2( void * pvParameters ) { } static void prvTask3( void * pvParameters ) { + const int task_id = 2; TickType_t xLastWakeTime = initial_release_time; - const TickType_t xFrequency = 25 / portTICK_PERIOD_MS; + const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; trigger_job_done(); // The first job instance just waits for an activation for( ;; ){ - // Actions -------------------------------------- +#ifdef IGNORE_INTERRUPTS + xTaskDelayUntil( &xLastWakeTime, xFrequency ); // periodic + int y = ulTaskNotifyTake(pdTRUE, 0); +#else int y = ulTaskNotifyTake(pdTRUE, portMAX_DELAY); // sporadic +#endif + RNG_RESET + // Actions -------------------------------------- xSemaphoreTake(xMutex, portMAX_DELAY); - volatile uint16_t x = fuzz_short_next(); + volatile uint16_t x = RNG_SHORT_NEXT; int torun = 0; if (y) { torun = CLAMP(x, 5000, 8000); @@ -286,18 +215,17 @@ static void prvTask3( void * pvParameters ) { xSemaphoreGive(xMutex); // --------------------------------------------- trigger_job_done(); - trigger_Qemu_break(); - // xTaskDelayUntil( &xLastWakeTime, xFrequency ); } } static void prvTask4( void * pvParameters ) { - initial_release_time = xTaskGetTickCount(); // The highest priority task sets the initial time + const int task_id = 3; TickType_t xLastWakeTime = initial_release_time; const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; for( ;; ){ + RNG_RESET // Actions -------------------------------------- - volatile uint16_t x = fuzz_short_next(); + volatile uint16_t x = RNG_SHORT_NEXT; WCET_CLAMP(x, 1000, 2000, TASK_4_MESSAGE) // --------------------------------------------- trigger_job_done(); @@ -305,15 +233,22 @@ static void prvTask4( void * pvParameters ) { } static void prvTask5( void * pvParameters ) { + const int task_id = 4; TickType_t xLastWakeTime = 0; const TickType_t xFrequency = 5 / portTICK_PERIOD_MS; trigger_job_done(); // The first job instance just waits for an activation for( ;; ){ - // Actions -------------------------------------- +#ifdef IGNORE_INTERRUPTS + xTaskDelayUntil( &xLastWakeTime, xFrequency ); // periodic + // int y = ulTaskNotifyTake(pdTRUE, 0); +#else int y = ulTaskNotifyTake(pdTRUE, portMAX_DELAY); // sporadic +#endif + RNG_RESET + // Actions -------------------------------------- int succ = xSemaphoreTake(xMutex, 0); // try to take the mutex if (succ == pdTRUE) { - volatile uint16_t x = fuzz_short_next(); + volatile uint16_t x = RNG_SHORT_NEXT; // uint16_t x = 2000; int torun = 0; torun = CLAMP(x, 0, 2000); @@ -322,10 +257,8 @@ static void prvTask5( void * pvParameters ) { } else { DO_TIME(50, TASK_5_MESSAGE) } - // xTaskDelayUntil( &xLastWakeTime, xFrequency ); // enforce a minimum inter-arrival time // --------------------------------------------- trigger_job_done(); - // xTaskDelayUntil( &xLastWakeTime, portMAX_DELAY ); // enforce a minimum inter-arrival time } } diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_waters.c b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_waters.c index d93df449..56101ac6 100644 --- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_waters.c +++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_waters.c @@ -28,116 +28,29 @@ #include #include #include -/* -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 20 // Multiplier to increase all waiting periods to make the schedule more tight an force preemptions -#include "arbitrary_loads.c" +#define NUM_TASKS 10 +#include "fuzzhelper.c" -__attribute__((noinline)) static void trigger_Qemu_break( void ) -{ - puts("Trigger"); - while (1) { - } -} - -__attribute__((noinline)) static void trigger_job_done( void ) -{ - puts("Job Done"); - // trigger_Qemu_break(); -} -// 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} - -#define DO_TIME(X, Y) WASTE_NSEC((X)) - -#ifndef FUZZ_BYTES -// Produce the worst case, ignore input -#define DEBUG_WCET(A) {A} -#endif - -#ifdef DEBUG_WCET +#ifdef INSERT_WC #define DEBUG_VAL(X,D) (D) - #define WCET_CLAMP(X, LB, UB, LABEL) DO_TIME(UB,LABEL) + #define WCET_CLAMP(X, LB, UB, LABEL) WASTE_NSEC(UB) #else #define DEBUG_VAL(X,D) (X) - #define WCET_CLAMP(X, LB, UB, LABEL) DO_TIME(CLAMP(X,LB,UB),LABEL) - #define DEBUG_WCET(A) + #define WCET_CLAMP(X, LB, UB, LABEL) WASTE_NSEC(CLAMP(X,LB,UB)) #endif -// Begin Input Stuff -#define NUM_TASKS 10 -#define MAX_INPUT_BYTES 4096 -volatile unsigned char FUZZ_INPUT[MAX_INPUT_BYTES] = {}; -volatile int INPUT_POINTERS[NUM_TASKS] = {}; -volatile uint32_t FUZZ_LENGTH = MAX_INPUT_BYTES;// ignored -// Read the Byte of Input, if the Input is exausted trigger the breakpoint instead -static unsigned char fuzz_char_next(int tasknum) { -#ifndef FUZZ_BYTES - return 255; -#endif -#ifdef PARTITION_INPUT - if (INPUT_POINTERS[tasknum] == 0) { - INPUT_POINTERS[tasknum] = tasknum * (MAX_INPUT_BYTES / NUM_TASKS); - } - if (INPUT_POINTERS[tasknum] >= (tasknum+1) * (MAX_INPUT_BYTES / NUM_TASKS)) { - trigger_Qemu_break(); - } - return FUZZ_INPUT[INPUT_POINTERS[tasknum]++]; -#else - // printf("Get next Input from %lx \n",FUZZ_INPUT); - if (INPUT_POINTERS[0] < FUZZ_LENGTH) { - INPUT_POINTERS[0]++; - // printf("Input no. %d %x\n",FUZZ_POINTER-1,FUZZ_INPUT[FUZZ_POINTER-1]); - return FUZZ_INPUT[INPUT_POINTERS[0]-1]; - } else { - // puts("End of Input"); - // Exausted inputs early - trigger_Qemu_break(); - } -#endif -} -static uint16_t fuzz_short_next(int tasknum) { - unsigned char field[2]; - field[0]=fuzz_char_next(tasknum); - field[1]=fuzz_char_next(tasknum); - uint16_t* sf = (uint16_t*) field; - return *sf; -} -static uint32_t fuzz_long_next(int tasknum) { - unsigned char field[4]; - field[0]=fuzz_char_next(tasknum); - field[1]=fuzz_char_next(tasknum); - field[2]=fuzz_char_next(tasknum); - field[3]=fuzz_char_next(tasknum); - 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 ); +static void prvTaskC21( void * pvParameters ); +static void prvTaskC22( void * pvParameters ); +static void prvTaskC32( void * pvParameters ); +static void prvTaskC31( void * pvParameters ); +static void prvTaskC23( void * pvParameters ); +static void prvTaskC14( void * pvParameters ); +static void prvTaskC11( void * pvParameters ); +static void prvTaskC12( void * pvParameters ); +static void prvTaskC33( void * pvParameters ); +static void prvTaskC13( void * pvParameters ); // Priorities using rate-monotonic scheduling // ties are decided favoring short wcets @@ -150,40 +63,40 @@ static void prvTask1129( void * pvParameters ); // 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 ) +#define mainTASK_C21_PRIO ( tskIDLE_PRIORITY + 1 ) +#define mainTASK_C22_PRIO ( tskIDLE_PRIORITY + 5 ) +#define mainTASK_C32_PRIO ( tskIDLE_PRIORITY + 8 ) +#define mainTASK_C31_PRIO ( tskIDLE_PRIORITY + 10 ) +#define mainTASK_C23_PRIO ( tskIDLE_PRIORITY + 9 ) +#define mainTASK_C14_PRIO ( tskIDLE_PRIORITY + 5 ) +#define mainTASK_C11_PRIO ( tskIDLE_PRIORITY + 5 ) +#define mainTASK_C12_PRIO ( tskIDLE_PRIORITY + 5 ) +#define mainTASK_C33_PRIO ( tskIDLE_PRIORITY + 2 ) +#define mainTASK_C13_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 ) +// #define mainTASK_C21_PRIO ( tskIDLE_PRIORITY + 1 ) +// #define mainTASK_C22_PRIO ( tskIDLE_PRIORITY + 5 ) +// #define mainTASK_C32_PRIO ( tskIDLE_PRIORITY + 8 ) +// #define mainTASK_C31_PRIO ( tskIDLE_PRIORITY + 10 ) +// #define mainTASK_C23_PRIO ( tskIDLE_PRIORITY + 9 ) +// #define mainTASK_C14_PRIO ( tskIDLE_PRIORITY + 4 ) +// #define mainTASK_C11_PRIO ( tskIDLE_PRIORITY + 7 ) +// #define mainTASK_C12_PRIO ( tskIDLE_PRIORITY + 6 ) +// #define mainTASK_C33_PRIO ( tskIDLE_PRIORITY + 2 ) +// #define mainTASK_C13_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 mainTASK_C21_PRIO ( tskIDLE_PRIORITY + 1 ) +// #define mainTASK_C22_PRIO ( tskIDLE_PRIORITY + 7 ) +// #define mainTASK_C32_PRIO ( tskIDLE_PRIORITY + 8 ) +// #define mainTASK_C31_PRIO ( tskIDLE_PRIORITY + 10 ) +// #define mainTASK_C23_PRIO ( tskIDLE_PRIORITY + 9 ) +// #define mainTASK_C14_PRIO ( tskIDLE_PRIORITY + 7 ) +// #define mainTASK_C11_PRIO ( tskIDLE_PRIORITY + 7 ) +// #define mainTASK_C12_PRIO ( tskIDLE_PRIORITY + 7 ) +// #define mainTASK_C33_PRIO ( tskIDLE_PRIORITY + 2 ) +// #define mainTASK_C13_PRIO ( tskIDLE_PRIORITY + 7 ) #define TASK_31_MESSAGE "01" #define TASK_78_MESSAGE "05" @@ -197,16 +110,16 @@ static void prvTask1129( void * pvParameters ); #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 TaskHandle_t xTaskC21 = NULL; +static TaskHandle_t xTaskC22 = NULL; +static TaskHandle_t xTaskC32 = NULL; +static TaskHandle_t xTaskC31 = NULL; +static TaskHandle_t xTaskC23 = NULL; +static TaskHandle_t xTaskC14 = NULL; +static TaskHandle_t xTaskC11 = NULL; +static TaskHandle_t xTaskC12 = NULL; +static TaskHandle_t xTaskC33 = NULL; +static TaskHandle_t xTaskC13 = NULL; static TickType_t initial_release_time = 0; @@ -229,76 +142,76 @@ void main_waters( void ) // 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. */ + xTaskCreate( prvTaskC21, /* The function that implements the task. */ + "C21", /* 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. */ + mainTASK_C21_PRIO, /* The priority assigned to the task. */ + &xTaskC21 ); /* 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. */ + xTaskCreate( prvTaskC22, /* The function that implements the task. */ + "C22", /* 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. */ + mainTASK_C22_PRIO, /* The priority assigned to the task. */ + &xTaskC22 ); /* The task handle is not required, so NULL is passed. */ - xTaskCreate( prvTask90, - "90", + xTaskCreate( prvTaskC32, + "C32", configMINIMAL_STACK_SIZE, NULL, - mainTASK_90_PRIO, - &xTask90 ); + mainTASK_C32_PRIO, + &xTaskC32 ); // This task is supposed to be sporadic - xTaskCreate( prvTask397, - "async_397", + xTaskCreate( prvTaskC31, + "async_C31", configMINIMAL_STACK_SIZE, NULL, - mainTASK_397_PRIO, - &xTask397 ); + mainTASK_C31_PRIO, + &xTaskC31 ); - xTaskCreate( prvTask400, - "400", + xTaskCreate( prvTaskC23, + "C23", configMINIMAL_STACK_SIZE, NULL, - mainTASK_400_PRIO, - &xTask400 ); + mainTASK_C23_PRIO, + &xTaskC23 ); - xTaskCreate( prvTask416, - "416", + xTaskCreate( prvTaskC14, + "C14", configMINIMAL_STACK_SIZE, NULL, - mainTASK_416_PRIO, - &xTask416 ); + mainTASK_C14_PRIO, + &xTaskC14 ); - xTaskCreate( prvTask579, - "579", + xTaskCreate( prvTaskC11, + "C11", configMINIMAL_STACK_SIZE, NULL, - mainTASK_579_PRIO, - &xTask579 ); + mainTASK_C11_PRIO, + &xTaskC11 ); - xTaskCreate( prvTask1009, - "1009", + xTaskCreate( prvTaskC12, + "C12", configMINIMAL_STACK_SIZE, NULL, - mainTASK_1009_PRIO, - &xTask1009 ); + mainTASK_C12_PRIO, + &xTaskC12 ); - xTaskCreate( prvTask1107, - "1107", + xTaskCreate( prvTaskC33, + "C33", configMINIMAL_STACK_SIZE, NULL, - mainTASK_1107_PRIO, - &xTask1107 ); + mainTASK_C33_PRIO, + &xTaskC33 ); - xTaskCreate( prvTask1129, - "1129", + xTaskCreate( prvTaskC13, + "C13", configMINIMAL_STACK_SIZE, NULL, - mainTASK_1129_PRIO, - &xTask1129 ); + mainTASK_C13_PRIO, + &xTaskC13 ); xTaskCreate( timing_supervisor_task, "supervisor", @@ -324,64 +237,65 @@ void main_waters( void ) } // Chain2: 31 -> 78 -> 400 -static void prvTask31( void * pvParameters ) { +static void prvTaskC21( void * pvParameters ) { + const int task_id = 0; TickType_t xLastWakeTime = initial_release_time; const TickType_t xFrequency = 100 / portTICK_PERIOD_MS; - int period_counter = 2; for( ;; ){ - WCET_END({if (--period_counter==0) {puts("End");}}) // Debugging + RNG_RESET // Actions -------------------------------------- // Exectime: f(x) = x // Output: g(x) = x % 2 - volatile uint16_t x = fuzz_short_next(0); - DEBUG_WCET(x=48940;) + volatile uint16_t x = RNG_SHORT_NEXT; WCET_CLAMP(x, 0, 48940, TASK_31_MESSAGE) trigger_job_done(); - // WCET_END({trigger_Qemu_break();}) - xTaskNotify(xTask78, DEBUG_VAL(x % 2, 1), eSetValueWithOverwrite); + xTaskNotify(xTaskC22, DEBUG_VAL(x % 2, 1), eSetValueWithOverwrite); // --------------------------------------------- xTaskDelayUntil( &xLastWakeTime, xFrequency );}// Wait for the next cycle. } // Chain2: 31 -> 78 -> 400 -static void prvTask78( void * pvParameters ) { +static void prvTaskC22( void * pvParameters ) { + const int task_id = 1; TickType_t xLastWakeTime = initial_release_time; const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; for( ;; ){ + RNG_RESET // Actions -------------------------------------- // Exectime: f(x,y) = c + y*20000 + rng(x)*50000 // Output: g(x,y) = y * (x % 4) - uint16_t x = fuzz_short_next(1); + uint16_t x = RNG_SHORT_NEXT; int y = ulTaskNotifyTake(pdTRUE, 0); volatile int torun = 6035; if (y > 0) { torun += 20000; } - if (DEBUG_VAL(CHANCE_1_IN_POWOF2(x, 5), 1)) { + if (DEBUG_VAL(((x % 100) <= 5), 1)) { torun += 50000; } WCET_CLAMP(torun, 0, 76035, TASK_78_MESSAGE) - xTaskNotify(xTask400, DEBUG_VAL(y * (x % 4), 2), eSetValueWithOverwrite); + xTaskNotify(xTaskC23, DEBUG_VAL(y * (x % 4), 2), eSetValueWithOverwrite); // --------------------------------------------- trigger_job_done(); xTaskDelayUntil( &xLastWakeTime, xFrequency );} } // Chain2: 31 -> 78 -> 400 -static void prvTask400( void * pvParameters ) { +static void prvTaskC23( void * pvParameters ) { + const int task_id = 2; TickType_t xLastWakeTime = initial_release_time; const TickType_t xFrequency = 2 / portTICK_PERIOD_MS; for( ;; ){ + RNG_RESET // Actions -------------------------------------- // Exectime: f(x,y) = rng(x)*y*c or (rng(x) % 1000) - uint32_t x = fuzz_long_next(2); + uint32_t x = RNG_LONG_NEXT; int y = ulTaskNotifyTake(pdTRUE, 0); volatile int torun = 0; - if (y == 2 && DEBUG_VAL(CHANCE_1_IN_POWOF2(x, 2), 1)) { + if (y == 2 && DEBUG_VAL(((x%100) <= 25), 1)) { torun = 1765; } else { torun = RNG_FROM(x) % 1000; - DEBUG_WCET(torun=999;) } WCET_CLAMP(torun, 0, 1765, TASK_400_MESSAGE) // --------------------------------------------- @@ -392,25 +306,26 @@ static void prvTask400( void * pvParameters ) { //================================================================== // Chain3: 397 -> 90 -> 1107 -static void prvTask397( void * pvParameters ) { +static void prvTaskC31( void * pvParameters ) { + const int task_id = 3; TickType_t xLastWakeTime = initial_release_time; const TickType_t xFrequency = 1 / portTICK_PERIOD_MS; for( ;; ){ + RNG_RESET // Exectime: f(x) = 20*x // Output: g(x) = x % 2 - volatile uint16_t x = fuzz_char_next(3); + volatile uint16_t x = RNG_CHAR_NEXT; x *= 32; - DEBUG_WCET(x=5830;) WCET_CLAMP(x, 0, 5830, TASK_397_MESSAGE); - xTaskNotify(xTask90, DEBUG_VAL((x/32) & 0x1, 0), eSetValueWithOverwrite); + xTaskNotify(xTaskC32, DEBUG_VAL((x/32) & 0x1, 0), eSetValueWithOverwrite); // 3 different activation strategies ------------- // activate sporadically from interrupts trigger_job_done(); -#ifdef FUZZ_INT_ACTIVATION - ulTaskNotifyTake(pdTRUE,portMAX_DELAY); -#else +#ifdef IGNORE_INTERRUPTS // activate with worst possible frequency (700us, but tick resolution is too low) xTaskDelayUntil( &xLastWakeTime, xFrequency ); +#else + ulTaskNotifyTake(pdTRUE,portMAX_DELAY); #endif // wait pseudo random many ticks // xTaskDelayUntil( &xLastWakeTime, CLAMP(RNG, 1, 100) / portTICK_PERIOD_MS ); @@ -418,17 +333,18 @@ static void prvTask397( void * pvParameters ) { } // Chain3: 397 -> 90 -> 1107 -static void prvTask90( void * pvParameters ) { +static void prvTaskC32( void * pvParameters ) { + const int task_id = 4; TickType_t xLastWakeTime = initial_release_time; const TickType_t xFrequency = 2 / portTICK_PERIOD_MS; for( ;; ){ + RNG_RESET // Actions -------------------------------------- // Exectime: f(x) = c + 100*x // Output: g(x) = x % 4 int y = ulTaskNotifyTake(pdTRUE, 0); - volatile uint16_t x = fuzz_char_next(4); + volatile uint16_t x = RNG_CHAR_NEXT; x *= 100; - DEBUG_WCET(x=20048;) int torun = 0; if (y) { torun = CLAMP(x, 5000, 10000); @@ -436,21 +352,22 @@ static void prvTask90( void * pvParameters ) { torun = CLAMP(x, 0, 20045); } WCET_CLAMP(torun, 0, 20045, TASK_90_MESSAGE) - xTaskNotify(xTask1107, DEBUG_VAL((x/100) % 4, 0), eSetValueWithOverwrite); + xTaskNotify(xTaskC33, DEBUG_VAL((x/100) % 4, 0), eSetValueWithOverwrite); // --------------------------------------------- trigger_job_done(); xTaskDelayUntil( &xLastWakeTime, xFrequency );} } // Chain3: 397 -> 90 -> 1107 -static void prvTask1107( void * pvParameters ) { +static void prvTaskC33( void * pvParameters ) { + const int task_id = 5; TickType_t xLastWakeTime = initial_release_time; const TickType_t xFrequency = 50 / portTICK_PERIOD_MS; for( ;; ){ + RNG_RESET // Actions -------------------------------------- // Exectime: f(x) = c - x*y - volatile uint16_t x = fuzz_short_next(5); - DEBUG_WCET(x=0;) + volatile uint16_t x = RNG_SHORT_NEXT; int y = ulTaskNotifyTake(pdTRUE, 0); int torun = 76865-((int)x)*y; WCET_CLAMP(torun, 10000, 76865, TASK_1107_MESSAGE) @@ -462,34 +379,37 @@ static void prvTask1107( void * pvParameters ) { //================================================================== // Chain1: 579 -> 1009 -> 1129 -> 416 -static void prvTask579( void * pvParameters ) { +static void prvTaskC11( void * pvParameters ) { + const int task_id = 6; // int period = 5; TickType_t xLastWakeTime = initial_release_time; const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; for( ;; ){ + RNG_RESET // if (--period==0) {puts("End");} // Debugging Marker // Actions -------------------------------------- // Exectime: f(x) = x>>8 & 0x0fff // Output: g(x) = x % 8 - uint32_t x = fuzz_long_next(6); + uint32_t x = RNG_LONG_NEXT; volatile int torun = (x>>8) & 0x0fff; - DEBUG_WCET(torun = 0x0fff;) WCET_CLAMP(torun, 500, 2460, TASK_579_MESSAGE) - xTaskNotify(xTask1009, DEBUG_VAL(x % 8, 0), eSetValueWithOverwrite); + xTaskNotify(xTaskC12, DEBUG_VAL(x % 8, 0), eSetValueWithOverwrite); // --------------------------------------------- trigger_job_done(); xTaskDelayUntil( &xLastWakeTime, xFrequency );} } // Chain1: 579 -> 1009 -> 1129 -> 416 -static void prvTask1009( void * pvParameters ) { +static void prvTaskC12( void * pvParameters ) { + const int task_id = 7; TickType_t xLastWakeTime = initial_release_time; const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; for( ;; ){ + RNG_RESET // 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(7); + uint16_t x = RNG_SHORT_NEXT; int y = ulTaskNotifyTake(pdTRUE, 0); volatile int torun = 0; if (x % 8 == y) { @@ -497,34 +417,30 @@ static void prvTask1009( void * pvParameters ) { } else { torun = CLAMP(x, 0, 40000); } - DEBUG_WCET(torun = 51485;) WCET_CLAMP(torun, 0, 51485, TASK_1009_MESSAGE) - xTaskNotify(xTask1129, DEBUG_VAL(x % 8 == y, 1), eSetValueWithOverwrite); + xTaskNotify(xTaskC13, DEBUG_VAL(x % 8 == y, 1), eSetValueWithOverwrite); // --------------------------------------------- trigger_job_done(); xTaskDelayUntil( &xLastWakeTime, xFrequency );} } // Chain1: 579 -> 1009 -> 1129 -> 416 -static void prvTask1129( void * pvParameters ) { +static void prvTaskC13( void * pvParameters ) { + const int task_id = 8; int period_counter = 2; TickType_t xLastWakeTime = initial_release_time; const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; for( ;; ){ + RNG_RESET // 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(8); + volatile uint32_t x = RNG_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 + CHANCE_1_IN_POWOF2(x, 5)) == 1; // XOR + volatile int do_short_run = (y + ((x%100)<=5)) == 1; // XOR int torun = 0; if (do_short_run > 0) { torun = 40000 + x; @@ -532,28 +448,28 @@ static void prvTask1129( void * pvParameters ) { torun = 80000 + x; } WCET_CLAMP(torun, 0, 145040, TASK_1129_MESSAGE) - xTaskNotify(xTask416, do_short_run, eSetValueWithOverwrite); + xTaskNotify(xTaskC14, do_short_run, eSetValueWithOverwrite); // --------------------------------------------- trigger_job_done(); xTaskDelayUntil( &xLastWakeTime, xFrequency );} } // Chain1: 579 -> 1009 -> 1129 -> 416 -static void prvTask416( void * pvParameters ) { +static void prvTaskC14( void * pvParameters ) { + const int task_id = 9; TickType_t xLastWakeTime = initial_release_time; const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; for( ;; ){ + RNG_RESET // Actions -------------------------------------- // Exectime: f(x,y) = if y ? c1+2*x : c2-x // longmax - shortmax: 76955 - volatile uint32_t x = (uint32_t)fuzz_short_next(9); + volatile uint32_t x = RNG_SHORT_NEXT; int y = ulTaskNotifyTake(pdTRUE, 0); volatile int torun = 0; if (y) { - 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) @@ -571,8 +487,8 @@ void vWatersIdleFunction() { void ISR_0_Handler( void ) { puts("Interrupt"); - if (xTask397) { - vTaskNotifyGiveFromISR(xTask397, NULL); + if (xTaskC31) { + vTaskNotifyGiveFromISR(xTaskC31, NULL); } }