diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/FreeRTOSConfig.h b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/FreeRTOSConfig.h index 2d046e95..22963398 100644 --- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/FreeRTOSConfig.h +++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/FreeRTOSConfig.h @@ -45,7 +45,7 @@ extern void vAssertCalled( void ); #define configQUEUE_REGISTRY_SIZE 20 #define configUSE_PREEMPTION 1 -#define configUSE_TIME_SLICING 0 +#define configUSE_TIME_SLICING 1 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configUSE_IDLE_HOOK 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 e3f91aa0..5b64d7c5 100644 --- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/arbitrary_loads.c +++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/arbitrary_loads.c @@ -6,7 +6,7 @@ volatile long _NONSENSE_VAR = 0; #define NS_PER_INS (1000000000 / configCPU_CLOCK_HZ) // 20MHz #define INS_PER_LOOP 5 // got this multiplier by testing with the goal of getting a 100 ms or 100 tick period #define INS_PER_PRINT 117 // got this multiplier by testing with the goal of getting a 100 ms or 100 tick period, 2 digits -#define GLOBAL_WCET_MULT 1 // Multiplier to increase all waiting periods to make the schedule more tight an force preemptions +#define GLOBAL_WCET_MULT 16 // Multiplier to increase all waiting periods to make the schedule more tight an force preemptions #define WASTE_TIME(X) for (int i=0; i<=((X*GLOBAL_WCET_MULT)/(NS_PER_INS*INS_PER_LOOP)); i++) {_NONSENSE_VAR+=i;} #define PRINT_TIME(X,Y) for (int i=0; i<=((X*GLOBAL_WCET_MULT)/((NS_PER_INS*INS_PER_PRINT))); i++) {puts(Y);} // #define PRINT_TIME(X,Y) WASTE_TIME(X) 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 b6b95106..88556f63 100644 --- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_waters.c +++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_waters.c @@ -51,6 +51,17 @@ __attribute__((noinline)) static void trigger_Qemu_break( void ) while (1) { } } +// #define DEBUG_WCET(A) {A} + +// #define WCET_END(A) +#define WCET_END(A) {A} + +#ifdef DEBUG_WCET + #define WCET_CLAMP(X, LB, UB, LABEL) PRINT_TIME(UB,LABEL) +#else + #define WCET_CLAMP(X, LB, UB, LABEL) PRINT_TIME(CLAMP(X,LB,UB),LABEL) + #define DEBUG_WCET(A) +#endif // Begin Input Stuff volatile unsigned char FUZZ_INPUT[4096] = {0xa,0xb,0xc,0xd,0xe,0xf}; @@ -106,28 +117,53 @@ static void prvTask1129( void * pvParameters ); // Chain3: 397 -> 90 -> 1107 // spor 2ms 50ms // cross-chain effect ideas: -// + +// RM + sort by chains #define mainTASK_31_PRIO ( tskIDLE_PRIORITY + 1 ) #define mainTASK_78_PRIO ( tskIDLE_PRIORITY + 5 ) #define mainTASK_90_PRIO ( tskIDLE_PRIORITY + 8 ) #define mainTASK_397_PRIO ( tskIDLE_PRIORITY + 10 ) #define mainTASK_400_PRIO ( tskIDLE_PRIORITY + 9 ) -#define mainTASK_416_PRIO ( tskIDLE_PRIORITY + 4 ) +#define mainTASK_416_PRIO ( tskIDLE_PRIORITY + 3 ) #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_1129_PRIO ( tskIDLE_PRIORITY + 4 ) + +// RM with pref for short +// #define mainTASK_31_PRIO ( tskIDLE_PRIORITY + 1 ) +// #define mainTASK_78_PRIO ( tskIDLE_PRIORITY + 5 ) +// #define mainTASK_90_PRIO ( tskIDLE_PRIORITY + 8 ) +// #define mainTASK_397_PRIO ( tskIDLE_PRIORITY + 10 ) +// #define mainTASK_400_PRIO ( tskIDLE_PRIORITY + 9 ) +// #define mainTASK_416_PRIO ( tskIDLE_PRIORITY + 4 ) +// #define mainTASK_579_PRIO ( tskIDLE_PRIORITY + 7 ) +// #define mainTASK_1009_PRIO ( tskIDLE_PRIORITY + 6 ) +// #define mainTASK_1107_PRIO ( tskIDLE_PRIORITY + 2 ) +// #define mainTASK_1129_PRIO ( tskIDLE_PRIORITY + 3 ) + +// Same Prio +// #define mainTASK_31_PRIO ( tskIDLE_PRIORITY + 1 ) +// #define mainTASK_78_PRIO ( tskIDLE_PRIORITY + 7 ) +// #define mainTASK_90_PRIO ( tskIDLE_PRIORITY + 8 ) +// #define mainTASK_397_PRIO ( tskIDLE_PRIORITY + 10 ) +// #define mainTASK_400_PRIO ( tskIDLE_PRIORITY + 9 ) +// #define mainTASK_416_PRIO ( tskIDLE_PRIORITY + 7 ) +// #define mainTASK_579_PRIO ( tskIDLE_PRIORITY + 7 ) +// #define mainTASK_1009_PRIO ( tskIDLE_PRIORITY + 7 ) +// #define mainTASK_1107_PRIO ( tskIDLE_PRIORITY + 2 ) +// #define mainTASK_1129_PRIO ( tskIDLE_PRIORITY + 7 ) #define TASK_31_MESSAGE "01" #define TASK_78_MESSAGE "05" #define TASK_90_MESSAGE "08" #define TASK_397_MESSAGE "10" #define TASK_400_MESSAGE "09" -#define TASK_416_MESSAGE "04" +#define TASK_416_MESSAGE "03" #define TASK_579_MESSAGE "07" #define TASK_1009_MESSAGE "06" #define TASK_1107_MESSAGE "02" -#define TASK_1129_MESSAGE "03" +#define TASK_1129_MESSAGE "04" // Handles for direct messages static TaskHandle_t xTask31 = NULL; @@ -239,12 +275,14 @@ static void prvTask31( void * pvParameters ) { const TickType_t xFrequency = 100 / portTICK_PERIOD_MS; int period_counter = 2; for( ;; ){ + WCET_END({if (--period_counter==0) {puts("End");}}) // Debugging // Actions -------------------------------------- - PRINT_TIME(48940, TASK_31_MESSAGE) - if (--period_counter==0) {puts("End");} - // uint16_t x = fuzz_short_next(); - // PRINT_TIME(CLAMP(x, 0, 2<<11), TASK_579_MESSAGE) - xTaskNotify(xTask78, 0, eSetValueWithOverwrite); + // Exectime: f(x) = x + // Output: g(x) = x % 2 + uint16_t x = fuzz_short_next(); + WCET_CLAMP(x, 0, 48940, TASK_31_MESSAGE) + WCET_END({puts("End");}) + xTaskNotify(xTask78, x % 2, eSetValueWithOverwrite); // --------------------------------------------- vTaskDelayUntil( &xLastWakeTime, xFrequency );}// Wait for the next cycle. } @@ -255,39 +293,54 @@ static void prvTask78( void * pvParameters ) { const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; for( ;; ){ // Actions -------------------------------------- - // uint16_t x = fuzz_short_next(); + // Exectime: f(x,y) = c + y*20000 + rng(x)*50000 + // Output: g(x,y) = y * (x % 4) + uint16_t x = fuzz_short_next(); int y = ulTaskNotifyTake(pdFALSE, 0); - PRINT_TIME(76035, TASK_78_MESSAGE) - // PRINT_TIME(CLAMP(x, 0, 2<<11), TASK_579_MESSAGE) - xTaskNotify(xTask400, 0, eSetValueWithOverwrite); + int torun = 6035; + if (y > 0) { + torun += 20000; + } + if (CHANCE_1_IN_POWOF2(x, 5)) { + torun += 50000; + } + WCET_CLAMP(torun, 0, 76035, TASK_78_MESSAGE) + xTaskNotify(xTask400, y * (x % 4), eSetValueWithOverwrite); // --------------------------------------------- vTaskDelayUntil( &xLastWakeTime, xFrequency );} } -// Chain3: 397 -> 90 -> 1107 -static void prvTask90( void * pvParameters ) { +// Chain2: 31 -> 78 -> 400 +static void prvTask400( void * pvParameters ) { TickType_t xLastWakeTime = xTaskGetTickCount(); const TickType_t xFrequency = 2 / portTICK_PERIOD_MS; for( ;; ){ // Actions -------------------------------------- - // Exectime: f(x) = c + x - // Output: g(x) = x % 4 - PRINT_TIME(20045, TASK_90_MESSAGE) + // Exectime: f(x,y) = rng(x)*y*c or (rng(x) % 1000) + uint32_t x = fuzz_long_next(); int y = ulTaskNotifyTake(pdFALSE, 0); - uint16_t x = fuzz_short_next(); - // PRINT_TIME(CLAMP(x, 0, 2<<11), TASK_579_MESSAGE) - xTaskNotify(xTask1107, x % 4, eSetValueWithOverwrite); + int torun = 0; + if (y == 2 && CHANCE_1_IN_POWOF2(x, 2)) { + torun = 1765; + } else { + torun = RNG_FROM(x) % 1000; + } + WCET_CLAMP(torun, 0, 1765, TASK_400_MESSAGE) // --------------------------------------------- vTaskDelayUntil( &xLastWakeTime, xFrequency );} } +//================================================================== + // Chain3: 397 -> 90 -> 1107 static void prvTask397( void * pvParameters ) { TickType_t xLastWakeTime = xTaskGetTickCount(); const TickType_t xFrequency = 1 / portTICK_PERIOD_MS; for( ;; ){ + // Exectime: f(x) = x + // Output: g(x) = x % 2 uint16_t x = fuzz_short_next(); - PRINT_TIME(5830, TASK_397_MESSAGE); + WCET_CLAMP(x, 0, 5830, TASK_397_MESSAGE); xTaskNotify(xTask90, x & 0x1, eSetValueWithOverwrite); // 3 different activation strategies ------------- // activate sporadically from interrupts @@ -299,58 +352,24 @@ static void prvTask397( void * pvParameters ) { } } -// Chain2: 31 -> 78 -> 400 -static void prvTask400( void * pvParameters ) { +// Chain3: 397 -> 90 -> 1107 +static void prvTask90( void * pvParameters ) { TickType_t xLastWakeTime = xTaskGetTickCount(); const TickType_t xFrequency = 2 / portTICK_PERIOD_MS; - for( ;; ){ - // Actions -------------------------------------- - // uint16_t x = fuzz_short_next(); - int y = ulTaskNotifyTake(pdFALSE, 0); - PRINT_TIME(1765, TASK_400_MESSAGE) - // --------------------------------------------- - vTaskDelayUntil( &xLastWakeTime, xFrequency );} -} - -// Chain1: 579 -> 1009 -> 1129 -> 416 -static void prvTask416( void * pvParameters ) { - TickType_t xLastWakeTime = xTaskGetTickCount(); - const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; - for( ;; ){ - // Actions -------------------------------------- - // uint16_t x = fuzz_short_next(); - int y = ulTaskNotifyTake(pdFALSE, 0); - PRINT_TIME(126955, TASK_416_MESSAGE) - // --------------------------------------------- - vTaskDelayUntil( &xLastWakeTime, xFrequency );} -} - -// Chain1: 579 -> 1009 -> 1129 -> 416 -static void prvTask579( void * pvParameters ) { - TickType_t xLastWakeTime = xTaskGetTickCount(); - const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; for( ;; ){ // Actions -------------------------------------- // Exectime: f(x) = c + x // Output: g(x) = x % 4 - PRINT_TIME(2460, TASK_579_MESSAGE) - // uint16_t x = fuzz_short_next(); - // PRINT_TIME(CLAMP(x, 0, 2<<11), TASK_579_MESSAGE) - xTaskNotify(xTask1009, 0, eSetValueWithOverwrite); - // --------------------------------------------- - vTaskDelayUntil( &xLastWakeTime, xFrequency );} -} - -// Chain1: 579 -> 1009 -> 1129 -> 416 -static void prvTask1009( void * pvParameters ) { - TickType_t xLastWakeTime = xTaskGetTickCount(); - const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; - for( ;; ){ - // Actions -------------------------------------- - // uint16_t x = fuzz_short_next(); int y = ulTaskNotifyTake(pdFALSE, 0); - PRINT_TIME(51485, TASK_1009_MESSAGE) - xTaskNotify(xTask1129, 0, eSetValueWithOverwrite); + uint16_t x = fuzz_short_next(); + int torun = 0; + if (y) { + torun = CLAMP(x, 5000, 10000); + } else { + torun = CLAMP(x, 0, 20045); + } + WCET_CLAMP(torun, 0, 20045, TASK_90_MESSAGE) + xTaskNotify(xTask1107, x % 4, eSetValueWithOverwrite); // --------------------------------------------- vTaskDelayUntil( &xLastWakeTime, xFrequency );} } @@ -361,9 +380,53 @@ static void prvTask1107( void * pvParameters ) { const TickType_t xFrequency = 50 / portTICK_PERIOD_MS; for( ;; ){ // Actions -------------------------------------- - // uint16_t x = fuzz_short_next(); + // Exectime: f(x) = c - x*y + uint16_t x = fuzz_short_next(); int y = ulTaskNotifyTake(pdFALSE, 0); - PRINT_TIME(76865, TASK_1107_MESSAGE) + int torun = 76865-((int)x)*y; + WCET_CLAMP(torun, 10000, 76865, TASK_1107_MESSAGE) + // --------------------------------------------- + vTaskDelayUntil( &xLastWakeTime, xFrequency );} +} + +//================================================================== + +// Chain1: 579 -> 1009 -> 1129 -> 416 +static void prvTask579( void * pvParameters ) { + // int period = 5; + TickType_t xLastWakeTime = xTaskGetTickCount(); + const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; + for( ;; ){ + // if (--period==0) {puts("End");} // Debugging Marker + // Actions -------------------------------------- + // Exectime: f(x) = x>>8 & 0x0fff + // Output: g(x) = x % 8 + uint32_t x = fuzz_long_next(); + int torun = (x>>8) & 0x0fff; + WCET_CLAMP(torun, 500, 2460, TASK_579_MESSAGE) + xTaskNotify(xTask1009, x % 8, eSetValueWithOverwrite); + // --------------------------------------------- + vTaskDelayUntil( &xLastWakeTime, xFrequency );} +} + +// Chain1: 579 -> 1009 -> 1129 -> 416 +static void prvTask1009( void * pvParameters ) { + TickType_t xLastWakeTime = xTaskGetTickCount(); + const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; + for( ;; ){ + // Actions -------------------------------------- + // Exectime: f(x,y) = if x%8 == y ? 40000+x : x (<40k) + // Output: g(x) = x % 8 == y + uint16_t x = fuzz_short_next(); + int y = ulTaskNotifyTake(pdFALSE, 0); + int torun = 0; + if (x % 8 == y) { + torun = 40000 + x; + } else { + torun = CLAMP(x, 0, 40000); + } + WCET_CLAMP(torun, 0, 51485, TASK_1009_MESSAGE) + xTaskNotify(xTask1129, x % 8 == y, eSetValueWithOverwrite); // --------------------------------------------- vTaskDelayUntil( &xLastWakeTime, xFrequency );} } @@ -374,13 +437,40 @@ static void prvTask1129( void * pvParameters ) { TickType_t xLastWakeTime = xTaskGetTickCount(); const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; for( ;; ){ + // if (--period_counter==0) {puts("End");} // Actions -------------------------------------- - // uint16_t x = fuzz_short_next(); + // Exectime: f(x,y) = if !y ? 80000+x : x (<40k) + // Output: g(x) = x % 4 + uint32_t x = (uint32_t)fuzz_short_next(); int y = ulTaskNotifyTake(pdFALSE, 0); - PRINT_TIME(145040, TASK_1129_MESSAGE) - if (--period_counter==0) {puts("End");} - // PRINT_TIME(CLAMP(x, 0, 2<<11), TASK_579_MESSAGE) - xTaskNotify(xTask416, 0, eSetValueWithOverwrite); + int torun = 0; + if (!y) { + torun = 80000 + x; + } else { + torun = x; + } + WCET_CLAMP(torun, 0, 145040, TASK_1129_MESSAGE) + xTaskNotify(xTask416, x % 4, eSetValueWithOverwrite); + // --------------------------------------------- + vTaskDelayUntil( &xLastWakeTime, xFrequency );} +} + +// Chain1: 579 -> 1009 -> 1129 -> 416 +static void prvTask416( void * pvParameters ) { + TickType_t xLastWakeTime = xTaskGetTickCount(); + const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; + for( ;; ){ + // Actions -------------------------------------- + // Exectime: f(x,y) = if y == 3 ? c-x : c+x + uint32_t x = (uint32_t)fuzz_short_next(); + int y = ulTaskNotifyTake(pdFALSE, 0); + int torun = 0; + if (y==3) { + torun = 70000 + x; + } else { + torun = 70000 - x; + } + PRINT_TIME(126955, TASK_416_MESSAGE) // --------------------------------------------- vTaskDelayUntil( &xLastWakeTime, xFrequency );} }