Commits (62)
image: $CI_REGISTRY_IMAGE/taste:latest
variables:
GIT_SUBMODULE_STRATEGY: recursive
stages:
- build
- post_build
build:
stage: build
script:
# As soon as TASTE moves from .bashrc.taste to .profile.taste this can be simplified
- echo -e "(source ~/.bashrc ; export TASTE_IN_DOCKER=1 ; make install ; make test )" > docker_workaround.sh
- chmod +x docker_workaround.sh
- ./docker_workaround.sh
artifacts:
paths:
- 'test/logs/*.err'
when: on_failure
expire_in: 2 weeks
templates/build-script.tmplt
templates/skeletons/makefile.tmplt
templates/skeletons/context-parameters.tmplt
templates/skeletons/sub/trigger.tmplt
......@@ -6,13 +5,8 @@ templates/skeletons/sub/makefile-filename.tmplt
templates/skeletons/sub/function-filename.tmplt
templates/skeletons/sub/interface.tmplt
templates/skeletons/sub/makefile.tmplt
templates/skeletons/sub/function.tmplt
templates/concurrency_view/sub/filenode.tmplt
templates/concurrency_view/sub/trigger.tmplt
templates/concurrency_view/sub/filepart.tmplt
templates/concurrency_view/sub/thread.tmplt
templates/concurrency_view/sub/filethread.tmplt
templates/concurrency_view/sub/fileblock.tmplt
templates/concurrency_view/sub/pi.tmplt
templates/concurrency_view/sub/ri.tmplt
templates/concurrency_view/sub/block.tmplt
......
This diff is collapsed.
......@@ -197,6 +197,9 @@ This template is identical for Skeleton and Glue subfolders.
|-
|Data_View
|DOCUMENTATION MISSING
|-
|Target
|DOCUMENTATION MISSING
|}
=== templates/skeletons/sub/makefile-filename.tmplt ===
This file is optional, if exists the result of parsing of this file is a name of output file for makefile.tmplt, otherwise this template will not be processed.
......@@ -284,6 +287,9 @@ This file is processed twice, first time for required interfaces of the function
|-
|Remote_Function_Names
|DOCUMENTATION MISSING
|-
|Param_Basic_Types
|DOCUMENTATION MISSING
|}
=== templates/skeletons/sub/makefile.tmplt ===
This template is processed when makefile-filename.tmplt exists.
......@@ -354,6 +360,21 @@ This file is processed for every node. The result of this file indicates if the
|-
|Data_View
|DOCUMENTATION MISSING
|-
|CPU_Family
|DOCUMENTATION MISSING
|-
|CPU_Platform
|DOCUMENTATION MISSING
|-
|CPU_Name
|DOCUMENTATION MISSING
|-
|Target
|DOCUMENTATION MISSING
|-
|CPU_Classifier
|DOCUMENTATION MISSING
|}
=== templates/concurrency_view/sub/thread.tmplt ===
This file is processed for every thread in every partition in every node.
......@@ -489,6 +510,21 @@ This file is processed for every thread in every partition in every node.
|-
|Data_View
|DOCUMENTATION MISSING
|-
|Param_Basic_Types
|DOCUMENTATION MISSING
|-
|Target
|DOCUMENTATION MISSING
|-
|Priority
|DOCUMENTATION MISSING
|-
|Dispatch_Offset_ms
|DOCUMENTATION MISSING
|-
|Stack_Size_In_Bytes
|DOCUMENTATION MISSING
|}
=== templates/concurrency_view/sub/pi.tmplt ===
The template pi.tmplt is evaluated many times for every protected and unprotected provided interface.
......@@ -562,6 +598,9 @@ The result of every evaluation is joined to one string and passed as a parameter
|-
|Remote_Function_Names
|DOCUMENTATION MISSING
|-
|Param_Basic_Types
|DOCUMENTATION MISSING
|}
=== templates/concurrency_view/sub/ri.tmplt ===
The template ri.tmplt is evaluated many times for every required interface.
......@@ -629,6 +668,9 @@ The result of every evaluation is koined to one string and passed as a parameter
|-
|Remote_Function_Names
|DOCUMENTATION MISSING
|-
|Param_Basic_Types
|DOCUMENTATION MISSING
|}
=== templates/concurrency_view/sub/block.tmplt ===
This template is evaluated for every block.
......@@ -776,11 +818,14 @@ This template is evaluated for every block.
|-
|Data_View
|DOCUMENTATION MISSING
|}
And all the system configuration obtained from the command line:
Interface_View, Deployment_View, Data_View, Binary_Path, Check_Data_View,
Output_Dir, Skeletons, Glue, Use_POHIC, Timer_Resolution, Debug_Flag,
No_Stdlib_Flag, Timer_Resolution, Other_Files (list of aadl files)
|-
|Target
|DOCUMENTATION MISSING
|}No_Stdlib_Flag, Timer_Resolution, Other_Files (list of aadl files)
=== templates/concurrency_view/sub/partition.tmplt ===
......@@ -893,6 +938,42 @@ This file is evaluated for every partition.
|-
|VP_Duration
|DOCUMENTATION MISSING
|-
|Device_CPU
|DOCUMENTATION MISSING
|-
|Device_Bus_Name
|DOCUMENTATION MISSING
|-
|Device_Init
|DOCUMENTATION MISSING
|-
|Device_AADL_Pkg
|DOCUMENTATION MISSING
|-
|Device_ASN1_Module
|DOCUMENTATION MISSING
|-
|Device_Port_Name
|DOCUMENTATION MISSING
|-
|Device_Config
|DOCUMENTATION MISSING
|-
|Device_Names
|DOCUMENTATION MISSING
|-
|Device_ASN1_File
|DOCUMENTATION MISSING
|-
|Device_Classifier
|DOCUMENTATION MISSING
|-
|Device_Language
|DOCUMENTATION MISSING
|-
|Device_ASN1_Sort
|DOCUMENTATION MISSING
|}
=== templates/concurrency_view/sub/node.tmplt ===
This file is evaluated for every node. The result of this file is saved to the file with name returned by filenode.tmplt. The result is also used as a parameter for system.tmplt.
......@@ -944,6 +1025,42 @@ This file is evaluated for every node. The result of this file is saved to the f
|-
|CPU_Instance
|DOCUMENTATION MISSING
|-
|Device_CPU
|DOCUMENTATION MISSING
|-
|Device_Bus_Name
|DOCUMENTATION MISSING
|-
|Device_AADL_Pkg
|DOCUMENTATION MISSING
|-
|Device_ASN1_Module
|DOCUMENTATION MISSING
|-
|Device_Port_Name
|DOCUMENTATION MISSING
|-
|Device_Config
|DOCUMENTATION MISSING
|-
|Device_Names
|DOCUMENTATION MISSING
|-
|Device_ASN1_File
|DOCUMENTATION MISSING
|-
|Device_Classifier
|DOCUMENTATION MISSING
|-
|Device_Language
|DOCUMENTATION MISSING
|-
|Device_ASN1_Sort
|DOCUMENTATION MISSING
|-
|Device_Init
|DOCUMENTATION MISSING
|}
=== templates/concurrency_view/sub/system.tmplt ===
This file is evaluated for every node. The result of this file is save to the file with name returned by
......@@ -1109,8 +1226,13 @@ filesys.tmplt.
|-
|Data_View
|DOCUMENTATION MISSING
|}
And all the system configuration obtained from the command line:
Interface_View, Deployment_View, Data_View, Binary_Path, Check_Data_View,
Output_Dir, Skeletons, Glue, Use_POHIC, Timer_Resolution, Debug_Flag,
No_Stdlib_Flag, Timer_Resolution, Other_Files (list of aadl files)
|-
|Target
|DOCUMENTATION MISSING
|-
|Device_Language
|DOCUMENTATION MISSING
|-
|Device_Init
|DOCUMENTATION MISSING
|}No_Stdlib_Flag, Timer_Resolution, Other_Files (list of aadl files)
......@@ -15,12 +15,12 @@ begin
if Model.Configuration.Debug_Flag then
TASTE.Dump.Dump_Input_Model (Model);
Model.Dump;
end if;
if Model.Configuration.Glue then
Model.Preprocessing;
Model.Add_Concurrency_View;
Model.Add_CV_Properties;
Model.Concurrency_View.Generate_CV;
end if;
......
......@@ -13,6 +13,7 @@ with System.Assertions,
GNAT.Command_Line,
Errors,
Locations,
Ocarina.AADL_Values,
Ocarina.Namet,
Ocarina.Configuration,
Ocarina.Files,
......@@ -32,6 +33,13 @@ use Ada.Text_IO,
Ocarina.Namet,
Ocarina;
-- for the parsing of ConcurrencyView_Properties.aadl:
-- with ocarina.BE_AADL; use ocarina.BE_AADL;
with Ocarina.ME_AADL.AADL_Tree.Nodes;
with Ocarina.ME_AADL.AADL_Tree.Nutils;
use Ocarina.ME_AADL.AADL_Tree.Nodes;
use Ocarina.ME_AADL.AADL_Tree.Nutils;
package body TASTE.AADL_Parser is
function Initialize return Taste_Configuration is
......@@ -71,12 +79,15 @@ package body TASTE.AADL_Parser is
Interface_Root := Ocarina.Parser.Parse
(AADL_Language, Interface_Root, File_Descr);
-- Parse TASTE_IV_Properties.aadl
Set_Str_To_Name_Buffer ("TASTE_IV_Properties.aadl");
File_Name := Ocarina.Files.Search_File (Name_Find);
File_Descr := Ocarina.Files.Load_File (File_Name);
Interface_Root := Ocarina.Parser.Parse (AADL_Language,
Interface_Root, File_Descr);
-- Parse library of AADL files (TASTE_IV_Properties, etc.)
for Each of Interface_AADL_Lib loop
Set_Str_To_Name_Buffer (Each);
File_Name := Ocarina.Files.Search_File (Name_Find);
File_Descr := Ocarina.Files.Load_File (File_Name);
Interface_Root := Ocarina.Parser.Parse (AADL_Language,
Interface_Root,
File_Descr);
end loop;
if Interface_Root = No_Node then
raise AADL_Parser_Error with "Interface view is incorrect";
......@@ -166,6 +177,23 @@ package body TASTE.AADL_Parser is
Dataview_root := Ocarina.Parser.Parse
(AADL_Language, Dataview_root, File_Descr);
end if;
-- If present, try and parse ConcurrencyView_Properties.aadl
Set_Str_To_Name_Buffer ("ConcurrencyView_Properties.aadl");
File_Name := Ocarina.Files.Search_File (Name_Find);
if File_Name = No_Name then
Put_Debug ("No ConcurrencyView_Properties.aadl file found");
else
Put_Info ("Parsing ConcurrencyView_Properties.aadl");
File_Descr := Ocarina.Files.Load_File (File_Name);
Concurrency_Properties_Root := Ocarina.Parser.Parse
(AADL_Language, Concurrency_Properties_Root, File_Descr);
if Concurrency_Properties_Root = No_Node then
raise AADL_Parser_Error with
"Error parsing ConcurrencyView_Properties.aadl";
end if;
end if;
return Cfg;
end Initialize;
......@@ -185,13 +213,14 @@ package body TASTE.AADL_Parser is
end;
if not Result.Configuration.No_Stdlib then
AADL_Lib.Append ("ocarina_components.aadl");
Deployment_AADL_Lib.Append ("ocarina_components.aadl");
end if;
if Deployment_Root /= No_Node
and not Result.Configuration.Deployment_View.Is_Empty
then
AADL_Lib.Append (Result.Configuration.Interface_View.Element);
Deployment_AADL_Lib.Append
(Result.Configuration.Interface_View.Element);
Result.Deployment_View :=
To_Holder (Parse_Deployment_View
(Deployment_Root, Result.Interface_View));
......@@ -209,14 +238,13 @@ package body TASTE.AADL_Parser is
end if;
Ocarina.Configuration.Reset_Modules;
Ocarina.Reset;
-- Ocarina.Reset; (No: This make the CV_Properties analysis fail)
if Result.Configuration.Check_Data_View then
raise Quit_Taste;
end if;
Semantic_Check.Check_Model (Result);
return Result;
exception
when Error : AADL_Parser_Error
......@@ -487,7 +515,10 @@ package body TASTE.AADL_Parser is
Protected_Block_name => Block.Ref_Function.Name,
Node => Block.Node,
PI => PI,
Output_Ports => Get_Output_Ports (Model, F));
Output_Ports => Get_Output_Ports (Model, F),
Priority => US ("1"),
Dispatch_Offset_Ms => US ("0"),
Stack_Size_In_Bytes => US ("50000"));
begin
CV.Nodes
(Node_Name).Partitions (Partition_Name).Threads.Include
......@@ -599,6 +630,8 @@ package body TASTE.AADL_Parser is
Type_Name => Sort,
Remote_Partition_Name =>
Part.Unsafe_Just.Name,
Remote_Function_Name =>
Remote.Function_Name,
Remote_Port_Name =>
Remote.Interface_Name));
else
......@@ -961,4 +994,200 @@ package body TASTE.AADL_Parser is
Model.Deployment_View.Replace_Element (DV);
end Preprocessing;
procedure Add_CV_Properties (Model : in out TASTE_Model) is
Nodes, -- To iterate on lists of nodes
AADL_Package,
System_Impl : Node_Id := No_Node;
procedure Report_Error is
begin
Put_Info ("No valid user-defined Concurrency View properties found:");
Put_Info ("Task priorities, offset and stack size will use default");
Put_Info ("values. IMPORTANT: you should set them in the editor!");
end Report_Error;
begin
if Concurrency_Properties_Root = No_Node
or else Kind (Concurrency_Properties_Root) /= K_AADL_Specification
or else Is_Empty (Declarations (Concurrency_Properties_Root))
then
Put_Debug ("CV_Properties Error 1");
Report_Error;
return;
end if;
-- AADL Unparser (add with/use Ocarina.BE_AADL):
-- Generate_AADL_Model (Concurrency_Properties_Root, False);
Put_Info ("Analysing user-defined Concurrency View properties");
Nodes := First_Node (Declarations (Concurrency_Properties_Root));
-- First look for the package declaration
while Present (Nodes) loop
case Kind (Nodes) is
when K_Package_Specification => AADL_Package := Nodes;
when others => null;
end case;
Nodes := Next_Node (Nodes);
end loop;
if AADL_Package = No_Node then
Put_Debug ("CV_Properties Error 2");
Report_Error;
return;
end if;
-- Then look for the system implementation
Nodes := First_Node (Declarations (AADL_Package));
while Present (Nodes) loop
case Kind (Nodes) is
when K_Component_Implementation => System_Impl := Nodes;
when others => null;
end case;
Nodes := Next_Node (Nodes);
end loop;
if System_Impl = No_Node or else Is_Empty (ATN.Properties (System_Impl))
then
Put_Debug ("CV_Properties Error 3");
Report_Error;
return;
end if;
Nodes := First_Node (ATN.Properties (System_Impl));
while Present (Nodes) loop -- Iterate over the properties
declare
Prop_Val : Node_Id := Property_Association_Value (Nodes);
Applies_To : constant List_Id := Applies_To_Prop (Nodes);
Paths : Node_Id; -- property applies to path
Partition,
Thread : Unbounded_String := Null_Unbounded_String;
-- Prop_Name shall be Stack_Size, Priority, or Dispatch_Offset
Prop_Name : constant String :=
(Get_Name_String (Display_Name (Identifier (Nodes))));
Number, Unit : Node_Id;
Number_Str,
Unit_Str : Unbounded_String := US ("");
Found : Boolean := False;
begin
if Single_Value (Prop_Val) = No_Node then
Put_Debug ("CV_Properties Error 4 - " & Prop_Name);
Report_Error;
return;
end if;
if (Prop_Name /= "Stack_Size" and Prop_Name /= "Priority"
and Prop_Name /= "Dispatch_Offset") or else Is_Empty (Applies_To)
then
Put_Debug ("Discarding unsupported CV Property: " & Prop_Name);
goto Next_Property;
end if;
-- Recovering the property value - they are all signed numbers
-- Check Ocarina-be_aadl-properties-values.adb for info
Prop_Val := Single_Value (Prop_Val);
if Kind (Prop_Val) /= K_Signed_AADLNumber then
Put_Debug ("CV_Properties Error 5 - " & Prop_Name);
Report_Error;
return;
end if;
-- OK We have the value and the unit:
Number := Number_Value (Prop_Val);
Number_Str := US (AADL_Values.Image (Value (Number)));
Unit := Unit_Identifier (Prop_Val);
if Present (Unit) then
Unit_Str := US (Get_Name_String (Display_Name (Unit)));
end if;
-- Check that the units are the expected ones (kb/ms)
if (Prop_Name = "Stack_Size"
and then (Unit_Str /= "kbyte" and Unit_Str /= "byte"))
or else (Prop_Name = "Dispatch_Offset" and then Unit_Str /= "ms")
then
Put_Error ("Unsupported units used in "
& "ConcurrencyView_Properties.aadl. Stack_Size in "
& "'byte' or 'kbyte' and Dispatch_Offset in 'ms'");
return;
end if;
if Prop_Name = "Stack_Size" and Unit_Str = "kbytes" then
-- Convert from kbytes to bytes
declare
Value_In_Bytes : constant Integer :=
Integer'Value (To_String (Number_Str)) * 1000;
begin
Number_Str := US (Value_In_Bytes'Img);
end;
end if;
-- Last we find the partition and thread it applies to.
-- (Check ocarina-be_aadl-properties.adb)
Paths := First_Node (Applies_To);
while Present (Paths) loop
declare
Contained_Elts : constant List_Id := List_Items (Paths);
List_Node : Node_Id :=
(if not Is_Empty (Contained_Elts)
then First_Node (Contained_Elts)
else No_Node);
begin
-- The following gets the path Partition.Thread_Name
-- If a longer path is needed a refactoring must be done
while Present (List_Node) loop
-- Kind (List_Node) = K_Identifier
if Partition = Null_Unbounded_String then
Partition := US (Get_Name_String
(Display_Name (List_Node)));
else
Thread := US
(Get_Name_String (Display_Name (List_Node)));
end if;
exit when Thread /= Null_Unbounded_String;
List_Node := Next_Node (List_Node);
end loop;
end;
-- We completed the parsing of one property
-- Prop_Name = Number_Str Unit_Str applies to Partition Thread
Put_Debug (Prop_Name & " := " & To_String (Number_str) & " "
& To_String (Unit_Str) & " applies to "
& To_String (Partition) & "." & To_String (Thread));
-- Checking in the generated concurrency view if the
-- partition and thread actually exist, and apply the property
Found := False;
for Node of Model.Concurrency_View.Nodes loop
exit when Found;
if Node.Partitions.Contains (To_String (Partition))
and then Node.Partitions (To_String (Partition))
.Threads.Contains (To_String (Thread))
then
if Prop_Name = "Priority" then
Node.Partitions (To_String (Partition))
.Threads (To_String (Thread)).Priority := Number_Str;
elsif Prop_Name = "Stack_Size" then
Node.Partitions (To_String (Partition))
.Threads (To_String (Thread)).Stack_Size_In_Bytes :=
Number_Str;
elsif Prop_Name = "Dispatch_Offset" then
Node.Partitions (To_String (Partition))
.Threads (To_String (Thread)).Dispatch_Offset_Ms :=
Number_Str;
end if;
Found := True;
end if;
end loop;
if not Found then
Put_Info ("The ConcurrencyView_Properties.aadl file "
& "references non-existing partition/thread : "
& To_String (Partition) & "."
& To_String (Thread));
end if;
Paths := Next_Node (Paths);
end loop;
end;
<<Next_Property>>
Nodes := Next_Node (Nodes);
end loop;
end Add_CV_Properties;
end TASTE.AADL_Parser;
......@@ -20,9 +20,14 @@ use Ada.Strings.Unbounded,
TASTE.Data_View;
package TASTE.AADL_Parser is
Interface_Root : Node_Id := No_Node;
Deployment_Root : Node_Id := No_Node;
Dataview_Root : Node_Id := No_Node;
Interface_Root,
Deployment_Root,
Dataview_Root : Node_Id := No_Node;
-- ConcurrencyView_Properties.aadl is parsed but not analyzed,
-- as it contains reference to the system threads which have not
-- been created yet. The backend templates get access to the values.
Concurrency_Properties_Root : Node_Id := No_Node;
-- Definition of the data model of a TASTE system
type TASTE_Model is tagged
......@@ -45,6 +50,15 @@ package TASTE.AADL_Parser is
procedure Add_Concurrency_View (Model : in out TASTE_Model)
with Pre => not Model.Deployment_View.Is_Empty;
-- Parse the ConcurrencyView_Properties.aadl file to extract user-defined
-- thread priorities, dispatch offset, stack sizes. Parsing is done at
-- AST level only, the model is not semantically checked because at this
-- point in the parsing the actual set of thread has not been computed,
-- so the AADL file references non-existing artefacts. There can be
-- reference to threads that will not be created at all, in which case
-- they can be ignored or reported to the user for information.
procedure Add_CV_Properties (Model : in out TASTE_Model);
function Find_Binding (Model : TASTE_Model;
F : Unbounded_String)
return Option_Partition.Option;
......
......@@ -109,18 +109,23 @@ package body TASTE.Backend.Code_Generators is
Close (Output_File);
end Generate_Global_Makefile;
-- Render a set (Tag) of interfaces by applying a template
-- Render a set of interfaces by applying a template
-- Result is an unbounded string, allowing each interface to use
-- multiple lines (combined with 'Indent)
function Process_Interfaces (Interfaces : Template_Vectors.Vector;
Path : String) return Tag
Path : String) return Unbounded_String
is
Result : Tag;
Result : Unbounded_String := Null_Unbounded_String;
Tmplt_Sign : constant String := Path & "interface.tmplt";
begin
for Each of Interfaces loop
-- if Result /= Null_Unbounded_String then
-- Result := Result & ASCII.LF;
-- end if;
Document_Template (Templates_Skeletons_Sub_Interface, Each);
Result := Result & String'(Parse (Tmplt_Sign, Each));
Result := Result & US (String'(Parse (Tmplt_Sign, Each)));
end loop;
return Result;
return Strip_String (Result);
end Process_Interfaces;
-- Generate the ASN.1 files translating Context Parameters
......@@ -330,7 +335,8 @@ package body TASTE.Backend.Code_Generators is
Trigger : constant Boolean :=
(Exists (Path & "/trigger.tmplt")
and then Strip_String (Parse
(Path & "/trigger.tmplt", Trig_Tmpl)) = "TRUE");
(Path & "/trigger.tmplt", Trig_Tmpl)) =
String'("TRUE"));
begin
Document_Template
(Templates_Skeletons_Sub_Function_Filename, File_Tmpl);
......
This diff is collapsed.
......@@ -6,6 +6,8 @@
with Ada.Containers.Indefinite_Ordered_Maps,
Ada.Strings.Unbounded,
Ada.Strings.Equal_Case_Insensitive,
Ada.Strings.Less_Case_Insensitive,
Text_IO,
Templates_Parser,
TASTE.Parser_Utils,
......@@ -24,6 +26,11 @@ package TASTE.Concurrency_View is
Concurrency_View_Error : exception;
function "="(Left, Right : Case_Insensitive_String) return Boolean
renames Ada.Strings.Equal_Case_Insensitive;
function "<"(Left, Right : Case_Insensitive_String) return Boolean
renames Ada.Strings.Less_Case_Insensitive;
type Protected_Block_PI is
record
Name : Unbounded_String;
......@@ -77,12 +84,16 @@ package TASTE.Concurrency_View is
Protected_Block_Name : Unbounded_String;
Output_Ports : Ports.Map;
Node : Option_Node.Option;
Priority,
Dispatch_Offset_Ms,
Stack_Size_In_Bytes : Unbounded_String := Null_Unbounded_String;
PI : Taste_Interface; -- Contains period, etc.
end record;
function To_Template (T : AADL_Thread) return Translate_Set;
package AADL_Threads is new Indefinite_Ordered_Maps (String, AADL_Thread);
package AADL_Threads is new Indefinite_Ordered_Maps
(Case_Insensitive_String, AADL_Thread);
type Partition_In_Port is
record
......@@ -100,6 +111,7 @@ package TASTE.Concurrency_View is
Port_Name, Type_Name : Unbounded_String;
Connected_Threads : String_Vectors.Vector;
Remote_Partition_Name,
Remote_Function_Name,
Remote_Port_Name : Unbounded_String; -- Other side
end record;
......@@ -115,7 +127,8 @@ package TASTE.Concurrency_View is
Out_Ports : Partition_Out_Ports.Map;
end record;
package CV_Partitions is new Indefinite_Ordered_Maps (String, CV_Partition);
package CV_Partitions is new Indefinite_Ordered_Maps
(Case_Insensitive_String, CV_Partition);
-- A node may contain several partitions (in case of TSP)
type CV_Node is tagged
......@@ -124,7 +137,8 @@ package TASTE.Concurrency_View is
Partitions : CV_Partitions.Map;
end record;
package CV_Nodes is new Indefinite_Ordered_Maps (String, CV_Node);
package CV_Nodes is new Indefinite_Ordered_Maps
(Case_Insensitive_String, CV_Node);
-- CV is made of a list of nodes, each containing a list of partitions
-- Partitions contain threads and passive functions as created during
......
......@@ -47,7 +47,7 @@ package body TASTE.Deployment_View is
Ocarina.FE_AADL.Parser.Add_Pre_Prop_Sets := True;
-- Parse all AADL files possibly needed to instantiate the model
for Each of AADL_Lib loop
for Each of Deployment_AADL_Lib loop
Set_Str_To_Name_Buffer (Each);
F := Ocarina.Files.Search_File (Name_Find);
Loc := Ocarina.Files.Load_File (F);
......@@ -69,6 +69,79 @@ package body TASTE.Deployment_View is
return Root_System (Root_Instance);
end Initialize;
function Device_Driver_Name (Driver : Taste_Device_Driver) return String is
Dot : constant Natural := Index (Driver.Name, ".");
Name : constant String := To_String (Driver.Name);
Device_Name : constant String :=
(if Dot > 0
then Name (Name'First .. Dot - 1)
else "ERROR_MALFORMED_DEVICE_NAME");
begin
return Device_Name;
end Device_Driver_Name;
function Drivers_To_Template (Drivers : Taste_Drivers.Vector)
return Translate_Set is
Device_Names,
Device_Package_Names,
Device_Classifiers,
Device_Associated_Processor_Names,
Device_Configurations,
Device_Accessed_Bus_Names,
Device_Accessed_Port_Names,
Device_Init_Entrypoints,
Device_Init_Languages,
Device_ASN1_Filenames,
Device_ASN1_Typenames,
Device_ASN1_Modules : Vector_Tag;
begin
for Driver of Drivers loop
declare
begin
Device_Names := Device_Names & Driver.Device_Driver_Name;
Device_Package_Names := Device_Package_Names
& Driver.Package_Name;
Device_Classifiers := Device_Classifiers
& Driver.Device_Classifier;
Device_Associated_Processor_Names :=
Device_Associated_Processor_Names
& Driver.Associated_Processor_Name;
Device_Configurations := Device_Configurations
& Driver.Device_Configuration;
Device_Accessed_Bus_Names := Device_Accessed_Bus_Names
& Driver.Accessed_Bus_Name;
Device_Accessed_Port_Names := Device_Accessed_Port_Names
& Driver.Accessed_Port_Name;
Device_ASN1_Filenames := Device_ASN1_Filenames
& Driver.ASN1_Filename;
Device_ASN1_Typenames := Device_ASN1_Typenames
& Driver.ASN1_Typename;
Device_ASN1_Modules := Device_ASN1_Modules
& Driver.ASN1_Module;
Device_Init_Entrypoints := Device_Init_Entrypoints
& Driver.Init_Function;
Device_Init_Languages := Device_Init_Languages
& Driver.Init_Language;
end;
end loop;
return +Assoc ("Device_Names", Device_Names)
& Assoc ("Device_AADL_Pkg", Device_Package_Names)
& Assoc ("Device_Classifier", Device_Classifiers)
& Assoc ("Device_CPU",
Device_Associated_Processor_Names)
& Assoc ("Device_Config", Device_Configurations)
& Assoc ("Device_Bus_Name",
Device_Accessed_Bus_Names)
& Assoc ("Device_Port_Name",
Device_Accessed_Port_Names)
& Assoc ("Device_ASN1_File", Device_ASN1_Filenames)
& Assoc ("Device_ASN1_Sort", Device_ASN1_Typenames)
& Assoc ("Device_ASN1_Module", Device_ASN1_Modules)
& Assoc ("Device_Init", Device_Init_Entrypoints)
& Assoc ("Device_Language", Device_Init_Languages);
end Drivers_To_Template;
---------------------------
-- AST Builder Functions --
---------------------------
......@@ -209,11 +282,38 @@ package body TASTE.Deployment_View is
Accessed_Port : Node_Id;
Device_Implementation : Node_Id;
Configuration_Data : Node_Id;
-- Init_Data is the subprogram containing the initialization function
Driver_Init_Data : Node_Id;
begin
Result.Name := US (Get_Name_String (Name (Identifier (CI))));
-- Get_Implementation returns the "abstract driver" part of the
-- device, which comes from the "Device_Driver" property of the
-- instance
Device_Implementation := Get_Implementation (CI);
-- Devices have a subprogram pointed to by this property:
-- Initialize_Entrypoint => classifier (Native_UART::Initialize);
-- This subprorgam has two properties of interest, e.g.:
-- Source_Name => "PolyORB_HI_Drivers_Native_UART.Initialize";
-- Source_Language => (Ada);
Driver_Init_Data := Get_Classifier_Property
(CI, Get_String_Name ("initialize_entrypoint"));
if Driver_Init_Data /= No_Node and then
Is_Defined_Property (Driver_Init_Data, "source_name")
then
Result.Init_Function :=
US (Get_Name_String (Get_String_Property
(Driver_Init_Data, "source_name")));
else
Result.Init_Function := US ("Error: driver init function missing");
end if;
Result.Init_Language := US (Get_Language (Driver_Init_Data));
Put_Debug ("Driver init: " & To_String (Result.Init_Function));
Put_Debug ("Driver Language: " & To_String (Result.Init_Language));
if Device_Implementation /= No_Node and then
Is_Defined_Property (Device_Implementation,
"deployment::configuration_type")
......@@ -740,6 +840,10 @@ package body TASTE.Deployment_View is
& To_String (Driver.ASN1_Typename));
Put_Line (Output, " |_ ASN.1 Module : "
& To_String (Driver.ASN1_Module));
Put_Line (Output, " |_ Init function : "
& To_String (Driver.Init_Function));
Put_Line (Output, " |_ Language : "
& To_String (Driver.Init_Language));
end loop;
end loop;
end Dump_Nodes;
......
......@@ -39,7 +39,7 @@ package TASTE.Deployment_View is
Empty_Deployment_View_Error : exception;
-- List of Ocarina AADL models needed to parse the deployment view
AADL_Lib : String_Vectors.Vector :=
Deployment_AADL_Lib : String_Vectors.Vector :=
Empty_Vector
& "TASTE_DV_Properties.aadl"
& "TASTE_IV_Properties.aadl"
......@@ -93,14 +93,21 @@ package TASTE.Deployment_View is
Device_Configuration,
Accessed_Bus_Name,
Accessed_Port_Name,
Init_Function,
Init_Language,
ASN1_Filename,
ASN1_Typename,
ASN1_Module : Unbounded_String;
end record;
function Device_Driver_Name (Driver : Taste_Device_Driver) return String;
package Taste_Drivers is
new Indefinite_Vectors (Natural, Taste_Device_Driver);
function Drivers_To_Template (Drivers : Taste_Drivers.Vector)
return Translate_Set;
-- Memory component specified at node level
type Taste_Memory is
record
......
......@@ -105,7 +105,9 @@ package body TASTE.Dump is
Filename : constant String :=
(if Check then Strip_String (Parse (File_Template)) else "");
Trigger : constant Boolean :=
(Check and then (Strip_String (Parse (Trig_Template)) = "TRUE"));
(Check
and then
(String'(Strip_String (Parse (Trig_Template))) = "TRUE"));
IV_Tags : Translate_Set; -- Interface View
DV_Tags : Translate_Set; -- Deployment View
......
......@@ -323,7 +323,7 @@ package body TASTE.Interface_View is
-- Parse a connection
function Parse_Connection (Conn : Node_Id) return Optional_Connection is
use Option_Connection;
use String_Vectors;
Channel_Name : constant String := AIN_Case (Conn);
Channels : String_Vectors.Vector := String_Vectors.Empty_Vector;
......@@ -506,7 +506,7 @@ package body TASTE.Interface_View is
Going_Out : Boolean := False;
Via_Channels : in out String_Vectors.Vector)
return Remote_Entity is
use String_Vectors;
Context : constant String :=
(if Functions.Contains (Key => From)
then To_String (Functions.Element (Key => From).Context)
......@@ -599,7 +599,6 @@ package body TASTE.Interface_View is
when CC_Data =>
declare
CP : constant Context_Parameter := Parse_CP (Subco);
use String_Vectors;
begin
if CP.Sort = "Timer" then
Result.Timers := Result.Timers
......@@ -1046,6 +1045,7 @@ package body TASTE.Interface_View is
& Assoc ("Language", Language_Spelling (F));
Result.Provided := Result.Provided & Interface_Tmplt;
-- Note: List of PIs include timers, while List_Of_(A)Sync do not.
List_Of_PIs := List_Of_PIs & Each.Name;
case Each.RCM is
when Cyclic_Operation | Sporadic_Operation =>
......
......@@ -26,14 +26,22 @@ use Ada.Containers,
package TASTE.Interface_View is
use Option_UString;
use Option_ULL;
use Option_UString,
Option_ULL,
String_Vectors;
-- Exceptions specific to the Interface View
No_RCM_Error : exception; -- Missing Periodic, Sporadic... property
Interface_Error : exception; -- Any kind of interface parsing error
Function_Error : exception; -- Any kind of function parsing error
-- List of Ocarina AADL models needed to parse the interface view
Interface_AADL_Lib : String_Vectors.Vector :=
Empty_Vector
& "TASTE_IV_Properties.aadl"
& "taste_properties.aadl"
& "arinc653.aadl";
type Synchronism is (Sync, Async);
function Get_Language (E : Node_Id) return String;
......
......@@ -122,6 +122,9 @@ package body TASTE.Parser_Utils is
return Ada.Strings.Fixed.Trim (Input_String, Strip_Set, Strip_Set);
end Strip_String;
function Strip_String (Input_US : Unbounded_String) return Unbounded_String
is (US (Strip_String (To_String (Input_US))));
-- str.join as in Python - join string arrays with a separator
function Join_Strings (Str_Set : String_Sets.Set;
Sep : String := ", ";
......@@ -175,7 +178,11 @@ package body TASTE.Parser_Utils is
Command : constant String := Ada.Command_Line.Command_Name;
use String_Holders;
IV, DeplV, DataV, OutDir : aliased GNAT.Strings.String_Access := null;
IV,
DeplV,
DataV,
OutDir,
Target : aliased GNAT.Strings.String_Access := null;
begin
-- Retrieve the path of the kazoo binary, to have a base prefix
-- to find the templates folder
......@@ -237,6 +244,11 @@ package body TASTE.Parser_Utils is
Long_Switch => "--output=",
Help => "Output directory (created if absent)",
Argument => "Folder");
Define_Switch (Config, Output => Target'Access,
Switch => "-t:",
Long_Switch => "--target=",
Help => "User-defined target (default pohic)",
Argument => "pohic");
Define_Switch (Config, Output => Result.Skeletons'Access,
Switch => "-w",
Long_Switch => "--gw",
......@@ -299,6 +311,11 @@ package body TASTE.Parser_Utils is
then To_Holder (OutDir.all)
else To_Holder ("."));
Result.Target :=
(if Target /= null and then Target.all'Length > 0
then To_Holder (Target.all)
else To_Holder ("pohic"));
if Version then
raise Exit_From_Command_Line;
end if;
......@@ -331,6 +348,7 @@ package body TASTE.Parser_Utils is
& Assoc ("Binary_Path", Config.Binary_Path.Element)
& Assoc ("Check_Data_View", Config.Check_Data_View)
& Assoc ("Output_Dir", Config.Output_Dir.Element)
& Assoc ("Target", Config.Target.Element)
& Assoc ("Skeletons", Config.Skeletons)
& Assoc ("Glue", Config.Glue)
& Assoc ("Use_POHIC", Config.Use_POHIC)
......
......@@ -65,7 +65,9 @@ package TASTE.Parser_Utils is
(if Is_Tty then ASCII.ESC & "[4m" else "");
function White_Bold return String is (if Is_Tty then White & Bold else "");
-- Remove spaces/newlines at beginning/end of string
function Strip_String (Input_String : String) return String;
function Strip_String (Input_US : Unbounded_String) return Unbounded_String;
procedure Put_Info (Info : String);
procedure Put_Error (Error : String);
......@@ -175,11 +177,12 @@ package TASTE.Parser_Utils is
subtype String_Holder is String_Holders.Holder;
type Taste_Configuration is tagged
record
Binary_Path : String_Holder;
Interface_View : String_Holder;
Deployment_View : String_Holder;
Data_View : String_Holder;
Output_Dir : String_Holder;
Binary_Path,
Interface_View,
Deployment_View,
Data_View,
Output_Dir,
Target : String_Holder;
Check_Data_View : aliased Boolean := False;
Skeletons : aliased Boolean := True;
Glue : aliased Boolean := False;
......
Subproject commit 88525f472cf7d79abf572d2d6fe773b9c7934fdc
Subproject commit 844cfcc630139c0c9c3c2c41f549946a26ee06c0
@@-- The following tags are available in this template:
@@--
@@-- @_Thread_Name_@ : Thread name
@@-- @_Partition_Name_@ : Partition containing this thread
@@-- @_Entry_Port_Name_@ : Name of the PI
@@-- @_RCM_@ : One of "CYCLIC_OPERATION", "SPORADIC_OPERATION"
@@-- @_Need_Mutex_@ : True if the PI is shared with others in the protected block
@@-- @_Pro_Block_Name_@ : Name of the protected function
@@-- @_Node_Name_@ : Name of the deployment node
@@-- @_Remote_Threads_@ : Vector tag: output remote thread list
@@-- @_RI_Port_Name_@ : |_ Corresponding local RI name
@@-- @_Remote_PIs_@ : |_ Associated PI Name
@@-- @_Remote_PI_Sorts_@ : |_ Optional param type of the remote thread
@@-- @_Remote_PI_Modules_@ : |_ Asn1 module of the optional param type
@@-- @_Thread_Name_@ : Thread name
@@-- @_Partition_Name_@ : Partition containing this thread
@@-- @_Entry_Port_Name_@ : Name of the PI
@@-- @_RCM_@ : One of "CYCLIC_OPERATION", "SPORADIC_OPERATION"
@@-- @_Need_Mutex_@ : True if the PI is shared with others in the protected block
@@-- @_Pro_Block_Name_@ : Name of the protected function
@@-- @_Node_Name_@ : Name of the deployment node
@@-- @_Remote_Threads_@ : Vector tag: output remote thread list
@@-- @_RI_Port_Name_@ : |_ Corresponding local RI name
@@-- @_Remote_PIs_@ : |_ Associated PI Name
@@-- @_Remote_PI_Sorts_@ : |_ Optional param type of the remote thread
@@-- @_Remote_PI_Modules_@ : |_ Asn1 module of the optional param type
@@-- @_Priority_@ : Thread priority
@@-- @_Dispatch_Offset_ms_@ : Dispatch offset (in ms)
@@-- @_Stack_Size_In_Bytes_@ : Stack size in bytes
@@-- Tags related to the PI that is at the origin of the thread creation:
@@-- @_Name_@, @_Kind_@, @_Parent_Function_@ : shoud be useless here
@@-- @_Param_Names_@, _Types_@, _ASN1_Modules, _Encodings_@, _Directions_@ : param vector tag
......@@ -81,10 +84,10 @@ properties
@@ELSE@@
Period => 1 ms;
@@END_IF@@
Dispatch_Offset => 0 ms;
Dispatch_Offset => @_Dispatch_Offset_ms_@ ms;
Compute_Execution_Time => @_WCET_@ ms .. @_WCET_@ ms;
Stack_Size => 50 KByte;
Priority => 1;
Stack_Size => @_Stack_Size_In_Bytes_@ Bytes;
Priority => @_Priority_@;
end @_CAPITALIZE:Thread_Name_@.others;
end @_CAPITALIZE:Thread_Name_@_Thread;
......@@ -7,11 +7,14 @@
@@-- @_Blocks_@ : Code generated for protected functions
@@-- @_Block_Names@ : Vector Tag: list of block (user functions) names
@@-- @_Block_Languages@ : |_ Corresponding implementation language
@@-- @_Block_Instance_Of_@: |_ Name of parent function (if instance)
@@-- @_Coverage_@ : True if user requested code coverage enable
@@-- @_Package_Name_@ : AADL Package name for the target (e.g. ocarina_porocessors_x86)
@@-- @_CPU_Name_@ : CPU Name (e.g. x86_linux)
@@-- @_CPU_Platform_@ : AADL CPU_Platform (e.g. PLATFORM_NATIVE)
@@-- @_CPU_Classifier_@ : AADL CPU Classifier (e.g. ocarina_processors_x86::x86.linux)
@@-- @_CPU_Family_@ : e.g. gr740 or x86
@@-- @_CPU_Instance_@ : e.g. rtems51_posix or linux
@@-- @_VP_Name_@ : Virtual processor name on which the partition is bounded
@@-- @_VP_Platform_@ : Virtual processor platform (e.g. PLATFORM_AIR)
@@-- @_VP_Classifier_@ : Virtual processor classifier
......@@ -71,6 +74,10 @@ project @_CAPITALIZE:Name_@ is
"../../@_LOWER:Block_Names_@/@_Block_Languages_@/src",
@@END_IF@@
"../../@_LOWER:Block_Names_@/@_Block_Languages_@/wrappers",
@@-- Instances: Add the folder of the parent function (in C++ and Ada)
@@IF@@ @_EXIST:Block_Instance_Of_@ and (@_Block_Languages_@ = CPP or @_Block_Languages_@ = Ada)
"../../@_LOWER:Block_Instance_Of_@/@_Block_Languages_@/src",
@@END_IF@@
@@END_TABLE@@
"../deploymentview_final/@_LOWER:Name_@")
& external_as_list("EXTERNAL_SOURCE_PATH", ":")
......