diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/copter_input.c b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/copter_input.c new file mode 100644 index 00000000..5a273fa2 --- /dev/null +++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/copter_input.c @@ -0,0 +1,130 @@ +#include +#include "arbitrary_loads.c" +#include + +/* +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_POINTERS[NUM_TASKS] = {0}; + +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)) { + exit(1); + } + return FUZZ_INPUT[INPUT_POINTERS[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 #define GLOBAL_WCET_MULT \ 1 // Multiplier to increase all waiting periods to make the schedule more - // tight an force preemptions + // tight and force preemptions #include "arbitrary_loads.c" +#ifdef INSERT_WC + #include "wcinput.h" +#endif + #define NUM_TASKS 15 #define MAX_INPUT_BYTES 4096 volatile unsigned char FUZZ_INPUT[MAX_INPUT_BYTES] = {}; @@ -40,7 +44,7 @@ static unsigned char fuzz_char_next(int tasknum) { if (INPUT_POINTERS[tasknum] >= (tasknum+1) * (MAX_INPUT_BYTES / NUM_TASKS)) { trigger_Qemu_break(); } - FUZZ_INPUT[INPUT_POINTERS[tasknum]++]; + return FUZZ_INPUT[INPUT_POINTERS[tasknum]++]; #else // printf("Get next Input from %lx \n",FUZZ_INPUT); if (INPUT_POINTERS[0] < FUZZ_LENGTH) { @@ -61,19 +65,20 @@ static unsigned char next(int tasknum) { return 255; #endif RNG_STATES[tasknum] = RNG_FROM(RNG_STATES[tasknum]); - unsigned char t = fuzz_char_next(tasknum); - return RNG_STATES[tasknum] ^ (((int)t << 8) + (int)t); + unsigned char i = fuzz_char_next(tasknum); + unsigned char val = RNG_STATES[tasknum] ^ (int)i; + return val; } // #define SHORT_CALC 50 // #define LONG_CALC 200 #ifdef FUZZ_BYTES -#define SHORT_CALC (25+next(task_id)%25) -#define LONG_CALC (150+next(task_id)%100) +#define SHORT_CALC (15+next(task_id)%35) +#define LONG_CALC (50+next(task_id)%150) #else #define SHORT_CALC (50) -#define LONG_CALC (250) +#define LONG_CALC (200) #endif #define HYPER_PERIOD 9 @@ -116,11 +121,56 @@ 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); @@ -163,13 +213,18 @@ void main_osek(void) { configMAX_PRIORITIES - 1, &xTaskTimeSupervisor ); +#ifdef INSERT_WC + for (int i=0; i= (tasknum+1) * (MAX_INPUT_BYTES / NUM_TASKS)) { trigger_Qemu_break(); } - FUZZ_INPUT[INPUT_POINTERS[tasknum]++]; + return FUZZ_INPUT[INPUT_POINTERS[tasknum]++]; #else // printf("Get next Input from %lx \n",FUZZ_INPUT); if (INPUT_POINTERS[0] < FUZZ_LENGTH) { diff --git a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_watersv2.c b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_watersv2.c index a3809970..9e622be2 100644 --- a/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_watersv2.c +++ b/FreeRTOS/Demo/CORTEX_M3_MPS2_QEMU_GCC/main_watersv2.c @@ -92,7 +92,7 @@ static unsigned char fuzz_char_next(int tasknum) { if (INPUT_POINTERS[tasknum] >= (tasknum+1) * (MAX_INPUT_BYTES / NUM_TASKS)) { trigger_Qemu_break(); } - FUZZ_INPUT[INPUT_POINTERS[tasknum]++]; + return FUZZ_INPUT[INPUT_POINTERS[tasknum]++]; #else // printf("Get next Input from %lx \n",FUZZ_INPUT); if (INPUT_POINTERS[0] < FUZZ_LENGTH) {