diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/Makefile b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/Makefile index e80848e9..3a8e6506 100644 --- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/Makefile +++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/Makefile @@ -149,6 +149,12 @@ ifeq ($(COPTER_DEMO), 1) CFLAGS := -DmainCOPTER_DEMO=1 else +ifeq ($(POLYCOPTER_DEMO), 1) + SOURCE_FILES += main_polycopter.c + + CFLAGS := -DmainPOLYCOPTER_DEMO=1 + CFLAGS += -Wno-overflow +else ifeq ($(RELEASE_DEMO), 1) SOURCE_FILES += main_release.c @@ -177,6 +183,7 @@ endif endif endif endif +endif ifeq ($(IGNORE_BYTES), 1) CFLAGS += -D IGNORE_BYTES=1 diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/arbitrary_loads.c b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/arbitrary_loads.c index 41ba5c31..3091fb26 100644 --- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/arbitrary_loads.c +++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/arbitrary_loads.c @@ -1,6 +1,9 @@ #ifndef ARB_LOAD_C #define ARB_LOAD_C 1 +#include +#include + // Time wasters ===== volatile long _NONSENSE_VAR = 0; #define QEMU_SHIFT 5 @@ -22,9 +25,9 @@ volatile long _NONSENSE_VAR = 0; // #define PRINT_TIME(X,Y) WASTE_TIME(X) // Clamps =========== -#define CLAMP_FLOOR(X,LB) ((X>LB)*X+(X<=LB)*LB) -#define CLAMP_CEILING(X,UB) ((X>UB)*UB+(X<=UB)*X) -#define CLAMP(X,LB,UB) CLAMP_CEILING(CLAMP_FLOOR(X,LB),UB) // branch-less clamping +#define CLAMP_FLOOR(X,LB) ((((X)>(LB))*(X))+(((X)<=(LB))*(LB))) +#define CLAMP_CEILING(X,UB) (((X)>(UB))*(UB)+((X)<=(UB))*(X)) +#define CLAMP(X,LB,UB) CLAMP_CEILING((CLAMP_FLOOR(X,LB)),UB) // branch-less clamping // Random numbers === // glibc @@ -33,16 +36,137 @@ volatile long _NONSENSE_VAR = 0; #define M 0x80000000ull #define C 12345ull static unsigned long long rng_seed = 2345745ull; -#define RNG rng_seed+=((A*((rng_seed+=C)-C)+C) % M) +#define RNG rng_seed=((A*rng_seed+C) % M) #define RNG_FROM(X) ((A*(X)+C) % M) // Challanges ======= #define CHANCE_1_IN_POWOF2(X,Y) (RNG_FROM(X)<(M>>Y)) // assume the type of x has more than y bits -// Branchless polynomes +// polynomes +#define IF_ELSE(X,Y,Z) ((X) ? (Y) : (Z)) +// #define IF_ELSE(X,Y,Z) (((X)*(Y))+((!(X))*(Z))) // branchless, takes a huge hit on performance +#define SADD(X,Y) IF_ELSE(((int32_t)(Y))<0, IF_ELSE(((int32_t)(X))INT_MAX-((int32_t)(Y)), INT_MAX, ((int32_t)(X))+((int32_t)(Y)))) +#define SSUB(X,Y) IF_ELSE(((int32_t)(Y))<0, IF_ELSE(((int32_t)(X))INT_MIN+((int32_t)(Y)), ((int32_t)(X))-((int32_t)(Y)), INT_MIN)) +#define ABS_DIFF(X,Y) (IF_ELSE(((int32_t)(X)<(int32_t)(Y)),(SSUB(Y,X)),(SSUB(X,Y)))) +#define SQUARE(X) ((X)*(X)) +#define AVG(X,Y) (((X)/2)+((Y)/2)) #define U_ABS_DIFF(X,Y) (__uint32_t)(((__uint32_t)X<(__uint32_t)Y)*((__uint32_t)Y-(__uint32_t)X)+((__uint32_t)X>=(__uint32_t)Y)*((__uint32_t)X-(__uint32_t)Y)) -#define CHECKED_SQUARE(X, OFF) (U_ABS_DIFF(X,OFF)<=0x0000FFFF)*(U_ABS_DIFF(X,OFF)*U_ABS_DIFF(X,OFF)) -#define HILL(X, OFF, H, W) (U_ABS_DIFF(X/((__uint32_t)W),OFF/((__uint32_t)W))<=0x0000FFFF)*(H>=CHECKED_SQUARE(X/((__uint32_t)W), (OFF/(__uint32_t)W)))*(H-CHECKED_SQUARE(X/((__uint32_t)W), (OFF/(__uint32_t)W))) +#define CHECKED_SQUARE(X) IF_ELSE((X)<=0x0000B504,SQUARE(X), INT_MAX) // int32_t safe +#define LIN(X,N,D,C) (C+((N)*((X)/(D)))) + +int32_t hill(int32_t x, int32_t off, int32_t h, int32_t w) { + return CLAMP_FLOOR(SSUB(h,CHECKED_SQUARE(ABS_DIFF(x,off)/w)),0); +} +int32_t valley(int32_t x, int32_t off, int32_t h, int32_t w) { + return CLAMP_CEILING(SADD(h,CHECKED_SQUARE(ABS_DIFF(x,off)/w)),0); +} + +#define HILL(X, OFF, H, W) hill(X, OFF, H, W) +#define VALLEY(X, OFF, H, W) valley(X, OFF, H, W) + +// #define HILL(X, OFF, H, W) CLAMP_FLOOR(SSUB(H,CHECKED_SQUARE(ABS_DIFF(X,OFF)/W)),0) +// #define VALLEY(X, OFF, H, W) CLAMP_CEILING(SADD(H,CHECKED_SQUARE(ABS_DIFF(X,OFF)/W)),0) + +#define STRETCH_i32(X) (X<<(8*(sizeof(int32_t)-sizeof(X)))) // stretch any integer to 32 bits + +#define JITTER(X, B) (RNG_FROM(X+B)%B) + +#define TRANSLATE_BOUNDS(X, FLB, FUB, TLB, TUB) (CLAMP(X,FLB,FUB)-FLB) / ((FUB-FLB)/(TUB-TLB)) + TLB + + + + + + + +#define FUNCTION_1(X) \ + HILL(X, 0, 200000, 800000) \ + + HILL(X, (INT_MIN/4)*3, 400000, 1500000) \ + + HILL(X, INT_MAX/2, 800000, 200000) \ + + CLAMP_FLOOR(LIN(SSUB(X, INT_MAX/4),5,100000,0),0) \ + + CLAMP_FLOOR(LIN(-X,5,100000,0),0) \ + + 200000 \ + - JITTER(X, 30000) + +#define FUNCTION_2(X) \ + VALLEY(X, 0, -200000, 800000) \ + + VALLEY(X, (INT_MIN/4)*3, -400000, 1500000) \ + + VALLEY(X, INT_MAX/2, -800000, 200000) \ + + CLAMP_FLOOR(LIN(SSUB(X, INT_MAX/4),5,100000,0),0) \ + + CLAMP_FLOOR(LIN(-X,5,-100000,0),0) \ + + 200000 \ + - JITTER(X, 30000) + +#define FUNCTION_3(X) \ + LIN(SADD(X, INT_MAX/2),5,100000,0) \ + + LIN(-X,2,100000,0) \ + - JITTER(X, 10000) + +#define FUNCTION_4(X) \ + LIN(SADD(X, 3*(INT_MAX/8)),-30,100000,0) \ + + LIN(SSUB(X, 3*(INT_MAX/8)),30,100000,0) \ + - JITTER(X, 10000) + +#define FUNCTION_5(X) \ + VALLEY(X, 0, -200000, 10000000) \ + + HILL(X, 0, 42000, 5000000) \ + - JITTER(X, 1000) + +#define FUNCTION_6(X) \ + LIN(X,1,2,0) \ + + HILL(X, -1500000000, 1000000000, 50000) \ + + VALLEY(X, 1500000000, -1000000000, 50000) \ + - JITTER(X, 1000) + +#define FUNCTION_7(X) \ + LIN(X,1,100000,0) \ + + HILL(X, 7*(INT_MIN/8), 140000, 200000) \ + + HILL(X, 6*(INT_MIN/8), 100000, 200000) \ + + HILL(X, 5*(INT_MIN/8), 80000, 200000) \ + + HILL(X, 4*(INT_MIN/8), 60000, 200000) \ + + HILL(X, 3*(INT_MIN/8), 70000, 200000) \ + + HILL(X, 2*(INT_MIN/8), 80000, 200000) \ + + HILL(X, 1*(INT_MIN/8), 90000, 200000) \ + + HILL(X, 1*(INT_MAX/8), 90000, 200000) \ + + HILL(X, 2*(INT_MAX/8), 80000, 200000) \ + + HILL(X, 3*(INT_MAX/8), 70000, 200000) \ + + HILL(X, 4*(INT_MAX/8), 60000, 200000) \ + + HILL(X, 5*(INT_MAX/8), 50000, 200000) \ + + HILL(X, 6*(INT_MAX/8), 40000, 200000) \ + + HILL(X, 7*(INT_MAX/8), 30000, 200000) \ + - JITTER(X, 1000) + +#define FUNCTION_8(X) \ + (X>INT_MIN/2)*HILL((X%(INT_MAX/3)), 0, 10000000, 50000) * (ABS_DIFF(X,0)/100000000) \ + + LIN(X, -1, 100, 0) \ + - JITTER(X, 1000) + +#define FUNCTION_9(X) \ + HILL(X, 3*(INT_MIN/4), 200000, 800000) \ + + HILL(X, 1*(INT_MIN/4), 200000, 800000) \ + + HILL(X, 3*(INT_MAX/4), 400000, 400000) \ + + (X<0)*LIN(X, 1, 10000, 0) \ + + (X>0)*LIN(X, -1, 10000, 0) \ + - JITTER(X, 1000) + +#define FUNCTION_10(X) \ + + (X<=0)*LIN(X, 1, 10000, 0) \ + + (X>0)*LIN(X, -1, 10000, 0) \ + + VALLEY(X, 0, -200000, 1000000) \ + + 200000 \ + - JITTER(X, 1000) + + +#define TRANSLATE_1(LB,UB) TRANSLATE_BOUNDS(x, 180000, 1000000, LB, UB) // FN 1 +#define TRANSLATE_2(LB,UB) TRANSLATE_BOUNDS(x, -500000, 390000, LB, UB) // FN 2 +#define TRANSLATE_3(LB,UB) TRANSLATE_BOUNDS(x, -8000, 80000, LB, UB) // FN 3 +#define TRANSLATE_4(LB,UB) TRANSLATE_BOUNDS(x, -480000, -250000, LB, UB) // FN 4 +#define TRANSLATE_5(LB,UB) TRANSLATE_BOUNDS(x, -193000, -155000, LB, UB) // FN 5 +#define TRANSLATE_6(LB,UB) TRANSLATE_BOUNDS(x, -400000000, 400000000, LB, UB) // FN 6 +#define TRANSLATE_7(LB,UB) TRANSLATE_BOUNDS(x, -20000, 120000, LB, UB) // FN 7 +#define TRANSLATE_8(LB,UB) TRANSLATE_BOUNDS(x, -20000000, 120000000, LB, UB) // FN 8 +#define TRANSLATE_9(LB,UB) TRANSLATE_BOUNDS(x, -200000, 220000, LB, UB) // FN 9 +#define TRANSLATE_10(LB,UB) TRANSLATE_BOUNDS(x, -10000, 150000, LB, UB) // FN 10 #endif \ No newline at end of file diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/fuzzhelper.c b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/fuzzhelper.c index b1109522..3fda3956 100644 --- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/fuzzhelper.c +++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/fuzzhelper.c @@ -81,9 +81,9 @@ static uint32_t fuzz_long_next(int 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) +#define INPUT_CHAR_NEXT fuzz_char_next(task_id) +#define INPUT_SHORT_NEXT fuzz_short_next(task_id) +#define INPUT_LONG_NEXT fuzz_long_next(task_id) // Randomization volatile uint32_t RNG_STATES[NUM_TASKS] = {}; diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main.c b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main.c index bfd1e058..cb7078f8 100644 --- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main.c +++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main.c @@ -123,6 +123,10 @@ int main() { main_osek(); } + #elif ( mainPOLYCOPTER_DEMO == 1 ) + { + main_osek(); + } #else { 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 94080593..a5b5962d 100644 --- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_copter.c +++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_copter.c @@ -20,17 +20,17 @@ #ifdef IGNORE_BYTES #define SHORT_CALC (50) #define LONG_CALC (200) - #define MAKE_OUTPUT (0) #else #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);} + #define MAKE_OUTPUT (OUTPUT_BITS(TASK_LAST_INPUT^TASK_RNG_STATE)) #else #define STATE_PLUS_DATA(X) {} + #define MAKE_OUTPUT (0) #endif #define HYPER_PERIOD 9 diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_polycopter.c b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_polycopter.c new file mode 100644 index 00000000..cac9c5fd --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_polycopter.c @@ -0,0 +1,484 @@ +#include +#include +#include +#include +#include +#include +#define GLOBAL_WCET_MULT \ + 1 // Multiplier to increase all waiting periods to make the schedule more + // tight and force preemptions +#define NUM_TASKS 15 +#include "fuzzhelper.c" + +#ifdef INSERT_WC + #include "wcinput.h" +#endif + +// #define SHORT_CALC 50 +// #define LONG_CALC 200 + +#ifdef IGNORE_BYTES + #define SHORT_CALC (50) + #define LONG_CALC (200) +#else + #define SHORT_CALC (15+RNG_CHAR_NEXT%35) + #define LONG_CALC (50+RNG_CHAR_NEXT%150) +#endif + +#ifdef COPTER_DATAFLOW + #define STATE_PLUS_DATA(X) {TASK_RNG_STATE+=(X);} + #define MAKE_OUTPUT (OUTPUT_BITS(TASK_LAST_INPUT^TASK_RNG_STATE)) +#else + #define STATE_PLUS_DATA(X) {} + #define MAKE_OUTPUT (0) +#endif + +#define HYPER_PERIOD 9 +#define SIMULATE_PERIODS 4 +static TickType_t initial_release_time = 0; +static TaskHandle_t xTaskTimeSupervisor = NULL; +static void timing_supervisor_task( void * pvParameters ) { + initial_release_time = xTaskGetTickCount(); // The highest priority task sets the initial time + TickType_t xLastWakeTime = initial_release_time; + const TickType_t xFrequency = (SIMULATE_PERIODS * HYPER_PERIOD) / portTICK_PERIOD_MS; + trigger_job_done(); + xTaskDelayUntil( &xLastWakeTime, xFrequency ); + trigger_job_done(); + trigger_Qemu_break(); + for( ;; ){} +} + +static void prv_SignalGatherInitiateTask(void *pvParameters); +static TaskHandle_t xTask_SignalGatherInitiateTask = NULL; +static void prv_SignalGatherFinishedTask(void *pvParameters); +static TaskHandle_t xTask_SignalGatherFinishedTask = NULL; +static void prv_SignalGatherTimeoutTask(void *pvParameters); +static TaskHandle_t xTask_SignalGatherTimeoutTask = NULL; +static void prv_SignalProcessingActuateTask(void *pvParameters); +static TaskHandle_t xTask_SignalProcessingActuateTask = NULL; +static void prv_SignalProcessingAttitudeTask(void *pvParameters); +static TaskHandle_t xTask_SignalProcessingAttitudeTask = NULL; +// static void prv_ActuateTask(void *pvParameters); +// static TaskHandle_t xTask_ActuateTask = NULL; +static void prv_FlightControlTask(void *pvParameters); +static TaskHandle_t xTask_FlightControlTask = NULL; +static void prv_FlightControlAttitudeTask(void *pvParameters); +static TaskHandle_t xTask_FlightControlAttitudeTask = NULL; +static void prv_FlightControlActuateTask(void *pvParameters); +static TaskHandle_t xTask_FlightControlActuateTask = NULL; +static void prv_MavlinkSendTask(void *pvParameters); +static TaskHandle_t xTask_MavlinkSendTask = NULL; +static void prv_CopterControlTask(void *pvParameters); +static TaskHandle_t xTask_CopterControlTask = NULL; +static void prv_MavlinkRecvHandler(void *pvParameters); +static TaskHandle_t xTask_MavlinkRecvHandler = NULL; + + +/* +WCETs (including overheads) rounded up to full us: +SGFinish: 630 +SGInitiate: 630 +SGTimeout: 423 + +SPActuate: 208 +SPAttitude: 206 + +FCActuate: 206 +FCAttitude: 208 +FC: 411 + +MSend: 476 +CControl: 470 + +ISR0: 108 + +Resources: +SPIBus (mutex) + SGInitiate 0 - 400 + SGTimeout 200 - 400 + MSend 200 - 250 + +SGT (notify) + SGInitiate send 200 A + SGTimeout wait 0 +SGF (notify) + SGInitiate send 200 B + SGTimeout send 423 A + SGFinish wait 0 +FCAt (notify) + FC send 200 + FCAttitude wait 0 +FCAc (notify) + FC send 201 + FCActuate wait 0 + +*/ + +static SemaphoreHandle_t xSemaphore_SPIBus; + +static TickType_t xFrequency_CopterControlWatchdogAlarm; + +void main_osek(void) { + for (int i = 0; i < NUM_TASKS; i++) { + RNG_STATES[i] = i; // Each task starts with a different seed + } + + xSemaphore_SPIBus = xSemaphoreCreateBinary(); + xSemaphoreGive(xSemaphore_SPIBus); + + xTaskCreate(prv_SignalGatherInitiateTask, "SGInitiate", + configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 9, // 24 + &xTask_SignalGatherInitiateTask); + xTaskCreate(prv_SignalGatherFinishedTask, "SGFinished", + configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 10, // 25 + &xTask_SignalGatherFinishedTask); + xTaskCreate(prv_SignalGatherTimeoutTask, "SGTimeout", + configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 8, // 23 + &xTask_SignalGatherTimeoutTask); + xTaskCreate(prv_SignalProcessingActuateTask, "SPActuate", + configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 7, // 22 + &xTask_SignalProcessingActuateTask); + xTaskCreate(prv_SignalProcessingAttitudeTask, "SPAttitude", + configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 6, // 21 + &xTask_SignalProcessingAttitudeTask); + // xTaskCreate(prv_ActuateTask, "ActuateTask", configMINIMAL_STACK_SIZE, NULL, + // tskIDLE_PRIORITY + 1, &xTask_ActuateTask); + xTaskCreate(prv_FlightControlTask, "FC", + configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 3, // 11 + &xTask_FlightControlTask); + xTaskCreate(prv_FlightControlAttitudeTask, "FCAttitude", + configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 4, // 12 + &xTask_FlightControlAttitudeTask); + xTaskCreate(prv_FlightControlActuateTask, "FCActuate", + configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 5, // 13 + &xTask_FlightControlActuateTask); + xTaskCreate(prv_MavlinkSendTask, "MSend", configMINIMAL_STACK_SIZE, + NULL, tskIDLE_PRIORITY + 2, &xTask_MavlinkSendTask); // 10 + xTaskCreate(prv_CopterControlTask, "CControl", + configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, // 1 + &xTask_CopterControlTask); + + xTaskCreate( timing_supervisor_task, + "supervisor", + configMINIMAL_STACK_SIZE, + NULL, + configMAX_PRIORITIES - 1, + &xTaskTimeSupervisor ); + +#ifdef INSERT_WC + for (int i=0; i 5) { +// } + +// if (count == 100) { +// timing_dump(); +// } +// } + +// void ISR_1_Handler(void) { +// // timing_start(2 | TIMING_POINT_START_INTERRUPT_FROM_IDLE); +// WASTE_USEC(SHORT_CALC); +// } +// void ISR_3_Handler(void) { +// // timing_start(2 | TIMING_POINT_START_INTERRUPT_FROM_IDLE); +// WASTE_USEC(SHORT_CALC); +// } +// void ISR_4_Handler(void) { +// // timing_start(2 | TIMING_POINT_START_INTERRUPT_FROM_IDLE); +// WASTE_USEC(SHORT_CALC); +// } +// void ISR_5_Handler(void) { +// // timing_start(2 | TIMING_POINT_START_INTERRUPT_FROM_IDLE); +// WASTE_USEC(SHORT_CALC); +// } +// void ISR_6_Handler(void) { +// // timing_start(2 | TIMING_POINT_START_INTERRUPT_FROM_IDLE); +// WASTE_USEC(SHORT_CALC); +// } +// void ISR_7_Handler(void) { +// // timing_start(2 | TIMING_POINT_START_INTERRUPT_FROM_IDLE); +// WASTE_USEC(SHORT_CALC); +// } +// void ISR_8_Handler(void) { +// // timing_start(2 | TIMING_POINT_START_INTERRUPT_FROM_IDLE); +// WASTE_USEC(SHORT_CALC); +// } \ No newline at end of file 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 56101ac6..f0e4257b 100644 --- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_waters.c +++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_waters.c @@ -29,10 +29,12 @@ #include #include -#define GLOBAL_WCET_MULT 20 // Multiplier to increase all waiting periods to make the schedule more tight an force preemptions +#define LOCAL_WCET_MULT 15 // Multiplier to increase all waiting periods to make the schedule more tight an force preemptions #define NUM_TASKS 10 #include "fuzzhelper.c" +#define INSERT_WC + #ifdef INSERT_WC #define DEBUG_VAL(X,D) (D) #define WCET_CLAMP(X, LB, UB, LABEL) WASTE_NSEC(UB) @@ -241,13 +243,15 @@ static void prvTaskC21( void * pvParameters ) { const int task_id = 0; TickType_t xLastWakeTime = initial_release_time; const TickType_t xFrequency = 100 / portTICK_PERIOD_MS; + const uint32_t upper_bound = 48940*LOCAL_WCET_MULT; for( ;; ){ RNG_RESET // Actions -------------------------------------- - // Exectime: f(x) = x + // Exectime: f(x) = x % 1000000 // Output: g(x) = x % 2 - volatile uint16_t x = RNG_SHORT_NEXT; - WCET_CLAMP(x, 0, 48940, TASK_31_MESSAGE) + // WC Input: x = 48941 + volatile uint32_t x = INPUT_LONG_NEXT % 1000000; + WCET_CLAMP(x, 0, upper_bound, TASK_31_MESSAGE) trigger_job_done(); xTaskNotify(xTaskC22, DEBUG_VAL(x % 2, 1), eSetValueWithOverwrite); // --------------------------------------------- @@ -262,18 +266,19 @@ static void prvTaskC22( void * pvParameters ) { for( ;; ){ RNG_RESET // Actions -------------------------------------- - // Exectime: f(x,y) = c + y*20000 + rng(x)*50000 + // Exectime: f(x,y) = c + (y!=0)*20000 + (x%100<=5)*(x!=0)*50000 // Output: g(x,y) = y * (x % 4) - uint16_t x = RNG_SHORT_NEXT; + // WC Input: x = 2, y = 1 + uint16_t x = INPUT_SHORT_NEXT; int y = ulTaskNotifyTake(pdTRUE, 0); volatile int torun = 6035; if (y > 0) { torun += 20000; } - if (DEBUG_VAL(((x % 100) <= 5), 1)) { + if (DEBUG_VAL(((x % 100) <= 5)*(x!=0), 1)) { torun += 50000; } - WCET_CLAMP(torun, 0, 76035, TASK_78_MESSAGE) + WCET_CLAMP(torun*LOCAL_WCET_MULT, 0, 76035*LOCAL_WCET_MULT, TASK_78_MESSAGE) xTaskNotify(xTaskC23, DEBUG_VAL(y * (x % 4), 2), eSetValueWithOverwrite); // --------------------------------------------- trigger_job_done(); @@ -289,15 +294,16 @@ static void prvTaskC23( void * pvParameters ) { RNG_RESET // Actions -------------------------------------- // Exectime: f(x,y) = rng(x)*y*c or (rng(x) % 1000) - uint32_t x = RNG_LONG_NEXT; + // WC Input: x = 2214, y = 2 + uint32_t x = INPUT_LONG_NEXT; int y = ulTaskNotifyTake(pdTRUE, 0); volatile int torun = 0; if (y == 2 && DEBUG_VAL(((x%100) <= 25), 1)) { - torun = 1765; + torun = 1766; } else { - torun = RNG_FROM(x) % 1000; + torun = (RNG_FROM(x) % 1000); } - WCET_CLAMP(torun, 0, 1765, TASK_400_MESSAGE) + WCET_CLAMP(torun*LOCAL_WCET_MULT, 0, 1765*LOCAL_WCET_MULT, TASK_400_MESSAGE) // --------------------------------------------- trigger_job_done(); xTaskDelayUntil( &xLastWakeTime, xFrequency );} @@ -312,12 +318,13 @@ static void prvTaskC31( void * pvParameters ) { const TickType_t xFrequency = 1 / portTICK_PERIOD_MS; for( ;; ){ RNG_RESET - // Exectime: f(x) = 20*x + // Exectime: f(x) = 32*x // Output: g(x) = x % 2 - volatile uint16_t x = RNG_CHAR_NEXT; + // WC Input: x = 255, + volatile uint16_t x = INPUT_CHAR_NEXT; x *= 32; - WCET_CLAMP(x, 0, 5830, TASK_397_MESSAGE); - xTaskNotify(xTaskC32, DEBUG_VAL((x/32) & 0x1, 0), eSetValueWithOverwrite); + WCET_CLAMP(x*LOCAL_WCET_MULT, 0, 5830*LOCAL_WCET_MULT, TASK_397_MESSAGE); + xTaskNotify(xTaskC32, DEBUG_VAL((x/32) & 0x1, 1), eSetValueWithOverwrite); // 3 different activation strategies ------------- // activate sporadically from interrupts trigger_job_done(); @@ -342,16 +349,17 @@ static void prvTaskC32( void * pvParameters ) { // Actions -------------------------------------- // Exectime: f(x) = c + 100*x // Output: g(x) = x % 4 + // WC Input: x = 204 (local), y = 1 int y = ulTaskNotifyTake(pdTRUE, 0); - volatile uint16_t x = RNG_CHAR_NEXT; + volatile uint16_t x = INPUT_CHAR_NEXT; x *= 100; int torun = 0; - if (y) { + if (!y) { torun = CLAMP(x, 5000, 10000); } else { torun = CLAMP(x, 0, 20045); } - WCET_CLAMP(torun, 0, 20045, TASK_90_MESSAGE) + WCET_CLAMP(torun*LOCAL_WCET_MULT, 0, 20045*LOCAL_WCET_MULT, TASK_90_MESSAGE) xTaskNotify(xTaskC33, DEBUG_VAL((x/100) % 4, 0), eSetValueWithOverwrite); // --------------------------------------------- trigger_job_done(); @@ -367,10 +375,11 @@ static void prvTaskC33( void * pvParameters ) { RNG_RESET // Actions -------------------------------------- // Exectime: f(x) = c - x*y - volatile uint16_t x = RNG_SHORT_NEXT; + // WC Input: x = 0 | y = 0 + volatile uint16_t x = INPUT_SHORT_NEXT; int y = ulTaskNotifyTake(pdTRUE, 0); int torun = 76865-((int)x)*y; - WCET_CLAMP(torun, 10000, 76865, TASK_1107_MESSAGE) + WCET_CLAMP(torun*LOCAL_WCET_MULT, 10000, 76865*LOCAL_WCET_MULT, TASK_1107_MESSAGE) // --------------------------------------------- trigger_job_done(); xTaskDelayUntil( &xLastWakeTime, xFrequency );} @@ -390,9 +399,10 @@ static void prvTaskC11( void * pvParameters ) { // Actions -------------------------------------- // Exectime: f(x) = x>>8 & 0x0fff // Output: g(x) = x % 8 - uint32_t x = RNG_LONG_NEXT; + // WC Input: x = 629760 + uint32_t x = INPUT_LONG_NEXT; volatile int torun = (x>>8) & 0x0fff; - WCET_CLAMP(torun, 500, 2460, TASK_579_MESSAGE) + WCET_CLAMP(torun*LOCAL_WCET_MULT, 500*LOCAL_WCET_MULT, 2460*LOCAL_WCET_MULT, TASK_579_MESSAGE) xTaskNotify(xTaskC12, DEBUG_VAL(x % 8, 0), eSetValueWithOverwrite); // --------------------------------------------- trigger_job_done(); @@ -409,7 +419,8 @@ static void prvTaskC12( void * pvParameters ) { // Actions -------------------------------------- // Exectime: f(x,y) = if x%8 == y ? 40000+x : x (<40k) // Output: g(x) = x % 8 == y - uint16_t x = RNG_SHORT_NEXT; + // WC Input: x = 12000, y = 0 + uint16_t x = INPUT_SHORT_NEXT; int y = ulTaskNotifyTake(pdTRUE, 0); volatile int torun = 0; if (x % 8 == y) { @@ -417,7 +428,7 @@ static void prvTaskC12( void * pvParameters ) { } else { torun = CLAMP(x, 0, 40000); } - WCET_CLAMP(torun, 0, 51485, TASK_1009_MESSAGE) + WCET_CLAMP(torun*LOCAL_WCET_MULT, 0, 51485*LOCAL_WCET_MULT, TASK_1009_MESSAGE) xTaskNotify(xTaskC13, DEBUG_VAL(x % 8 == y, 1), eSetValueWithOverwrite); // --------------------------------------------- trigger_job_done(); @@ -438,7 +449,8 @@ static void prvTaskC13( void * pvParameters ) { // 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 = RNG_SHORT_NEXT; + // WC Input: x = , y = 1 + volatile uint32_t x = INPUT_SHORT_NEXT; int y = ulTaskNotifyTake(pdTRUE, 0); volatile int do_short_run = (y + ((x%100)<=5)) == 1; // XOR int torun = 0; @@ -447,7 +459,7 @@ static void prvTaskC13( void * pvParameters ) { } else { torun = 80000 + x; } - WCET_CLAMP(torun, 0, 145040, TASK_1129_MESSAGE) + WCET_CLAMP(torun*LOCAL_WCET_MULT, 0, 145040*LOCAL_WCET_MULT, TASK_1129_MESSAGE) xTaskNotify(xTaskC14, do_short_run, eSetValueWithOverwrite); // --------------------------------------------- trigger_job_done(); @@ -464,7 +476,7 @@ static void prvTaskC14( void * pvParameters ) { // Actions -------------------------------------- // Exectime: f(x,y) = if y ? c1+2*x : c2-x // longmax - shortmax: 76955 - volatile uint32_t x = RNG_SHORT_NEXT; + volatile uint32_t x = INPUT_SHORT_NEXT; int y = ulTaskNotifyTake(pdTRUE, 0); volatile int torun = 0; if (y) { @@ -472,7 +484,7 @@ static void prvTaskC14( void * pvParameters ) { } else { torun = 50000 - CLAMP_CEILING(x, 50000); } - WCET_CLAMP(torun, 10000, 126955, TASK_416_MESSAGE) + WCET_CLAMP(torun*LOCAL_WCET_MULT, 10000*LOCAL_WCET_MULT, 126955*LOCAL_WCET_MULT, TASK_416_MESSAGE) // --------------------------------------------- trigger_job_done(); xTaskDelayUntil( &xLastWakeTime, xFrequency );}