partitioned inputs, hyhperperiod limits, link markers, new example

This commit is contained in:
Alwin Berger 2024-09-10 15:08:57 +02:00
parent 5fe9744db9
commit d1fca2842e
6 changed files with 559 additions and 84 deletions

View File

@ -94,11 +94,21 @@ ifeq ($(WATERS_DEMO), 1)
CFLAGS := -DmainCREATE_WATERS_DEMO=1 CFLAGS := -DmainCREATE_WATERS_DEMO=1
else else
ifeq ($(WATERSPART_DEMO), 1)
SOURCE_FILES += main_waterspart.c
CFLAGS := -DmainCREATE_WATERS_DEMO=1
else
ifeq ($(WATERSV2_DEMO), 1) ifeq ($(WATERSV2_DEMO), 1)
SOURCE_FILES += main_watersv2.c SOURCE_FILES += main_watersv2.c
CFLAGS := -DmainCREATE_WATERS_DEMO=1 CFLAGS := -DmainCREATE_WATERS_DEMO=1
else else
ifeq ($(WATERSPARTV2_DEMO), 1)
SOURCE_FILES += main_waterspartv2.c
CFLAGS := -DmainCREATE_WATERS_DEMO=1
else
ifeq ($(MAN_DEMO), 1) ifeq ($(MAN_DEMO), 1)
SOURCE_FILES += main_manual.c SOURCE_FILES += main_manual.c
@ -133,6 +143,11 @@ ifdef GEN_DEMO
SOURCE_FILES += main_gen_$(GEN_DEMO).c SOURCE_FILES += main_gen_$(GEN_DEMO).c
CFLAGS := -DmainCREATE_GEN_DEMO=1 CFLAGS := -DmainCREATE_GEN_DEMO=1
else
ifeq ($(RELEASE_DEMO), 1)
SOURCE_FILES += main_release.c
CFLAGS := -DmainCREATE_RELEASE_DEMO=1
else else
SOURCE_FILES += main_blinky.c SOURCE_FILES += main_blinky.c
@ -153,10 +168,16 @@ endif
endif endif
endif endif
endif endif
endif
endif
endif
ifeq ($(INTERRUPT_ACTIVATION), 1) ifeq ($(INTERRUPT_ACTIVATION), 1)
CFLAGS += -D INTERRUPT_ACTIVATION=1 CFLAGS += -D INTERRUPT_ACTIVATION=1
endif endif
ifeq ($(PARTITION_INPUT), 1)
CFLAGS += -D PARTITION_INPUT=1
endif
DEFINES := -DQEMU_SOC_MPS2 -DHEAP3 DEFINES := -DQEMU_SOC_MPS2 -DHEAP3

View File

@ -115,6 +115,10 @@ int main()
{ {
main_interact(); main_interact();
} }
#elif ( mainCREATE_RELEASE_DEMO == 1 )
{
main_release();
}
#else #else
{ {

View File

@ -0,0 +1,329 @@
/*
* FreeRTOS V202111.00
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* https://www.FreeRTOS.org
* https://github.com/FreeRTOS
*
*/
#include <FreeRTOS.h>
#include <task.h>
#include <queue.h>
#include <stdio.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
#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))
#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
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 prvTask2( void * pvParameters );
static void prvTask3( void * pvParameters );
static void prvTask4( 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_2_PRIO ( tskIDLE_PRIORITY + 2 )
#define mainTASK_3_PRIO ( tskIDLE_PRIORITY + 3 )
#define mainTASK_4_PRIO ( tskIDLE_PRIORITY + 4 )
#define mainTASK_5_PRIO ( tskIDLE_PRIORITY + 5 )
#define TASK_1_MESSAGE "01"
#define TASK_2_MESSAGE "02"
#define TASK_3_MESSAGE "03"
#define TASK_4_MESSAGE "04"
#define TASK_5_MESSAGE "05"
// Handles for direct messages
static TaskHandle_t xTask1 = NULL;
static TaskHandle_t xTask2 = NULL;
static TaskHandle_t xTask3 = NULL;
static TaskHandle_t xTask4 = NULL;
static TaskHandle_t xTask5 = NULL;
static TickType_t initial_release_time = 0;
static SemaphoreHandle_t xMutex;
void main_release( void )
{
xMutex = xSemaphoreCreateBinary();
xSemaphoreGive(xMutex);
// puts("Main function");
/* Start the two tasks as described in the comments at the top of this
* file. */
xTaskCreate( prvTask1, /* The function that implements the task. */
"T1", /* 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. */
NULL, /* The parameter passed to the task - not used in this case. */
mainTASK_1_PRIO, /* The priority assigned to the task. */
&xTask1 ); /* The task handle is not required, so NULL is passed. */
xTaskCreate( prvTask2, /* The function that implements the task. */
"T2", /* 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. */
NULL, /* The parameter passed to the task - not used in this case. */
mainTASK_2_PRIO, /* The priority assigned to the task. */
&xTask2 ); /* The task handle is not required, so NULL is passed. */
// This task is supposed to be sporadic
xTaskCreate( prvTask3,
"T3",
configMINIMAL_STACK_SIZE,
NULL,
mainTASK_3_PRIO,
&xTask3 );
xTaskCreate( prvTask4,
"T4",
configMINIMAL_STACK_SIZE,
NULL,
mainTASK_4_PRIO,
&xTask4 );
// This task is supposed to be sporadic
xTaskCreate( prvTask5,
"T5",
configMINIMAL_STACK_SIZE,
NULL,
mainTASK_5_PRIO,
&xTask5 );
/* Start the tasks and timer running. */
// puts("Start scheduler");
vTaskStartScheduler();
/* If all is well, the scheduler will now be running, and the following
* line will never be reached. If the following line does execute, then
* there was insufficient FreeRTOS heap memory available for the Idle and/or
* timer tasks to be created. See the memory management section on the
* FreeRTOS web site for more details on the FreeRTOS heap
* http://www.freertos.org/a00111.html. */
for( ; ; )
{
}
}
static void prvTask1( void * pvParameters ) {
TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 100 / portTICK_PERIOD_MS;
for( ;; ){
// Actions --------------------------------------
volatile uint16_t x = fuzz_short_next();
WCET_CLAMP(x, 8000, 10000, TASK_1_MESSAGE)
xTaskNotify(xTask2, DEBUG_VAL(x % 2, 1), eSetValueWithOverwrite);
// ---------------------------------------------
trigger_job_done();
trigger_Qemu_break();
xTaskDelayUntil( &xLastWakeTime, xFrequency );}// Wait for the next cycle.
}
static void prvTask2( void * pvParameters ) {
TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 50 / portTICK_PERIOD_MS;
for( ;; ){
// Actions --------------------------------------
uint16_t x = fuzz_short_next();
DO_TIME(1000, TASK_2_MESSAGE)
xSemaphoreTake(xMutex, portMAX_DELAY);
volatile int torun = 2000;
if (DEBUG_VAL(CHANCE_1_IN_POWOF2(x, 5), 1)) {
torun += 2000;
}
int y = ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
xSemaphoreGive(xMutex);
// ---------------------------------------------
trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );}
}
static void prvTask3( void * pvParameters ) {
TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 25 / portTICK_PERIOD_MS;
trigger_job_done(); // The first job instance just waits for an activation
for( ;; ){
// Actions --------------------------------------
int y = ulTaskNotifyTake(pdTRUE, portMAX_DELAY); // sporadic
xSemaphoreTake(xMutex, portMAX_DELAY);
volatile uint16_t x = fuzz_short_next();
int torun = 0;
if (y) {
torun = CLAMP(x, 5000, 8000);
} else {
torun = CLAMP(x, 0, 12000);
}
DO_TIME(torun, TASK_3_MESSAGE)
xSemaphoreGive(xMutex);
// ---------------------------------------------
trigger_job_done();
trigger_Qemu_break();
// xTaskDelayUntil( &xLastWakeTime, xFrequency );
}
}
static void prvTask4( void * pvParameters ) {
initial_release_time = xTaskGetTickCount(); // The highest priority task sets the initial time
TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 10 / portTICK_PERIOD_MS;
for( ;; ){
// Actions --------------------------------------
volatile uint16_t x = fuzz_short_next();
WCET_CLAMP(x, 1000, 2000, TASK_4_MESSAGE)
// ---------------------------------------------
trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );}
}
static void prvTask5( void * pvParameters ) {
TickType_t xLastWakeTime = 0;
const TickType_t xFrequency = 5 / portTICK_PERIOD_MS;
trigger_job_done(); // The first job instance just waits for an activation
for( ;; ){
// Actions --------------------------------------
int y = ulTaskNotifyTake(pdTRUE, portMAX_DELAY); // sporadic
int succ = xSemaphoreTake(xMutex, 0); // try to take the mutex
if (succ == pdTRUE) {
// volatile uint16_t x = fuzz_short_next();
uint16_t x = 2000;
int torun = 0;
torun = CLAMP(x, 0, 2000);
DO_TIME(torun, TASK_5_MESSAGE)
xSemaphoreGive(xMutex);
} else {
DO_TIME(50, TASK_5_MESSAGE)
}
// xTaskDelayUntil( &xLastWakeTime, xFrequency ); // enforce a minimum inter-arrival time
// ---------------------------------------------
trigger_job_done();
// xTaskDelayUntil( &xLastWakeTime, portMAX_DELAY ); // enforce a minimum inter-arrival time
}
}
void vWatersIdleFunction() {
for (int i; i<1000; i++) {
puts("0 ");
}
}
void ISR_0_Handler( void )
{
puts("Interrupt");
if (xTask3) {
vTaskNotifyGiveFromISR(xTask3, NULL);
}
}
void ISR_1_Handler( void )
{
puts("Interrupt");
if (xTask5) {
vTaskNotifyGiveFromISR(xTask5, NULL);
}
}
/*-----------------------------------------------------------*/

View File

@ -51,6 +51,12 @@ __attribute__((noinline)) static void trigger_Qemu_break( void )
while (1) { 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 // if this macro is set, the code will be modified to produce the worst case
// #define DEBUG_WCET(A) {A} // #define DEBUG_WCET(A) {A}
@ -69,35 +75,48 @@ __attribute__((noinline)) static void trigger_Qemu_break( void )
#endif #endif
// Begin Input Stuff // Begin Input Stuff
volatile unsigned char FUZZ_INPUT[4096] = {0xa,0xb,0xc,0xd,0xe,0xf}; #define PARTITION_INPUT
volatile uint32_t FUZZ_LENGTH = 4096; #define NUM_TASKS 10
volatile uint32_t FUZZ_POINTER = 0; #define MAX_INPUT_BYTES 4096
volatile unsigned char FUZZ_INPUT[MAX_INPUT_BYTES] = {};
volatile int INPUT_POINTERS[NUM_TASKS] = {};
volatile uint32_t FUZZ_LENGTH = MAX_INPUT_BYTES;// ignored
// Read the Byte of Input, if the Input is exausted trigger the breakpoint instead // Read the Byte of Input, if the Input is exausted trigger the breakpoint instead
static unsigned char fuzz_char_next(void) { 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
// printf("Get next Input from %lx \n",FUZZ_INPUT); // printf("Get next Input from %lx \n",FUZZ_INPUT);
if (FUZZ_POINTER < FUZZ_LENGTH) { if (INPUT_POINTERS[0] < FUZZ_LENGTH) {
FUZZ_POINTER++; INPUT_POINTERS[0]++;
// printf("Input no. %d %x\n",FUZZ_POINTER-1,FUZZ_INPUT[FUZZ_POINTER-1]); // printf("Input no. %d %x\n",FUZZ_POINTER-1,FUZZ_INPUT[FUZZ_POINTER-1]);
return FUZZ_INPUT[FUZZ_POINTER-1]; return FUZZ_INPUT[INPUT_POINTERS[0]-1];
} else { } else {
// puts("End of Input"); // puts("End of Input");
// Exausted inputs early // Exausted inputs early
trigger_Qemu_break(); trigger_Qemu_break();
} }
#endif
} }
static uint16_t fuzz_short_next(void) { static uint16_t fuzz_short_next(int tasknum) {
unsigned char field[2]; unsigned char field[2];
field[0]=fuzz_char_next(); field[0]=fuzz_char_next(tasknum);
field[1]=fuzz_char_next(); field[1]=fuzz_char_next(tasknum);
uint16_t* sf = (uint16_t*) field; uint16_t* sf = (uint16_t*) field;
return *sf; return *sf;
} }
static uint32_t fuzz_long_next(void) { static uint32_t fuzz_long_next(int tasknum) {
unsigned char field[4]; unsigned char field[4];
field[0]=fuzz_char_next(); field[0]=fuzz_char_next(tasknum);
field[1]=fuzz_char_next(); field[1]=fuzz_char_next(tasknum);
field[2]=fuzz_char_next(); field[2]=fuzz_char_next(tasknum);
field[3]=fuzz_char_next(); field[3]=fuzz_char_next(tasknum);
uint32_t* sf = (uint32_t*) field; uint32_t* sf = (uint32_t*) field;
return *sf; return *sf;
} }
@ -182,6 +201,22 @@ static TaskHandle_t xTask1009 = NULL;
static TaskHandle_t xTask1107 = NULL; static TaskHandle_t xTask1107 = NULL;
static TaskHandle_t xTask1129 = NULL; static TaskHandle_t xTask1129 = NULL;
static TickType_t initial_release_time = 0;
#define HYPER_PERIOD 50
#define SIMULATE_PERIODS 2
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( ;; ){}
}
void main_waters( void ) void main_waters( void )
{ {
// puts("Main function"); // puts("Main function");
@ -258,6 +293,13 @@ void main_waters( void )
mainTASK_1129_PRIO, mainTASK_1129_PRIO,
&xTask1129 ); &xTask1129 );
xTaskCreate( timing_supervisor_task,
"supervisor",
configMINIMAL_STACK_SIZE,
NULL,
configMAX_PRIORITIES - 1,
&xTaskTimeSupervisor );
/* Start the tasks and timer running. */ /* Start the tasks and timer running. */
// puts("Start scheduler"); // puts("Start scheduler");
@ -276,7 +318,7 @@ void main_waters( void )
// Chain2: 31 -> 78 -> 400 // Chain2: 31 -> 78 -> 400
static void prvTask31( void * pvParameters ) { static void prvTask31( void * pvParameters ) {
TickType_t xLastWakeTime = xTaskGetTickCount(); TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 100 / portTICK_PERIOD_MS; const TickType_t xFrequency = 100 / portTICK_PERIOD_MS;
int period_counter = 2; int period_counter = 2;
for( ;; ){ for( ;; ){
@ -284,10 +326,11 @@ static void prvTask31( void * pvParameters ) {
// Actions -------------------------------------- // Actions --------------------------------------
// Exectime: f(x) = x // Exectime: f(x) = x
// Output: g(x) = x % 2 // Output: g(x) = x % 2
volatile uint16_t x = fuzz_short_next(); volatile uint16_t x = fuzz_short_next(0);
DEBUG_WCET(x=48940;) DEBUG_WCET(x=48940;)
WCET_CLAMP(x, 0, 48940, TASK_31_MESSAGE) WCET_CLAMP(x, 0, 48940, TASK_31_MESSAGE)
WCET_END({trigger_Qemu_break();}) trigger_job_done();
// WCET_END({trigger_Qemu_break();})
xTaskNotify(xTask78, DEBUG_VAL(x % 2, 1), eSetValueWithOverwrite); xTaskNotify(xTask78, DEBUG_VAL(x % 2, 1), eSetValueWithOverwrite);
// --------------------------------------------- // ---------------------------------------------
xTaskDelayUntil( &xLastWakeTime, xFrequency );}// Wait for the next cycle. xTaskDelayUntil( &xLastWakeTime, xFrequency );}// Wait for the next cycle.
@ -295,13 +338,13 @@ static void prvTask31( void * pvParameters ) {
// Chain2: 31 -> 78 -> 400 // Chain2: 31 -> 78 -> 400
static void prvTask78( void * pvParameters ) { static void prvTask78( void * pvParameters ) {
TickType_t xLastWakeTime = xTaskGetTickCount(); TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; const TickType_t xFrequency = 10 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
// Actions -------------------------------------- // Actions --------------------------------------
// Exectime: f(x,y) = c + y*20000 + rng(x)*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)
uint16_t x = fuzz_short_next(); uint16_t x = fuzz_short_next(1);
int y = ulTaskNotifyTake(pdTRUE, 0); int y = ulTaskNotifyTake(pdTRUE, 0);
volatile int torun = 6035; volatile int torun = 6035;
if (y > 0) { if (y > 0) {
@ -313,17 +356,18 @@ static void prvTask78( void * pvParameters ) {
WCET_CLAMP(torun, 0, 76035, TASK_78_MESSAGE) WCET_CLAMP(torun, 0, 76035, TASK_78_MESSAGE)
xTaskNotify(xTask400, DEBUG_VAL(y * (x % 4), 2), eSetValueWithOverwrite); xTaskNotify(xTask400, DEBUG_VAL(y * (x % 4), 2), eSetValueWithOverwrite);
// --------------------------------------------- // ---------------------------------------------
trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );} xTaskDelayUntil( &xLastWakeTime, xFrequency );}
} }
// Chain2: 31 -> 78 -> 400 // Chain2: 31 -> 78 -> 400
static void prvTask400( void * pvParameters ) { static void prvTask400( void * pvParameters ) {
TickType_t xLastWakeTime = xTaskGetTickCount(); TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 2 / portTICK_PERIOD_MS; const TickType_t xFrequency = 2 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
// 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)
uint32_t x = fuzz_long_next(); uint32_t x = fuzz_long_next(2);
int y = ulTaskNotifyTake(pdTRUE, 0); int y = ulTaskNotifyTake(pdTRUE, 0);
volatile int torun = 0; volatile int torun = 0;
if (y == 2 && DEBUG_VAL(CHANCE_1_IN_POWOF2(x, 2), 1)) { if (y == 2 && DEBUG_VAL(CHANCE_1_IN_POWOF2(x, 2), 1)) {
@ -334,6 +378,7 @@ static void prvTask400( void * pvParameters ) {
} }
WCET_CLAMP(torun, 0, 1765, TASK_400_MESSAGE) WCET_CLAMP(torun, 0, 1765, TASK_400_MESSAGE)
// --------------------------------------------- // ---------------------------------------------
trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );} xTaskDelayUntil( &xLastWakeTime, xFrequency );}
} }
@ -341,17 +386,19 @@ static void prvTask400( void * pvParameters ) {
// Chain3: 397 -> 90 -> 1107 // Chain3: 397 -> 90 -> 1107
static void prvTask397( void * pvParameters ) { static void prvTask397( void * pvParameters ) {
TickType_t xLastWakeTime = xTaskGetTickCount(); TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 1 / portTICK_PERIOD_MS; const TickType_t xFrequency = 1 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
// Exectime: f(x) = x // Exectime: f(x) = 20*x
// Output: g(x) = x % 2 // Output: g(x) = x % 2
volatile uint16_t x = fuzz_short_next(); volatile uint16_t x = fuzz_char_next(3);
x *= 32;
DEBUG_WCET(x=5830;) DEBUG_WCET(x=5830;)
WCET_CLAMP(x, 0, 5830, TASK_397_MESSAGE); WCET_CLAMP(x, 0, 5830, TASK_397_MESSAGE);
xTaskNotify(xTask90, DEBUG_VAL(x & 0x1, 0), eSetValueWithOverwrite); 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();
#ifdef INTERRUPT_ACTIVATION #ifdef INTERRUPT_ACTIVATION
ulTaskNotifyTake(pdTRUE,portMAX_DELAY); ulTaskNotifyTake(pdTRUE,portMAX_DELAY);
#else #else
@ -365,14 +412,15 @@ static void prvTask397( void * pvParameters ) {
// Chain3: 397 -> 90 -> 1107 // Chain3: 397 -> 90 -> 1107
static void prvTask90( void * pvParameters ) { static void prvTask90( void * pvParameters ) {
TickType_t xLastWakeTime = xTaskGetTickCount(); TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 2 / portTICK_PERIOD_MS; const TickType_t xFrequency = 2 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
// Actions -------------------------------------- // Actions --------------------------------------
// Exectime: f(x) = c + x // Exectime: f(x) = c + 100*x
// Output: g(x) = x % 4 // Output: g(x) = x % 4
int y = ulTaskNotifyTake(pdTRUE, 0); int y = ulTaskNotifyTake(pdTRUE, 0);
volatile uint16_t x = fuzz_short_next(); volatile uint16_t x = fuzz_char_next(4);
x *= 100;
DEBUG_WCET(x=20048;) DEBUG_WCET(x=20048;)
int torun = 0; int torun = 0;
if (y) { if (y) {
@ -381,24 +429,26 @@ static void prvTask90( void * pvParameters ) {
torun = CLAMP(x, 0, 20045); torun = CLAMP(x, 0, 20045);
} }
WCET_CLAMP(torun, 0, 20045, TASK_90_MESSAGE) WCET_CLAMP(torun, 0, 20045, TASK_90_MESSAGE)
xTaskNotify(xTask1107, DEBUG_VAL(x % 4, 0), eSetValueWithOverwrite); xTaskNotify(xTask1107, DEBUG_VAL((x/100) % 4, 0), eSetValueWithOverwrite);
// --------------------------------------------- // ---------------------------------------------
trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );} xTaskDelayUntil( &xLastWakeTime, xFrequency );}
} }
// Chain3: 397 -> 90 -> 1107 // Chain3: 397 -> 90 -> 1107
static void prvTask1107( void * pvParameters ) { static void prvTask1107( void * pvParameters ) {
TickType_t xLastWakeTime = xTaskGetTickCount(); TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 50 / portTICK_PERIOD_MS; const TickType_t xFrequency = 50 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
// Actions -------------------------------------- // Actions --------------------------------------
// Exectime: f(x) = c - x*y // Exectime: f(x) = c - x*y
volatile uint16_t x = fuzz_short_next(); volatile uint16_t x = fuzz_short_next(5);
DEBUG_WCET(x=0;) DEBUG_WCET(x=0;)
int y = ulTaskNotifyTake(pdTRUE, 0); int y = ulTaskNotifyTake(pdTRUE, 0);
int torun = 76865-((int)x)*y; int torun = 76865-((int)x)*y;
WCET_CLAMP(torun, 10000, 76865, TASK_1107_MESSAGE) WCET_CLAMP(torun, 10000, 76865, TASK_1107_MESSAGE)
// --------------------------------------------- // ---------------------------------------------
trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );} xTaskDelayUntil( &xLastWakeTime, xFrequency );}
} }
@ -407,31 +457,32 @@ static void prvTask1107( void * pvParameters ) {
// Chain1: 579 -> 1009 -> 1129 -> 416 // Chain1: 579 -> 1009 -> 1129 -> 416
static void prvTask579( void * pvParameters ) { static void prvTask579( void * pvParameters ) {
// int period = 5; // int period = 5;
TickType_t xLastWakeTime = xTaskGetTickCount(); TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; const TickType_t xFrequency = 10 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
// 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
uint32_t x = fuzz_long_next(); uint32_t x = fuzz_long_next(6);
volatile int torun = (x>>8) & 0x0fff; volatile int torun = (x>>8) & 0x0fff;
DEBUG_WCET(torun = 0x0fff;) DEBUG_WCET(torun = 0x0fff;)
WCET_CLAMP(torun, 500, 2460, TASK_579_MESSAGE) WCET_CLAMP(torun, 500, 2460, TASK_579_MESSAGE)
xTaskNotify(xTask1009, DEBUG_VAL(x % 8, 0), eSetValueWithOverwrite); xTaskNotify(xTask1009, DEBUG_VAL(x % 8, 0), eSetValueWithOverwrite);
// --------------------------------------------- // ---------------------------------------------
trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );} xTaskDelayUntil( &xLastWakeTime, xFrequency );}
} }
// Chain1: 579 -> 1009 -> 1129 -> 416 // Chain1: 579 -> 1009 -> 1129 -> 416
static void prvTask1009( void * pvParameters ) { static void prvTask1009( void * pvParameters ) {
TickType_t xLastWakeTime = xTaskGetTickCount(); TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; const TickType_t xFrequency = 10 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
// 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
uint16_t x = fuzz_short_next(); uint16_t x = fuzz_short_next(7);
int y = ulTaskNotifyTake(pdTRUE, 0); int y = ulTaskNotifyTake(pdTRUE, 0);
volatile int torun = 0; volatile int torun = 0;
if (x % 8 == y) { if (x % 8 == y) {
@ -443,13 +494,14 @@ static void prvTask1009( void * pvParameters ) {
WCET_CLAMP(torun, 0, 51485, TASK_1009_MESSAGE) WCET_CLAMP(torun, 0, 51485, TASK_1009_MESSAGE)
xTaskNotify(xTask1129, DEBUG_VAL(x % 8 == y, 1), eSetValueWithOverwrite); xTaskNotify(xTask1129, DEBUG_VAL(x % 8 == y, 1), eSetValueWithOverwrite);
// --------------------------------------------- // ---------------------------------------------
trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );} xTaskDelayUntil( &xLastWakeTime, xFrequency );}
} }
// Chain1: 579 -> 1009 -> 1129 -> 416 // Chain1: 579 -> 1009 -> 1129 -> 416
static void prvTask1129( void * pvParameters ) { static void prvTask1129( void * pvParameters ) {
int period_counter = 2; int period_counter = 2;
TickType_t xLastWakeTime = xTaskGetTickCount(); TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; const TickType_t xFrequency = 10 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
// if (--period_counter==0) {puts("End");} // if (--period_counter==0) {puts("End");}
@ -458,7 +510,7 @@ static void prvTask1129( void * pvParameters ) {
// 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
volatile uint32_t x = (uint32_t)fuzz_short_next(); volatile uint32_t x = (uint32_t)fuzz_short_next(8);
int y = ulTaskNotifyTake(pdTRUE, 0); int y = ulTaskNotifyTake(pdTRUE, 0);
DEBUG_WCET( DEBUG_WCET(
static char flag=0; static char flag=0;
@ -475,18 +527,19 @@ static void prvTask1129( void * pvParameters ) {
WCET_CLAMP(torun, 0, 145040, TASK_1129_MESSAGE) WCET_CLAMP(torun, 0, 145040, TASK_1129_MESSAGE)
xTaskNotify(xTask416, do_short_run, eSetValueWithOverwrite); xTaskNotify(xTask416, do_short_run, eSetValueWithOverwrite);
// --------------------------------------------- // ---------------------------------------------
trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );} xTaskDelayUntil( &xLastWakeTime, xFrequency );}
} }
// Chain1: 579 -> 1009 -> 1129 -> 416 // Chain1: 579 -> 1009 -> 1129 -> 416
static void prvTask416( void * pvParameters ) { static void prvTask416( void * pvParameters ) {
TickType_t xLastWakeTime = xTaskGetTickCount(); TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; const TickType_t xFrequency = 10 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
// 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 = (uint32_t)fuzz_short_next(); volatile uint32_t x = (uint32_t)fuzz_short_next(9);
int y = ulTaskNotifyTake(pdTRUE, 0); int y = ulTaskNotifyTake(pdTRUE, 0);
volatile int torun = 0; volatile int torun = 0;
if (y) { if (y) {
@ -498,6 +551,7 @@ static void prvTask416( void * pvParameters ) {
} }
WCET_CLAMP(torun, 10000, 126955, TASK_416_MESSAGE) WCET_CLAMP(torun, 10000, 126955, TASK_416_MESSAGE)
// --------------------------------------------- // ---------------------------------------------
trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );} xTaskDelayUntil( &xLastWakeTime, xFrequency );}
} }
@ -507,7 +561,7 @@ void vWatersIdleFunction() {
} }
} }
void isr_starter( void ) void ISR_0_Handler( void )
{ {
puts("Interrupt"); puts("Interrupt");
if (xTask397) { if (xTask397) {

View File

@ -43,7 +43,7 @@ If they disagree ReplicateC will be started by mutex.
If all the Replicates disagree now the sampler will be engaged once more If all the Replicates disagree now the sampler will be engaged once more
*/ */
#define GLOBAL_WCET_MULT 25 // Multiplier to increase all waiting periods to make the schedule more tight an force preemptions #define GLOBAL_WCET_MULT 15 // Multiplier to increase all waiting periods to make the schedule more tight an force preemptions
#include "arbitrary_loads.c" #include "arbitrary_loads.c"
__attribute__((noinline)) static void trigger_Qemu_break( void ) __attribute__((noinline)) static void trigger_Qemu_break( void )
@ -52,6 +52,12 @@ __attribute__((noinline)) static void trigger_Qemu_break( void )
while (1) { 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 // if this macro is set, the code will be modified to produce the worst case
// #define DEBUG_WCET(A) {A} // #define DEBUG_WCET(A) {A}
@ -72,35 +78,48 @@ __attribute__((noinline)) static void trigger_Qemu_break( void )
// #define INTERRUPT_ACTIVATION 1 // #define INTERRUPT_ACTIVATION 1
// Begin Input Stuff // Begin Input Stuff
volatile unsigned char FUZZ_INPUT[4096] = {0xa,0xb,0xc,0xd,0xe,0xf}; #define PARTITION_INPUT
volatile uint32_t FUZZ_LENGTH = 4096; #define NUM_TASKS 10
volatile uint32_t FUZZ_POINTER = 0; #define MAX_INPUT_BYTES 4096
volatile unsigned char FUZZ_INPUT[MAX_INPUT_BYTES] = {};
volatile int INPUT_POINTERS[NUM_TASKS] = {};
volatile uint32_t FUZZ_LENGTH = MAX_INPUT_BYTES;// ignored
// Read the Byte of Input, if the Input is exausted trigger the breakpoint instead // Read the Byte of Input, if the Input is exausted trigger the breakpoint instead
static unsigned char fuzz_char_next(void) { 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
// printf("Get next Input from %lx \n",FUZZ_INPUT); // printf("Get next Input from %lx \n",FUZZ_INPUT);
if (FUZZ_POINTER < FUZZ_LENGTH) { if (INPUT_POINTERS[0] < FUZZ_LENGTH) {
FUZZ_POINTER++; INPUT_POINTERS[0]++;
// printf("Input no. %d %x\n",FUZZ_POINTER-1,FUZZ_INPUT[FUZZ_POINTER-1]); // printf("Input no. %d %x\n",FUZZ_POINTER-1,FUZZ_INPUT[FUZZ_POINTER-1]);
return FUZZ_INPUT[FUZZ_POINTER-1]; return FUZZ_INPUT[INPUT_POINTERS[0]-1];
} else { } else {
// puts("End of Input"); // puts("End of Input");
// Exausted inputs early // Exausted inputs early
trigger_Qemu_break(); trigger_Qemu_break();
} }
#endif
} }
static uint16_t fuzz_short_next(void) { static uint16_t fuzz_short_next(int tasknum) {
unsigned char field[2]; unsigned char field[2];
field[0]=fuzz_char_next(); field[0]=fuzz_char_next(tasknum);
field[1]=fuzz_char_next(); field[1]=fuzz_char_next(tasknum);
uint16_t* sf = (uint16_t*) field; uint16_t* sf = (uint16_t*) field;
return *sf; return *sf;
} }
static uint32_t fuzz_long_next(void) { static uint32_t fuzz_long_next(int tasknum) {
unsigned char field[4]; unsigned char field[4];
field[0]=fuzz_char_next(); field[0]=fuzz_char_next(tasknum);
field[1]=fuzz_char_next(); field[1]=fuzz_char_next(tasknum);
field[2]=fuzz_char_next(); field[2]=fuzz_char_next(tasknum);
field[3]=fuzz_char_next(); field[3]=fuzz_char_next(tasknum);
uint32_t* sf = (uint32_t*) field; uint32_t* sf = (uint32_t*) field;
return *sf; return *sf;
} }
@ -187,6 +206,22 @@ static TaskHandle_t xTask1129 = NULL;
static SemaphoreHandle_t xSemaphoreSpor; static SemaphoreHandle_t xSemaphoreSpor;
static TickType_t initial_release_time = 0;
#define HYPER_PERIOD 50
#define SIMULATE_PERIODS 2
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( ;; ){}
}
void main_waters( void ) void main_waters( void )
{ {
xSemaphoreSpor = xSemaphoreCreateBinary(); xSemaphoreSpor = xSemaphoreCreateBinary();
@ -265,6 +300,14 @@ void main_waters( void )
mainTASK_1129_PRIO, mainTASK_1129_PRIO,
&xTask1129 ); &xTask1129 );
xTaskCreate( timing_supervisor_task,
"supervisor",
configMINIMAL_STACK_SIZE,
NULL,
configMAX_PRIORITIES - 1,
&xTaskTimeSupervisor );
/* Start the tasks and timer running. */ /* Start the tasks and timer running. */
// puts("Start scheduler"); // puts("Start scheduler");
@ -283,7 +326,7 @@ void main_waters( void )
// Chain2: 31 -> 78 -> 400 // Chain2: 31 -> 78 -> 400
static void prvTask31( void * pvParameters ) { static void prvTask31( void * pvParameters ) {
TickType_t xLastWakeTime = xTaskGetTickCount(); TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 100 / portTICK_PERIOD_MS; const TickType_t xFrequency = 100 / portTICK_PERIOD_MS;
// int period_counter = 2; // int period_counter = 2;
for( ;; ){ for( ;; ){
@ -291,10 +334,12 @@ static void prvTask31( void * pvParameters ) {
// Actions -------------------------------------- // Actions --------------------------------------
// Exectime: f(x) = x // Exectime: f(x) = x
// Output: g(x) = x % 2 // Output: g(x) = x % 2
volatile uint16_t x = fuzz_short_next(); volatile uint16_t x = fuzz_short_next(0);
DEBUG_WCET(x=48940;) DEBUG_WCET(x=48940;)
WCET_CLAMP(x, 0, 48940, TASK_31_MESSAGE) WCET_CLAMP(x, 0, 48940, TASK_31_MESSAGE)
WCET_END({trigger_Qemu_break();}) trigger_job_done();
// trigger_Qemu_break();
// WCET_END({trigger_Qemu_break();})
xTaskNotify(xTask78, DEBUG_VAL(1 + x % 2, 1+1), eSetValueWithOverwrite); xTaskNotify(xTask78, DEBUG_VAL(1 + x % 2, 1+1), eSetValueWithOverwrite);
// --------------------------------------------- // ---------------------------------------------
xTaskDelayUntil( &xLastWakeTime, xFrequency );}// Wait for the next cycle. xTaskDelayUntil( &xLastWakeTime, xFrequency );}// Wait for the next cycle.
@ -302,13 +347,13 @@ static void prvTask31( void * pvParameters ) {
// Chain2: 31 -> 78 -> 400 // Chain2: 31 -> 78 -> 400
static void prvTask78( void * pvParameters ) { static void prvTask78( void * pvParameters ) {
TickType_t xLastWakeTime = xTaskGetTickCount(); TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; const TickType_t xFrequency = 10 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
// Actions -------------------------------------- // Actions --------------------------------------
// Exectime: f(x,y) = c + y*20000 + rng(x)*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)
uint16_t x = fuzz_short_next(); uint16_t x = fuzz_short_next(1);
int y = ulTaskNotifyTake(pdTRUE, 0); int y = ulTaskNotifyTake(pdTRUE, 0);
volatile int torun = 6035; volatile int torun = 6035;
if (y > 1) { if (y > 1) {
@ -322,17 +367,18 @@ static void prvTask78( void * pvParameters ) {
xTaskNotify(xTask400, DEBUG_VAL(1 + y * (x % 4), 1+2), eSetValueWithOverwrite); xTaskNotify(xTask400, DEBUG_VAL(1 + y * (x % 4), 1+2), eSetValueWithOverwrite);
} }
// --------------------------------------------- // ---------------------------------------------
trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );} xTaskDelayUntil( &xLastWakeTime, xFrequency );}
} }
// Chain2: 31 -> 78 -> 400 // Chain2: 31 -> 78 -> 400
static void prvTask400( void * pvParameters ) { static void prvTask400( void * pvParameters ) {
TickType_t xLastWakeTime = xTaskGetTickCount(); TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 2 / portTICK_PERIOD_MS; const TickType_t xFrequency = 2 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
// 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)
uint32_t x = fuzz_long_next(); uint32_t x = fuzz_char_next(2);
int y = ulTaskNotifyTake(pdTRUE, 0); int y = ulTaskNotifyTake(pdTRUE, 0);
volatile int torun = 0; volatile int torun = 0;
if (y == 3 && DEBUG_VAL(CHANCE_1_IN_POWOF2(x, 2), 1)) { if (y == 3 && DEBUG_VAL(CHANCE_1_IN_POWOF2(x, 2), 1)) {
@ -342,10 +388,11 @@ static void prvTask400( void * pvParameters ) {
DEBUG_WCET(torun=999;) DEBUG_WCET(torun=999;)
} }
WCET_CLAMP(torun, 0, 1765, TASK_400_MESSAGE) WCET_CLAMP(torun, 0, 1765, TASK_400_MESSAGE)
if (y) { // if (y) {
WCET_END({trigger_Qemu_break();}) // WCET_END({trigger_Qemu_break();})
} // }
// --------------------------------------------- // ---------------------------------------------
trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );} xTaskDelayUntil( &xLastWakeTime, xFrequency );}
} }
@ -353,11 +400,13 @@ static void prvTask400( void * pvParameters ) {
// Chain3: 397 -> 90 -> 1107 // Chain3: 397 -> 90 -> 1107
static void prvTask397( void * pvParameters ) { static void prvTask397( void * pvParameters ) {
TickType_t xLastWakeTime = xTaskGetTickCount(); // initial_release_time = xTaskGetTickCount(); // The highest priority task sets the initial 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( ;; ){
// 3 different activation strategies ------------- // 3 different activation strategies -------------
// activate sporadically from interrupts // activate sporadically from interrupts
trigger_job_done();
#ifdef INTERRUPT_ACTIVATION #ifdef INTERRUPT_ACTIVATION
ulTaskNotifyTake(pdTRUE,portMAX_DELAY); ulTaskNotifyTake(pdTRUE,portMAX_DELAY);
#else #else
@ -369,7 +418,8 @@ static void prvTask397( void * pvParameters ) {
// ----------------------------------------------- // -----------------------------------------------
// Exectime: f(x) = x // Exectime: f(x) = x
// Output: g(x) = x % 2 // Output: g(x) = x % 2
volatile uint16_t x = fuzz_short_next(); volatile uint16_t x = fuzz_char_next(3);
x *= 20;
DEBUG_WCET(x=5830;) DEBUG_WCET(x=5830;)
WCET_CLAMP(x, 0, 5830, TASK_397_MESSAGE); WCET_CLAMP(x, 0, 5830, TASK_397_MESSAGE);
if (CHANCE_1_IN_POWOF2(x, 2)) { if (CHANCE_1_IN_POWOF2(x, 2)) {
@ -378,21 +428,22 @@ static void prvTask397( void * pvParameters ) {
xSemaphoreGive(xSemaphoreSpor); xSemaphoreGive(xSemaphoreSpor);
} }
} else { } else {
xTaskNotify(xTask90, DEBUG_VAL(1 + x & 0x1, 1), eSetValueWithOverwrite); xTaskNotify(xTask90, DEBUG_VAL(1 + (x/20) & 0x1, 1), eSetValueWithOverwrite);
} }
} }
} }
// Chain3: 397 -> 90 -> 1107 // Chain3: 397 -> 90 -> 1107
static void prvTask90( void * pvParameters ) { static void prvTask90( void * pvParameters ) {
TickType_t xLastWakeTime = xTaskGetTickCount(); TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 2 / portTICK_PERIOD_MS; const TickType_t xFrequency = 2 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
// Actions -------------------------------------- // Actions --------------------------------------
// Exectime: f(x) = c + x // Exectime: f(x) = c + x
// Output: g(x) = x % 4 // Output: g(x) = x % 4
int y = ulTaskNotifyTake(pdTRUE, 0); int y = ulTaskNotifyTake(pdTRUE, 0);
volatile uint16_t x = fuzz_short_next(); volatile uint16_t x = fuzz_char_next(4);
x *= 100;
DEBUG_WCET(x=20048;) DEBUG_WCET(x=20048;)
int torun = 0; int torun = 0;
if (y == 2) { if (y == 2) {
@ -402,25 +453,27 @@ static void prvTask90( void * pvParameters ) {
} }
WCET_CLAMP(torun, 0, 20045, TASK_90_MESSAGE) WCET_CLAMP(torun, 0, 20045, TASK_90_MESSAGE)
if (y) { if (y) {
xTaskNotify(xTask1107, DEBUG_VAL(x % 4, 0), eSetValueWithOverwrite); xTaskNotify(xTask1107, DEBUG_VAL((x/100) % 4, 0), eSetValueWithOverwrite);
} }
// --------------------------------------------- // ---------------------------------------------
trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );} xTaskDelayUntil( &xLastWakeTime, xFrequency );}
} }
// Chain3: 397 -> 90 -> 1107 // Chain3: 397 -> 90 -> 1107
static void prvTask1107( void * pvParameters ) { static void prvTask1107( void * pvParameters ) {
TickType_t xLastWakeTime = xTaskGetTickCount(); TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 50 / portTICK_PERIOD_MS; const TickType_t xFrequency = 50 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
// Actions -------------------------------------- // Actions --------------------------------------
// Exectime: f(x) = c - x*y // Exectime: f(x) = c - x*y
volatile uint16_t x = fuzz_short_next(); volatile uint16_t x = fuzz_short_next(5);
DEBUG_WCET(x=0;) DEBUG_WCET(x=0;)
int y = ulTaskNotifyTake(pdTRUE, 0); int y = ulTaskNotifyTake(pdTRUE, 0);
int torun = 76865-((int)x)*y; int torun = 76865-((int)x)*y;
WCET_CLAMP(torun, 10000, 76865, TASK_1107_MESSAGE) WCET_CLAMP(torun, 10000, 76865, TASK_1107_MESSAGE)
// --------------------------------------------- // ---------------------------------------------
trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );} xTaskDelayUntil( &xLastWakeTime, xFrequency );}
} }
@ -430,7 +483,7 @@ static int sem_at_579 = 0;
// Chain1: 579 -> 1009 -> 1129 -> 416 // Chain1: 579 -> 1009 -> 1129 -> 416
static void prvTask579( void * pvParameters ) { static void prvTask579( void * pvParameters ) {
// int period = 5; // int period = 5;
TickType_t xLastWakeTime = xTaskGetTickCount(); TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; const TickType_t xFrequency = 10 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
// if (--period==0) {puts("End");} // Debugging Marker // if (--period==0) {puts("End");} // Debugging Marker
@ -441,7 +494,7 @@ static void prvTask579( void * pvParameters ) {
if (y && !sem_at_579) { if (y && !sem_at_579) {
sem_at_579 = xSemaphoreTake(xSemaphoreSpor, portMAX_DELAY); sem_at_579 = xSemaphoreTake(xSemaphoreSpor, portMAX_DELAY);
} }
uint32_t x = fuzz_long_next(); uint32_t x = fuzz_long_next(6);
volatile int torun = (x>>8) & 0x0fff; volatile int torun = (x>>8) & 0x0fff;
DEBUG_WCET(torun = 0x0fff;) DEBUG_WCET(torun = 0x0fff;)
WCET_CLAMP(torun, 500, 2460, TASK_579_MESSAGE) WCET_CLAMP(torun, 500, 2460, TASK_579_MESSAGE)
@ -455,18 +508,19 @@ static void prvTask579( void * pvParameters ) {
} }
} }
// --------------------------------------------- // ---------------------------------------------
trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );} xTaskDelayUntil( &xLastWakeTime, xFrequency );}
} }
// Chain1: 579 -> 1009 -> 1129 -> 416 // Chain1: 579 -> 1009 -> 1129 -> 416
static void prvTask1009( void * pvParameters ) { static void prvTask1009( void * pvParameters ) {
TickType_t xLastWakeTime = xTaskGetTickCount(); TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; const TickType_t xFrequency = 10 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
// 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
uint16_t x = fuzz_short_next(); uint16_t x = fuzz_short_next(7);
int y = ulTaskNotifyTake(pdTRUE, 0); int y = ulTaskNotifyTake(pdTRUE, 0);
volatile int torun = 0; volatile int torun = 0;
if (x % 8 == (y-1)) { if (x % 8 == (y-1)) {
@ -480,13 +534,14 @@ static void prvTask1009( void * pvParameters ) {
xTaskNotify(xTask1129, DEBUG_VAL(1 + x % 8 == y, 2), eSetValueWithOverwrite); xTaskNotify(xTask1129, DEBUG_VAL(1 + x % 8 == y, 2), eSetValueWithOverwrite);
} }
// --------------------------------------------- // ---------------------------------------------
trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );} xTaskDelayUntil( &xLastWakeTime, xFrequency );}
} }
// Chain1: 579 -> 1009 -> 1129 -> 416 // Chain1: 579 -> 1009 -> 1129 -> 416
static void prvTask1129( void * pvParameters ) { static void prvTask1129( void * pvParameters ) {
int period_counter = 2; int period_counter = 2;
TickType_t xLastWakeTime = xTaskGetTickCount(); TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; const TickType_t xFrequency = 10 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
// if (--period_counter==0) {puts("End");} // if (--period_counter==0) {puts("End");}
@ -495,7 +550,7 @@ static void prvTask1129( void * pvParameters ) {
// 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
volatile uint32_t x = (uint32_t)fuzz_short_next(); volatile uint32_t x = (uint32_t)fuzz_short_next(8);
int y = ulTaskNotifyTake(pdTRUE, 0); int y = ulTaskNotifyTake(pdTRUE, 0);
DEBUG_WCET( DEBUG_WCET(
static char flag=0; static char flag=0;
@ -514,18 +569,19 @@ static void prvTask1129( void * pvParameters ) {
xTaskNotify(xTask416, do_short_run, eSetValueWithOverwrite); xTaskNotify(xTask416, do_short_run, eSetValueWithOverwrite);
} }
// --------------------------------------------- // ---------------------------------------------
trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );} xTaskDelayUntil( &xLastWakeTime, xFrequency );}
} }
// Chain1: 579 -> 1009 -> 1129 -> 416 // Chain1: 579 -> 1009 -> 1129 -> 416
static void prvTask416( void * pvParameters ) { static void prvTask416( void * pvParameters ) {
TickType_t xLastWakeTime = xTaskGetTickCount(); TickType_t xLastWakeTime = initial_release_time;
const TickType_t xFrequency = 10 / portTICK_PERIOD_MS; const TickType_t xFrequency = 10 / portTICK_PERIOD_MS;
for( ;; ){ for( ;; ){
// 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 = (uint32_t)fuzz_short_next(); volatile uint32_t x = (uint32_t)fuzz_short_next(9);
int y = ulTaskNotifyTake(pdTRUE, 0); int y = ulTaskNotifyTake(pdTRUE, 0);
volatile int torun = 0; volatile int torun = 0;
if (y-1) { if (y-1) {
@ -540,6 +596,7 @@ static void prvTask416( void * pvParameters ) {
xTaskNotifyIndexed(xTask579, 1, 1337, eSetValueWithOverwrite); xTaskNotifyIndexed(xTask579, 1, 1337, eSetValueWithOverwrite);
} }
// --------------------------------------------- // ---------------------------------------------
trigger_job_done();
xTaskDelayUntil( &xLastWakeTime, xFrequency );} xTaskDelayUntil( &xLastWakeTime, xFrequency );}
} }

View File

@ -51,7 +51,17 @@ SECTIONS
__APP_CODE_START__ = .; __APP_CODE_START__ = .;
*main_*.o(.text*) *main_*.o(.text*)
__APP_CODE_END__ = .; __APP_CODE_END__ = .;
*(EXCLUDE_FILE (*main_*.o) .text*) __API_CODE_START__ = .;
*startup.o(.text*)
*port.o(.text*)
*tasks.o(.text*)
*list.o(.text*)
*queue.o(.text*)
*timers.o(.text*)
*event_groups.o(.text*)
*heap_3.o(.text*)
__API_CODE_END__ = .;
*(EXCLUDE_FILE (*main_*.o *startup.o *port.o *tasks.o *list.o *queue.o *timers.o *event_groups.o *heap_3.o) .text*)
KEEP (*(.init)) KEEP (*(.init))
KEEP (*(.fini)) KEEP (*(.fini))
KEEP(*(.eh_frame)) KEEP(*(.eh_frame))