Commit 92fdfc86 authored by Maxime Perrotin's avatar Maxime Perrotin
Browse files

Add support of multiple SDL instances

(merge work from IB Krates)
parent e135c378
...@@ -232,6 +232,25 @@ procedure BuildSupport is ...@@ -232,6 +232,25 @@ procedure BuildSupport is
end if; end if;
end; end;
declare
InstanceOf : constant Name_Id :=
Get_Instance_Of (CI);
begin
if InstanceOf /= No_Name then
C_Set_Instance_Of (Get_Name_String (InstanceOf),
Get_Name_String (InstanceOf)'Length);
end if;
end;
declare
IsComponent : constant Boolean :=
Get_Is_Component_Type (CI);
begin
if IsComponent then
C_Set_Is_Component_Type;
end if;
end;
-- Parse the functional states of this FV -- Parse the functional states of this FV
if not Is_Empty (Subcomponents (CI)) then if not Is_Empty (Subcomponents (CI)) then
FV_Subco := First_Node (Subcomponents (CI)); FV_Subco := First_Node (Subcomponents (CI));
......
...@@ -213,6 +213,38 @@ package body Buildsupport_Utils is ...@@ -213,6 +213,38 @@ package body Buildsupport_Utils is
return Get_String_Property (D, Ellidiss_Tool_Version); return Get_String_Property (D, Ellidiss_Tool_Version);
end Get_Ellidiss_Tool_Version; end Get_Ellidiss_Tool_Version;
-------------------------------
-- Get_Instance_Of --
-------------------------------
function Get_Instance_Of (Device : Node_Id) return Name_Id is
Instance_Of : Name_id := No_Name;
begin
if Is_Defined_Property (Device, "taste_iv_properties::instance_of")
then
Instance_Of := Get_String_Property
(Device, Get_String_Name
("taste_iv_properties::instance_of"));
end if;
return Instance_Of;
end Get_Instance_Of;
-------------------------------
-- Get_Is_Component_Type --
-------------------------------
function Get_Is_Component_Type (Device : Node_Id) return Boolean is
Is_Component_Type : Boolean := False;
begin
if Is_Defined_Property (Device, "taste_iv_properties::is_component_type")
then
Is_Component_Type := Get_Boolean_Property
(Device, Get_String_Name
("taste_iv_properties::is_component_type"));
end if;
return Is_Component_Type;
end Get_Is_Component_Type;
------------------------ ------------------------
-- Get_Interface_Name -- -- Get_Interface_Name --
------------------------ ------------------------
......
...@@ -81,6 +81,10 @@ package Buildsupport_Utils is ...@@ -81,6 +81,10 @@ package Buildsupport_Utils is
function Get_Ellidiss_Tool_Version (D : Node_Id) return Name_Id; function Get_Ellidiss_Tool_Version (D : Node_Id) return Name_Id;
function Get_Instance_Of (Device : Node_Id) return Name_Id;
function Get_Is_Component_Type (Device : Node_Id) return Boolean;
function Get_Interface_Name (D : Node_Id) return Name_Id; function Get_Interface_Name (D : Node_Id) return Name_Id;
function Get_Env_Vars (D : Node_Id) return Name_Id; function Get_Env_Vars (D : Node_Id) return Name_Id;
......
...@@ -198,8 +198,14 @@ package Imported_Routines is ...@@ -198,8 +198,14 @@ package Imported_Routines is
procedure C_Set_Debug_Messages; procedure C_Set_Debug_Messages;
procedure C_New_Drivers_Section; procedure C_New_Drivers_Section;
procedure C_End_Drivers_Section; procedure C_End_Drivers_Section;
procedure C_Set_Instance_Of
(component : String;
len : Integer);
procedure C_Set_Is_Component_Type;
private private
pragma Import (C, C_Set_Instance_Of, "Set_Instance_Of");
pragma Import (C, C_Set_Is_Component_Type, "Set_Is_Component_Type");
pragma Import (C, C_New_Drivers_Section, "New_Drivers_Section"); pragma Import (C, C_New_Drivers_Section, "New_Drivers_Section");
pragma Import (C, C_End_Drivers_Section, "End_Drivers_Section"); pragma Import (C, C_End_Drivers_Section, "End_Drivers_Section");
pragma Import (C, C_Set_PolyORBHI_C, "Set_PolyorbHI_C"); pragma Import (C, C_Set_PolyORBHI_C, "Set_PolyorbHI_C");
......
...@@ -714,20 +714,21 @@ void GLUE_C_Backend(FV * fv) ...@@ -714,20 +714,21 @@ void GLUE_C_Backend(FV * fv)
); );
} }
if (false == fv->is_component_type) {
if (c == fv->language || gui == fv->language || ada == fv->language || vdm == fv->language if (c == fv->language || gui == fv->language || ada == fv->language || vdm == fv->language
|| qgenada == fv->language || qgenc == fv->language || qgenada == fv->language || qgenc == fv->language
|| rtds == fv->language || cpp == fv->language || opengeode == fv->language || rtds == fv->language || cpp == fv->language || opengeode == fv->language
|| micropython == fv->language) { || micropython == fv->language) {
Init_C_Glue_Backend(fv); Init_C_Glue_Backend(fv);
FOREACH(i, Interface, fv->interfaces, { FOREACH(i, Interface, fv->interfaces, {
GLUE_C_ProvidedInterface(i); GLUE_C_ProvidedInterface(i);
} }
); );
}
} }
/* for all languages except ObjectGeode (sdl) and Blackbox devices, generate invoke_ri.c */ /* for all languages except ObjectGeode (sdl) and Blackbox devices, generate invoke_ri.c */
if (sdl != fv->language && blackbox_device != fv->language) { if (sdl != fv->language && blackbox_device != fv->language && true != fv->is_component_type) {
FOREACH(i, Interface, fv->interfaces, { FOREACH(i, Interface, fv->interfaces, {
GLUE_C_InvokeRI(i); GLUE_C_InvokeRI(i);
} }
......
...@@ -145,6 +145,15 @@ void Create_script() ...@@ -145,6 +145,15 @@ void Create_script()
/* OpenGEODE-specific: call code generator on the fly */ /* OpenGEODE-specific: call code generator on the fly */
FOREACH (fv, FV, get_system_ast()->functions, { FOREACH (fv, FV, get_system_ast()->functions, {
if (sdl == fv->language) { if (sdl == fv->language) {
if (NULL != fv->instance_of) {
fprintf(script,
"# Generate code for function %s (instance of OpenGEODE function %s)\n"
"cd \"$SKELS\"/%s && "
"opengeode --toAda system_structure.pr ../%s/%s.pr "
"&& rm -f %s.ad* "
"&& cd $OLDPWD\n\n",
fv->name, fv->instance_of, fv->name, fv->instance_of, fv->instance_of, fv->instance_of);
} else {
fprintf(script, fprintf(script,
"# Generate code for OpenGEODE function %s\n" "# Generate code for OpenGEODE function %s\n"
"cd \"$SKELS\"/%s && " "cd \"$SKELS\"/%s && "
...@@ -152,6 +161,7 @@ void Create_script() ...@@ -152,6 +161,7 @@ void Create_script()
"&& cd $OLDPWD\n\n", "&& cd $OLDPWD\n\n",
fv->name, fv->name, fv->name); fv->name, fv->name, fv->name);
} }
}
}); });
/* VDM-Specific: call code generator and B mappers */ /* VDM-Specific: call code generator and B mappers */
...@@ -247,7 +257,8 @@ void Create_script() ...@@ -247,7 +257,8 @@ void Create_script()
fprintf (script, "--subCPP "); fprintf (script, "--subCPP ");
break; break;
case sdl: case sdl:
case ada: fprintf (script, "--subAda "); case ada: if (fv->is_component_type == true) fprintf (script, "--with-extra-Ada-code ");
else fprintf (script, "--subAda ");
break; break;
case vhdl: fprintf (script, "--subVHDL "); case vhdl: fprintf (script, "--subVHDL ");
break; break;
...@@ -263,7 +274,8 @@ void Create_script() ...@@ -263,7 +274,8 @@ void Create_script()
break; break;
} }
fprintf (script, "%s", fv->name); if (fv->is_component_type == true) fprintf (script, "%s", fv->name);
else fprintf (script, "%s", fv->name);
/* ObjectGEODE systems are treated differently from all other languages, /* ObjectGEODE systems are treated differently from all other languages,
because it directly refers to .pr files, instead of zip files because it directly refers to .pr files, instead of zip files
if (sdl == fv->language) { UNCOMMENT WHEN OPENGEODE FULLY SUPPORTED if (sdl == fv->language) { UNCOMMENT WHEN OPENGEODE FULLY SUPPORTED
...@@ -276,6 +288,9 @@ void Create_script() ...@@ -276,6 +288,9 @@ void Create_script()
if (rtds == fv->language && NULL == fv->zipfile) { if (rtds == fv->language && NULL == fv->zipfile) {
fprintf (script, ":\"$SKELS\"/%s/%s.zip", fv->name, fv->name); fprintf (script, ":\"$SKELS\"/%s/%s.zip", fv->name, fv->name);
} }
else if (true == fv->is_component_type) {
fprintf (script, ":\"$SKELS\"/%s", fv->name);
}
else if (NULL != fv->zipfile) { else if (NULL != fv->zipfile) {
fprintf (script, ":%s", fv->zipfile); fprintf (script, ":%s", fv->zipfile);
} }
......
...@@ -409,7 +409,7 @@ void GLUE_OG_Backend(FV * fv) ...@@ -409,7 +409,7 @@ void GLUE_OG_Backend(FV * fv)
{ {
if (fv->system_ast->context->onlycv) if (fv->system_ast->context->onlycv)
return; return;
if (sdl == fv->language) { if ((sdl == fv->language) && (false == fv->is_component_type)) {
Create_OG_files(fv); Create_OG_files(fv);
FOREACH(i, Interface, fv->interfaces, { FOREACH(i, Interface, fv->interfaces, {
GLUE_OG_Interface(i); GLUE_OG_Interface(i);
......
...@@ -517,6 +517,17 @@ void Set_Stack(char *val, size_t len) ...@@ -517,6 +517,17 @@ void Set_Stack(char *val, size_t len)
build_string(&(system_ast->context->stacksize), val, len); build_string(&(system_ast->context->stacksize), val, len);
} }
void Set_Instance_Of(char *component, size_t len)
{
assert (0 < len && NULL != fv);
build_string (&(fv->instance_of), component, len);
}
void Set_Is_Component_Type()
{
assert (NULL != fv);
fv->is_component_type = true;
}
/* End of context-related functions */ /* End of context-related functions */
...@@ -1138,6 +1149,40 @@ Interface *FindInterface(FV * function, char *interface_name) ...@@ -1138,6 +1149,40 @@ Interface *FindInterface(FV * function, char *interface_name)
return result; return result;
} }
/* FindParameter of a given Interface */
void CompareParName(Parameter * p, Parameter ** result)
{
if (NULL == p->name || NULL == search_name)
return;
if (!strcmp(p->name, search_name)) {
*result = p;
SetSearchName(NULL);
}
}
Parameter *FindInParameter(Interface *i, char *param_name)
{
Parameter *result = NULL;
SetSearchName(param_name);
FOREACH(p, Parameter, i->in, {
CompareParName(p, &result);})
SetSearchName(NULL);
return result;
}
Parameter *FindOutParameter(Interface * i, char *param_name)
{
Parameter *result = NULL;
SetSearchName(param_name);
FOREACH(p, Parameter, i->out, {
CompareParName(p, &result);})
SetSearchName(NULL);
return result;
}
/* Given a PI (from any function) and a known caller, find the corresponding /* Given a PI (from any function) and a known caller, find the corresponding
* RI in the remote function * RI in the remote function
*/ */
......
...@@ -121,7 +121,7 @@ void C_End() ...@@ -121,7 +121,7 @@ void C_End()
); );
} }
if (get_context()->gw && if (get_context()->gw && (false == fv->is_component_type) &&
(NULL == fv->zipfile || get_context()->glue)) { (NULL == fv->zipfile || get_context()->glue)) {
GW_SDL_Backend(fv); GW_SDL_Backend(fv);
GW_Simulink_Backend(fv); GW_Simulink_Backend(fv);
...@@ -136,7 +136,7 @@ void C_End() ...@@ -136,7 +136,7 @@ void C_End()
} }
/* Export to SMP2: generate glue code and Python AST */ /* Export to SMP2: generate glue code and Python AST */
if (true == get_context()->smp2) { if (true == get_context()->smp2 && (false == fv->is_component_type)) {
GLUE_OG_Backend(fv); GLUE_OG_Backend(fv);
GLUE_RTDS_Backend(fv); GLUE_RTDS_Backend(fv);
GLUE_MiniCV_Backend(fv); GLUE_MiniCV_Backend(fv);
...@@ -174,35 +174,37 @@ void C_End() ...@@ -174,35 +174,37 @@ void C_End()
* Execute various backends applicable to each FV * Execute various backends applicable to each FV
*/ */
FOREACH(fv, FV, get_system_ast()->functions, { FOREACH(fv, FV, get_system_ast()->functions, {
/* if (false == fv->is_component_type) {
* Call 'asn2dataModel' if glue code is not required /*
* (to avoid slowing down the orchestrator, which is * Call 'asn2dataModel' if glue code is not required
* the only place where the glue code is requested * (to avoid slowing down the orchestrator, which is
*/ * the only place where the glue code is requested
if (get_context()->gw && !get_context()->glue && NULL == fv->zipfile) { */
Call_asn2dataModel(fv); if (get_context()->gw && !get_context()->glue && NULL == fv->zipfile) {
} Call_asn2dataModel(fv);
}
/* Process all functional states declared in the interface view */ /* Process all functional states declared in the interface view */
if (get_context()->gw && (NULL == fv->zipfile || get_context()->glue)) { if (get_context()->gw && (NULL == fv->zipfile || get_context()->glue)) {
Process_Context_Parameters(fv); Process_Context_Parameters(fv);
} }
/* Process function directives */ /* Process function directives */
if (get_context()->glue || get_context()->test) { if (get_context()->glue || get_context()->test) {
Process_Directives (fv); Process_Directives (fv);
} }
if (get_context()->glue) { if (get_context()->glue) {
GLUE_OG_Backend(fv); GLUE_OG_Backend(fv);
GLUE_RTDS_Backend(fv); GLUE_RTDS_Backend(fv);
GLUE_MiniCV_Backend(fv); GLUE_MiniCV_Backend(fv);
GLUE_C_Backend(fv); GLUE_C_Backend(fv);
GLUE_GUI_Backend(fv); GLUE_GUI_Backend(fv);
GLUE_Ada_Wrappers_Backend(fv); GLUE_Ada_Wrappers_Backend(fv);
GLUE_C_Wrappers_Backend(fv); GLUE_C_Wrappers_Backend(fv);
GLUE_VT_Backend(fv); GLUE_VT_Backend(fv);
GLUE_MicroPython_Backend(fv); GLUE_MicroPython_Backend(fv);
}
} }
}) })
......
...@@ -927,6 +927,8 @@ void Create_FV(FV ** fv) ...@@ -927,6 +927,8 @@ void Create_FV(FV ** fv)
/* is this function a timer manager? */ /* is this function a timer manager? */
(*fv)->timer = false; (*fv)->timer = false;
(*fv)->timer_list = NULL; (*fv)->timer_list = NULL;
(*fv)->is_component_type = false;
(*fv)->instance_of = NULL;
} }
} }
...@@ -963,6 +965,9 @@ void Clear_FV(FV * fv) ...@@ -963,6 +965,9 @@ void Clear_FV(FV * fv)
if (NULL != fv->process) { if (NULL != fv->process) {
fv->process = NULL; fv->process = NULL;
} }
if (NULL != fv->instance_of) {
fv->instance_of = NULL;
}
} }
......
...@@ -157,7 +157,6 @@ FV *Add_timer_manager(Process *node, FV_list *fv_with_timer) ...@@ -157,7 +157,6 @@ FV *Add_timer_manager(Process *node, FV_list *fv_with_timer)
// platforms (e.g. RTEMS) and (2) unnecessary since the PI is protected // platforms (e.g. RTEMS) and (2) unnecessary since the PI is protected
fprintf (code, " if (timers[%s].state == active && " fprintf (code, " if (timers[%s].state == active && "
"0 == --timers[%s].value) {\n" "0 == --timers[%s].value) {\n"
//"1 == __sync_fetch_and_sub(&timers[%s].value, 1)) {\n"
" %s_RI_%s();\n" " %s_RI_%s();\n"
" timers[%s].state = inactive;\n" " timers[%s].state = inactive;\n"
" }\n\n", " }\n\n",
...@@ -205,7 +204,6 @@ void Add_timers_to_function (FV *fv, FV *timer_manager) ...@@ -205,7 +204,6 @@ void Add_timers_to_function (FV *fv, FV *timer_manager)
" assert (*val %% %d == 0);\n" " assert (*val %% %d == 0);\n"
" timers[%s_%s].state = active;\n" " timers[%s_%s].state = active;\n"
" timers[%s_%s].value = *val / %d;\n" " timers[%s_%s].value = *val / %d;\n"
//" __sync_lock_test_and_set(&timers[%s_%s].value, *val / %d);\n"
"}\n\n", "}\n\n",
timer_manager->name, timer_manager->name,
fv->name, fv->name,
...@@ -836,6 +834,7 @@ void Add_api(Process *node, FV_list *all_fv) ...@@ -836,6 +834,7 @@ void Add_api(Process *node, FV_list *all_fv)
/* Add a PI for each of the node's functions */ /* Add a PI for each of the node's functions */
FOREACH (function, FV, all_fv, { FOREACH (function, FV, all_fv, {
if (false == function->is_component_type) {
Interface *pi = NULL; Interface *pi = NULL;
Interface *ri = NULL; Interface *ri = NULL;
Create_Interface(&pi); Create_Interface(&pi);
...@@ -874,6 +873,7 @@ void Add_api(Process *node, FV_list *all_fv) ...@@ -874,6 +873,7 @@ void Add_api(Process *node, FV_list *all_fv)
free(ri->distant_fv); free(ri->distant_fv);
ri->distant_fv = make_string("%s", fv->name); ri->distant_fv = make_string("%s", fv->name);
APPEND_TO_LIST(Interface, function->interfaces, ri); APPEND_TO_LIST(Interface, function->interfaces, ri);
}
}); });
/* Set flag indicating that this function was created during VT */ /* Set flag indicating that this function was created during VT */
...@@ -933,6 +933,7 @@ void Add_api(Process *node, FV_list *all_fv) ...@@ -933,6 +933,7 @@ void Add_api(Process *node, FV_list *all_fv)
"}\n\n", fv->name); "}\n\n", fv->name);
FOREACH(function, FV, all_fv, { FOREACH(function, FV, all_fv, {
if (false == function->is_component_type) {
char *decl = NULL; char *decl = NULL;
char *task_id = NULL; char *task_id = NULL;
char *port = NULL; char *port = NULL;
...@@ -972,6 +973,7 @@ void Add_api(Process *node, FV_list *all_fv) ...@@ -972,6 +973,7 @@ void Add_api(Process *node, FV_list *all_fv)
fprintf(code, "}\n\n"); fprintf(code, "}\n\n");
free(decl); free(decl);
}
}); });
fprintf (header, "#ifdef __cplusplus\n" fprintf (header, "#ifdef __cplusplus\n"
...@@ -1169,7 +1171,9 @@ void Preprocessing_Backend (System *s) ...@@ -1169,7 +1171,9 @@ void Preprocessing_Backend (System *s)
}); });
FOREACH (fv, FV, s->functions, { FOREACH (fv, FV, s->functions, {
Preprocess_FV(fv); if (true != fv->is_component_type) {
Preprocess_FV(fv);
}
}); });
/* Propagate calling thread to distant PI (recursively) /* Propagate calling thread to distant PI (recursively)
...@@ -1177,7 +1181,7 @@ void Preprocessing_Backend (System *s) ...@@ -1177,7 +1181,7 @@ void Preprocessing_Backend (System *s)
* then go through all their RIs recursively until reaching another thread, * then go through all their RIs recursively until reaching another thread,
* and set that the function is a calling thread of the reached one */ * and set that the function is a calling thread of the reached one */
FOREACH(fv, FV, s->functions, { FOREACH(fv, FV, s->functions, {
if (thread_runtime == fv->runtime_nature) { if ((thread_runtime == fv->runtime_nature) && (true != fv->is_component_type)) {
FOREACH(i, Interface, fv->interfaces, { FOREACH(i, Interface, fv->interfaces, {
if (RI == i->direction) Propagate_Calling_Thread (i, &fv); if (RI == i->direction) Propagate_Calling_Thread (i, &fv);
}) })
...@@ -1186,7 +1190,7 @@ void Preprocessing_Backend (System *s) ...@@ -1186,7 +1190,7 @@ void Preprocessing_Backend (System *s)
/* Add each RI of passive functions as RI of their calling threads */ /* Add each RI of passive functions as RI of their calling threads */
FOREACH(fv, FV, s->functions, { FOREACH(fv, FV, s->functions, {
if(passive_runtime==fv->runtime_nature) { if((passive_runtime==fv->runtime_nature) && (true != fv->is_component_type)) {
FOREACH(i, Interface, fv->interfaces, { FOREACH(i, Interface, fv->interfaces, {
if (RI==i->direction && i->distant_qgen->language == other) { if (RI==i->direction && i->distant_qgen->language == other) {
/* Add to calling threads only of PIs that actually call /* Add to calling threads only of PIs that actually call
...@@ -1240,7 +1244,7 @@ void Preprocessing_Backend (System *s) ...@@ -1240,7 +1244,7 @@ void Preprocessing_Backend (System *s)
/* Find the FV of the caller */ /* Find the FV of the caller */
FOREACH (fv, FV, get_system_ast()->functions, { FOREACH (fv, FV, get_system_ast()->functions, {
if (!strcmp (fv->name, cnt->dst_system)) caller = fv; if (!strcmp (fv->name, cnt->dst_system) && (true != fv->is_component_type)) caller = fv;
}); });
assert (NULL != caller); assert (NULL != caller);
...@@ -1252,7 +1256,7 @@ void Preprocessing_Backend (System *s) ...@@ -1252,7 +1256,7 @@ void Preprocessing_Backend (System *s)
/* Find the FV of the callee */ /* Find the FV of the callee */
FOREACH (fv, FV, get_system_ast()->functions, { FOREACH (fv, FV, get_system_ast()->functions, {
if (!strcmp (fv->name, ri->distant_fv)) callee = fv; if (!strcmp (fv->name, ri->distant_fv) && (true != fv->is_component_type)) callee = fv;
}); });
/* If the caller is passive we must create one connection /* If the caller is passive we must create one connection
......
/* Buildsupport is (c) 2008-2015 European Space Agency /* Buildsupport is (c) 2008-2017 European Space Agency
* contact: maxime.perrotin@esa.int * contact: maxime.perrotin@esa.int
* License is LGPL, check LICENSE file */ * License is LGPL, check LICENSE file */
/* /*
...@@ -68,10 +68,16 @@ void Create_New_SDL_Structure(FV * fv) ...@@ -68,10 +68,16 @@ void Create_New_SDL_Structure(FV * fv)
char *filename = make_string("%s.pr", fv->name); char *filename = make_string("%s.pr", fv->name);
/* If not already existing, also create an empty system_implementation.pr /* If not already existing, also create an empty system_implementation.pr
* file - includes timer declarations, if any */ * file - includes timer declarations, if any.
if (!file_exists (path, filename)) { * Do not create in case the function is an instance of a generic function*/
if (!file_exists (path, filename) && (NULL == fv->instance_of)) {
create_file (path, filename, &process); create_file (path, filename, &process);
fprintf (process, "PROCESS %s;\n", fv->name); if (fv->is_component_type == false) {
fprintf (process, "PROCESS %s;\n", fv->name);
} else {
fprintf (process, "PROCESS type %s;\n", fv->name);
}
if (NULL != fv->timer_list) { if (NULL != fv->timer_list) {
fprintf (process, "/* CIF TEXT (10, 10), (200, 250) */\n"); fprintf (process, "/* CIF TEXT (10, 10), (200, 250) */\n");
fprintf (process, "-- Timers defined in the interface view\n" fprintf (process, "-- Timers defined in the interface view\n"
...@@ -88,8 +94,12 @@ void Create_New_SDL_Structure(FV * fv) ...@@ -88,8 +94,12 @@ void Create_New_SDL_Structure(FV * fv)