Compare commits

..

No commits in common. "wcet-demo" and "eval-24-10-30" have entirely different histories.

24 changed files with 488 additions and 3344 deletions

View File

@ -45,7 +45,7 @@ extern void vAssertCalled( void );
#define configQUEUE_REGISTRY_SIZE 20 #define configQUEUE_REGISTRY_SIZE 20
#define configUSE_PREEMPTION 1 #define configUSE_PREEMPTION 1
#define configUSE_TIME_SLICING 0 #define configUSE_TIME_SLICING 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
#define configUSE_IDLE_HOOK 1 #define configUSE_IDLE_HOOK 1
@ -131,5 +131,5 @@ extern void vLoggingPrintf( const char * pcFormatString,
#endif #endif
#define configUSE_TASK_NOTIFICATIONS 1 #define configUSE_TASK_NOTIFICATIONS 1
#define configTASK_NOTIFICATION_ARRAY_ENTRIES 10 #define configTASK_NOTIFICATION_ARRAY_ENTRIES 4
#endif /* FREERTOS_CONFIG_H */ #endif /* FREERTOS_CONFIG_H */

View File

@ -149,26 +149,10 @@ ifeq ($(COPTER_DEMO), 1)
CFLAGS := -DmainCOPTER_DEMO=1 CFLAGS := -DmainCOPTER_DEMO=1
else else
ifeq ($(POLYCOPTER_DEMO), 1)
SOURCE_FILES += main_polycopter.c
CFLAGS := -DmainPOLYCOPTER_DEMO=1
CFLAGS += -Wno-overflow
else
ifeq ($(RELEASE_DEMO), 1) ifeq ($(RELEASE_DEMO), 1)
SOURCE_FILES += main_release.c SOURCE_FILES += main_release.c
CFLAGS := -DmainCREATE_RELEASE_DEMO=1 CFLAGS := -DmainCREATE_RELEASE_DEMO=1
else
ifeq ($(WATERSGEN_DEMO), 1)
SOURCE_FILES += main_watersgen$(SEED).c
CFLAGS := -DmainCREATE_WATERSGEN_DEMO=1
else
ifeq ($(TEST_DEMO), 1)
SOURCE_FILES += main_test.c
CFLAGS := -DmainCREATE_TEST_DEMO=1
else else
SOURCE_FILES += main_blinky.c SOURCE_FILES += main_blinky.c
@ -193,26 +177,13 @@ endif
endif endif
endif endif
endif endif
endif
endif
endif
ifeq ($(IGNORE_BYTES), 1) ifeq ($(INTERRUPT_ACTIVATION), 1)
CFLAGS += -D IGNORE_BYTES=1 CFLAGS += -D INTERRUPT_ACTIVATION=1
endif
ifeq ($(IGNORE_INTERRUPTS), 1)
CFLAGS += -D IGNORE_INTERRUPTS=1
endif endif
ifeq ($(PARTITION_INPUT), 1) ifeq ($(PARTITION_INPUT), 1)
CFLAGS += -D PARTITION_INPUT=1 CFLAGS += -D PARTITION_INPUT=1
endif endif
ifeq ($(IGNORE_INTERNAL_STATE), 1)
CFLAGS += -D IGNORE_INTERNAL_STATE=1
endif
ifeq ($(INSERT_WC), 1)
CFLAGS += -D INSERT_WC=1
endif
CFLAGS += $(SPECIAL_CFLAGS)
DEFINES := -DQEMU_SOC_MPS2 -DHEAP3 DEFINES := -DQEMU_SOC_MPS2 -DHEAP3

View File

@ -1,10 +1,6 @@
#ifndef ARB_LOAD_C #ifndef ARB_LOAD_C
#define ARB_LOAD_C 1 #define ARB_LOAD_C 1
#include <limits.h>
#include <stdint.h>
#include "util_macros.h"
// Time wasters ===== // Time wasters =====
volatile long _NONSENSE_VAR = 0; volatile long _NONSENSE_VAR = 0;
#define QEMU_SHIFT 5 #define QEMU_SHIFT 5
@ -25,9 +21,28 @@ volatile long _NONSENSE_VAR = 0;
#define PRINT_MSEC(X,Y) PRINT_NSEC(X*1000000,Y) #define PRINT_MSEC(X,Y) PRINT_NSEC(X*1000000,Y)
// #define PRINT_TIME(X,Y) WASTE_TIME(X) // #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 state ====== // Random numbers ===
// glibc
// https://en.wikipedia.org/wiki/Linear_congruential_generator
#define A 1103515245ull
#define M 0x80000000ull
#define C 12345ull
static unsigned long long rng_seed = 2345745ull; static unsigned long long rng_seed = 2345745ull;
#define RNG rng_seed=RNG_FROM(rng_seed); #define RNG rng_seed+=((A*((rng_seed+=C)-C)+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
#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)))
#endif #endif

View File

@ -0,0 +1,6 @@
#include <FreeRTOS.h>
#include <FreeRTOSConfig.h>
#include <task.h>
#include <list.h>
#include "../../Source/tasks.c"

View File

@ -1,8 +0,0 @@
#include <FreeRTOS.h>
#include <FreeRTOSConfig.h>
#include <task.h>
#include <list.h>
#include <queue.h>
#include "../../../Source/queue.c"
#include "../../../Source/tasks.c"

View File

@ -1,184 +0,0 @@
#![allow(non_camel_case_types,non_snake_case,non_upper_case_globals,deref_nullptr,unused)]
use serde::{Deserialize, Serialize};
/*========== Start of generated Code =============*/
pub type char_ptr = ::std::os::raw::c_uint;
pub type void_ptr = ::std::os::raw::c_uint;
pub type ListItem_t_ptr = ::std::os::raw::c_uint;
pub type QueueDefinition_ptr = ::std::os::raw::c_uint;
pub type StackType_t_ptr = ::std::os::raw::c_uint;
pub type i_ptr8 = ::std::os::raw::c_uint;
pub type tskTaskControlBlock_ptr = ::std::os::raw::c_uint;
pub type xLIST_ptr = ::std::os::raw::c_uint;
pub type xLIST_ITEM_ptr = ::std::os::raw::c_uint;
/* automatically generated by rust-bindgen 0.71.1 */
pub const configASSERT_DEFINED: u32 = 1;
pub const configQUEUE_REGISTRY_SIZE: u32 = 20;
pub const configUSE_PREEMPTION: u32 = 1;
pub const configUSE_TIME_SLICING: u32 = 0;
pub const configUSE_PORT_OPTIMISED_TASK_SELECTION: u32 = 0;
pub const configUSE_IDLE_HOOK: u32 = 1;
pub const configUSE_TICK_HOOK: u32 = 1;
pub const configUSE_DAEMON_TASK_STARTUP_HOOK: u32 = 0;
pub const configMAX_TASK_NAME_LEN: u32 = 10;
pub const configUSE_TRACE_FACILITY: u32 = 0;
pub const configUSE_STATS_FORMATTING_FUNCTIONS: u32 = 0;
pub const configUSE_16_BIT_TICKS: u32 = 0;
pub const configIDLE_SHOULD_YIELD: u32 = 1;
pub const configUSE_CO_ROUTINES: u32 = 0;
pub const configMAX_PRIORITIES: u32 = 15;
pub const configMAX_CO_ROUTINE_PRIORITIES: u32 = 2;
pub const configTIMER_QUEUE_LENGTH: u32 = 20;
pub const configTIMER_TASK_PRIORITY: u32 = 14;
pub const configUSE_COUNTING_SEMAPHORES: u32 = 1;
pub const configSUPPORT_DYNAMIC_ALLOCATION: u32 = 1;
pub const configSUPPORT_STATIC_ALLOCATION: u32 = 1;
pub const configNUM_TX_DESCRIPTORS: u32 = 15;
pub const configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN: u32 = 2;
pub const configUSE_QUEUE_SETS: u32 = 1;
pub const configUSE_MALLOC_FAILED_HOOK: u32 = 1;
pub const configUSE_MUTEXES: u32 = 1;
pub const configUSE_RECURSIVE_MUTEXES: u32 = 1;
pub const configUSE_TIMERS: u32 = 1;
pub const INCLUDE_vTaskPrioritySet: u32 = 1;
pub const INCLUDE_uxTaskPriorityGet: u32 = 1;
pub const INCLUDE_vTaskDelete: u32 = 1;
pub const INCLUDE_vTaskCleanUpResources: u32 = 0;
pub const INCLUDE_vTaskSuspend: u32 = 1;
pub const INCLUDE_vTaskDelayUntil: u32 = 1;
pub const INCLUDE_vTaskDelay: u32 = 1;
pub const INCLUDE_uxTaskGetStackHighWaterMark: u32 = 1;
pub const INCLUDE_uxTaskGetStackHighWaterMark2: u32 = 1;
pub const INCLUDE_xTaskGetSchedulerState: u32 = 1;
pub const INCLUDE_xTimerGetTimerDaemonTaskHandle: u32 = 1;
pub const INCLUDE_xTaskGetIdleTaskHandle: u32 = 1;
pub const INCLUDE_xTaskGetHandle: u32 = 1;
pub const INCLUDE_eTaskGetState: u32 = 1;
pub const INCLUDE_xSemaphoreGetMutexHolder: u32 = 1;
pub const INCLUDE_xTimerPendFunctionCall: u32 = 1;
pub const INCLUDE_xTaskAbortDelay: u32 = 1;
pub const projCOVERAGE_TEST: u32 = 0;
pub const configKERNEL_INTERRUPT_PRIORITY: u32 = 255;
pub const configMAX_SYSCALL_INTERRUPT_PRIORITY: u32 = 191;
pub const configMAC_INTERRUPT_PRIORITY: u32 = 5;
pub const configUSE_TASK_NOTIFICATIONS: u32 = 1;
pub const configTASK_NOTIFICATION_ARRAY_ENTRIES: u32 = 10;
/* automatically generated by rust-bindgen 0.71.1 */
pub type StackType_t = u32;
pub type UBaseType_t = ::std::os::raw::c_uint;
pub type TickType_t = u32;
#[repr(C)]
#[derive(Debug, Copy, Clone, Default, Serialize, Deserialize)]
pub struct xLIST_ITEM {
pub xItemValue: TickType_t,
pub pxNext: xLIST_ITEM_ptr,
pub pxPrevious: xLIST_ITEM_ptr,
pub pvOwner: void_ptr,
pub pvContainer: xLIST_ptr,
}
pub type ListItem_t = xLIST_ITEM;
#[repr(C)]
#[derive(Debug, Copy, Clone, Default, Serialize, Deserialize)]
pub struct xMINI_LIST_ITEM {
pub xItemValue: TickType_t,
pub pxNext: xLIST_ITEM_ptr,
pub pxPrevious: xLIST_ITEM_ptr,
}
pub type MiniListItem_t = xMINI_LIST_ITEM;
#[repr(C)]
#[derive(Debug, Copy, Clone, Default, Serialize, Deserialize)]
pub struct xLIST {
pub uxNumberOfItems: UBaseType_t,
pub pxIndex: ListItem_t_ptr,
pub xListEnd: MiniListItem_t,
}
pub type List_t = xLIST;
pub type TaskHandle_t = tskTaskControlBlock_ptr;
pub const eTaskState_eRunning: eTaskState = 0;
pub const eTaskState_eReady: eTaskState = 1;
pub const eTaskState_eBlocked: eTaskState = 2;
pub const eTaskState_eSuspended: eTaskState = 3;
pub const eTaskState_eDeleted: eTaskState = 4;
pub const eTaskState_eInvalid: eTaskState = 5;
pub type eTaskState = ::std::os::raw::c_uint;
#[repr(C)]
#[derive(Debug, Copy, Clone, Default, Serialize, Deserialize)]
pub struct xTASK_STATUS {
pub xHandle: TaskHandle_t,
pub pcTaskName: char_ptr,
pub xTaskNumber: UBaseType_t,
pub eCurrentState: eTaskState,
pub uxCurrentPriority: UBaseType_t,
pub uxBasePriority: UBaseType_t,
pub ulRunTimeCounter: u32,
pub pxStackBase: StackType_t_ptr,
pub usStackHighWaterMark: u16,
}
pub type TaskStatus_t = xTASK_STATUS;
pub type QueueHandle_t = QueueDefinition_ptr;
#[repr(C)]
#[derive(Debug, Copy, Clone, Default, Serialize, Deserialize)]
pub struct QueuePointers {
pub pcTail: i_ptr8,
pub pcReadFrom: i_ptr8,
}
pub type QueuePointers_t = QueuePointers;
#[repr(C)]
#[derive(Debug, Copy, Clone, Default, Serialize, Deserialize)]
pub struct SemaphoreData {
pub xMutexHolder: TaskHandle_t,
pub uxRecursiveCallCount: UBaseType_t,
}
pub type SemaphoreData_t = SemaphoreData;
#[repr(C)]
#[derive(Copy, Clone)]
pub struct QueueDefinition {
pub pcHead: i_ptr8,
pub pcWriteTo: i_ptr8,
pub u: QueueDefinition__bindgen_ty_1,
pub xTasksWaitingToSend: List_t,
pub xTasksWaitingToReceive: List_t,
pub uxMessagesWaiting: UBaseType_t,
pub uxLength: UBaseType_t,
pub uxItemSize: UBaseType_t,
pub cRxLock: i8,
pub cTxLock: i8,
pub ucStaticallyAllocated: u8,
pub pxQueueSetContainer: QueueDefinition_ptr,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union QueueDefinition__bindgen_ty_1 {
pub xQueue: QueuePointers_t,
pub xSemaphore: SemaphoreData_t,
}
pub type xQUEUE = QueueDefinition;
pub type Queue_t = xQUEUE;
#[repr(C)]
#[derive(Debug, Copy, Clone, Default, Serialize, Deserialize)]
pub struct QUEUE_REGISTRY_ITEM {
pub pcQueueName: char_ptr,
pub xHandle: QueueHandle_t,
}
pub type xQueueRegistryItem = QUEUE_REGISTRY_ITEM;
pub type QueueRegistryItem_t = xQueueRegistryItem;
#[repr(C)]
#[derive(Debug, Copy, Clone, Default, Serialize, Deserialize)]
pub struct tskTaskControlBlock {
pub pxTopOfStack: StackType_t_ptr,
pub xStateListItem: ListItem_t,
pub xEventListItem: ListItem_t,
pub uxPriority: UBaseType_t,
pub pxStack: StackType_t_ptr,
pub pcTaskName: [::std::os::raw::c_char; 10usize],
pub uxBasePriority: UBaseType_t,
pub uxMutexesHeld: UBaseType_t,
pub ulNotifiedValue: [u32; 10usize],
pub ucNotifyState: [u8; 10usize],
pub ucStaticallyAllocated: u8,
pub ucDelayAborted: u8,
}
pub type tskTCB = tskTaskControlBlock;
pub type TCB_t = tskTCB;

View File

@ -1,4 +0,0 @@
#![allow(non_camel_case_types,non_snake_case,non_upper_case_globals,deref_nullptr,unused)]
use serde::{Deserialize, Serialize};
/*========== Start of generated Code =============*/

View File

@ -1,20 +0,0 @@
#!/bin/sh
set -e
rm -f bindings.i bindings.rs _bindings.rs _header.rs _config.rs
arm-none-eabi-gcc -E bindgen.h \
-I ../../../Source/include -I ../../../Source/portable/GCC/ARM_CM3 -I .. > bindings.i
bindgen bindings.i --ignore-functions --no-layout-tests \
--allowlist-type "TaskStatus_t|List_t|QueueRegistryItem_t|QueueHandle_t|Queue_t|TCB_t" \
-- --target=armv7a-none-eabi > _bindings.rs
bindgen ../FreeRTOSConfig.h --ignore-functions --no-layout-tests > _config.rs
while IFS= read -r line; do
echo pub type $line = "::std::os::raw::c_uint;" | sed -f transform.sed
done <<< "$(grep -oE "\*mut [A-Z:_a-z0-9]*|\*const [A-Z:a-z_]*char" _bindings.rs | sort | uniq)" > _header.rs
cat header.rs _header.rs _config.rs _bindings.rs | sed -f transform.sed > bindings.rs
rm -f bindings.i _bindings.rs _header.rs _config.rs

View File

@ -1,130 +0,0 @@
#include <stdio.h>
#include "arbitrary_loads.c"
#include <stdlib.h>
/*
Wait patterns per task in us:
0: LONG_CALC, LONG_CALC, LONG_CALC
1: LONG_CALC, LONG_CALC, LONG_CALC
2: LONG_CALC, LONG_CALC, LONG_CALC
3: LONG_CALC
4: LONG_CALC
5: LONG_CALC, LONG_CALC
6: LONG_CALC
7: LONG_CALC
8: LONG_CALC, SHORT_CALC, LONG_CALC
9: LONG_CALC, SHORT_CALC, LONG_CALC
10: SHORT_CALC, SHORT_CALC
11: LONG_CALC
*/
#define REP_VA0(...)
#define REP_VA1(...) __VA_ARGS__
#define REP_VA2(...) REP_VA1(__VA_ARGS__),__VA_ARGS__
#define REP_VA3(...) REP_VA2(__VA_ARGS__),__VA_ARGS__
#define REP_VA4(...) REP_VA3(__VA_ARGS__),__VA_ARGS__
#define REP_VA5(...) REP_VA4(__VA_ARGS__),__VA_ARGS__
#define REP_VA6(...) REP_VA5(__VA_ARGS__),__VA_ARGS__
#define REP_VA7(...) REP_VA6(__VA_ARGS__),__VA_ARGS__
#define REP_VA8(...) REP_VA7(__VA_ARGS__),__VA_ARGS__
#define REP_VA9(...) REP_VA8(__VA_ARGS__),__VA_ARGS__
#define REP_VA10(...) REP_VA9(__VA_ARGS__),__VA_ARGS__
#define REP_VA(HUNDREDS,TENS,ONES,...) \
REP_VA##HUNDREDS(REP_VA10(REP_VA10(__VA_ARGS__))) \
REP_VA##TENS(REP_VA10(__VA_ARGS__)) \
REP_VA##ONES(__VA_ARGS__)
int rng_iter(int seed, int iter) {
int state = seed;
for (int i = 0; i < iter; i++) {
state = RNG_FROM(state);
}
return state;
}
#define SHORT_CALC 35
#define LONG_CALC 150
#define ELEMS(X) sizeof(X)/sizeof(X[0])
unsigned char max_input_for_seed_after(int seed, int iter, unsigned char goal) {
int state = rng_iter(seed, iter+1);
unsigned char need = (state & 0xFF) ^ (goal-1);
return need;
}
#define NUM_TASKS 15
#define MAX_INPUT_BYTES 4096
#define INPUT_PER_JOB 273 // MAX_INPUT_BYTES / NUM_TASKS
unsigned char FUZZ_INPUT[MAX_INPUT_BYTES] = {0};
size_t INPUT_POINTER = 0;
size_t INPUT_CURSORS[NUM_TASKS] = {0};
static unsigned char fuzz_char_next(int tasknum) {
if (INPUT_CURSORS[tasknum] == 0) {
INPUT_CURSORS[tasknum] = tasknum * (MAX_INPUT_BYTES / NUM_TASKS);
}
if (INPUT_CURSORS[tasknum] >= (tasknum+1) * (MAX_INPUT_BYTES / NUM_TASKS)) {
exit(1);
}
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};
static unsigned char next(int tasknum) {
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 CODE_PER_JOB(N) \
INPUT_POINTER = N * INPUT_PER_JOB; \
for (int i = 0; i < ELEMS(task_##N) && i < INPUT_PER_JOB; i++) { \
int per = ELEMS(task_##N)/300; \
unsigned char input = max_input_for_seed_after(N, i, task_##N[i]); \
FUZZ_INPUT[INPUT_POINTER++] = input; \
printf("//T%d_%d[%d]: %d -> %d\n", N, i/per, i%per, input, task_##N[i]); \
}
int main() {
int task_0[] = {REP_VA(3,0,0, LONG_CALC,LONG_CALC,LONG_CALC)};
int task_1[] = {REP_VA(3,0,0, LONG_CALC,LONG_CALC,LONG_CALC)};
int task_2[] = {REP_VA(3,0,0, LONG_CALC,LONG_CALC,LONG_CALC)};
int task_3[] = {REP_VA(3,0,0, LONG_CALC)};
int task_4[] = {REP_VA(3,0,0, LONG_CALC)};
int task_5[] = {REP_VA(3,0,0, LONG_CALC,LONG_CALC)};
int task_6[] = {REP_VA(3,0,0, LONG_CALC)};
int task_7[] = {REP_VA(3,0,0, LONG_CALC)};
int task_8[] = {REP_VA(3,0,0, LONG_CALC,SHORT_CALC,LONG_CALC)};
int task_9[] = {REP_VA(3,0,0, LONG_CALC,SHORT_CALC,LONG_CALC)};
int task_10[] = {REP_VA(3,0,0, SHORT_CALC,SHORT_CALC)};
int task_11[] = {REP_VA(3,0,0, LONG_CALC)};
CODE_PER_JOB(0);
CODE_PER_JOB(1);
CODE_PER_JOB(2);
CODE_PER_JOB(3);
CODE_PER_JOB(4);
CODE_PER_JOB(5);
CODE_PER_JOB(6);
CODE_PER_JOB(7);
CODE_PER_JOB(8);
CODE_PER_JOB(9);
CODE_PER_JOB(10);
CODE_PER_JOB(11);
printf("unsigned char WC_ARRAY[%d] = {\n", MAX_INPUT_BYTES);
for (int i = 0; i<MAX_INPUT_BYTES; i++) {
printf("%d,", FUZZ_INPUT[i]);
}
printf("};\n");
// for (int i = 0; i < INPUT_PER_JOB; i++) {
// printf("next: %d\n", next(0));
// }
}

View File

@ -1,143 +0,0 @@
#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 2
#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 INSERT_WC
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 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] = {};
#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

@ -123,18 +123,6 @@ int main()
{ {
main_osek(); main_osek();
} }
#elif ( mainPOLYCOPTER_DEMO == 1 )
{
main_osek();
}
#elif ( mainCREATE_WATERSGEN_DEMO == 1 )
{
main_waters();
}
#elif ( mainCREATE_TEST_DEMO == 1 )
{
main_test();
}
#else #else
{ {

View File

@ -6,32 +6,48 @@
#include <CMSDK_CM3.h> #include <CMSDK_CM3.h>
#define GLOBAL_WCET_MULT \ #define GLOBAL_WCET_MULT \
1 // Multiplier to increase all waiting periods to make the schedule more 1 // Multiplier to increase all waiting periods to make the schedule more
// tight and force preemptions // tight an force preemptions
#define NUM_TASKS 15 #include "arbitrary_loads.c"
#include "fuzzhelper.c"
#ifdef INSERT_WC #define NUM_TASKS 15
#include "wcinput.h" #define MAX_INPUT_BYTES 4096
#endif volatile unsigned char FUZZ_INPUT[MAX_INPUT_BYTES] = {};
volatile int INPUT_POINTERS[NUM_TASKS] = {};
volatile uint32_t FUZZ_LENGTH = MAX_INPUT_BYTES;// ignored
__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) {
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();
}
FUZZ_INPUT[INPUT_POINTERS[tasknum]++];
}
volatile int RNG_STATES[NUM_TASKS] = {};
static unsigned char next(int tasknum) {
RNG_STATES[tasknum] = RNG_FROM(RNG_STATES[tasknum]);
unsigned char t = fuzz_char_next(tasknum);
return RNG_STATES[tasknum] ^ (((int)t << 8) + (int)t);
}
// #define SHORT_CALC 50 // #define SHORT_CALC 50
// #define LONG_CALC 200 // #define LONG_CALC 200
#ifdef IGNORE_BYTES #define SHORT_CALC (25+next(task_id)%25)
#define SHORT_CALC (50) #define LONG_CALC (150+next(task_id)%100)
#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)+1)
#else
#define STATE_PLUS_DATA(X) {}
#define MAKE_OUTPUT (1)
#endif
#define HYPER_PERIOD 9 #define HYPER_PERIOD 9
#define SIMULATE_PERIODS 4 #define SIMULATE_PERIODS 4
@ -73,56 +89,11 @@ static TaskHandle_t xTask_CopterControlTask = NULL;
static void prv_MavlinkRecvHandler(void *pvParameters); static void prv_MavlinkRecvHandler(void *pvParameters);
static TaskHandle_t xTask_MavlinkRecvHandler = NULL; 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 SemaphoreHandle_t xSemaphore_SPIBus;
static TickType_t xFrequency_CopterControlWatchdogAlarm; static TickType_t xFrequency_CopterControlWatchdogAlarm;
void main_osek(void) { 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(); xSemaphore_SPIBus = xSemaphoreCreateBinary();
xSemaphoreGive(xSemaphore_SPIBus); xSemaphoreGive(xSemaphore_SPIBus);
@ -165,32 +136,26 @@ void main_osek(void) {
configMAX_PRIORITIES - 1, configMAX_PRIORITIES - 1,
&xTaskTimeSupervisor ); &xTaskTimeSupervisor );
#ifdef INSERT_WC
for (int i=0; i<MAX_INPUT_BYTES; i++) {
FUZZ_INPUT[i] = WC_ARRAY[i];
}
#endif
vTaskStartScheduler(); vTaskStartScheduler();
for( ; ; ) for( ; ; )
{ {
} }
} }
int round = 0; int round;
static void prv_SignalGatherInitiateTask(void *pvParameters) { static void prv_SignalGatherInitiateTask(void *pvParameters) {
const int task_id = 0; const int task_id = 0;
TickType_t xLastWakeTime = initial_release_time; TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 3 / portTICK_PERIOD_MS; const TickType_t xFrequency = 3 / portTICK_PERIOD_MS;
do { do {
RNG_RESET
// timing_start(0); // timing_start(0);
xSemaphoreTake(xSemaphore_SPIBus, portMAX_DELAY); xSemaphoreTake(xSemaphore_SPIBus, 1);
WASTE_USEC(LONG_CALC); WASTE_USEC(LONG_CALC);
if ((round % 2) == 0) { if ((round % 2) == 0) {
xTaskNotify(xTask_SignalGatherTimeoutTask, MAKE_OUTPUT, eSetValueWithOverwrite); xTaskNotify(xTask_SignalGatherTimeoutTask, 0, eNoAction);
} else { } else {
xTaskNotify(xTask_SignalGatherFinishedTask, MAKE_OUTPUT, eSetValueWithOverwrite); xTaskNotify(xTask_SignalGatherFinishedTask, 0, eNoAction);
} }
round++; round++;
WASTE_USEC(LONG_CALC); WASTE_USEC(LONG_CALC);
@ -205,13 +170,11 @@ static void prv_SignalGatherFinishedTask(void *pvParameters) {
const int task_id = 1; const int task_id = 1;
trigger_job_done(); trigger_job_done();
do { 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); WASTE_USEC(LONG_CALC);
xTaskNotify(xTask_SignalProcessingAttitudeTask, MAKE_OUTPUT, eSetValueWithOverwrite); xTaskNotify(xTask_SignalProcessingAttitudeTask, 0, eNoAction);
WASTE_USEC(LONG_CALC); WASTE_USEC(LONG_CALC);
xTaskNotify(xTask_SignalProcessingActuateTask, MAKE_OUTPUT, eSetValueWithOverwrite); xTaskNotify(xTask_SignalProcessingActuateTask, 0, eNoAction);
WASTE_USEC(LONG_CALC); WASTE_USEC(LONG_CALC);
trigger_job_done(); trigger_job_done();
} while (1); } while (1);
@ -221,15 +184,13 @@ static void prv_SignalGatherTimeoutTask(void *pvParameters) {
const int task_id = 2; const int task_id = 2;
trigger_job_done(); trigger_job_done();
do { 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); WASTE_USEC(LONG_CALC);
xSemaphoreTake(xSemaphore_SPIBus, portMAX_DELAY); xSemaphoreTake(xSemaphore_SPIBus, 1);
WASTE_USEC(LONG_CALC); WASTE_USEC(LONG_CALC);
xSemaphoreGive(xSemaphore_SPIBus); xSemaphoreGive(xSemaphore_SPIBus);
WASTE_USEC(LONG_CALC); WASTE_USEC(LONG_CALC);
xTaskNotify(xTask_SignalGatherFinishedTask, MAKE_OUTPUT, eSetValueWithOverwrite); xTaskNotify(xTask_SignalGatherFinishedTask, 0, eNoAction);
trigger_job_done(); trigger_job_done();
} while (1); } while (1);
} }
@ -240,9 +201,7 @@ static void prv_SignalProcessingActuateTask(void *pvParameters) {
const int task_id = 3; const int task_id = 3;
trigger_job_done(); trigger_job_done();
do { 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); WASTE_USEC(LONG_CALC);
trigger_job_done(); trigger_job_done();
} while (1); } while (1);
@ -252,10 +211,9 @@ static void prv_SignalProcessingAttitudeTask(void *pvParameters) {
const int task_id = 4; const int task_id = 4;
trigger_job_done(); trigger_job_done();
do { 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); WASTE_USEC(LONG_CALC);
// timing_end(0);
trigger_job_done(); trigger_job_done();
} while (1); } while (1);
} }
@ -265,12 +223,11 @@ static void prv_FlightControlTask(void *pvParameters) {
TickType_t xLastWakeTime = initial_release_time; TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 9 / portTICK_PERIOD_MS; const TickType_t xFrequency = 9 / portTICK_PERIOD_MS;
do { do {
RNG_RESET
// timing_start(1 | TIMING_POINT_IS_HIGHEST_PRIO); // timing_start(1 | TIMING_POINT_IS_HIGHEST_PRIO);
WASTE_USEC(LONG_CALC); WASTE_USEC(LONG_CALC);
xTaskNotify(xTask_FlightControlAttitudeTask, 0, eSetValueWithOverwrite); xTaskNotify(xTask_FlightControlAttitudeTask, 0, eNoAction);
xTaskNotify(xTask_FlightControlActuateTask, 0, eSetValueWithOverwrite); xTaskNotify(xTask_FlightControlActuateTask, 0, eNoAction);
xTaskNotify(xTask_MavlinkSendTask, 0, eSetValueWithOverwrite); xTaskNotify(xTask_MavlinkSendTask, 0, eNoAction);
WASTE_USEC(LONG_CALC); WASTE_USEC(LONG_CALC);
trigger_job_done(); trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency ); xTaskDelayUntil( &xLastWakeTime, xFrequency );
@ -281,9 +238,7 @@ static void prv_FlightControlAttitudeTask(void *pvParameters) {
const int task_id = 6; const int task_id = 6;
trigger_job_done(); trigger_job_done();
do { 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); WASTE_USEC(LONG_CALC);
trigger_job_done(); trigger_job_done();
} while (1); } while (1);
@ -293,9 +248,7 @@ static void prv_FlightControlActuateTask(void *pvParameters) {
const int task_id = 7; const int task_id = 7;
trigger_job_done(); trigger_job_done();
do { 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); WASTE_USEC(LONG_CALC);
trigger_job_done(); trigger_job_done();
} while (1); } while (1);
@ -305,11 +258,9 @@ static void prv_MavlinkSendTask(void *pvParameters) {
const int task_id = 8; const int task_id = 8;
trigger_job_done(); trigger_job_done();
do { 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); WASTE_USEC(LONG_CALC);
xSemaphoreTake(xSemaphore_SPIBus, portMAX_DELAY); xSemaphoreTake(xSemaphore_SPIBus, 1);
WASTE_USEC(SHORT_CALC); WASTE_USEC(SHORT_CALC);
// NVIC_SetPendingIRQ(1); // NVIC_SetPendingIRQ(1);
xSemaphoreGive(xSemaphore_SPIBus); xSemaphoreGive(xSemaphore_SPIBus);
@ -321,18 +272,9 @@ static void prv_MavlinkSendTask(void *pvParameters) {
static void prv_CopterControlTask(void *pvParameters) { static void prv_CopterControlTask(void *pvParameters) {
const int task_id = 9; const int task_id = 9;
TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 5 / portTICK_PERIOD_MS;
trigger_job_done(); trigger_job_done();
do { do {
RNG_RESET 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); WASTE_USEC(LONG_CALC);
vTaskSuspendAll(); vTaskSuspendAll();
WASTE_USEC(SHORT_CALC); WASTE_USEC(SHORT_CALC);
@ -345,22 +287,18 @@ static void prv_CopterControlTask(void *pvParameters) {
} }
void ISR_0_Handler(void) { void ISR_0_Handler(void) {
if (xTask_CopterControlTask != NULL) {
const int task_id = 10; const int task_id = 10;
RNG_RESET
// timing_start(2 | TIMING_POINT_START_INTERRUPT_FROM_IDLE); // timing_start(2 | TIMING_POINT_START_INTERRUPT_FROM_IDLE);
WASTE_USEC(SHORT_CALC); WASTE_USEC(SHORT_CALC);
xTaskNotifyFromISR(xTask_CopterControlTask, 1, eSetValueWithOverwrite, NULL); xTaskNotifyFromISR(xTask_CopterControlTask, 0, eNoAction, NULL);
WASTE_USEC(SHORT_CALC); WASTE_USEC(SHORT_CALC);
} }
}
static void prv_CopterControlWatchdogTask(void *pvParameters) { static void prv_CopterControlWatchdogTask(void *pvParameters) {
const int task_id = 11; const int task_id = 11;
TickType_t xLastWakeTime = initial_release_time; TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; const TickType_t xFrequency = 10 / portTICK_PERIOD_MS;
do { do {
RNG_RESET
WASTE_USEC(LONG_CALC); WASTE_USEC(LONG_CALC);
trigger_job_done(); trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency ); xTaskDelayUntil( &xLastWakeTime, xFrequency );

View File

@ -57,12 +57,7 @@ SemaphoreHandle_t l_sem;
#define DO_TIME(X, Y) WASTE_USEC((X)) #define DO_TIME(X, Y) WASTE_USEC((X))
// #define DO_TIME(X, Y) PRINT_USEC((X), Y) // #define DO_TIME(X, Y) PRINT_USEC((X), Y)
#define WCET_CLAMP(X, LB, UB, LABEL) DO_TIME((CLAMP(X,LB,UB)),LABEL) #define WCET_CLAMP(X, LB, UB, LABEL) DO_TIME((CLAMP(X,LB,UB)),LABEL)
// #define WCET_CLAMP(X, LB, UB, LABEL) DO_TIME(UB,LABEL)
#ifndef FUZZ_BYTES
// Produce the worst case, ignore input
#undef WCET_CLAMP
#define WCET_CLAMP(X, LB, UB, LABEL) DO_TIME(UB,LABEL)
#endif
__attribute__((noinline)) static void trigger_Qemu_break( void ) __attribute__((noinline)) static void trigger_Qemu_break( void )
{ {
@ -102,7 +97,7 @@ void h_task(void *params) {
TickType_t xLastWakeTime = initial_release_time; TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 1 / portTICK_PERIOD_MS; const TickType_t xFrequency = 1 / portTICK_PERIOD_MS;
while (1) { while (1) {
#ifdef FUZZ_INT_ACTIVATION #ifdef INTERRUPT_ACTIVATION
ulTaskNotifyTake(pdTRUE,portMAX_DELAY); ulTaskNotifyTake(pdTRUE,portMAX_DELAY);
#else #else
xTaskDelayUntil( &xLastWakeTime, xFrequency ); xTaskDelayUntil( &xLastWakeTime, xFrequency );

View File

@ -355,7 +355,7 @@ static void prvC3T1( void * pvParameters ) {
xTaskNotify(xC3T2, DEBUG_VAL(x & 0x1, 0), eSetValueWithOverwrite); xTaskNotify(xC3T2, DEBUG_VAL(x & 0x1, 0), eSetValueWithOverwrite);
// 3 different activation strategies ------------- // 3 different activation strategies -------------
// activate sporadically from interrupts // activate sporadically from interrupts
#ifdef FUZZ_INT_ACTIVATION #ifdef INTERRUPT_ACTIVATION
ulTaskNotifyTake(pdTRUE,portMAX_DELAY); ulTaskNotifyTake(pdTRUE,portMAX_DELAY);
#else #else
// activate with worst possible frequency (700us, but tick resolution is too low) // activate with worst possible frequency (700us, but tick resolution is too low)

View File

@ -1,576 +0,0 @@
#include <FreeRTOS.h>
#include <queue.h>
#include <semphr.h>
#include <stdio.h>
#include <task.h>
#include <CMSDK_CM3.h>
#define GLOBAL_WCET_MULT \
1 // Multiplier to increase all waiting periods to make the schedule more
// tight and force preemptions
#define NUM_TASKS 15
#define MACRO_ONLY 1
#include "fuzzhelper.c"
#include "polynomic_functions.h"
// #ifdef INSERT_WC
// #include "wcinput.h"
// #endif
#ifdef INSERT_WC
#define WC_SWITCH(X,D) ((X)*0+(D)*1)
#else
#ifdef IGNORE_BYTES
#define WC_SWITCH(X,D) ((X)*0+(D)*1)
#else
#define WC_SWITCH(X,D) ((X)*1+(D)*0)
#endif
#endif
// #define SHORT_CALC 50
// #define LONG_CALC 200
#ifdef IGNORE_BYTES
#define SHORT_CALC (50)
#define LONG_CALC (175)
#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)+1)
#else
#define STATE_PLUS_DATA(X) {}
#define MAKE_OUTPUT (1)
#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<MAX_INPUT_BYTES; i++) {
// FUZZ_INPUT[i] = WC_ARRAY[i];
// }
// #endif
vTaskStartScheduler();
for( ; ; )
{
}
}
int round = 0;
static void prv_SignalGatherInitiateTask(void *pvParameters) {
const int task_id = 0;
TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 3 / portTICK_PERIOD_MS;
uint16_t inp = 0;
volatile int x=0;
do {
RNG_RESET
// timing_start(0);
xSemaphoreTake(xSemaphore_SPIBus, portMAX_DELAY);
inp = INPUT_SHORT_NEXT;
x = STRETCH_i32(inp);
x = FUNCTION_1(x);
x = TRANSLATE_1(x, 50, 175);
x = WC_SWITCH(x, 175);
WASTE_USEC(x);
if ((round % 2) == 0) {
xTaskNotify(xTask_SignalGatherTimeoutTask, MAKE_OUTPUT, eSetValueWithOverwrite);
} else {
xTaskNotify(xTask_SignalGatherFinishedTask, MAKE_OUTPUT, eSetValueWithOverwrite);
}
round++;
inp = INPUT_SHORT_NEXT;
x = STRETCH_i32(inp);
x = FUNCTION_2(x);
x = TRANSLATE_2(x, 50, 175);
x = WC_SWITCH(x, 175);
WASTE_USEC(x);
xSemaphoreGive(xSemaphore_SPIBus);
inp = INPUT_SHORT_NEXT;
x = STRETCH_i32(inp);
x = FUNCTION_3(x);
x = TRANSLATE_3(x, 50, 175);
x = WC_SWITCH(x, 175);
WASTE_USEC(x);
trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );
} while (1);
}
static void prv_SignalGatherFinishedTask(void *pvParameters) {
const int task_id = 1;
uint16_t inp = 0;
volatile int x=0;
trigger_job_done();
do {
RNG_RESET
unsigned long int y = 0;
xTaskNotifyWait(0,ULONG_MAX,&y,portMAX_DELAY);
STATE_PLUS_DATA(y) // introduce a data dependency
inp = INPUT_SHORT_NEXT * CLAMP(y, 1, 3);
x = STRETCH_i32(inp);
x = FUNCTION_1(x);
x = TRANSLATE_1(x, 50, 175);
x = WC_SWITCH(x, 175);
WASTE_USEC(x);
xTaskNotify(xTask_SignalProcessingAttitudeTask, MAKE_OUTPUT, eSetValueWithOverwrite);
inp = INPUT_SHORT_NEXT * CLAMP(y, 1, 3);
x = STRETCH_i32(inp);
x = FUNCTION_4(x);
x = TRANSLATE_4(x, 50, 175);
x = WC_SWITCH(x, 175);
WASTE_USEC(x);
xTaskNotify(xTask_SignalProcessingActuateTask, MAKE_OUTPUT, eSetValueWithOverwrite);
inp = INPUT_SHORT_NEXT * CLAMP(y, 1, 3);
x = STRETCH_i32(inp);
x = FUNCTION_5(x);
x = TRANSLATE_5(x, 50, 175);
x = WC_SWITCH(x, 175);
WASTE_USEC(x);
trigger_job_done();
} while (1);
}
static void prv_SignalGatherTimeoutTask(void *pvParameters) {
const int task_id = 2;
uint16_t inp = 0;
volatile int x=0;
trigger_job_done();
do {
RNG_RESET
unsigned long int y = 0;
xTaskNotifyWait(0,ULONG_MAX,&y,portMAX_DELAY);
STATE_PLUS_DATA(y) // introduce a data dependency
inp = INPUT_SHORT_NEXT * CLAMP(y, 1, 3);
x = STRETCH_i32(inp);
x = FUNCTION_6(x);
x = TRANSLATE_6(x, 50, 175);
x = WC_SWITCH(x, 175);
WASTE_USEC(x);
xSemaphoreTake(xSemaphore_SPIBus, portMAX_DELAY);
inp = INPUT_SHORT_NEXT * CLAMP(y, 1, 3);
x = STRETCH_i32(inp);
x = FUNCTION_7(x);
x = TRANSLATE_7(x, 50, 175);
x = WC_SWITCH(x, 175);
WASTE_USEC(x);
xSemaphoreGive(xSemaphore_SPIBus);
inp = INPUT_SHORT_NEXT * CLAMP(y, 1, 3);
x = STRETCH_i32(inp);
x = FUNCTION_8(x);
x = TRANSLATE_8(x, 50, 175);
x = WC_SWITCH(x, 175);
WASTE_USEC(x);
xTaskNotify(xTask_SignalGatherFinishedTask, MAKE_OUTPUT, eSetValueWithOverwrite);
trigger_job_done();
} while (1);
}
volatile int calculate;
static void prv_SignalProcessingActuateTask(void *pvParameters) {
const int task_id = 3;
uint16_t inp = 0;
volatile int x=0;
trigger_job_done();
do {
RNG_RESET
unsigned long int y = 0;
xTaskNotifyWait(0,ULONG_MAX,&y,portMAX_DELAY);
STATE_PLUS_DATA(y) // introduce a data dependency
inp = INPUT_SHORT_NEXT * CLAMP(y, 1, 3);
x = STRETCH_i32(inp);
x = FUNCTION_9(x);
x = TRANSLATE_9(x, 50, 175);
x = WC_SWITCH(x, 175);
WASTE_USEC(x);
trigger_job_done();
} while (1);
}
static void prv_SignalProcessingAttitudeTask(void *pvParameters) {
const int task_id = 4;
uint16_t inp = 0;
volatile int x=0;
trigger_job_done();
do {
RNG_RESET
unsigned long int y = 0;
xTaskNotifyWait(0,ULONG_MAX,&y,portMAX_DELAY);
STATE_PLUS_DATA(y) // introduce a data dependency
inp = INPUT_SHORT_NEXT * CLAMP(y, 1, 3);
x = STRETCH_i32(inp);
x = FUNCTION_10(x);
x = TRANSLATE_10(x, 50, 175);
x = WC_SWITCH(x, 175);
WASTE_USEC(x);
trigger_job_done();
} while (1);
}
static void prv_FlightControlTask(void *pvParameters) {
const int task_id = 5;
TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 9 / portTICK_PERIOD_MS;
uint16_t inp = 0;
volatile int x=0;
do {
RNG_RESET
// timing_start(1 | TIMING_POINT_IS_HIGHEST_PRIO);
inp = INPUT_SHORT_NEXT;
x = STRETCH_i32(inp);
x = FUNCTION_1(x);
x = TRANSLATE_1(x, 50, 175);
x = WC_SWITCH(x, 175);
WASTE_USEC(x);
xTaskNotify(xTask_FlightControlAttitudeTask, 0, eSetValueWithOverwrite);
xTaskNotify(xTask_FlightControlActuateTask, 0, eSetValueWithOverwrite);
xTaskNotify(xTask_MavlinkSendTask, 0, eSetValueWithOverwrite);
inp = INPUT_SHORT_NEXT;
x = STRETCH_i32(inp);
x = FUNCTION_2(x);
x = TRANSLATE_2(x, 50, 175);
x = WC_SWITCH(x, 175);
WASTE_USEC(x);
trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );
} while (1);
}
static void prv_FlightControlAttitudeTask(void *pvParameters) {
const int task_id = 6;
uint16_t inp = 0;
volatile int x=0;
trigger_job_done();
do {
RNG_RESET
unsigned long int y = 0;
xTaskNotifyWait(0,ULONG_MAX,&y,portMAX_DELAY);
STATE_PLUS_DATA(y) // introduce a data dependency
inp = INPUT_SHORT_NEXT * CLAMP(y, 1, 3);
x = STRETCH_i32(inp);
x = FUNCTION_3(x);
x = TRANSLATE_3(x, 50, 175);
x = WC_SWITCH(x, 175);
WASTE_USEC(x);
trigger_job_done();
} while (1);
}
static void prv_FlightControlActuateTask(void *pvParameters) {
const int task_id = 7;
uint16_t inp = 0;
volatile int x=0;
trigger_job_done();
do {
RNG_RESET
unsigned long int y = 0;
xTaskNotifyWait(0,ULONG_MAX,&y,portMAX_DELAY);
STATE_PLUS_DATA(y) // introduce a data dependency
inp = INPUT_SHORT_NEXT * CLAMP(y, 1, 3);
x = STRETCH_i32(inp);
x = FUNCTION_4(x);
x = TRANSLATE_4(x, 50, 175);
x = WC_SWITCH(x, 175);
WASTE_USEC(x);
trigger_job_done();
} while (1);
}
static void prv_MavlinkSendTask(void *pvParameters) {
const int task_id = 8;
uint16_t inp = 0;
volatile int x=0;
trigger_job_done();
do {
RNG_RESET
unsigned long int y = 0;
xTaskNotifyWait(0,ULONG_MAX,&y,portMAX_DELAY);
STATE_PLUS_DATA(y) // introduce a data dependency
inp = INPUT_SHORT_NEXT * CLAMP(y, 1, 3);
x = STRETCH_i32(inp);
x = FUNCTION_5(x);
x = TRANSLATE_5(x, 50, 175);
x = WC_SWITCH(x, 175);
WASTE_USEC(x);
xSemaphoreTake(xSemaphore_SPIBus, portMAX_DELAY);
inp = INPUT_SHORT_NEXT * CLAMP(y, 1, 3);
x = STRETCH_i32(inp);
x = FUNCTION_1(x);
x = TRANSLATE_1(x, 50, 175);
x = WC_SWITCH(x, 175);
WASTE_USEC(x);
// NVIC_SetPendingIRQ(1);
xSemaphoreGive(xSemaphore_SPIBus);
inp = INPUT_SHORT_NEXT * CLAMP(y, 1, 3);
x = STRETCH_i32(inp);
x = FUNCTION_6(x);
x = TRANSLATE_6(x, 50, 175);
x = WC_SWITCH(x, 175);
WASTE_USEC(x);
// timing_end(1);
trigger_job_done();
} while (1);
}
static void prv_CopterControlTask(void *pvParameters) {
const int task_id = 9;
TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 5 / portTICK_PERIOD_MS;
uint16_t inp = 0;
volatile int x=0;
trigger_job_done();
do {
RNG_RESET
#ifndef IGNORE_INTERRUPTS
unsigned long int y = 0;
xTaskNotifyWait(0,ULONG_MAX,&y,portMAX_DELAY);
#else
xTaskDelayUntil( &xLastWakeTime, xFrequency );
unsigned long int y = 0;
xTaskNotifyWait(0,ULONG_MAX,&y,0);
#endif
STATE_PLUS_DATA(y) // introduce a data dependency
inp = INPUT_SHORT_NEXT * CLAMP(y, 1, 3);
x = STRETCH_i32(inp);
x = FUNCTION_7(x);
x = TRANSLATE_7(x, 50, 175);
x = WC_SWITCH(x, 175);
WASTE_USEC(x);
vTaskSuspendAll();
inp = INPUT_SHORT_NEXT * CLAMP(y, 1, 3);
x = STRETCH_i32(inp);
x = FUNCTION_6(x);
x = TRANSLATE_6(x, 15, 50);
x = WC_SWITCH(x, 50);
WASTE_USEC(x);
xTaskResumeAll();
inp = INPUT_SHORT_NEXT * CLAMP(y, 1, 3);
x = STRETCH_i32(inp);
x = FUNCTION_8(x);
x = TRANSLATE_8(x, 50, 175);
x = WC_SWITCH(x, 175);
WASTE_USEC(x);
// timing_end(2);
trigger_job_done();
} while (1);
}
void ISR_0_Handler(void) {
uint16_t inp = 0;
volatile int x=0;
if (xTask_CopterControlTask != NULL) {
const int task_id = 10;
RNG_RESET
// timing_start(2 | TIMING_POINT_START_INTERRUPT_FROM_IDLE);
inp = INPUT_SHORT_NEXT;
x = STRETCH_i32(inp);
x = FUNCTION_9(x);
x = TRANSLATE_9(x, 15, 50);
x = WC_SWITCH(x, 50);
WASTE_USEC(x);
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xTaskNotifyFromISR(xTask_CopterControlTask, MAKE_OUTPUT, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
inp = INPUT_SHORT_NEXT;
x = STRETCH_i32(inp);
x = FUNCTION_10(x);
x = TRANSLATE_10(x, 15, 50);
x = WC_SWITCH(x, 50);
WASTE_USEC(x);
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
}
static void prv_CopterControlWatchdogTask(void *pvParameters) {
const int task_id = 11;
TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 10 / portTICK_PERIOD_MS;
uint16_t inp = 0;
volatile int x=0;
do {
RNG_RESET
inp = INPUT_SHORT_NEXT;
x = STRETCH_i32(inp);
x = FUNCTION_9(x);
x = TRANSLATE_9(x, 50, 175);
x = WC_SWITCH(x, 175);
WASTE_USEC(x);
trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );
} while (1);
}
// void PreIdleHook() {
// static int count = 0;
// kout << "---\n";
// timing_print();
// if (++count > 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);
// }

View File

@ -29,29 +29,103 @@
#include <queue.h> #include <queue.h>
#include <stdio.h> #include <stdio.h>
#include <semphr.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 // #define GLOBAL_WCET_MULT 20 // Multiplier to increase all waiting periods to make the schedule more tight an force preemptions
#include "fuzzhelper.c" #include "arbitrary_loads.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_USEC((X)) #define DO_TIME(X, Y) WASTE_USEC((X))
#ifdef INSERT_WC #ifdef DEBUG_WCET
#define DEBUG_VAL(X,D) ((D)*1+(X)*0) #define DEBUG_VAL(X,D) (D)
#define DEBUG_INST(X) {X} #define WCET_CLAMP(X, LB, UB, LABEL) WASTE_NSEC(CLAMP(X,LB,UB),LABEL)
#else #else
#define DEBUG_VAL(X,D) ((X)*1+(D)*0) #define DEBUG_VAL(X,D) (X)
#define DEBUG_INST(X) {} #define WCET_CLAMP(X, LB, UB, LABEL) DO_TIME(CLAMP(X,LB,UB),LABEL)
#define DEBUG_WCET(A)
#endif #endif
#define WCET_CLAMP(X, LB, UB, LABEL) {volatile int _xtime = CLAMP(X,LB,UB); volatile int _timetorun = DEBUG_VAL(_xtime, UB); WASTE_USEC(_timetorun);}
// #define DO_TIME(X,Y) WASTE_USEC(DEBUG_VAL((X),(Y)))
// 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 prvTask1( void * pvParameters );
static void prvTask2( void * pvParameters ); static void prvTask2( void * pvParameters );
static void prvTask3( void * pvParameters ); static void prvTask3( void * pvParameters );
static void prvTask4( void * pvParameters ); static void prvTask4( void * pvParameters );
static void prvTask5( 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_1_PRIO ( tskIDLE_PRIORITY + 1 )
#define mainTASK_2_PRIO ( tskIDLE_PRIORITY + 2 ) #define mainTASK_2_PRIO ( tskIDLE_PRIORITY + 2 )
#define mainTASK_3_PRIO ( tskIDLE_PRIORITY + 3 ) #define mainTASK_3_PRIO ( tskIDLE_PRIORITY + 3 )
@ -75,8 +149,8 @@ static TickType_t initial_release_time = 0;
static SemaphoreHandle_t xMutex; static SemaphoreHandle_t xMutex;
#define HYPER_PERIOD 40 // nothing interesting happens after 40ms #define HYPER_PERIOD 25
#define SIMULATE_PERIODS 1 #define SIMULATE_PERIODS 2
static TaskHandle_t xTaskTimeSupervisor = NULL; static TaskHandle_t xTaskTimeSupervisor = NULL;
static void timing_supervisor_task( void * pvParameters ) { static void timing_supervisor_task( void * pvParameters ) {
initial_release_time = xTaskGetTickCount(); // The highest priority task sets the initial time initial_release_time = xTaskGetTickCount(); // The highest priority task sets the initial time
@ -156,38 +230,32 @@ void main_release( void )
} }
static void prvTask1( void * pvParameters ) { static void prvTask1( void * pvParameters ) {
const int task_id = 0;
TickType_t xLastWakeTime = initial_release_time; TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 120 / portTICK_PERIOD_MS; const TickType_t xFrequency = 100 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
RNG_RESET
// Actions -------------------------------------- // Actions --------------------------------------
volatile uint16_t x = INPUT_SHORT_NEXT; volatile uint16_t x = fuzz_short_next();
WCET_CLAMP(x, 5000, 7200, TASK_1_MESSAGE) WCET_CLAMP(x, 8000, 10000, TASK_1_MESSAGE)
xTaskNotify(xTask2, DEBUG_VAL(x % 2, 0), eSetValueWithOverwrite); xTaskNotify(xTask2, DEBUG_VAL(x % 2, 1), eSetValueWithOverwrite);
// --------------------------------------------- // ---------------------------------------------
trigger_job_done(); trigger_job_done();
// trigger_Qemu_break(); trigger_Qemu_break();
xTaskDelayUntil( &xLastWakeTime, xFrequency );}// Wait for the next cycle. xTaskDelayUntil( &xLastWakeTime, xFrequency );}// Wait for the next cycle.
} }
static void prvTask2( void * pvParameters ) { static void prvTask2( void * pvParameters ) {
const int task_id = 1;
TickType_t xLastWakeTime = initial_release_time; TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 60 / portTICK_PERIOD_MS; const TickType_t xFrequency = 50 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
RNG_RESET
// Actions -------------------------------------- // Actions --------------------------------------
uint16_t x = INPUT_SHORT_NEXT; uint16_t x = fuzz_short_next();
DO_TIME(1000, 1000) DO_TIME(1000, TASK_2_MESSAGE)
xSemaphoreTake(xMutex, portMAX_DELAY); xSemaphoreTake(xMutex, portMAX_DELAY);
volatile int torun = 1000; volatile int torun = 2000;
if (DEBUG_VAL(CHANCE_1_IN_POWOF2(x, 5), 1)) { if (DEBUG_VAL(CHANCE_1_IN_POWOF2(x, 5), 1)) {
torun += 1000; torun += 2000;
} }
WCET_CLAMP(torun, 1000, 2000, "") int y = ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
unsigned long int y = 0;
xTaskNotifyWait(0,ULONG_MAX,&y,portMAX_DELAY);
xSemaphoreGive(xMutex); xSemaphoreGive(xMutex);
// --------------------------------------------- // ---------------------------------------------
trigger_job_done(); trigger_job_done();
@ -195,77 +263,64 @@ static void prvTask2( void * pvParameters ) {
} }
static void prvTask3( void * pvParameters ) { static void prvTask3( void * pvParameters ) {
const int task_id = 2;
TickType_t xLastWakeTime = initial_release_time; TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 30 / portTICK_PERIOD_MS; // 312500 isns minia const TickType_t xFrequency = 25 / portTICK_PERIOD_MS;
trigger_job_done(); // The first job instance just waits for an activation trigger_job_done(); // The first job instance just waits for an activation
for( ;; ){ for( ;; ){
#ifdef IGNORE_INTERRUPTS
xTaskDelayUntil( &xLastWakeTime, xFrequency ); // periodic
unsigned long int y = 0;
xTaskNotifyWait(0,ULONG_MAX,&y,0);
#else
unsigned long int y = 0;
xTaskNotifyWait(0,ULONG_MAX,&y,portMAX_DELAY); // sporadic
#endif
RNG_RESET
// Actions -------------------------------------- // Actions --------------------------------------
DO_TIME(100, 100) int y = ulTaskNotifyTake(pdTRUE, portMAX_DELAY); // sporadic
xSemaphoreTake(xMutex, portMAX_DELAY); // wost time: right after T2 locks the mutex xSemaphoreTake(xMutex, portMAX_DELAY);
volatile uint16_t x = INPUT_SHORT_NEXT; volatile uint16_t x = fuzz_short_next();
int torun = 0; int torun = 0;
if ((int)y!=0) { if (y) {
torun = CLAMP(x, 0, 5000); torun = CLAMP(x, 5000, 8000);
} else { } else {
torun = CLAMP(x, 1000, 4000); torun = CLAMP(x, 0, 12000);
} }
WCET_CLAMP(torun, 4000, 5000, "") DO_TIME(torun, TASK_3_MESSAGE)
xSemaphoreGive(xMutex); xSemaphoreGive(xMutex);
DO_TIME(100, 100)
// --------------------------------------------- // ---------------------------------------------
trigger_job_done(); trigger_job_done();
trigger_Qemu_break();
// xTaskDelayUntil( &xLastWakeTime, xFrequency );
} }
} }
static void prvTask4( void * pvParameters ) { static void prvTask4( void * pvParameters ) {
const int task_id = 3; initial_release_time = xTaskGetTickCount(); // The highest priority task sets the initial time
TickType_t xLastWakeTime = initial_release_time; TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; const TickType_t xFrequency = 10 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
RNG_RESET
// Actions -------------------------------------- // Actions --------------------------------------
volatile uint16_t x = INPUT_SHORT_NEXT; volatile uint16_t x = fuzz_short_next();
WCET_CLAMP(x, 100, 500, TASK_4_MESSAGE) WCET_CLAMP(x, 1000, 2000, TASK_4_MESSAGE)
// --------------------------------------------- // ---------------------------------------------
trigger_job_done(); trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );} xTaskDelayUntil( &xLastWakeTime, xFrequency );}
} }
static void prvTask5( void * pvParameters ) { static void prvTask5( void * pvParameters ) {
const int task_id = 4;
TickType_t xLastWakeTime = 0; TickType_t xLastWakeTime = 0;
const TickType_t xFrequency = 5 / portTICK_PERIOD_MS; // 156250 isns minia, worst time whenever the mutex is unlocked const TickType_t xFrequency = 5 / portTICK_PERIOD_MS;
trigger_job_done(); // The first job instance just waits for an activation trigger_job_done(); // The first job instance just waits for an activation
for( ;; ){ for( ;; ){
#ifdef IGNORE_INTERRUPTS
xTaskDelayUntil( &xLastWakeTime, xFrequency ); // periodic
// int y = ulTaskNotifyTake(pdTRUE, 0);
#else
unsigned long int y = 0;
xTaskNotifyWait(0,ULONG_MAX,&y,portMAX_DELAY); // sporadic
#endif
RNG_RESET
// Actions -------------------------------------- // Actions --------------------------------------
int y = ulTaskNotifyTake(pdTRUE, portMAX_DELAY); // sporadic
int succ = xSemaphoreTake(xMutex, 0); // try to take the mutex int succ = xSemaphoreTake(xMutex, 0); // try to take the mutex
if (succ == pdTRUE) { if (succ == pdTRUE) {
volatile uint16_t x = INPUT_SHORT_NEXT; // volatile uint16_t x = fuzz_short_next();
WCET_CLAMP(x, 0, 2000, "") uint16_t x = 2000;
int torun = 0;
torun = CLAMP(x, 0, 2000);
DO_TIME(torun, TASK_5_MESSAGE)
xSemaphoreGive(xMutex); xSemaphoreGive(xMutex);
} else { } else {
DO_TIME(50, 50) DO_TIME(50, TASK_5_MESSAGE)
} }
// xTaskDelayUntil( &xLastWakeTime, xFrequency ); // enforce a minimum inter-arrival time
// --------------------------------------------- // ---------------------------------------------
trigger_job_done(); trigger_job_done();
// xTaskDelayUntil( &xLastWakeTime, portMAX_DELAY ); // enforce a minimum inter-arrival time
} }
} }
@ -278,13 +333,9 @@ void vWatersIdleFunction() {
void ISR_0_Handler( void ) void ISR_0_Handler( void )
{ {
const int task_id = 5;
puts("Interrupt"); puts("Interrupt");
if (xTask3) { if (xTask3) {
volatile uint16_t x = INPUT_SHORT_NEXT; vTaskNotifyGiveFromISR(xTask3, NULL);
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xTaskNotifyFromISR(xTask3, DEBUG_VAL((x%10) == 0, 1), eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
} }
} }
@ -292,25 +343,8 @@ void ISR_1_Handler( void )
{ {
puts("Interrupt"); puts("Interrupt");
if (xTask5) { if (xTask5) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE; vTaskNotifyGiveFromISR(xTask5, NULL);
xTaskNotifyFromISR(xTask5, 1, eSetValueWithOverwrite, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
} }
} }
/*
Worst interrupt times
trigger T3 right after T2 aquired the mutex
trigger T5 right after T2 and T3 release the mutex
"isr_0_times":Right([
349695
]),
"isr_1_times":Right([
350632, 506882, 667601, 889476
])
*/
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/

View File

@ -28,34 +28,108 @@
#include <task.h> #include <task.h>
#include <queue.h> #include <queue.h>
#include <stdio.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 LOCAL_WCET_MULT 12 // Multiplier to increase all waiting periods to make the schedule more tight an force preemptions #define GLOBAL_WCET_MULT 20 // Multiplier to increase all waiting periods to make the schedule more tight an force preemptions
#include "arbitrary_loads.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))
#ifdef DEBUG_WCET
#define DEBUG_VAL(X,D) (D)
#define WCET_CLAMP(X, LB, UB, LABEL) WASTE_NSEC(CLAMP(X,LB,UB),LABEL)
#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)
#endif
// Begin Input Stuff
#define NUM_TASKS 10 #define NUM_TASKS 10
#include "fuzzhelper.c" #define MAX_INPUT_BYTES 4096
volatile unsigned char FUZZ_INPUT[MAX_INPUT_BYTES] = {};
#ifdef INSERT_WC volatile int INPUT_POINTERS[NUM_TASKS] = {};
#define DEBUG_VAL(X,D) ((D)+1*(X)*0) 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) {
#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();
}
FUZZ_INPUT[INPUT_POINTERS[tasknum]++];
#else #else
#define DEBUG_VAL(X,D) ((X)+1*(D)*0) // 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 #endif
#define WCET_CLAMP(X, LB, UB, LABEL) {volatile int _xtime = CLAMP(X,LB,UB); volatile int _timetorun = DEBUG_VAL(_xtime, UB); WASTE_NSEC(_timetorun);} }
static uint16_t fuzz_short_next(int tasknum) {
#ifdef WATERS_UNSYNCHRONIZED unsigned char field[2];
#define NOTIFY_WAIT_TIME 0 field[0]=fuzz_char_next(tasknum);
#else field[1]=fuzz_char_next(tasknum);
#define NOTIFY_WAIT_TIME portMAX_DELAY uint16_t* sf = (uint16_t*) field;
#endif return *sf;
}
static void prvTaskC21( void * pvParameters ); static uint32_t fuzz_long_next(int tasknum) {
static void prvTaskC22( void * pvParameters ); unsigned char field[4];
static void prvTaskC32( void * pvParameters ); field[0]=fuzz_char_next(tasknum);
static void prvTaskC31( void * pvParameters ); field[1]=fuzz_char_next(tasknum);
static void prvTaskC23( void * pvParameters ); field[2]=fuzz_char_next(tasknum);
static void prvTaskC14( void * pvParameters ); field[3]=fuzz_char_next(tasknum);
static void prvTaskC11( void * pvParameters ); uint32_t* sf = (uint32_t*) field;
static void prvTaskC12( void * pvParameters ); return *sf;
static void prvTaskC33( void * pvParameters ); }
static void prvTaskC13( void * pvParameters ); // 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 );
// Priorities using rate-monotonic scheduling // Priorities using rate-monotonic scheduling
// ties are decided favoring short wcets // ties are decided favoring short wcets
@ -68,40 +142,40 @@ static void prvTaskC13( void * pvParameters );
// cross-chain effect ideas: // cross-chain effect ideas:
// RM + sort by chains // RM + sort by chains
#define mainTASK_C21_PRIO ( tskIDLE_PRIORITY + 1 ) #define mainTASK_31_PRIO ( tskIDLE_PRIORITY + 1 )
#define mainTASK_C22_PRIO ( tskIDLE_PRIORITY + 5 ) #define mainTASK_78_PRIO ( tskIDLE_PRIORITY + 5 )
#define mainTASK_C32_PRIO ( tskIDLE_PRIORITY + 8 ) #define mainTASK_90_PRIO ( tskIDLE_PRIORITY + 8 )
#define mainTASK_C31_PRIO ( tskIDLE_PRIORITY + 10 ) #define mainTASK_397_PRIO ( tskIDLE_PRIORITY + 10 )
#define mainTASK_C23_PRIO ( tskIDLE_PRIORITY + 9 ) #define mainTASK_400_PRIO ( tskIDLE_PRIORITY + 9 )
#define mainTASK_C14_PRIO ( tskIDLE_PRIORITY + 5 ) #define mainTASK_416_PRIO ( tskIDLE_PRIORITY + 5 )
#define mainTASK_C11_PRIO ( tskIDLE_PRIORITY + 5 ) #define mainTASK_579_PRIO ( tskIDLE_PRIORITY + 5 )
#define mainTASK_C12_PRIO ( tskIDLE_PRIORITY + 5 ) #define mainTASK_1009_PRIO ( tskIDLE_PRIORITY + 5 )
#define mainTASK_C33_PRIO ( tskIDLE_PRIORITY + 2 ) #define mainTASK_1107_PRIO ( tskIDLE_PRIORITY + 2 )
#define mainTASK_C13_PRIO ( tskIDLE_PRIORITY + 5 ) #define mainTASK_1129_PRIO ( tskIDLE_PRIORITY + 5 )
// RM with pref for short // RM with pref for short
// #define mainTASK_C21_PRIO ( tskIDLE_PRIORITY + 1 ) // #define mainTASK_31_PRIO ( tskIDLE_PRIORITY + 1 )
// #define mainTASK_C22_PRIO ( tskIDLE_PRIORITY + 5 ) // #define mainTASK_78_PRIO ( tskIDLE_PRIORITY + 5 )
// #define mainTASK_C32_PRIO ( tskIDLE_PRIORITY + 8 ) // #define mainTASK_90_PRIO ( tskIDLE_PRIORITY + 8 )
// #define mainTASK_C31_PRIO ( tskIDLE_PRIORITY + 10 ) // #define mainTASK_397_PRIO ( tskIDLE_PRIORITY + 10 )
// #define mainTASK_C23_PRIO ( tskIDLE_PRIORITY + 9 ) // #define mainTASK_400_PRIO ( tskIDLE_PRIORITY + 9 )
// #define mainTASK_C14_PRIO ( tskIDLE_PRIORITY + 4 ) // #define mainTASK_416_PRIO ( tskIDLE_PRIORITY + 4 )
// #define mainTASK_C11_PRIO ( tskIDLE_PRIORITY + 7 ) // #define mainTASK_579_PRIO ( tskIDLE_PRIORITY + 7 )
// #define mainTASK_C12_PRIO ( tskIDLE_PRIORITY + 6 ) // #define mainTASK_1009_PRIO ( tskIDLE_PRIORITY + 6 )
// #define mainTASK_C33_PRIO ( tskIDLE_PRIORITY + 2 ) // #define mainTASK_1107_PRIO ( tskIDLE_PRIORITY + 2 )
// #define mainTASK_C13_PRIO ( tskIDLE_PRIORITY + 3 ) // #define mainTASK_1129_PRIO ( tskIDLE_PRIORITY + 3 )
// Same Prio // Same Prio
// #define mainTASK_C21_PRIO ( tskIDLE_PRIORITY + 1 ) // #define mainTASK_31_PRIO ( tskIDLE_PRIORITY + 1 )
// #define mainTASK_C22_PRIO ( tskIDLE_PRIORITY + 7 ) // #define mainTASK_78_PRIO ( tskIDLE_PRIORITY + 7 )
// #define mainTASK_C32_PRIO ( tskIDLE_PRIORITY + 8 ) // #define mainTASK_90_PRIO ( tskIDLE_PRIORITY + 8 )
// #define mainTASK_C31_PRIO ( tskIDLE_PRIORITY + 10 ) // #define mainTASK_397_PRIO ( tskIDLE_PRIORITY + 10 )
// #define mainTASK_C23_PRIO ( tskIDLE_PRIORITY + 9 ) // #define mainTASK_400_PRIO ( tskIDLE_PRIORITY + 9 )
// #define mainTASK_C14_PRIO ( tskIDLE_PRIORITY + 7 ) // #define mainTASK_416_PRIO ( tskIDLE_PRIORITY + 7 )
// #define mainTASK_C11_PRIO ( tskIDLE_PRIORITY + 7 ) // #define mainTASK_579_PRIO ( tskIDLE_PRIORITY + 7 )
// #define mainTASK_C12_PRIO ( tskIDLE_PRIORITY + 7 ) // #define mainTASK_1009_PRIO ( tskIDLE_PRIORITY + 7 )
// #define mainTASK_C33_PRIO ( tskIDLE_PRIORITY + 2 ) // #define mainTASK_1107_PRIO ( tskIDLE_PRIORITY + 2 )
// #define mainTASK_C13_PRIO ( tskIDLE_PRIORITY + 7 ) // #define mainTASK_1129_PRIO ( tskIDLE_PRIORITY + 7 )
#define TASK_31_MESSAGE "01" #define TASK_31_MESSAGE "01"
#define TASK_78_MESSAGE "05" #define TASK_78_MESSAGE "05"
@ -115,16 +189,16 @@ static void prvTaskC13( void * pvParameters );
#define TASK_1129_MESSAGE "04" #define TASK_1129_MESSAGE "04"
// Handles for direct messages // Handles for direct messages
static TaskHandle_t xTaskC21 = NULL; static TaskHandle_t xTask31 = NULL;
static TaskHandle_t xTaskC22 = NULL; static TaskHandle_t xTask78 = NULL;
static TaskHandle_t xTaskC32 = NULL; static TaskHandle_t xTask90 = NULL;
static TaskHandle_t xTaskC31 = NULL; static TaskHandle_t xTask397 = NULL;
static TaskHandle_t xTaskC23 = NULL; static TaskHandle_t xTask400 = NULL;
static TaskHandle_t xTaskC14 = NULL; static TaskHandle_t xTask416 = NULL;
static TaskHandle_t xTaskC11 = NULL; static TaskHandle_t xTask579 = NULL;
static TaskHandle_t xTaskC12 = NULL; static TaskHandle_t xTask1009 = NULL;
static TaskHandle_t xTaskC33 = NULL; static TaskHandle_t xTask1107 = NULL;
static TaskHandle_t xTaskC13 = NULL; static TaskHandle_t xTask1129 = NULL;
static TickType_t initial_release_time = 0; static TickType_t initial_release_time = 0;
@ -147,76 +221,76 @@ void main_waters( void )
// puts("Main function"); // puts("Main function");
/* Start the two tasks as described in the comments at the top of this /* Start the two tasks as described in the comments at the top of this
* file. */ * file. */
xTaskCreate( prvTaskC21, /* The function that implements the task. */ xTaskCreate( prvTask31, /* 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. */ "31", /* 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. */ 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. */ NULL, /* The parameter passed to the task - not used in this case. */
mainTASK_C21_PRIO, /* The priority assigned to the task. */ mainTASK_31_PRIO, /* The priority assigned to the task. */
&xTaskC21 ); /* The task handle is not required, so NULL is passed. */ &xTask31 ); /* The task handle is not required, so NULL is passed. */
xTaskCreate( prvTaskC22, /* The function that implements the task. */ xTaskCreate( prvTask78, /* 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. */ "78", /* 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. */ 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. */ NULL, /* The parameter passed to the task - not used in this case. */
mainTASK_C22_PRIO, /* The priority assigned to the task. */ mainTASK_78_PRIO, /* The priority assigned to the task. */
&xTaskC22 ); /* The task handle is not required, so NULL is passed. */ &xTask78 ); /* The task handle is not required, so NULL is passed. */
xTaskCreate( prvTaskC32, xTaskCreate( prvTask90,
"C32", "90",
configMINIMAL_STACK_SIZE, configMINIMAL_STACK_SIZE,
NULL, NULL,
mainTASK_C32_PRIO, mainTASK_90_PRIO,
&xTaskC32 ); &xTask90 );
// This task is supposed to be sporadic // This task is supposed to be sporadic
xTaskCreate( prvTaskC31, xTaskCreate( prvTask397,
"async_C31", "async_397",
configMINIMAL_STACK_SIZE, configMINIMAL_STACK_SIZE,
NULL, NULL,
mainTASK_C31_PRIO, mainTASK_397_PRIO,
&xTaskC31 ); &xTask397 );
xTaskCreate( prvTaskC23, xTaskCreate( prvTask400,
"C23", "400",
configMINIMAL_STACK_SIZE, configMINIMAL_STACK_SIZE,
NULL, NULL,
mainTASK_C23_PRIO, mainTASK_400_PRIO,
&xTaskC23 ); &xTask400 );
xTaskCreate( prvTaskC14, xTaskCreate( prvTask416,
"C14", "416",
configMINIMAL_STACK_SIZE, configMINIMAL_STACK_SIZE,
NULL, NULL,
mainTASK_C14_PRIO, mainTASK_416_PRIO,
&xTaskC14 ); &xTask416 );
xTaskCreate( prvTaskC11, xTaskCreate( prvTask579,
"C11", "579",
configMINIMAL_STACK_SIZE, configMINIMAL_STACK_SIZE,
NULL, NULL,
mainTASK_C11_PRIO, mainTASK_579_PRIO,
&xTaskC11 ); &xTask579 );
xTaskCreate( prvTaskC12, xTaskCreate( prvTask1009,
"C12", "1009",
configMINIMAL_STACK_SIZE, configMINIMAL_STACK_SIZE,
NULL, NULL,
mainTASK_C12_PRIO, mainTASK_1009_PRIO,
&xTaskC12 ); &xTask1009 );
xTaskCreate( prvTaskC33, xTaskCreate( prvTask1107,
"C33", "1107",
configMINIMAL_STACK_SIZE, configMINIMAL_STACK_SIZE,
NULL, NULL,
mainTASK_C33_PRIO, mainTASK_1107_PRIO,
&xTaskC33 ); &xTask1107 );
xTaskCreate( prvTaskC13, xTaskCreate( prvTask1129,
"C13", "1129",
configMINIMAL_STACK_SIZE, configMINIMAL_STACK_SIZE,
NULL, NULL,
mainTASK_C13_PRIO, mainTASK_1129_PRIO,
&xTaskC13 ); &xTask1129 );
xTaskCreate( timing_supervisor_task, xTaskCreate( timing_supervisor_task,
"supervisor", "supervisor",
@ -242,73 +316,66 @@ void main_waters( void )
} }
// Chain2: 31 -> 78 -> 400 // Chain2: 31 -> 78 -> 400
static void prvTaskC21( void * pvParameters ) { static void prvTask31( void * pvParameters ) {
const int task_id = 0;
TickType_t xLastWakeTime = initial_release_time; TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 100 / portTICK_PERIOD_MS; const TickType_t xFrequency = 100 / portTICK_PERIOD_MS;
const uint32_t upper_bound = 48940*LOCAL_WCET_MULT; int period_counter = 2;
for( ;; ){ for( ;; ){
RNG_RESET WCET_END({if (--period_counter==0) {puts("End");}}) // Debugging
// Actions -------------------------------------- // Actions --------------------------------------
// Exectime: f(x) = x % 1000000 // Exectime: f(x) = x
// Output: g(x) = x % 2 // Output: g(x) = x % 2
// WC Input: x = 48941 volatile uint16_t x = fuzz_short_next(0);
volatile uint32_t x = INPUT_LONG_NEXT % 1000000; DEBUG_WCET(x=48940;)
WCET_CLAMP(x, 0, upper_bound, TASK_31_MESSAGE) WCET_CLAMP(x, 0, 48940, TASK_31_MESSAGE)
trigger_job_done(); trigger_job_done();
xTaskNotify(xTaskC22, DEBUG_VAL(x % 2, 1), eSetValueWithOverwrite); // WCET_END({trigger_Qemu_break();})
xTaskNotify(xTask78, DEBUG_VAL(x % 2, 1), eSetValueWithOverwrite);
// --------------------------------------------- // ---------------------------------------------
xTaskDelayUntil( &xLastWakeTime, xFrequency );}// Wait for the next cycle. xTaskDelayUntil( &xLastWakeTime, xFrequency );}// Wait for the next cycle.
} }
// Chain2: 31 -> 78 -> 400 // Chain2: 31 -> 78 -> 400
static void prvTaskC22( void * pvParameters ) { static void prvTask78( void * pvParameters ) {
const int task_id = 1;
TickType_t xLastWakeTime = initial_release_time; TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; const TickType_t xFrequency = 10 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
RNG_RESET
// Actions -------------------------------------- // Actions --------------------------------------
// Exectime: f(x,y) = c + (y!=0)*20000 + (x%100<=5)*(x!=0)*50000 // Exectime: f(x,y) = c + y*20000 + rng(x)*50000
// Output: g(x,y) = y * (x % 4) // Output: g(x,y) = y * (x % 4)
// WC Input: x = 2, y = 1 uint16_t x = fuzz_short_next(1);
uint16_t x = INPUT_SHORT_NEXT; int y = ulTaskNotifyTake(pdTRUE, 0);
unsigned long int y = 0;
xTaskNotifyWait(0,ULONG_MAX,&y,0);
volatile int torun = 6035; volatile int torun = 6035;
if ((int)y > 0) { if (y > 0) {
torun += 20000; torun += 20000;
} }
if (DEBUG_VAL(((x % 100) <= 5)*(x!=0), 1)) { if (DEBUG_VAL(CHANCE_1_IN_POWOF2(x, 5), 1)) {
torun += 50000; torun += 50000;
} }
WCET_CLAMP(torun*LOCAL_WCET_MULT, 0, 76035*LOCAL_WCET_MULT, TASK_78_MESSAGE) WCET_CLAMP(torun, 0, 76035, TASK_78_MESSAGE)
xTaskNotify(xTaskC23, DEBUG_VAL((int)y * (x % 4), 2), eSetValueWithOverwrite); xTaskNotify(xTask400, DEBUG_VAL(y * (x % 4), 2), eSetValueWithOverwrite);
// --------------------------------------------- // ---------------------------------------------
trigger_job_done(); trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );} xTaskDelayUntil( &xLastWakeTime, xFrequency );}
} }
// Chain2: 31 -> 78 -> 400 // Chain2: 31 -> 78 -> 400
static void prvTaskC23( void * pvParameters ) { static void prvTask400( void * pvParameters ) {
const int task_id = 2;
TickType_t xLastWakeTime = initial_release_time; TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 2 / portTICK_PERIOD_MS; const TickType_t xFrequency = 2 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
RNG_RESET
// Actions -------------------------------------- // Actions --------------------------------------
// Exectime: f(x,y) = rng(x)*y*c or (rng(x) % 1000) // Exectime: f(x,y) = rng(x)*y*c or (rng(x) % 1000)
// WC Input: x = 2214, y = 2 uint32_t x = fuzz_long_next(2);
uint32_t x = INPUT_LONG_NEXT; int y = ulTaskNotifyTake(pdTRUE, 0);
unsigned long int y = 0;
xTaskNotifyWait(0,ULONG_MAX,&y,0);
volatile int torun = 0; volatile int torun = 0;
if (y == 2 && DEBUG_VAL(((x%100) <= 25), 1)) { if (y == 2 && DEBUG_VAL(CHANCE_1_IN_POWOF2(x, 2), 1)) {
torun = 1766; torun = 1765;
} else { } else {
torun = (RNG_FROM(x) % 1000); torun = RNG_FROM(x) % 1000;
DEBUG_WCET(torun=999;)
} }
WCET_CLAMP(torun*LOCAL_WCET_MULT, 0, 1765*LOCAL_WCET_MULT, TASK_400_MESSAGE) WCET_CLAMP(torun, 0, 1765, TASK_400_MESSAGE)
// --------------------------------------------- // ---------------------------------------------
trigger_job_done(); trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );} xTaskDelayUntil( &xLastWakeTime, xFrequency );}
@ -317,27 +384,25 @@ static void prvTaskC23( void * pvParameters ) {
//================================================================== //==================================================================
// Chain3: 397 -> 90 -> 1107 // Chain3: 397 -> 90 -> 1107
static void prvTaskC31( void * pvParameters ) { static void prvTask397( void * pvParameters ) {
const int task_id = 3;
TickType_t xLastWakeTime = initial_release_time; TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 1 / portTICK_PERIOD_MS; const TickType_t xFrequency = 1 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
RNG_RESET // Exectime: f(x) = 20*x
// Exectime: f(x) = 32*x
// Output: g(x) = x % 2 // Output: g(x) = x % 2
// WC Input: x = 255, volatile uint16_t x = fuzz_char_next(3);
volatile uint16_t x = INPUT_CHAR_NEXT;
x *= 32; x *= 32;
WCET_CLAMP(x*LOCAL_WCET_MULT, 0, 5830*LOCAL_WCET_MULT, TASK_397_MESSAGE); DEBUG_WCET(x=5830;)
xTaskNotify(xTaskC32, DEBUG_VAL((x/32) & 0x1, 1), eSetValueWithOverwrite); WCET_CLAMP(x, 0, 5830, TASK_397_MESSAGE);
xTaskNotify(xTask90, DEBUG_VAL((x/32) & 0x1, 0), eSetValueWithOverwrite);
// 3 different activation strategies ------------- // 3 different activation strategies -------------
// activate sporadically from interrupts // activate sporadically from interrupts
trigger_job_done(); trigger_job_done();
#ifdef IGNORE_INTERRUPTS #ifdef INTERRUPT_ACTIVATION
ulTaskNotifyTake(pdTRUE,portMAX_DELAY);
#else
// activate with worst possible frequency (700us, but tick resolution is too low) // activate with worst possible frequency (700us, but tick resolution is too low)
xTaskDelayUntil( &xLastWakeTime, xFrequency ); xTaskDelayUntil( &xLastWakeTime, xFrequency );
#else
ulTaskNotifyTake(pdTRUE,portMAX_DELAY);
#endif #endif
// wait pseudo random many ticks // wait pseudo random many ticks
// xTaskDelayUntil( &xLastWakeTime, CLAMP(RNG, 1, 100) / portTICK_PERIOD_MS ); // xTaskDelayUntil( &xLastWakeTime, CLAMP(RNG, 1, 100) / portTICK_PERIOD_MS );
@ -345,48 +410,42 @@ static void prvTaskC31( void * pvParameters ) {
} }
// Chain3: 397 -> 90 -> 1107 // Chain3: 397 -> 90 -> 1107
static void prvTaskC32( void * pvParameters ) { static void prvTask90( void * pvParameters ) {
const int task_id = 4;
TickType_t xLastWakeTime = initial_release_time; TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 2 / portTICK_PERIOD_MS; const TickType_t xFrequency = 2 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
RNG_RESET
// Actions -------------------------------------- // Actions --------------------------------------
// Exectime: f(x) = c + 100*x // Exectime: f(x) = c + 100*x
// Output: g(x) = x % 4 // Output: g(x) = x % 4
// WC Input: x = 204 (local), y = 1 int y = ulTaskNotifyTake(pdTRUE, 0);
unsigned long int y = 0; volatile uint16_t x = fuzz_char_next(4);
xTaskNotifyWait(0,ULONG_MAX,&y,0);
volatile uint16_t x = INPUT_CHAR_NEXT;
x *= 100; x *= 100;
DEBUG_WCET(x=20048;)
int torun = 0; int torun = 0;
if (!y) { if (y) {
torun = CLAMP(x, 5000, 10000); torun = CLAMP(x, 5000, 10000);
} else { } else {
torun = CLAMP(x, 0, 20045); torun = CLAMP(x, 0, 20045);
} }
WCET_CLAMP(torun*LOCAL_WCET_MULT, 0, 20045*LOCAL_WCET_MULT, TASK_90_MESSAGE) WCET_CLAMP(torun, 0, 20045, TASK_90_MESSAGE)
xTaskNotify(xTaskC33, DEBUG_VAL((x/100) % 4, 0), eSetValueWithOverwrite); xTaskNotify(xTask1107, DEBUG_VAL((x/100) % 4, 0), eSetValueWithOverwrite);
// --------------------------------------------- // ---------------------------------------------
trigger_job_done(); trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );} xTaskDelayUntil( &xLastWakeTime, xFrequency );}
} }
// Chain3: 397 -> 90 -> 1107 // Chain3: 397 -> 90 -> 1107
static void prvTaskC33( void * pvParameters ) { static void prvTask1107( void * pvParameters ) {
const int task_id = 5;
TickType_t xLastWakeTime = initial_release_time; TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 50 / portTICK_PERIOD_MS; const TickType_t xFrequency = 50 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
RNG_RESET
// Actions -------------------------------------- // Actions --------------------------------------
// Exectime: f(x) = c - x*y // Exectime: f(x) = c - x*y
// WC Input: x = 0 | y = 0 volatile uint16_t x = fuzz_short_next(5);
volatile uint16_t x = INPUT_SHORT_NEXT; DEBUG_WCET(x=0;)
unsigned long int y = 0; int y = ulTaskNotifyTake(pdTRUE, 0);
xTaskNotifyWait(0,ULONG_MAX,&y,0); int torun = 76865-((int)x)*y;
int torun = 76865-((int)x)*(int)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(); trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );} xTaskDelayUntil( &xLastWakeTime, xFrequency );}
@ -395,113 +454,101 @@ static void prvTaskC33( void * pvParameters ) {
//================================================================== //==================================================================
// Chain1: 579 -> 1009 -> 1129 -> 416 // Chain1: 579 -> 1009 -> 1129 -> 416
static void prvTaskC11( void * pvParameters ) { static void prvTask579( void * pvParameters ) {
const int task_id = 6;
// int period = 5; // int period = 5;
TickType_t xLastWakeTime = initial_release_time; TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; const TickType_t xFrequency = 10 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
RNG_RESET
// if (--period==0) {puts("End");} // Debugging Marker // if (--period==0) {puts("End");} // Debugging Marker
// Actions -------------------------------------- // Actions --------------------------------------
// Exectime: f(x) = x>>8 & 0x0fff // Exectime: f(x) = x>>8 & 0x0fff
// Output: g(x) = x % 8 // Output: g(x) = x % 8
// WC Input: x = 629760 uint32_t x = fuzz_long_next(6);
uint32_t x = INPUT_LONG_NEXT;
xTaskNotify(xTaskC12, DEBUG_VAL(x % 8, 0), eSetValueWithOverwrite);
volatile int torun = (x>>8) & 0x0fff; volatile int torun = (x>>8) & 0x0fff;
WCET_CLAMP(torun*LOCAL_WCET_MULT, 500*LOCAL_WCET_MULT, 2460*LOCAL_WCET_MULT, TASK_579_MESSAGE) DEBUG_WCET(torun = 0x0fff;)
WCET_CLAMP(torun, 500, 2460, TASK_579_MESSAGE)
xTaskNotify(xTask1009, DEBUG_VAL(x % 8, 0), eSetValueWithOverwrite);
// --------------------------------------------- // ---------------------------------------------
trigger_job_done(); trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );} xTaskDelayUntil( &xLastWakeTime, xFrequency );}
} }
// Chain1: 579 -> 1009 -> 1129 -> 416 // Chain1: 579 -> 1009 -> 1129 -> 416
static void prvTaskC12( void * pvParameters ) { static void prvTask1009( void * pvParameters ) {
const int task_id = 7;
TickType_t xLastWakeTime = initial_release_time; TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; const TickType_t xFrequency = 10 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
RNG_RESET
// Actions -------------------------------------- // Actions --------------------------------------
// Exectime: f(x,y) = if x%8 == y ? 40000+x : x (<40k) // Exectime: f(x,y) = if x%8 == y ? 40000+x : x (<40k)
// Output: g(x) = x % 8 == y // Output: g(x) = x % 8 == y
// WC Input: x = 12000, y = 0 uint16_t x = fuzz_short_next(7);
uint16_t x = INPUT_SHORT_NEXT; int y = ulTaskNotifyTake(pdTRUE, 0);
unsigned long int y = 0;
xTaskNotifyWait(0,ULONG_MAX,&y,NOTIFY_WAIT_TIME);
xTaskNotify(xTaskC13, DEBUG_VAL((x % 8 == y), 1), eSetValueWithOverwrite);
volatile int torun = 0; volatile int torun = 0;
if (x % 8 == y) { if (x % 8 == y) {
torun = 40000 + x; torun = 40000 + x;
} else { } else {
torun = CLAMP(x, 0, 40000); torun = CLAMP(x, 0, 40000);
} }
WCET_CLAMP(torun*LOCAL_WCET_MULT, 0, 51485*LOCAL_WCET_MULT, TASK_1009_MESSAGE) DEBUG_WCET(torun = 51485;)
WCET_CLAMP(torun, 0, 51485, TASK_1009_MESSAGE)
xTaskNotify(xTask1129, DEBUG_VAL(x % 8 == y, 1), eSetValueWithOverwrite);
// --------------------------------------------- // ---------------------------------------------
trigger_job_done(); trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );} xTaskDelayUntil( &xLastWakeTime, xFrequency );}
} }
// Chain1: 579 -> 1009 -> 1129 -> 416 // Chain1: 579 -> 1009 -> 1129 -> 416
static void prvTaskC13( void * pvParameters ) { static void prvTask1129( void * pvParameters ) {
const int task_id = 8;
int period_counter = 2; int period_counter = 2;
TickType_t xLastWakeTime = initial_release_time; TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; const TickType_t xFrequency = 10 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
RNG_RESET
// if (--period_counter==0) {puts("End");} // if (--period_counter==0) {puts("End");}
// Actions -------------------------------------- // Actions --------------------------------------
// Exectime: f(x,y) = if y && rng(x) ? c1+x : c2+x // Exectime: f(x,y) = if y && rng(x) ? c1+x : c2+x
// Output: g(x) = y && rng(x) // Output: g(x) = y && rng(x)
// longmax - shortmax: 39505 // longmax - shortmax: 39505
// most likely long case, which causes a short case in next task // most likely long case, which causes a short case in next task
// WC Input: x = 65535 , y = 0 for "long" run volatile uint32_t x = (uint32_t)fuzz_short_next(8);
// WC Input: x = 65535 , y = 1 for "short" run int y = ulTaskNotifyTake(pdTRUE, 0);
// globally, short runs consume more time in subsequent jobs DEBUG_WCET(
volatile uint32_t x = INPUT_SHORT_NEXT; static char flag=0;
unsigned long int y = 0; if (flag++ == 0 | flag == 5 | flag == 8 | flag == 9) {x = 65529;}
xTaskNotifyWait(0,ULONG_MAX,&y,NOTIFY_WAIT_TIME); else {x = 0xffff;}
volatile int do_short_run = (y + ((x%100)<=5)) == 1; // XOR )
xTaskNotify(xTaskC14, DEBUG_VAL(do_short_run, 1), eSetValueWithOverwrite); volatile int do_short_run = (y + CHANCE_1_IN_POWOF2(x, 5)) == 1; // XOR
int torun = 0; int torun = 0;
if (do_short_run > 0) { if (do_short_run > 0) {
torun = 40000 + x; torun = 40000 + x;
} else { } else {
torun = 80000 + x; torun = 80000 + x;
} }
#ifdef INSERT_WC WCET_CLAMP(torun, 0, 145040, TASK_1129_MESSAGE)
// to reach the global wcrt, take the shorter case xTaskNotify(xTask416, do_short_run, eSetValueWithOverwrite);
WCET_CLAMP(torun*LOCAL_WCET_MULT, 0, (40000+0xFFFF)*LOCAL_WCET_MULT, TASK_1129_MESSAGE)
#else
WCET_CLAMP(torun*LOCAL_WCET_MULT, 0, 145040*LOCAL_WCET_MULT, TASK_1129_MESSAGE)
#endif
// --------------------------------------------- // ---------------------------------------------
trigger_job_done(); trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );} xTaskDelayUntil( &xLastWakeTime, xFrequency );}
} }
// Chain1: 579 -> 1009 -> 1129 -> 416 // Chain1: 579 -> 1009 -> 1129 -> 416
static void prvTaskC14( void * pvParameters ) { static void prvTask416( void * pvParameters ) {
const int task_id = 9;
TickType_t xLastWakeTime = initial_release_time; TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; const TickType_t xFrequency = 10 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
RNG_RESET
// Actions -------------------------------------- // Actions --------------------------------------
// Exectime: f(x,y) = if y ? c1+2*x : c2-x // Exectime: f(x,y) = if y ? c1+2*x : c2-x
// longmax - shortmax: 76955 // longmax - shortmax: 76955
volatile uint32_t x = INPUT_SHORT_NEXT; volatile uint32_t x = (uint32_t)fuzz_short_next(9);
unsigned long int y = 0; int y = ulTaskNotifyTake(pdTRUE, 0);
xTaskNotifyWait(0,ULONG_MAX,&y,NOTIFY_WAIT_TIME);
volatile int torun = 0; volatile int torun = 0;
if (y) { if (y) {
DEBUG_WCET(x=0xffff;)
torun = x*3; torun = x*3;
} else { } else {
DEBUG_WCET(x=0;)
torun = 50000 - CLAMP_CEILING(x, 50000); torun = 50000 - CLAMP_CEILING(x, 50000);
} }
WCET_CLAMP(torun*LOCAL_WCET_MULT, 10000*LOCAL_WCET_MULT, 126955*LOCAL_WCET_MULT, TASK_416_MESSAGE) WCET_CLAMP(torun, 10000, 126955, TASK_416_MESSAGE)
// --------------------------------------------- // ---------------------------------------------
trigger_job_done(); trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );} xTaskDelayUntil( &xLastWakeTime, xFrequency );}
@ -516,10 +563,8 @@ void vWatersIdleFunction() {
void ISR_0_Handler( void ) void ISR_0_Handler( void )
{ {
puts("Interrupt"); puts("Interrupt");
if (xTaskC31) { if (xTask397) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE; vTaskNotifyGiveFromISR(xTask397, NULL);
vTaskNotifyGiveFromISR(xTaskC31, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -75,7 +75,7 @@ __attribute__((noinline)) static void trigger_job_done( void )
#define DEBUG_WCET(A) #define DEBUG_WCET(A)
#endif #endif
// #define FUZZ_INT_ACTIVATION 1 // #define INTERRUPT_ACTIVATION 1
// Begin Input Stuff // Begin Input Stuff
#define NUM_TASKS 10 #define NUM_TASKS 10
@ -92,7 +92,7 @@ static unsigned char fuzz_char_next(int tasknum) {
if (INPUT_POINTERS[tasknum] >= (tasknum+1) * (MAX_INPUT_BYTES / NUM_TASKS)) { if (INPUT_POINTERS[tasknum] >= (tasknum+1) * (MAX_INPUT_BYTES / NUM_TASKS)) {
trigger_Qemu_break(); trigger_Qemu_break();
} }
return FUZZ_INPUT[INPUT_POINTERS[tasknum]++]; FUZZ_INPUT[INPUT_POINTERS[tasknum]++];
#else #else
// printf("Get next Input from %lx \n",FUZZ_INPUT); // printf("Get next Input from %lx \n",FUZZ_INPUT);
if (INPUT_POINTERS[0] < FUZZ_LENGTH) { if (INPUT_POINTERS[0] < FUZZ_LENGTH) {
@ -406,7 +406,7 @@ static void prvTask397( void * pvParameters ) {
// 3 different activation strategies ------------- // 3 different activation strategies -------------
// activate sporadically from interrupts // activate sporadically from interrupts
trigger_job_done(); trigger_job_done();
#ifdef FUZZ_INT_ACTIVATION #ifdef INTERRUPT_ACTIVATION
ulTaskNotifyTake(pdTRUE,portMAX_DELAY); ulTaskNotifyTake(pdTRUE,portMAX_DELAY);
#else #else
// activate with worst possible frequency (700us, but tick resolution is too low) // activate with worst possible frequency (700us, but tick resolution is too low)

View File

@ -1,94 +0,0 @@
#ifndef __POLYNOMIC_FUNCTIONS_H__
#define __POLYNOMIC_FUNCTIONS_H__
#include "util_macros.h"
#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(I, LB,UB) TRANSLATE_BOUNDS((I), 180000, 1000000, LB, UB) // FN 1
#define TRANSLATE_2(I, LB,UB) TRANSLATE_BOUNDS((I), -500000, 390000, LB, UB) // FN 2
#define TRANSLATE_3(I, LB,UB) TRANSLATE_BOUNDS((I), -8000, 80000, LB, UB) // FN 3
#define TRANSLATE_4(I, LB,UB) TRANSLATE_BOUNDS((I), -480000, -250000, LB, UB) // FN 4
#define TRANSLATE_5(I, LB,UB) TRANSLATE_BOUNDS((I), -193000, -155000, LB, UB) // FN 5
#define TRANSLATE_6(I, LB,UB) TRANSLATE_BOUNDS((I), -400000000, 400000000, LB, UB) // FN 6
#define TRANSLATE_7(I, LB,UB) TRANSLATE_BOUNDS((I), -20000, 120000, LB, UB) // FN 7
#define TRANSLATE_8(I, LB,UB) TRANSLATE_BOUNDS((I), -20000000, 120000000, LB, UB) // FN 8
#define TRANSLATE_9(I, LB,UB) TRANSLATE_BOUNDS((I), -200000, 220000, LB, UB) // FN 9
#define TRANSLATE_10(I, LB,UB) TRANSLATE_BOUNDS((I), -10000, 150000, LB, UB) // FN 10
#endif

View File

@ -0,0 +1,8 @@
// Manual Types
pub type xLIST_ITEM_ptr = ::std::os::raw::c_uint;
pub type xLIST_ptr = ::std::os::raw::c_uint;
pub type ListItem_t_ptr = ::std::os::raw::c_uint;
pub type StackType_t_ptr = ::std::os::raw::c_uint;
pub type char_ptr = ::std::os::raw::c_uint;
pub type void_ptr = ::std::os::raw::c_uint;

View File

@ -1,130 +0,0 @@
#ifndef __UTIL_MACROS_H__
#define __UTIL_MACROS_H__
#include <limits.h>
#include <stdint.h>
// Veriadic macros ==
#define REP_VA0(...)
#define REP_VA1(...) __VA_ARGS__
#define REP_VA2(...) REP_VA1(__VA_ARGS__),__VA_ARGS__
#define REP_VA3(...) REP_VA2(__VA_ARGS__),__VA_ARGS__
#define REP_VA4(...) REP_VA3(__VA_ARGS__),__VA_ARGS__
#define REP_VA5(...) REP_VA4(__VA_ARGS__),__VA_ARGS__
#define REP_VA6(...) REP_VA5(__VA_ARGS__),__VA_ARGS__
#define REP_VA7(...) REP_VA6(__VA_ARGS__),__VA_ARGS__
#define REP_VA8(...) REP_VA7(__VA_ARGS__),__VA_ARGS__
#define REP_VA9(...) REP_VA8(__VA_ARGS__),__VA_ARGS__
#define REP_VA10(...) REP_VA9(__VA_ARGS__),__VA_ARGS__
#define REP_VA(HUNDREDS,TENS,ONES,...) \
REP_VA##HUNDREDS(REP_VA10(REP_VA10(__VA_ARGS__))) \
REP_VA##TENS(REP_VA10(__VA_ARGS__)) \
REP_VA##ONES(__VA_ARGS__)
// Random numbers ===
// glibc
// https://en.wikipedia.org/wiki/Linear_congruential_generator
#define __UTIL_RNG_A 1103515245ull
#define __UTIL_RNG_M 0x80000000ull
#define __UTIL_RNG_C 12345ull
#define RNG_FROM(X) ((__UTIL_RNG_A*(X)+__UTIL_RNG_C) % __UTIL_RNG_M)
// Challanges =======
#define CHANCE_1_IN_POWOF2(X,Y) (RNG_FROM(X)<(__UTIL_RNG_M>>Y)) // assume the type of x has more than y bits
// branchless, takes a large hit on performance
#ifdef BRANCHLESS_TERNARY
#define IF_ELSE(X,Y,Z) (((X)*(Y))+((!(X))*(Z)))
#else
#define IF_ELSE(X,Y,Z) ((X) ? (Y) : (Z))
#endif
// Arithmetic =======
static inline int32_t sadd_i32(int32_t a, int32_t b) {
return IF_ELSE((b>=0),
IF_ELSE((a > INT32_MAX - b), INT32_MAX, a + b),
IF_ELSE((a < INT32_MIN - b), INT32_MIN, a + b));
}
static inline int32_t ssub_i32(int32_t a, int32_t b) {
return IF_ELSE((b>=0),
IF_ELSE((a < INT32_MIN + b), INT32_MIN, a - b),
IF_ELSE((a > INT32_MAX + b), INT32_MAX, a - b));
}
static inline int32_t ssquare_i32(int32_t a) {
return IF_ELSE((a <= 0x0000B504 ), a*a, INT32_MAX);
}
static inline int32_t abs_i32(int32_t a) {
return IF_ELSE((a > 0), a, IF_ELSE((a == INT32_MIN), INT32_MAX, -a));
}
static inline int32_t abs_diff_i32(int32_t a, int32_t b) {
return IF_ELSE((a > b), (a-b), (b-a));
}
static inline int32_t min_i32(int32_t a, int32_t b) {
return IF_ELSE((a > b), b, a);
}
static inline int32_t max_i32(int32_t a, int32_t b) {
return IF_ELSE((a > b), b, a);
}
static inline int32_t clamp_i32(int32_t x, int32_t lb, int32_t ub) {
return IF_ELSE((x < lb), lb, IF_ELSE((x > ub), ub, x));
}
static inline int32_t lin_i32(int32_t x, int32_t nom, int32_t den, int32_t c) {
int64_t tmp = ((int64_t)x * nom) / den + c;
return IF_ELSE((tmp < (int64_t)INT32_MAX), (int32_t)tmp, INT32_MAX);
}
static inline int32_t hill_i32(int32_t x, int32_t off, int32_t h, int32_t w) {
return max_i32(ssub_i32(h,ssquare_i32(abs_diff_i32(x,off)/w)),0);
}
static inline int32_t valley_i32(int32_t x, int32_t off, int32_t h, int32_t w) {
return min_i32(sadd_i32(h,ssquare_i32(abs_diff_i32(x,off)/w)),0);
}
//#define MACRO_ONLY
#ifdef MACRO_ONLY
// macros only increses the code size exponentially
// Branchless 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)
#define SADD(X,Y) IF_ELSE(((int32_t)(Y))<0, IF_ELSE(((int32_t)(X))<INT_MIN-((int32_t)(Y)), INT_MIN, ((int32_t)(X))+((int32_t)Y)), 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_MAX+((int32_t)(Y)), ((int32_t)(X))-((int32_t)Y), INT_MAX), 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 AVG(X,Y) (((X)/2)+((Y)/2))
#define SQUARE(X) ((X)*(X))
#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))))
#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))
#else
#define CLAMP_FLOOR(X,LB) max_i32(X, LB)
#define CLAMP_CEILING(X,UB) min_i32(X, UB)
#define CLAMP(X,LB,UB) clamp_i32(X, LB, UB)
#define SADD(X,Y) sadd_i32(X, Y)
#define SSUB(X,Y) ssub_i32(X, Y)
#define ABS_DIFF(X,Y) abs_diff_i32(X,Y)
#define AVG(X,Y) (((X)/2)+((Y)/2))
#define SQUARE(X) ((X)*(X))
#define CHECKED_SQUARE(X) ssquare_i32(X)
#define LIN(X,N,D,C) lin_i32(X,N,D,C)
#define HILL(X, OFF, H, W) hill_i32(X, OFF, H, W)
#define VALLEY(X, OFF, H, W) valley_i32(X, OFF, H, W)
#endif
// Input handling ==
#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 TRANSLATE_BOUNDS(X, FLB, FUB, TLB, TUB) ( ((CLAMP(X,FLB,FUB)-FLB)*(TUB-TLB)) / ((FUB-FLB)) + TLB )
#endif // __UTIL_MACROS_H__

View File

@ -0,0 +1,3 @@
while IFS= read -r line; do
echo pub type $line = "::std::os::raw::c_uint;" | sed -f transform.sed
done <<< "$(grep -oE "\*mut [A-Z:_a-z]*|\*const [A-Z:a-z_]*char" build/bindings.rs | sort | uniq)" > build/header.rs