Commit 0266a2e0 authored by Maxime Perrotin's avatar Maxime Perrotin
Browse files

Stronger type system

parent 74e305fe
......@@ -2,7 +2,7 @@
 
# Resource object code
#
# Created: Wed Jun 18 19:48:04 2014
# Created: Wed Jun 18 20:54:58 2014
# by: The Resource Compiler for PySide (Qt v4.8.6)
#
# WARNING! All changes made in this file will be lost!
......@@ -75,7 +75,9 @@ TMPVAR = 0
# ASN.1 types used to support the signature of special operators
INTEGER = type('IntegerType', (object,), {'kind': 'IntegerType'})
INT32 = type('Integer32Type', (object,), {'kind': 'Integer32Type'})
INT32 = type('Integer32Type', (object,), {'kind': 'Integer32Type',
'Min':'-2147483648',
'Max':'2147483647'})
NUMERICAL = type('NumericalType', (object,), {'kind': 'Numerical'})
TIMER = type('TimerType', (object,), {'kind': 'TimerType'})
REAL = type('RealType', (object,), {'kind': 'RealType'})
......@@ -427,6 +429,22 @@ def check_and_fix_op_params(op_name, expr_list, context):
.format(expr.right.inputString))
def check_range(typeref, type_to_check):
''' Verify the that the Min/Max bounds of two types are compatible
Called to test that assignments are withing allowed range
both types assumed to be basic types
'''
try:
if float(type_to_check.Min) < float(typeref.Min) \
or float(type_to_check.Max) > float(typeref.Max):
raise TypeError('Expression evaluation in range [{}..{}], '
'outside expected range [{}..{}]'
.format(type_to_check.Min, type_to_check.Max,
typeref.Min, typeref.Max))
except AttributeError:
raise TypeError('Missing range')
def check_type_compatibility(primary, typeRef, context):
'''
Check if an ogAST.Primary (raw value, enumerated, ASN.1 Value...)
......@@ -486,9 +504,11 @@ def check_type_compatibility(primary, typeRef, context):
elif isinstance(primary, ogAST.PrimInteger) \
and actual_type.kind.startswith('Integer'):
return
elif isinstance(primary, ogAST.PrimReal) \
and actual_type.kind.startswith('Real'):
return
elif isinstance(primary, ogAST.PrimBoolean) \
and actual_type.kind.startswith('Boolean'):
return
......@@ -631,9 +651,18 @@ def compare_types(type_a, type_b):
'StringType'):
# Allow Octet String values to be printable strings.. for convenience
return
elif not(type_a.kind in ('IntegerType', 'Integer32Type', 'RealType') and
type_b.kind in ('IntegerType', 'Integer32Type', 'RealType')):
raise TypeError('Int/Real mismatch')
elif not(type_a.kind in ('IntegerType', 'Integer32Type') and
type_b.kind in ('IntegerType', 'Integer32Type')):
raise TypeError('One type is an integer, not the other one')
elif any(side.kind == 'RealType' for side in (type_a, type_b)):
raise TypeError('One type is an REAL, not the other one')
elif all(side.kind.startswith('Integer') for side in (type_a, type_b)) \
or all(side.kind == 'RealType' for side in (type_a, type_b)):
pass # XXX no need for type check here, only at assignments
# if float(type_b.Min) < float(type_a.Min) \
# or float(type_b.Max) > float(type_a.Max):
# raise TypeError('Range [{}..{}] incompatible with range [{}..{}]'
# .format(type_b.Min, type_b.Max, type_a.Min, type_a.Max))
else:
return
......@@ -697,6 +726,17 @@ def find_type(path, context):
break
else:
if main.lower() in SPECIAL_OPERATORS:
param = path[1].get('procParams') or []
if not param:
raise TypeError('Missing parameter in {} operator call'
.format(main))
# Retrieve type of first parameter - all operators need it
first_param = param[0]
first_type = find_variable(first_param.inputString, context)\
if first_param.exprType == UNKNOWN_TYPE else \
first_param.exprType
first_basic = find_basic_type(first_type)
# Special operators require type elaboration
if main.lower() == 'present':
result = type('present', (object,),
......@@ -704,33 +744,45 @@ def find_type(path, context):
'EnumValues': {}})
# present(choiceType): must return an enum
# with elements being the choice options
param, = path[1].get('procParams') or [None]
if not param:
raise TypeError('Missing parameter in PRESENT clause')
if len(param) != 1:
raise TypeError('Wrong number of parameters in '
'PRESENT clause (only one expected)')
if first_basic.kind != 'ChoiceType':
raise TypeError('PRESENT parameter'
' must be a CHOICE type:' + str(path))
else:
check_type = find_variable(param.inputString, context)\
if param.exprType == UNKNOWN_TYPE else \
param.exprType
param_type = find_basic_type(check_type)
if param_type.kind != 'ChoiceType':
raise TypeError('PRESENT parameter'
' must be a CHOICE type:' + str(path))
else:
result.EnumValues = param_type.Children
elif main.lower() in ('length', 'abs', 'fix'):
# XXX length et abs: we must set Min and Max
# and abs may return a RealType, not always integer
result = INTEGER
# type('lenabs', (object,), {'kind': 'IntegerType'})
result.EnumValues = first_basic.Children
elif main.lower() in ('length', 'fix'):
if len(param) != 1:
raise TypeError('Wrong number of parameters in {} '
'operator'.format(main))
# result is an integer type with range of the param type
result = type('fix', (INTEGER,), {'Min': first_basic.Min,
'Max': first_basic.Max})
elif main.lower() == 'float':
result = REAL
if len(param) != 1:
raise TypeError('Wrong number of parameters in {} '
'operator'.format(main))
result = type('float_op', (REAL,), {'Min': first_basic.Min,
'Max': first_basic.Max})
elif main.lower() == 'power':
# Result can be int or real, depending on first param
param = path[1].get('procParams')[0]
check_type = find_variable(param.inputString, context) \
if param.exprType == UNKNOWN_TYPE else \
param.exprType
result = find_basic_type(check_type)
second = param[1]
second_type = find_variable(second.inputString, context)\
if second.exprType == UNKNOWN_TYPE else \
second.exprType
second_basic = find_basic_type(second_type)
try:
result = type('Power', (first_basic,),
{'Min':str(pow(float(first_basic.Min),
float(second_basic.Min))),
'Max':str(pow(float(first_basic.Max),
float(second_basic.Max)))})
except OverflowError:
raise TypeError('Result can exceeds 64-bits')
elif main.lower() == 'abs':
result = type('Abs', (first_basic,),
{'Min':str(max(float(first_basic.Min), 0)),
'Max':str(max(float(first_basic.Max), 0))})
else: # write and writeln return void
pass
if result.kind == 'ReferenceType':
......@@ -793,7 +845,6 @@ def fix_expression_types(expr, context):
and isinstance(uk_expr, ogAST.PrimPath) \
and len(uk_expr.value) == 1:
try:
#exprType = find_variable(uk_expr.inputString, context)
exprType = find_variable(uk_expr.value[0], context)
# Differentiate DCL and FPAR variables
use_type = ogAST.PrimVariable
......@@ -901,8 +952,6 @@ def fix_expression_types(expr, context):
expr.right.value['value'] = check_expr.right
elif isinstance(expr.right, ogAST.PrimIfThenElse):
for det in ('then', 'else'):
#if expr.right.value[det].exprType == UNKNOWN_TYPE:
# expr.right.value[det].exprType = expr.left.exprType
# Recursively fix possibly missing types in the expression
check_expr = ogAST.ExprAssign()
check_expr.left = ogAST.PrimPath()
......@@ -934,12 +983,23 @@ def fix_expression_types(expr, context):
else:
raise TypeError('Bitwise operators only work with '
'booleans and arrays of booleans')
if expr.right.is_raw != expr.left.is_raw:
check_type_compatibility(raw_expr, ref_type, context)
raw_expr.exprType = ref_type
if not raw_expr.exprType.kind.startswith(('Integer', 'Real')):
# Raw int/real must keep their type because of the range
# that can be computed
raw_expr.exprType = ref_type
else:
compare_types(expr.left.exprType, expr.right.exprType)
if isinstance(expr, ogAST.ExprAssign):
# Assignment with numerical value: check range
basic = find_basic_type(expr.left.exprType)
if basic.kind.startswith(('Integer', 'Real')):
check_range(basic, find_basic_type(expr.right.exprType))
def expression_list(root, context):
''' Parse a list of expression parameters '''
......@@ -1231,14 +1291,35 @@ def expression(root, context):
lexer.LE,
lexer.IN):
expr.exprType = BOOLEAN
# elif root.type == lexer.PLUS:
# Adjust type constraint upper range with sum of expressions
# Create a new type to store the new constraint
# INCORRECT TO DO IT HERE - we must check right and left types FIRST
# expr.exprType = type('Plus_Type',
# (find_basic_type(expr.left.exprType),), {})
# expr.exprType.Max = str(int(find_basic_type(expr.left.exprType).Max) +
# int(find_basic_type(expr.right.exprType).Max))
# Expressions returning a numerical type must have their range defined
# accordingly with the kind of opration used between operand:
elif root.type in (lexer.PLUS, lexer.ASTERISK, lexer.DASH,
lexer.DIV, lexer.MOD, lexer.REM):
basic = find_basic_type(expr.left.exprType)
left = find_basic_type(expr.left.exprType)
right = find_basic_type(expr.right.exprType)
if isinstance(expr, ogAST.ExprPlus):
attrs = {'Min': str(float(left.Min) + float(right.Min)),
'Max': str(float(left.Max) + float(right.Max))}
expr.exprType = type('Plus', (basic,), attrs)
elif isinstance(expr, ogAST.ExprMul):
attrs = {'Min': str(float(left.Min) * float(right.Min)),
'Max': str(float(left.Max) * float(right.Max))}
expr.exprType = type('Mul', (basic,), attrs)
elif isinstance(expr, ogAST.ExprMinus):
attrs = {'Min': str(float(left.Min) - float(right.Min)),
'Max': str(float(left.Max) - float(right.Max))}
expr.exprType = type('Minus', (basic,), attrs)
elif isinstance(expr, ogAST.ExprDiv):
attrs = {'Min': str(float(left.Min) / float(right.Min)),
'Max': str(float(left.Max) / float(right.Max))}
expr.exprType = type('Div', (basic,), attrs)
elif isinstance(expr, (ogAST.ExprMod, ogAST.ExprRem)):
attrs = {'Min': right.Min, 'Max': right.Max}
expr.exprType = type('Mod', (basic,), attrs)
elif root.type in (lexer.OR, lexer.AND, lexer.XOR):
# in the case of bitwise operators, if both sides are arrays,
# then the result is an array too
......@@ -2710,7 +2791,6 @@ def for_loop(root, context):
forloop['var'] = child.text
# Implicit variable declaration for the iterator
context_scope = dict(context.variables)
#context.variables[child.text] = (INT32, 0)
elif child.type == lexer.VARIABLE:
list_var, err, warn = primary_value(child, context)
forloop['list'] = ogAST.PrimVariable(primary=list_var)
......@@ -2741,7 +2821,21 @@ def for_loop(root, context):
context.variables[forloop['var']] = (forloop['type'], 0)
else:
# Using a range - set type of iterator to standard integer
context.variables[forloop['var']] = (INT32, 0)
start_expr, stop_expr = forloop['range']['start'], \
forloop['range']['stop']
if not start_expr:
r_min = '0'
else:
basic = find_basic_type(start_expr.exprType)
r_min = basic.Min if basic != UNKNOWN_TYPE else '0'
basic = find_basic_type(stop_expr.exprType)
r_max = basic.Max if basic != UNKNOWN_TYPE else '4294967295'
# basic may be UNKNOWN_TYPE if the expression is a
# reference to an ASN.1 constant - their values are not
# currently visible to the SDL parser
result_type = type('for_range', (INT32,), {'Min': r_min,
'Max': r_max})
context.variables[forloop['var']] = (result_type, 0)
forloop['transition'], err, warn = transition(
child, parent=for_loop, context=context)
......
This diff is collapsed.
This diff is collapsed.
......@@ -6,7 +6,7 @@ in (via_toto);
out (ret0);
STATE hello;
SUBSTRUCTURE
/* CIF PROCEDURE (528, 303), (73, 35) */
/* CIF PROCEDURE (892, 436), (73, 35) */
PROCEDURE entry;
/* CIF START (178, 136), (70, 35) */
START;
......@@ -33,9 +33,9 @@ dcl myresult T_UInt8 := 4;
-- use the proper one
dcl result T_UInt32 := 9;
/* CIF ENDTEXT */
/* CIF PROCEDURE (558, 143), (70, 35) */
/* CIF PROCEDURE (558, 143), (70, 33) */
PROCEDURE exit
/* CIF COMMENT (648, 119), (157, 93) */
/* CIF COMMENT (648, 118), (157, 93) */
COMMENT 'Special exit
procedure - called
automatically when
......@@ -150,14 +150,14 @@ ENDSUBSTRUCTURE;
dcl result T_uint32 :=0;
/* CIF ENDTEXT */
/* CIF PROCEDURE (17, 198), (70, 35) */
/* CIF PROCEDURE (-19, 183), (70, 35) */
PROCEDURE foo;
/* CIF START (190, 53), (70, 35) */
START;
/* CIF RETURN (207, 103), (35, 35) */
RETURN ;
ENDPROCEDURE;
/* CIF PROCEDURE (0, 254), (66, 35) */
/* CIF PROCEDURE (-24, 247), (66, 35) */
PROCEDURE toto;
/* CIF TEXT (371, 134), (298, 140) */
-- Declare your variables
......@@ -172,15 +172,15 @@ START;
DECISION i;
/* CIF ANSWER (131, 206), (73, 23) */
(1):
/* CIF TASK (127, 244), (80, 35) */
TASK i := i + 1;
/* CIF TASK (96, 244), (143, 35) */
TASK i := (i + 1) mod 127;
/* CIF RETURN (150, 294), (35, 35) */
RETURN ;
/* CIF ANSWER (223, 206), (70, 23) */
/* CIF ANSWER (249, 206), (70, 23) */
ELSE:
/* CIF PROCEDURECALL (223, 244), (70, 35) */
/* CIF PROCEDURECALL (249, 244), (70, 35) */
CALL foo;
/* CIF RETURN (240, 294), (35, 35) */
/* CIF RETURN (266, 294), (35, 35) */
RETURN ;
ENDDECISION;
ENDPROCEDURE;
......
/* CIF PROCESS (150, 150), (150, 75) */
PROCESS trafficlight;
STATE Maintenance;
SUBSTRUCTURE
STATE YellowOff;
SUBSTRUCTURE
/* CIF PROCEDURE (239, 367), (73, 35) */
PROCEDURE entry;
/* CIF START (180, 35), (70, 35) */
START;
/* CIF PROCEDURECALL (122, 85), (186, 35) */
CALL set_timer(500, timeout);
/* CIF OUTPUT (109, 135), (211, 35) */
OUTPUT SetTrafficLightColor(all_off);
/* CIF RETURN (197, 185), (35, 35) */
RETURN ;
ENDPROCEDURE;
/* CIF START (348, 437), (70, 35) */
START;
/* CIF NEXTSTATE (348, 487), (70, 35) */
NEXTSTATE idle;
/* CIF STATE (558, 458), (70, 35) */
STATE idle;
ENDSTATE;
ENDSUBSTRUCTURE;
STATE YellowOn;
SUBSTRUCTURE
/* CIF PROCEDURE (291, 312), (73, 35) */
PROCEDURE entry;
/* CIF START (292, 124), (70, 35) */
START;
/* CIF PROCEDURECALL (234, 174), (186, 35) */
CALL set_timer(500, timeout);
/* CIF OUTPUT (221, 224), (211, 35) */
OUTPUT SetTrafficLightColor(yellow);
/* CIF RETURN (309, 274), (35, 35) */
RETURN ;
ENDPROCEDURE;
/* CIF START (495, 331), (70, 35) */
START;
/* CIF NEXTSTATE (489, 381), (81, 35) */
NEXTSTATE idle;
/* CIF STATE (696, 342), (67, 35) */
STATE idle;
ENDSTATE;
ENDSUBSTRUCTURE;
/* CIF START (752, 254), (70, 35) */
START;
/* CIF PROCEDURECALL (671, 304), (231, 35) */
CALL writeln('Entering Maintenance');
/* CIF NEXTSTATE (740, 354), (94, 35) */
NEXTSTATE YellowOn;
/* CIF STATE (738, 459), (97, 35) */
STATE YellowOff;
/* CIF INPUT (743, 514), (87, 35) */
INPUT timeout;
/* CIF NEXTSTATE (736, 564), (102, 35) */
NEXTSTATE YellowOn;
ENDSTATE;
/* CIF STATE (740, 354), (94, 35) */
STATE YellowOn;
/* CIF INPUT (743, 409), (87, 35) */
INPUT timeout;
/* CIF NEXTSTATE (738, 459), (97, 35) */
NEXTSTATE YellowOff;
ENDSTATE;
ENDSUBSTRUCTURE;
STATE on;
SUBSTRUCTURE
STATE PedWaiting;
......@@ -75,6 +7,15 @@ SUBSTRUCTURE
out (counter_expired);
STATE waitOn;
SUBSTRUCTURE
/* CIF PROCEDURE (560, 288), (70, 35) */
PROCEDURE exit;
/* CIF START (280, 159), (70, 35) */
START;
/* CIF TASK (198, 209), (233, 35) */
TASK counter := (counter + 1) mod 255;
/* CIF RETURN (297, 259), (35, 35) */
RETURN ;
ENDPROCEDURE;
/* CIF PROCEDURE (548, 222), (73, 35) */
PROCEDURE entry;
/* CIF START (185, 47), (70, 35) */
......@@ -84,15 +25,6 @@ CALL set_timer(500, timeout);
/* CIF RETURN (202, 147), (35, 35) */
RETURN ;
ENDPROCEDURE;
/* CIF PROCEDURE (560, 288), (70, 35) */
PROCEDURE exit;
/* CIF START (280, 159), (70, 35) */
START;
/* CIF TASK (230, 209), (170, 35) */
TASK counter := counter + 1;
/* CIF RETURN (297, 259), (35, 35) */
RETURN ;
ENDPROCEDURE;
/* CIF START (371, 56), (70, 35) */
START;
/* CIF NEXTSTATE (347, 106), (117, 35) */
......@@ -227,6 +159,74 @@ INPUT PedestrianRequest
NEXTSTATE PedWaiting;
ENDSTATE;
ENDSUBSTRUCTURE;
STATE Maintenance;
SUBSTRUCTURE
STATE YellowOff;
SUBSTRUCTURE
/* CIF PROCEDURE (239, 367), (73, 35) */
PROCEDURE entry;
/* CIF START (180, 35), (70, 35) */
START;
/* CIF PROCEDURECALL (122, 85), (186, 35) */
CALL set_timer(500, timeout);
/* CIF OUTPUT (109, 135), (211, 35) */
OUTPUT SetTrafficLightColor(all_off);
/* CIF RETURN (197, 185), (35, 35) */
RETURN ;
ENDPROCEDURE;
/* CIF START (348, 437), (70, 35) */
START;
/* CIF NEXTSTATE (348, 487), (70, 35) */
NEXTSTATE idle;
/* CIF STATE (558, 458), (70, 35) */
STATE idle;
ENDSTATE;
ENDSUBSTRUCTURE;
STATE YellowOn;
SUBSTRUCTURE
/* CIF PROCEDURE (291, 312), (73, 35) */
PROCEDURE entry;
/* CIF START (292, 124), (70, 35) */
START;
/* CIF PROCEDURECALL (234, 174), (186, 35) */
CALL set_timer(500, timeout);
/* CIF OUTPUT (221, 224), (211, 35) */
OUTPUT SetTrafficLightColor(yellow);
/* CIF RETURN (309, 274), (35, 35) */
RETURN ;
ENDPROCEDURE;
/* CIF START (495, 331), (70, 35) */
START;
/* CIF NEXTSTATE (489, 381), (81, 35) */
NEXTSTATE idle;
/* CIF STATE (696, 342), (67, 35) */
STATE idle;
ENDSTATE;
ENDSUBSTRUCTURE;
/* CIF START (752, 254), (70, 35) */
START;
/* CIF PROCEDURECALL (671, 304), (231, 35) */
CALL writeln('Entering Maintenance');
/* CIF NEXTSTATE (740, 354), (94, 35) */
NEXTSTATE YellowOn;
/* CIF STATE (738, 459), (97, 35) */
STATE YellowOff;
/* CIF INPUT (743, 514), (87, 35) */
INPUT timeout;
/* CIF NEXTSTATE (736, 564), (102, 35) */
NEXTSTATE YellowOn;
ENDSTATE;
/* CIF STATE (740, 354), (94, 35) */
STATE YellowOn;
/* CIF INPUT (743, 409), (87, 35) */
INPUT timeout;
/* CIF NEXTSTATE (738, 459), (97, 35) */
NEXTSTATE YellowOff;
ENDSTATE;
ENDSUBSTRUCTURE;
/* CIF TEXT (-2, 10), (271, 250) */
TIMER timeout;
......@@ -238,12 +238,6 @@ dcl request T_Boolean;
START;
/* CIF NEXTSTATE (298, 100), (70, 35) */
NEXTSTATE Off;
/* CIF STATE (694, 56), (70, 35) */
STATE on;
ENDSTATE;
/* CIF STATE (554, 53), (116, 35) */
STATE Maintenance;
ENDSTATE;
/* CIF STATE (380, 54), (160, 35) */
......@@ -267,5 +261,11 @@ ELSE:
NEXTSTATE Maintenance;
ENDDECISION;
ENDSTATE;
/* CIF STATE (554, 53), (116, 35) */
STATE Maintenance;
ENDSTATE;
/* CIF STATE (694, 56), (70, 35) */
STATE on;
ENDSTATE;
ENDPROCESS trafficlight;
\ No newline at end of file
/* CIF PROCESS (150, 150), (150, 75) */
PROCESS orchestrator;
/* CIF TEXT (-354, 12), (289, 173) */
-- GNC Orchestrator for the VEGA simulator
......@@ -62,12 +63,12 @@ COMMENT 'Set data computed
by the Simulink model
(Simulator) in the GNC
input vector';
/* CIF PROCEDURECALL (314, 232), (100, 50) */
/* CIF PROCEDURECALL (313, 232), (100, 50) */
CALL Scheduler
(intr)
/* CIF COMMENT (434, 232), (170, 50) */
COMMENT 'Call the GNC function';
/* CIF PROCEDURECALL (181, 297), (366, 50) */
/* CIF PROCEDURECALL (180, 297), (366, 50) */
CALL S_GET_GNC_LV_SIM_INPUTS_FOR_NEXT_MAJOR_CYCLE
(gnc_output)
/* CIF COMMENT (567, 297), (175, 50) */
......@@ -87,9 +88,9 @@ COMMENT 'Plot only every 50 major cycles
(otherwise performance is too low)';
/* CIF ANSWER (254, 562), (100, 35) */
(true):
/* CIF TASK (169, 612), (270, 68) */
/* CIF TASK (166, 612), (276, 68) */
TASK plot_data!major_cycle := major_cycle,
plot_data!subcycle := sub_cycle,
plot_data!subcycle := sub_cycle mod 7,
plot_data!gnc_inputs := gnc_input,
plot_data!gnc_outputs := gnc_output;
/* CIF OUTPUT (224, 695), (159, 50) */
......@@ -97,21 +98,21 @@ OUTPUT plot(plot_data);
/* CIF ANSWER (449, 562), (100, 35) */
(false):
ENDDECISION;
/* CIF DECISION (305, 760), (118, 70) */
/* CIF DECISION (304, 760), (118, 70) */
DECISION sub_cycle = 7
/* CIF COMMENT (443, 770), (199, 50) */
COMMENT 'Compute next major cycle';
/* CIF ANSWER (197, 850), (100, 35) */
/* CIF ANSWER (165, 850), (100, 35) */
(true):
/* CIF TASK (137, 900), (220, 53) */
/* CIF TASK (74, 900), (283, 53) */
TASK sub_cycle := 0,
major_cycle := major_cycle + 1;
/* CIF PROCEDURECALL (127, 968), (240, 50) */
major_cycle := (major_cycle + 1) mod 100;
/* CIF PROCEDURECALL (95, 968), (240, 50) */
CALL S_JUMP_TO_NEXT_MAJOR_CYCLE;
/* CIF ANSWER (424, 850), (100, 35) */
/* CIF ANSWER (445, 850), (100, 35) */
(false):
/* CIF TASK (377, 900), (194, 50) */
TASK sub_cycle := sub_cycle + 1;
/* CIF TASK (367, 900), (257, 50) */
TASK sub_cycle := (sub_cycle + 1) mod 100;
ENDDECISION;
/* CIF NEXTSTATE (314, 1033), (100, 50) */
NEXTSTATE Running;
......
/* CIF PROCESS (150, 150), (150, 75) */
PROCESS fce;
/* CIF TEXT (0, 597), (320, 142) */
-- The task of the FCE is to serve as a backup
-- for S/C attitude control
-- The FCE SW is designed to be independent
-- from the OBC CSW to prevent any failure
-- propagation from OBC to FCE
/* CIF ENDTEXT */
/* CIF TEXT (0, 5), (442, 584) */
-- Declaration of variables stored in RAM
......@@ -38,14 +47,6 @@ DCL FCE_Stop_Control Bool_ty := false;
-- As defined in Figure 6-6
TIMER mmo_sep_check_delay;
/* CIF ENDTEXT */
/* CIF TEXT (0, 597), (320, 142) */
-- The task of the FCE is to serve as a backup
-- for S/C attitude control
-- The FCE SW is designed to be independent
-- from the OBC CSW to prevent any failure
-- propagation from OBC to FCE
/* CIF ENDTEXT */
/* CIF PROCEDURE (8, 823), (135, 64) */
PROCEDURE Bootup_actions;
/* CIF TEXT (0, 0), (387, 130) */
......@@ -67,34 +68,21 @@ COMMENT 'determine: