Commit 43ecb12e authored by Maxime Perrotin's avatar Maxime Perrotin

Make timer resolution user-defined

parent 63b0d5c3
...@@ -2,7 +2,7 @@ buildsupport is a low-level TASTE command, responsible for the generation of ske ...@@ -2,7 +2,7 @@ buildsupport is a low-level TASTE command, responsible for the generation of ske
License: LGPL (see LICENSE file) License: LGPL (see LICENSE file)
Copyright (c) 2008-2015 European Space Agency Copyright (c) 2008-2016 European Space Agency
...@@ -66,6 +66,7 @@ procedure BuildSupport is ...@@ -66,6 +66,7 @@ procedure BuildSupport is
Success : Boolean; Success : Boolean;
OutDir : Integer := 0; OutDir : Integer := 0;
Stack_Val : Integer := 0; Stack_Val : Integer := 0;
Timer_Resolution : Integer := 0;
Subs : Node_id; Subs : Node_id;
Interface_view : Integer := 0; Interface_view : Integer := 0;
Concurrency_view : Integer := 0; Concurrency_view : Integer := 0;
...@@ -168,6 +169,13 @@ procedure BuildSupport is ...@@ -168,6 +169,13 @@ procedure BuildSupport is
Ada.Command_Line.Argument (stack_val)'Length); Ada.Command_Line.Argument (stack_val)'Length);
end if; end if;
-- Set the timer resolution value
if Timer_Resolution > 0 then
Imported_Routines.C_Set_Timer_Resolution
(Ada.Command_Line.Argument (Timer_Resolution),
Ada.Command_Line.Argument (Timer_Resolution)'Length);
end if;
-- Current_function is read from the list of system subcomponents -- Current_function is read from the list of system subcomponents
Current_function := First_Node (Subcomponents (My_System)); Current_function := First_Node (Subcomponents (My_System));
...@@ -1334,6 +1342,7 @@ procedure BuildSupport is ...@@ -1334,6 +1342,7 @@ procedure BuildSupport is
Previous_CView : Boolean := False; Previous_CView : Boolean := False;
Previous_DataView : Boolean := False; Previous_DataView : Boolean := False;
Previous_Stack : Boolean := False; Previous_Stack : Boolean := False;
Previous_TimerRes : Boolean := False;
begin begin
for J in 1 .. Ada.Command_Line.Argument_Count loop for J in 1 .. Ada.Command_Line.Argument_Count loop
-- Parse the file corresponding to the Jth argument of the -- Parse the file corresponding to the Jth argument of the
...@@ -1359,6 +1368,10 @@ procedure BuildSupport is ...@@ -1359,6 +1368,10 @@ procedure BuildSupport is
Stack_Val := J; Stack_Val := J;
Previous_Stack := false; Previous_Stack := false;
elsif Previous_TimerRes then
Timer_Resolution := J;
Previous_TimerRes := false;
elsif Ada.Command_Line.Argument (J) = "--polyorb-hi-c" elsif Ada.Command_Line.Argument (J) = "--polyorb-hi-c"
or else Ada.Command_Line.Argument (J) = "-p" or else Ada.Command_Line.Argument (J) = "-p"
or else Ada.Command_Line.Argument (J) = "-polyorb-hi-c" or else Ada.Command_Line.Argument (J) = "-polyorb-hi-c"
...@@ -1423,6 +1436,12 @@ procedure BuildSupport is ...@@ -1423,6 +1436,12 @@ procedure BuildSupport is
then then
Previous_Stack := True; Previous_Stack := True;
elsif Ada.Command_Line.Argument (J) = "--timer"
or else Ada.Command_Line.Argument (J) = "-timer"
or else Ada.Command_Line.Argument (J) = "-x"
then
Previous_TimerRes := True;
elsif Ada.Command_Line.Argument (J) = "--deploymentview" elsif Ada.Command_Line.Argument (J) = "--deploymentview"
or else Ada.Command_Line.Argument (J) = "-c" or else Ada.Command_Line.Argument (J) = "-c"
then then
......
...@@ -69,7 +69,9 @@ package body Buildsupport_Utils is ...@@ -69,7 +69,9 @@ package body Buildsupport_Utils is
Put ("-g, --debug" & HT & HT & HT & HT); Put ("-g, --debug" & HT & HT & HT & HT);
Put_Line ("Generate runtime debug output"); Put_Line ("Generate runtime debug output");
Put ("-s, --stack <stack-value>" & HT & HT); Put ("-s, --stack <stack-value>" & HT & HT);
Put_Line ("Set the size of the stack in kbytes (default 100)"); Put_Line ("Set the size of the stack per thread in kbytes (default 50)");
Put ("-x, --timer <timer-resolution in ms>" & HT);
Put_Line ("Set the timer resolution (default 100 ms)");
Put ("-v, --version" & HT & HT & HT & HT); Put ("-v, --version" & HT & HT & HT & HT);
Put_Line ("Display buildsupport version number"); Put_Line ("Display buildsupport version number");
Put ("-p, --polyorb-hi-c" & HT & HT & HT); Put ("-p, --polyorb-hi-c" & HT & HT & HT);
......
...@@ -8,6 +8,7 @@ package Imported_Routines is ...@@ -8,6 +8,7 @@ package Imported_Routines is
procedure C_Set_OutDir (Dir : String; Len : Integer); procedure C_Set_OutDir (Dir : String; Len : Integer);
procedure C_Set_Stack (Val : String; Len : Integer); procedure C_Set_Stack (Val : String; Len : Integer);
procedure C_Set_Timer_Resolution (Val : String; Len : Integer);
procedure C_New_APLC (Arg : String; Len : Integer); procedure C_New_APLC (Arg : String; Len : Integer);
procedure C_New_FV (Arg : String; Len : Integer; CS : String); procedure C_New_FV (Arg : String; Len : Integer; CS : String);
...@@ -211,6 +212,7 @@ private ...@@ -211,6 +212,7 @@ private
pragma Import (C, C_Set_Interfaceview, "Set_Interfaceview"); pragma Import (C, C_Set_Interfaceview, "Set_Interfaceview");
pragma Import (C, C_Set_Dataview, "Set_Dataview"); pragma Import (C, C_Set_Dataview, "Set_Dataview");
pragma Import (C, C_Set_Stack, "Set_Stack"); pragma Import (C, C_Set_Stack, "Set_Stack");
pragma Import (C, C_Set_Timer_Resolution, "Set_Timer_Resolution");
pragma Import (C, C_New_APLC, "New_APLC"); pragma Import (C, C_New_APLC, "New_APLC");
pragma Import (C, C_New_FV, "New_FV"); pragma Import (C, C_New_FV, "New_FV");
pragma Import (C, C_Add_PI, "Add_PI"); pragma Import (C, C_Add_PI, "Add_PI");
......
...@@ -445,6 +445,22 @@ void Set_Test() ...@@ -445,6 +445,22 @@ void Set_Test()
} }
} }
void Set_Timer_Resolution(char *val, size_t len) {
errno = 0;
if (NULL != (system_ast->context)) {
char *str = make_string("%.*s", len, val);
int time_res = (int) strtol(str, (char **)NULL, 10);
if (0 != errno) {
ERROR("** Error: Timer resolution must be a valid number\n");
}
else {
printf("[INFO] Set timer resolution to %d\n", time_res);
system_ast->context->timer_resolution = time_res;
}
}
}
/* Set Future - Flag that can be used for temporary purposes, /* Set Future - Flag that can be used for temporary purposes,
* like when migrating from one TASTE version to another one when all * like when migrating from one TASTE version to another one when all
* tools are not ready. * tools are not ready.
......
...@@ -887,6 +887,7 @@ void Create_Context(Context ** context) ...@@ -887,6 +887,7 @@ void Create_Context(Context ** context)
(*context)->polyorb_hi_c = 0; (*context)->polyorb_hi_c = 0;
(*context)->stacksize = NULL; (*context)->stacksize = NULL;
(*context)->needs_basictypes = false; (*context)->needs_basictypes = false;
(*context)->timer_resolution = 100; // milliseconds
} }
// Free the memory of a Context data structure // Free the memory of a Context data structure
......
...@@ -46,6 +46,7 @@ FV *Add_timer_manager(Process *node, FV_list *fv_with_timer) ...@@ -46,6 +46,7 @@ FV *Add_timer_manager(Process *node, FV_list *fv_with_timer)
char *name = NULL; char *name = NULL;
char *path = NULL; char *path = NULL;
FILE *hook = NULL; FILE *hook = NULL;
int timer_res = get_context()->timer_resolution;
name = make_string ("%s_timer_manager", node->name); name = make_string ("%s_timer_manager", node->name);
...@@ -57,17 +58,17 @@ FV *Add_timer_manager(Process *node, FV_list *fv_with_timer) ...@@ -57,17 +58,17 @@ FV *Add_timer_manager(Process *node, FV_list *fv_with_timer)
assert (NULL != fv && NULL != interface); assert (NULL != fv && NULL != interface);
interface->name = make_string ("tick_100ms"); interface->name = make_string ("tick_%dms", timer_res);
interface->distant_fv = NULL; interface->distant_fv = NULL;
interface->direction = PI; interface->direction = PI;
interface->synchronism = asynch; interface->synchronism = asynch;
interface->rcm = cyclic; interface->rcm = cyclic;
/* clock rate for timers is 100 ms */ /* clock rate for timers is 100 ms by default */
interface->period = 100; interface->period = timer_res;
interface->parent_fv = fv; interface->parent_fv = fv;
interface->wcet_high = 10; interface->wcet_high = 1;
interface->wcet_low = 10; interface->wcet_low = 1;
interface->wcet_low_unit = make_string ("ms"); interface->wcet_low_unit = make_string ("ms");
interface->wcet_high_unit = make_string ("ms"); interface->wcet_high_unit = make_string ("ms");
APPEND_TO_LIST (Interface, fv->interfaces, interface); APPEND_TO_LIST (Interface, fv->interfaces, interface);
...@@ -101,9 +102,10 @@ FV *Add_timer_manager(Process *node, FV_list *fv_with_timer) ...@@ -101,9 +102,10 @@ FV *Add_timer_manager(Process *node, FV_list *fv_with_timer)
fv->name); fv->name);
fprintf (header, "void %s_startup();\n\n" fprintf (header, "void %s_startup();\n\n"
"void %s_PI_tick_100ms();\n\n", "void %s_PI_tick_%dms();\n\n",
fv->name, fv->name,
fv->name); fv->name,
timer_res);
fprintf (code, "#include <assert.h>\n\n" fprintf (code, "#include <assert.h>\n\n"
"#include \"%s.h\"\n\n", fv->name); "#include \"%s.h\"\n\n", fv->name);
...@@ -145,8 +147,10 @@ FV *Add_timer_manager(Process *node, FV_list *fv_with_timer) ...@@ -145,8 +147,10 @@ FV *Add_timer_manager(Process *node, FV_list *fv_with_timer)
"}\n\n", fv->name); "}\n\n", fv->name);
/* Generate the timer manager code for the cyclic interface */ /* Generate the timer manager code for the cyclic interface */
fprintf (code, "void %s_PI_tick_100ms()\n" fprintf (code, "void %s_PI_tick_%dms()\n"
"{\n", fv->name); "{\n",
fv->name,
timer_res);
FOREACH (timer, String, all_timers, { FOREACH (timer, String, all_timers, {
fprintf (code, " if (timers[%s].state == active && " fprintf (code, " if (timers[%s].state == active && "
...@@ -175,12 +179,14 @@ void Add_timers_to_function (FV *fv, FV *timer_manager) ...@@ -175,12 +179,14 @@ void Add_timers_to_function (FV *fv, FV *timer_manager)
Interface *expire = NULL, *set_timer = NULL, *reset_timer = NULL; Interface *expire = NULL, *set_timer = NULL, *reset_timer = NULL;
Parameter *param = NULL; Parameter *param = NULL;
Interface *cyclic_pi = NULL; Interface *cyclic_pi = NULL;
int timer_res = get_context()->timer_resolution;
char *cyclic_name = make_string("tick_%dms", timer_res);
assert (NULL != header && NULL != code); assert (NULL != header && NULL != code);
/* Find the cyclic interface of the timer manager */ /* Find the cyclic interface of the timer manager */
FOREACH(pi, Interface, timer_manager->interfaces, { FOREACH(pi, Interface, timer_manager->interfaces, {
if (!strcmp(pi->name, "tick_100ms")) cyclic_pi = pi; if (!strcmp(pi->name, cyclic_name)) cyclic_pi = pi;
}); });
...@@ -192,18 +198,21 @@ void Add_timers_to_function (FV *fv, FV *timer_manager) ...@@ -192,18 +198,21 @@ void Add_timers_to_function (FV *fv, FV *timer_manager)
timer); timer);
fprintf (code, "void %s_PI_%s_SET_%s(const asn1SccT_UInt32 *val)\n" fprintf (code, "void %s_PI_%s_SET_%s(const asn1SccT_UInt32 *val)\n"
"{\n" "{\n"
" /* Timer value must be multiple of 100 ms */\n" " /* Timer value must be multiple of %d ms */\n"
" assert (*val %% 100 == 0);\n" " assert (*val %% %d == 0);\n"
" timers[%s_%s].state = active;\n" " timers[%s_%s].state = active;\n"
" timers[%s_%s].value = *val / 100;\n" " timers[%s_%s].value = *val / %d;\n"
"}\n\n", "}\n\n",
timer_manager->name, timer_manager->name,
fv->name, fv->name,
timer, timer,
timer_res,
timer_res,
fv->name, fv->name,
timer, timer,
fv->name, fv->name,
timer); timer,
timer_res);
fprintf (header, "void %s_PI_%s_RESET_%s();\n\n", fprintf (header, "void %s_PI_%s_RESET_%s();\n\n",
timer_manager->name, timer_manager->name,
fv->name, fv->name,
...@@ -227,7 +236,7 @@ void Add_timers_to_function (FV *fv, FV *timer_manager) ...@@ -227,7 +236,7 @@ void Add_timers_to_function (FV *fv, FV *timer_manager)
expire->direction = PI; expire->direction = PI;
expire->synchronism = asynch; expire->synchronism = asynch;
expire->rcm = sporadic; expire->rcm = sporadic;
expire->period = 100; expire->period = timer_res;
expire->parent_fv = fv; expire->parent_fv = fv;
expire->wcet_high = 10; expire->wcet_high = 10;
expire->wcet_low = 10; expire->wcet_low = 10;
......
...@@ -38,6 +38,7 @@ void Set_OutDir(char *o,size_t len); ...@@ -38,6 +38,7 @@ void Set_OutDir(char *o,size_t len);
void Set_Interfaceview (char *name, size_t len); void Set_Interfaceview (char *name, size_t len);
void Set_Dataview (char *name, size_t len); void Set_Dataview (char *name, size_t len);
void Set_Test(); void Set_Test();
void Set_Timer_Resolution(char *val, size_t len);
void Set_Future(); void Set_Future();
void Set_OnlyCV(); void Set_OnlyCV();
void Set_AADLV2(); void Set_AADLV2();
......
...@@ -204,6 +204,7 @@ DECLARE_LIST (Interface) ...@@ -204,6 +204,7 @@ DECLARE_LIST (Interface)
/* /*
* Type used to store context-dependent parameters (eg. output directory) * Type used to store context-dependent parameters (eg. output directory)
* (initialized in practical_functions.c, update it when you add a field)
*/ */
typedef struct t_context { typedef struct t_context {
char *output; char *output;
...@@ -221,6 +222,7 @@ typedef struct t_context { ...@@ -221,6 +222,7 @@ typedef struct t_context {
char *stacksize; char *stacksize;
int polyorb_hi_c; int polyorb_hi_c;
bool needs_basictypes; bool needs_basictypes;
int timer_resolution;
} Context; } Context;
/* /*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment