------------------------------------------------------------------------------ ------------------------------------------------------------------------------ -- Cheddar is a GNU GPL real time scheduling analysis tool. -- This program provides services to automatically check performances -- of real time architectures. -- -- Copyright (C) 2002-2010, by Frank Singhoff, Alain Plantec, Jerome Legrand -- -- The Cheddar project was started in 2002 by -- the LISyC Team, University of Western Britanny. -- -- Since 2008, Ellidiss technologies also contributes to the development of -- Cheddar and provides industrial support. -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 2 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- -- -- Contact : cheddar@listes.univ-brest.fr -- ----------------------------------------------------------------------------- -- Last update : -- $Rev: 523 $ -- $Date: 2012-09-26 15:09:39 +0200 (Wed, 26 Sep 2012) $ -- $Author: fotsing $ ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ with framework_config; use framework_config; with Translate; use Translate; with Ada.Exceptions; use Ada.Exceptions; with tasks; use tasks; with Task_Set; use Task_Set; use Task_Set.Generic_Task_Set; with Address_Spaces; use Address_Spaces; with Address_Space_Set; use Address_Space_Set; use address_space_Set.Generic_address_space_Set; with scheduler_interface; use scheduler_interface; with time_unit_events; use time_unit_events; use time_unit_events.Time_Unit_Package; with arinc_653_schema; use arinc_653_schema; use arinc_653_schema.PartitionType_List_package; use arinc_653_schema.ProcessType_List_package; use arinc_653_schema.Partition_Schedule_element_List_package; use arinc_653_schema.Window_Schedule_Element_List_Package; with Ada.Numerics.Aux; use Ada.Numerics.Aux; with framework; use framework; with scheduling_analysis; use scheduling_analysis; package body arinc_653_Services is procedure Check_Arinc_653 (Sys : in System) is Ad_Iterator : address_spaces_iterator; Ta_Iterator : Tasks_Iterator; current_scheduler : Schedulers_Type; A_Address_space : address_space_ptr; begin if (get_number_of_elements (sys.Address_Spaces) > 0) then reset_iterator (sys.Address_Spaces, Ad_Iterator); current_element (sys.Address_Spaces, A_Address_Space, Ad_Iterator); current_scheduler:=a_address_space.scheduling.scheduler_type; if (current_scheduler /= Hierarchical_Cyclic_Protocol) and (current_scheduler /= Hierarchical_Round_Robin_Protocol) then Raise_Exception (Invalid_scheduler'Identity, To_String ( Lb_Invalid_Scheduler(Current_Language))); end if; reset_iterator (sys.Address_Spaces, Ad_Iterator); loop current_element (sys.Address_Spaces, A_Address_Space, Ad_Iterator); if (current_scheduler /= a_address_space.scheduling.scheduler_type) then Raise_Exception (Invalid_scheduler'Identity, To_String ( Lb_require_same_Scheduler_on_all_address_space(Current_Language))); end if; exit when is_last_element (sys.Address_Spaces, Ad_Iterator); next_element (sys.Address_Spaces, Ad_Iterator); end loop; end if; end check_arinc_653; function Build_ARINC653_Module (Sched : in Scheduling_Table_Ptr; Sys : in System; majorTimeFrame : in natural) return ARINC_653_Module_Ptr is a_sched : scheduling_sequence_ptr; a_mod : arinc_653_module_ptr; a_partition : partitiontype_ptr; a_process : processtype_ptr; a_Partition_Schedule_element : Partition_Schedule_Element_ptr; a_window_schedule_element : window_schedule_element_ptr; Ad_Iterator : address_spaces_iterator; Ta_Iterator : Tasks_Iterator; par_Iterator : Partition_Schedule_Element_Iterator; A_task : Generic_task_ptr; A_Address_space : address_space_ptr; begin -- Create the module -- a_mod := new arinc_653_module; a_mod.modulename:=to_unbounded_string("cheddar"); -- Add processes and partitions -- if (get_number_of_elements (sys.Address_Spaces) > 0) then reset_iterator (sys.Address_Spaces, Ad_Iterator); loop current_element (sys.Address_Spaces, A_Address_Space, Ad_Iterator); a_partition:=new partitiontype; a_partition.partitionname:=a_address_space.name; add(a_mod.partition, a_partition); if (get_number_of_elements (sys.Tasks) > 0) then reset_iterator (sys.Tasks, Ta_Iterator); loop current_element (sys.Tasks, A_Task, Ta_Iterator); a_process:= new processtype; a_process.name:=a_task.name; add(a_partition.process, a_process); exit when is_last_element (sys.Tasks, Ta_Iterator); next_element (sys.Tasks, Ta_Iterator); end loop; end if; exit when is_last_element (sys.Address_Spaces, Ad_Iterator); next_element (sys.Address_Spaces, Ad_Iterator); end loop; end if; -- Export partition scheduling -- a_mod.module_schedule:= new module_schedule_type; a_mod.module_schedule.MajorFrameSeconds:=double(majorTimeFrame); -- Create a Partition_Schedule_Element for each partition -- if (get_number_of_elements (sys.Address_Spaces) > 0) then reset_iterator (sys.Address_Spaces, Ad_Iterator); loop current_element (sys.Address_Spaces, A_Address_Space, Ad_Iterator); a_partition_schedule_element := new partition_schedule_element; a_partition_schedule_element.PartitionName:=a_address_space.name; a_partition_schedule_element.PeriodSeconds:=double(a_address_space.scheduling.period); a_partition_schedule_element.PeriodDurationSeconds:=double(a_address_space.scheduling.capacity); add(a_mod.module_schedule.Partition_Schedule, a_partition_schedule_element); exit when is_last_element (sys.Address_Spaces, Ad_Iterator); next_element (sys.Address_Spaces, Ad_Iterator); end loop; end if; -- Fill each Partition_Schedule_Element with schedule table computed -- by cheddar -- for k in 0 .. Sched.nb_entries - 1 loop a_sched:=sched.entries(k).data.result; for I in 0 .. a_Sched.nb_entries - 1 loop if (a_Sched.entries (I).data.type_of_event = ADDRESS_SPACE_ACTIVATION) then -- Look for the corresponding partition -- reset_head_iterator (a_mod.module_schedule.Partition_Schedule, Par_Iterator); loop current_element (a_mod.module_schedule.Partition_Schedule, a_partition_schedule_element, Par_Iterator); -- Store the event in the PST table -- if (a_partition_schedule_element.partitionName=a_sched.entries(I).data.activation_address_space) then a_window_schedule_element := new window_schedule_element; a_window_schedule_element.windowStartSeconds:=double(a_sched.entries(i).item); a_window_schedule_element.windowDurationSeconds:=double(a_sched.entries(I).data.duration); a_window_schedule_element.PartitionPeriodStart:=false; if (natural(a_partition_schedule_element.PeriodSeconds) /= 0) then if (a_sched.entries(i).item mod natural(a_partition_schedule_element.PeriodSeconds) = 0) then a_window_schedule_element.PartitionPeriodStart:=true; end if; end if; add(a_partition_schedule_element.window_schedule, A_window_schedule_element); end if; exit when is_tail_element (a_mod.module_schedule.Partition_Schedule, Par_Iterator); next_element (a_mod.module_schedule.Partition_Schedule, Par_Iterator); end loop; end if; end loop; end loop; return a_mod; end Build_ARINC653_Module; end arinc_653_Services;