diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/Makefile b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/Makefile index 71fae43f..36098ae8 100644 --- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/Makefile +++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/Makefile @@ -124,6 +124,11 @@ ifeq ($(MINIMAL_DEMO), 1) CFLAGS := -DmainCREATE_MINIMAL_DEMO=1 else +ifeq ($(INTERACT_DEMO), 1) + SOURCE_FILES += main_interact.c + + CFLAGS := -DmainCREATE_INTERACT_DEMO=1 +else ifdef GEN_DEMO SOURCE_FILES += main_gen_$(GEN_DEMO).c @@ -147,6 +152,7 @@ endif endif endif endif +endif ifeq ($(INTERRUPT_ACTIVATION), 1) CFLAGS += -D INTERRUPT_ACTIVATION=1 diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main.c b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main.c index 77017810..af2d04aa 100644 --- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main.c +++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main.c @@ -111,6 +111,10 @@ int main() { main_gen(); } + #elif ( mainCREATE_INTERACT_DEMO == 1 ) + { + main_interact(); + } #else { @@ -154,10 +158,15 @@ void vApplicationStackOverflowHook( TaskHandle_t pxTask, } } /*-----------------------------------------------------------*/ +// #include "tasks.h" +// #include +// char buffer2[512] = {0}; void vApplicationIdleHook( void ) { volatile size_t xFreeHeapSpace; + // vTaskList(buffer2); + // puts(buffer2); /* This is just a trivial example of an idle hook. It is called on each * cycle of the idle task. It must *NOT* attempt to block. In this case the diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_interact.c b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_interact.c new file mode 100644 index 00000000..93327702 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_interact.c @@ -0,0 +1,321 @@ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" + + +/* +Async -> H +(E2 F2 (short)) +A -> B1 (enable ISR) | B2 (run longer) -> C +D -> (E1 | E2) & (F1 | F2) +(F2) -> K +(E1) -> L +(K+L) -> M +I(100ms) +*/ + + +// Task priorities +#define H_PRIO ( tskIDLE_PRIORITY + 10 ) +#define E2_PRIO ( tskIDLE_PRIORITY + 9 ) +#define F2_PRIO ( tskIDLE_PRIORITY + 9 ) +#define A_PRIO ( tskIDLE_PRIORITY + 7 ) +#define B_PRIO ( tskIDLE_PRIORITY + 8 ) +#define C_PRIO ( tskIDLE_PRIORITY + 7 ) +#define D_PRIO ( tskIDLE_PRIORITY + 6 ) +#define E1_PRIO ( tskIDLE_PRIORITY + 6 ) +#define F1_PRIO ( tskIDLE_PRIORITY + 6 ) +#define K_PRIO ( tskIDLE_PRIORITY + 5 ) +#define L_PRIO ( tskIDLE_PRIORITY + 5 ) +#define M_PRIO ( tskIDLE_PRIORITY + 9 ) +#define LOW_PRIO ( tskIDLE_PRIORITY + 1 ) + +// Task handles +TaskHandle_t h_task_handle = NULL; +TaskHandle_t e2_task_handle = NULL; +TaskHandle_t f2_task_handle = NULL; +TaskHandle_t a_task_handle = NULL; +TaskHandle_t b1_task_handle = NULL; +TaskHandle_t b2_task_handle = NULL; +TaskHandle_t c_task_handle = NULL; +TaskHandle_t d_task_handle = NULL; +TaskHandle_t e1_task_handle = NULL; +TaskHandle_t f1_task_handle = NULL; +TaskHandle_t k_task_handle = NULL; +TaskHandle_t l_task_handle = NULL; +TaskHandle_t m_task_handle = NULL; +TaskHandle_t low_task_handle = NULL; + +// Semaphores and other synchronization objects +SemaphoreHandle_t h_active_sem; +SemaphoreHandle_t k_sem; +SemaphoreHandle_t l_sem; + +#include +#include +#include "arbitrary_loads.c" +#define WCET_CLAMP(X, LB, UB, LABEL) PRINT_TIME(CLAMP(X,LB,UB),LABEL) + +__attribute__((noinline)) static void trigger_Qemu_break( void ) +{ + puts("Trigger"); + while (1) { + } +} + +// Input Stuff +volatile unsigned int FUZZ_INPUT[2048] = {0xa,0xb,0xc,0xd}; +volatile uint32_t FUZZ_LENGTH = 64; +volatile uint32_t FUZZ_POINTER = 0; +// Read the Byte of Input, if the Input is exausted trigger the breakpoint instead +static unsigned int fuzz_int_next(void) { + // printf("Get next Input from %lx \n",FUZZ_INPUT); + if (FUZZ_POINTER < 2048) { + uint32_t temp = __atomic_add_fetch(&FUZZ_POINTER,(uint32_t)1,__ATOMIC_SEQ_CST); + // FUZZ_POINTER++; + // return FUZZ_INPUT[FUZZ_POINTER-1]; + return ((unsigned int*)FUZZ_INPUT)[temp-1]; + } else { + // Exausted inputs early + puts("Exhausted"); + trigger_Qemu_break(); + } +} + +void h_task(void *params) { + while (1) { + ulTaskNotifyTake(pdTRUE,portMAX_DELAY); + if (xSemaphoreTake( h_active_sem, 0 ) == pdTRUE) { + PRINT_TIME(1*1000*1000,"h ") + } + } +} + +// Chain: A -> B1 (enable ISR) | B2 (run longer) -> C +static void a_task( void * pvParameters ) { + TickType_t xLastWakeTime = xTaskGetTickCount(); + const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; + for( ;; ){ + char buf[10]; + uint32_t x = fuzz_int_next(); + // TickType_t start = xTaskGetTickCount(); + // itoa(end-start, buf, 10); + // printf("Start: %d\n", start); + WCET_CLAMP(x % 1000000, 0, 1*1000*1000,"a ") + // TickType_t end = xTaskGetTickCount(); + // printf("Ends: %d\n", end); + // itoa(end-start, buf, 10); + // printf("Diff: %10s\n", buf); + if CHANCE_1_IN_POWOF2(x, 3) { + xTaskNotify(b1_task_handle, 1, eSetValueWithOverwrite); + } else { + xTaskNotify(b2_task_handle, 1, eSetValueWithOverwrite); + } + // --------------------------------------------- + vTaskDelayUntil( &xLastWakeTime, xFrequency );} +} + +// Chain: A -> B1 (enable ISR) | B2 (run longer) -> C +static void b1_task( void * pvParameters ) { + TickType_t xLastWakeTime = xTaskGetTickCount(); + const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; + for( ;; ){ + int y = ulTaskNotifyTake(pdTRUE, xFrequency); + if (y) { + uint32_t x = fuzz_int_next() % 4000000; + xSemaphoreGive(h_active_sem); + + WCET_CLAMP(x, 1*1000*1000, 4*1000*1000, "b1") + + xSemaphoreTake(h_active_sem, portMAX_DELAY); + xTaskNotify(c_task_handle, 1, eSetValueWithOverwrite); + } + // --------------------------------------------- + vTaskDelayUntil( &xLastWakeTime, xFrequency );} +} + +// Chain: A -> B1 (enable ISR) | B2 (run longer) -> C +static void b2_task( void * pvParameters ) { + TickType_t xLastWakeTime = xTaskGetTickCount(); + const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; + for( ;; ){ + int y = ulTaskNotifyTake(pdTRUE, xFrequency); + if (y) { + uint32_t x = fuzz_int_next() % 6000000; + + volatile int torun = x+1000000; + WCET_CLAMP(torun, 3*1000*1000, 6*1000*1000, "b2") + + xTaskNotify(c_task_handle, 1, eSetValueWithOverwrite); + } + // --------------------------------------------- + vTaskDelayUntil( &xLastWakeTime, xFrequency );} +} + +// Chain: A -> B1 (enable ISR) | B2 (run longer) -> C +static void c_task( void * pvParameters ) { + TickType_t xLastWakeTime = xTaskGetTickCount(); + const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; + for( ;; ){ + int y = ulTaskNotifyTake(pdTRUE, xFrequency); + if (y) { + PRINT_TIME(1*1000*1000,"c ") + } + // --------------------------------------------- + vTaskDelayUntil( &xLastWakeTime, xFrequency );} +} + +// Chain: D -> (E1 | E2) & (F1 | F2) +void d_task(void *params) { + TickType_t xLastWakeTime = xTaskGetTickCount(); + const TickType_t xFrequency = 20 / portTICK_PERIOD_MS; + for( ;; ){ + uint32_t x = fuzz_int_next() % 6000000; + WCET_CLAMP(x, 3*1000*1000, 6*1000*1000, "d ") + if CHANCE_1_IN_POWOF2(x, 3) { + xTaskNotify(e2_task_handle, 1, eSetValueWithOverwrite); + xTaskNotify(f2_task_handle, 1, eSetValueWithOverwrite); + } else { + xTaskNotify(f1_task_handle, 1, eSetValueWithOverwrite); + xTaskNotify(e1_task_handle, 1, eSetValueWithOverwrite); + } + // --------------------------------------------- + vTaskDelayUntil( &xLastWakeTime, xFrequency );} +} +// Chain: D -> (E1 | E2) & (F1 | F2) +void e1_task(void *params) { + TickType_t xLastWakeTime = xTaskGetTickCount(); + const TickType_t xFrequency = 20 / portTICK_PERIOD_MS; + for( ;; ){ + int y = ulTaskNotifyTake(pdTRUE, xFrequency); + if (y) { + uint32_t x = fuzz_int_next() % 2000000; + WCET_CLAMP(x, 1*1000*1000, 2*1000*1000, "e1") + } + // --------------------------------------------- + vTaskDelayUntil( &xLastWakeTime, xFrequency );} +} +// Chain: D -> (E1 | E2) & (F1 | F2) +void e2_task(void *params) { + TickType_t xLastWakeTime = xTaskGetTickCount(); + const TickType_t xFrequency = 5 / portTICK_PERIOD_MS; + for( ;; ){ + int y = ulTaskNotifyTake(pdTRUE, xFrequency); + if (y) { + uint32_t x = fuzz_int_next() % 1000000; + WCET_CLAMP(x, 200000, 1000000, "e2") + xTaskNotify(l_task_handle, 1, eSetValueWithOverwrite); + } + // --------------------------------------------- + vTaskDelayUntil( &xLastWakeTime, xFrequency );} +} +// Chain: D -> (E1 | E2) & (F1 | F2) +void f1_task(void *params) { + TickType_t xLastWakeTime = xTaskGetTickCount(); + const TickType_t xFrequency = 20 / portTICK_PERIOD_MS; + for( ;; ){ + int y = ulTaskNotifyTake(pdTRUE, xFrequency); + if (y) { + uint32_t x = fuzz_int_next() % 2000000; + WCET_CLAMP(x, 1*1000*1000, 2*1000*1000, "f1") + } + // --------------------------------------------- + vTaskDelayUntil( &xLastWakeTime, xFrequency );} +} +// Chain: D -> (E1 | E2) & (F1 | F2) +void f2_task(void *params) { + TickType_t xLastWakeTime = xTaskGetTickCount(); + const TickType_t xFrequency = 5 / portTICK_PERIOD_MS; + for( ;; ){ + int y = ulTaskNotifyTake(pdTRUE, xFrequency); + if (y) { + uint32_t x = fuzz_int_next() % 1000000; + WCET_CLAMP(x, 200000, 1000000, "f2") + xTaskNotify(k_task_handle, 1, eSetValueWithOverwrite); + } + // --------------------------------------------- + vTaskDelayUntil( &xLastWakeTime, xFrequency );} +} + +// Chain: K + L -> M +void k_task(void *params) { + TickType_t xLastWakeTime = xTaskGetTickCount(); + const TickType_t xFrequency = 25 / portTICK_PERIOD_MS; + for( ;; ){ + int y = ulTaskNotifyTake(pdTRUE, xFrequency); + if (y) { + PRINT_TIME(1*1000*1000,"k ") + xSemaphoreGive(k_sem); + } + // --------------------------------------------- + vTaskDelayUntil( &xLastWakeTime, xFrequency );} +} +// Chain: K + L -> M +void l_task(void *params) { + TickType_t xLastWakeTime = xTaskGetTickCount(); + const TickType_t xFrequency = 25 / portTICK_PERIOD_MS; + for( ;; ){ + int y = ulTaskNotifyTake(pdTRUE, xFrequency); + if (y) { + PRINT_TIME(1*1000*1000,"l ") + xSemaphoreGive(l_sem); + } + // --------------------------------------------- + vTaskDelayUntil( &xLastWakeTime, xFrequency );} +} +// Chain: K + L -> M +void m_task(void *params) { + TickType_t xLastWakeTime = xTaskGetTickCount(); + const TickType_t xFrequency = 5 / portTICK_PERIOD_MS; + for( ;; ){ + xSemaphoreTake(k_sem, portMAX_DELAY); + xSemaphoreTake(l_sem, portMAX_DELAY); + uint32_t x = fuzz_int_next() % 3000000; + WCET_CLAMP(x, 1*1000*1000, 3*1000*1000, "m ") + // --------------------------------------------- + vTaskDelayUntil( &xLastWakeTime, xFrequency );} +} + +void low_task(void *params) { + TickType_t xLastWakeTime = xTaskGetTickCount(); + const TickType_t xFrequency = 50 / portTICK_PERIOD_MS; + for( ;; ){ + PRINT_TIME(100*1000*1000,"lo") + trigger_Qemu_break(); + // --------------------------------------------- + vTaskDelayUntil( &xLastWakeTime, xFrequency );} +} + +void main_interact(void) { + // Initialize synchronization objects + h_active_sem = xSemaphoreCreateCounting(10, 0); + k_sem = xSemaphoreCreateCounting(3, 0); + l_sem = xSemaphoreCreateCounting(3, 0); + + // Create tasks + xTaskCreate(h_task, "h", configMINIMAL_STACK_SIZE, NULL, H_PRIO, &h_task_handle); + xTaskCreate(e2_task, "e2", configMINIMAL_STACK_SIZE, NULL, E2_PRIO, &e2_task_handle); + xTaskCreate(f2_task, "f2", configMINIMAL_STACK_SIZE, NULL, F2_PRIO, &f2_task_handle); + xTaskCreate(a_task, "a", configMINIMAL_STACK_SIZE, NULL, H_PRIO, &a_task_handle); + xTaskCreate(b1_task, "b2", configMINIMAL_STACK_SIZE, NULL, B_PRIO, &b1_task_handle); + xTaskCreate(b2_task, "b2", configMINIMAL_STACK_SIZE, NULL, B_PRIO, &b2_task_handle); + xTaskCreate(c_task, "c", configMINIMAL_STACK_SIZE, NULL, C_PRIO, &c_task_handle); + xTaskCreate(d_task, "d", configMINIMAL_STACK_SIZE, NULL, D_PRIO, &d_task_handle); + xTaskCreate(e1_task, "e1", configMINIMAL_STACK_SIZE, NULL, E1_PRIO, &e1_task_handle); + xTaskCreate(f1_task, "f1", configMINIMAL_STACK_SIZE, NULL, F1_PRIO, &f1_task_handle); + xTaskCreate(k_task, "k", configMINIMAL_STACK_SIZE, NULL, K_PRIO, &k_task_handle); + xTaskCreate(l_task, "l", configMINIMAL_STACK_SIZE, NULL, L_PRIO, &l_task_handle); + xTaskCreate(m_task, "m", configMINIMAL_STACK_SIZE, NULL, M_PRIO, &m_task_handle); + xTaskCreate(low_task, "LOW", configMINIMAL_STACK_SIZE, NULL, LOW_PRIO, &low_task_handle); + + vTaskStartScheduler(); + trigger_Qemu_break(); +} + +void isr_starter( void ) +{ + puts("Interrupt"); + if (h_task_handle) { + vTaskNotifyGiveFromISR(h_task_handle, NULL); + } +} \ No newline at end of file