unify input handling, data dependencies for copter

This commit is contained in:
Alwin Berger 2025-02-12 17:01:08 +01:00
parent 145954e374
commit 39d2851bcc
6 changed files with 377 additions and 429 deletions

View File

@ -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

View File

@ -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};

View File

@ -0,0 +1,140 @@
#ifndef __FUZZHELPER_C__
#define __FUZZHELPER_C__
#include "arbitrary_loads.c"
#include <stdint.h>
// #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

View File

@ -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);

View File

@ -29,108 +29,26 @@
#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 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
}
}

View File

@ -28,116 +28,29 @@
#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
*/
#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);
}
}