From b97fdd56d8e8b8a4fdc2781886c3766ac60f7a44 Mon Sep 17 00:00:00 2001 From: Alwin Berger Date: Mon, 6 Feb 2023 12:37:32 +0100 Subject: [PATCH] waters: insert chains --- .../CORTEX_M3_MPS2_QEMU_GCC/arbitrary_loads.c | 8 +- .../CORTEX_M3_MPS2_QEMU_GCC/main_waters.c | 101 +++++++++++------- 2 files changed, 69 insertions(+), 40 deletions(-) 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 4bb8a671..e3f91aa0 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,7 @@ #ifndef ARB_LOAD_C #define ARB_LOAD_C 1 +// Time wasters ===== 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 @@ -9,16 +10,21 @@ volatile long _NONSENSE_VAR = 0; #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) + +// 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 +// Random numbers === #define A (unsigned int)2000000011 // prime #define M (unsigned int)4000000007 // prime #define C (unsigned int)1283612343 static unsigned int rng_seed = 2345745; #define RNG rng_seed+=((A*((rng_seed+=C)-C)+C) % M) #define RNG_FROM(X) ((A*X+C) % M) -#define CHANCE_1_IN_POWOF2(X,Y) (RNG_FROM(X)<(M>>Y)) + +// Challanges ======= +#define CHANCE_1_IN_POWOF2(X,Y) (RNG_FROM(X)<(M>>Y)) // assume the type of x has more than y bits #endif \ 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 81e69708..b6b95106 100644 --- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_waters.c +++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_waters.c @@ -99,6 +99,14 @@ static void prvTask1129( void * pvParameters ); // Priorities using rate-monotonic scheduling // ties are decided favoring short wcets +// Chain1: 579 -> 1009 -> 1129 -> 416 +// 10ms 10ms 10ms 10ms +// Chain2: 31 -> 78 -> 400 +// 100ms 10ms 2ms +// Chain3: 397 -> 90 -> 1107 +// spor 2ms 50ms +// cross-chain effect ideas: +// #define mainTASK_31_PRIO ( tskIDLE_PRIORITY + 1 ) #define mainTASK_78_PRIO ( tskIDLE_PRIORITY + 5 ) #define mainTASK_90_PRIO ( tskIDLE_PRIORITY + 8 ) @@ -159,12 +167,13 @@ void main_waters( void ) mainTASK_90_PRIO, &xTask90 ); - // xTaskCreate( prvTask397, - // "397", - // configMINIMAL_STACK_SIZE, - // NULL, - // mainTASK_397_PRIO, - // &xTask397 ); + // This task is supposed to be sporadic + xTaskCreate( prvTask397, + "397", + configMINIMAL_STACK_SIZE, + NULL, + mainTASK_397_PRIO, + &xTask397 ); xTaskCreate( prvTask400, "400", @@ -224,36 +233,38 @@ void main_waters( void ) } } +// Chain2: 31 -> 78 -> 400 static void prvTask31( void * pvParameters ) { TickType_t xLastWakeTime = xTaskGetTickCount(); const TickType_t xFrequency = 100 / portTICK_PERIOD_MS; + int period_counter = 2; for( ;; ){ // Actions -------------------------------------- - // Exectime: f(x) = c + x - // Output: g(x) = x % 4 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(xTask1009, x % 4, eSetValueWithOverwrite); + xTaskNotify(xTask78, 0, eSetValueWithOverwrite); // --------------------------------------------- vTaskDelayUntil( &xLastWakeTime, xFrequency );}// Wait for the next cycle. } +// Chain2: 31 -> 78 -> 400 static void prvTask78( void * pvParameters ) { TickType_t xLastWakeTime = xTaskGetTickCount(); const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; for( ;; ){ // Actions -------------------------------------- - // Exectime: f(x) = c + x - // Output: g(x) = x % 4 - PRINT_TIME(76035, TASK_78_MESSAGE) // 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(xTask1009, x % 4, eSetValueWithOverwrite); + xTaskNotify(xTask400, 0, eSetValueWithOverwrite); // --------------------------------------------- vTaskDelayUntil( &xLastWakeTime, xFrequency );} } +// Chain3: 397 -> 90 -> 1107 static void prvTask90( void * pvParameters ) { TickType_t xLastWakeTime = xTaskGetTickCount(); const TickType_t xFrequency = 2 / portTICK_PERIOD_MS; @@ -262,49 +273,59 @@ static void prvTask90( void * pvParameters ) { // Exectime: f(x) = c + x // Output: g(x) = x % 4 PRINT_TIME(20045, TASK_90_MESSAGE) - // uint16_t x = fuzz_short_next(); + int y = ulTaskNotifyTake(pdFALSE, 0); + uint16_t x = fuzz_short_next(); // PRINT_TIME(CLAMP(x, 0, 2<<11), TASK_579_MESSAGE) - // xTaskNotify(xTask1009, x % 4, eSetValueWithOverwrite); + xTaskNotify(xTask1107, x % 4, eSetValueWithOverwrite); // --------------------------------------------- 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( ;; ){ - ulTaskNotifyTake(pdTRUE,portMAX_DELAY); - PRINT_TIME(5830, TASK_397_MESSAGE);} + uint16_t x = fuzz_short_next(); + PRINT_TIME(5830, TASK_397_MESSAGE); + xTaskNotify(xTask90, x & 0x1, eSetValueWithOverwrite); + // 3 different activation strategies ------------- + // activate sporadically from interrupts + // ulTaskNotifyTake(pdTRUE,portMAX_DELAY); + // activate with worst possible frequency (700us, but tick resolution is too low) + vTaskDelayUntil( &xLastWakeTime, xFrequency ); + // wait pseudo random many ticks + // vTaskDelayUntil( &xLastWakeTime, CLAMP(RNG, 1, 100) / portTICK_PERIOD_MS ); + } } +// 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(1765, TASK_400_MESSAGE) // uint16_t x = fuzz_short_next(); - // PRINT_TIME(CLAMP(x, 0, 2<<11), TASK_579_MESSAGE) - // xTaskNotify(xTask1009, x % 4, eSetValueWithOverwrite); + 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 -------------------------------------- - // Exectime: f(x) = c + x - // Output: g(x) = x % 4 - PRINT_TIME(126955, TASK_416_MESSAGE) // uint16_t x = fuzz_short_next(); - // PRINT_TIME(CLAMP(x, 0, 2<<11), TASK_579_MESSAGE) - // xTaskNotify(xTask1009, x % 4, eSetValueWithOverwrite); + 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; @@ -315,50 +336,51 @@ static void prvTask579( void * pvParameters ) { PRINT_TIME(2460, TASK_579_MESSAGE) // uint16_t x = fuzz_short_next(); // PRINT_TIME(CLAMP(x, 0, 2<<11), TASK_579_MESSAGE) - // xTaskNotify(xTask1009, x % 4, eSetValueWithOverwrite); + 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 -------------------------------------- - // int y = ulTaskNotifyTake(pdFALSE, 0); - PRINT_TIME(51485, TASK_1009_MESSAGE); + // uint16_t x = fuzz_short_next(); + int y = ulTaskNotifyTake(pdFALSE, 0); + PRINT_TIME(51485, TASK_1009_MESSAGE) + xTaskNotify(xTask1129, 0, eSetValueWithOverwrite); // --------------------------------------------- vTaskDelayUntil( &xLastWakeTime, xFrequency );} } +// Chain3: 397 -> 90 -> 1107 static void prvTask1107( void * pvParameters ) { TickType_t xLastWakeTime = xTaskGetTickCount(); const TickType_t xFrequency = 50 / portTICK_PERIOD_MS; for( ;; ){ // Actions -------------------------------------- - // Exectime: f(x) = c + x - // Output: g(x) = x % 4 - PRINT_TIME(76865, TASK_1107_MESSAGE) // uint16_t x = fuzz_short_next(); - // PRINT_TIME(CLAMP(x, 0, 2<<11), TASK_579_MESSAGE) - // xTaskNotify(xTask1009, x % 4, eSetValueWithOverwrite); + int y = ulTaskNotifyTake(pdFALSE, 0); + PRINT_TIME(76865, TASK_1107_MESSAGE) // --------------------------------------------- vTaskDelayUntil( &xLastWakeTime, xFrequency );} } +// Chain1: 579 -> 1009 -> 1129 -> 416 static void prvTask1129( void * pvParameters ) { int period_counter = 2; TickType_t xLastWakeTime = xTaskGetTickCount(); const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; for( ;; ){ // Actions -------------------------------------- - // Exectime: f(x) = c + x - // Output: g(x) = x % 4 + // uint16_t x = fuzz_short_next(); + int y = ulTaskNotifyTake(pdFALSE, 0); PRINT_TIME(145040, TASK_1129_MESSAGE) if (--period_counter==0) {puts("End");} - // uint16_t x = fuzz_short_next(); // PRINT_TIME(CLAMP(x, 0, 2<<11), TASK_579_MESSAGE) - // xTaskNotify(xTask1009, x % 4, eSetValueWithOverwrite); + xTaskNotify(xTask416, 0, eSetValueWithOverwrite); // --------------------------------------------- vTaskDelayUntil( &xLastWakeTime, xFrequency );} } @@ -371,6 +393,7 @@ void vWatersIdleFunction() { void isr_starter( void ) { + xTaskNotifyGive(xTask397); } /*-----------------------------------------------------------*/