Version 1.19 – release date: June 21, 2017

We are pleased to announce the release of CPAL V1.19. This release improves the usability of the multi-interpreteur whose purpose is to simulate CPAL programs executed on distinct computing resources for instance to model multicore/distributed systems. Precisely, a new programmatic way to configure the simulation replaces a csv file. In addition, a few constructs that ease the use of the language and the code generation to C language have also been added.

Note: this is a maintenance release distributed only as command-line binaries for Windows, Mac and Linux platforms. Users of the CPAL-editor should update the path to the binaries manually in “Edition – Parameters” menu of the editor.

What is new

  • ADDED: partial and empty initialization of collections

    
    /* Partial init of queue, stack and arrays */
    var queue<uint8>: q1[5]  = {1, 2};
    var stack<uint8>: s1[10] = {3, 4, 5};
    var queue<uint8>: a1[10] = {1, 2, 3};
    
    /* Empty init of a collection needed in struct. initialization */
    struct A_Struct {
      stack<uint8>: s2[10];
      uint8: x;
    };
    
    var A_Struct: foo = { {}, 2 };
    
    init() {
      assert(q1.count() == 2);
      assert(s1.count() == 3);
      assert(foo.s2.is_empty());
    }
    
    
  • ADDED: insertions in collections holding simple scalar types (integers and floating point values) can be performed in a sorted manner (increasing order of numerical value), using insert_sorted()

    
    init()
    {
      var queue<uint8>: q[6] = {3,7}; /* partial init */
      q.push(4); /* 4 is placed at the tail of the queue */
      q.insert_sorted(5);  /* sorted insertion from the head of the queue */
      q.insert_sorted(1);  /* first position */
      q.insert_sorted(10); /* last position */
      loop over q with it {
        IO.print("%u ", it.current); /* 1 3 5 7 4 10 */
      }
    }
    
  • ADDED: iterate over the list of processes though system.processes variable for introspection at runtime, here for instance to compute the CPU load

    
    processdef A_Proc()
    {
        state Main {
        }
    }
    
    process A_Proc: p1[100ms]();
    process A_Proc: p2[200ms]();
    
    @cpal:time
    {
        p1.execution_time = 50ms;
        p2.execution_time = 50ms;
    }
    
    init()
    {
        var float64: load = 0.0;
        loop over system.processes with it {
            IO.println("id: %u period %t\n", it.current.pid, it.current.period);
            load = load + float64.as(it.current.execution_time) / float64.as(it.current.period);
        }
        IO.println("system load %f\n", load);
    }
    
  • ADDED: programmatic configuration of the multi-interpreter illustrated below with a 10 nodes CAN network, where the behaviour of node X is defined in Ecu_X.ast file and the communication channels between the node and the CAN bus are resp. powertrain50_Ecu_%u_out (sent frames) and powertrain50_Ecu_%u_in (received frames).

    
    include "annotations/simu/multi.cpal"
    var System_Multi: can_hs_wfcs_2010;
    init()
    {
            var Cpal_Node: ecu;
            var Cpal_Flow: dataflow;
            var Cpal_Node: powertrain50 = {
                     "powertrain50",
                     "powertrain50.ast",
                    Scheduling_Policy.FIFO
            };
            var uint8: i = 0;
            can_hs_wfcs_2010.nodes.push(powertrain50);
            for (i=0;i<10;i=i+1) {
                    uint8.print(ecu.name,"Ecu_%u", i);
                    uint8.print(ecu.model_file,"Ecu_%u.ast", i);
                    ecu.sched_policy = Scheduling_Policy.FIFO;
                    can_hs_wfcs_2010.nodes.push(ecu);
                    dataflow.src.node= ecu;
                    uint8.print(dataflow.src.name,"powertrain50_Ecu_%u_out",i);
                    dataflow.target.node= powertrain50;
                    uint8.print(dataflow.target.name,"powertrain50_Ecu_%u.intf",i);
                    can_hs_wfcs_2010.flows.push(dataflow);
            }
    }
    
    

What has been fixed or changed

  • Possibility to use process instance name in process instantiation

    
    processdef A_Proc(in Process_Instance: p, in time64 :  period)
    {
            state Main {
                    assert(p.period==100ms);
                    assert(period==100ms);
            }
    }
     /* process can be used in the arguments of its own instantiation */
    process A_Proc: p[100ms](p, p.period);
    

Test coverage metrics (figures for embedded Linux platform)

  • Test code coverage for parser, runtime engine and cpal2x: 83.1% (lines of code), 92.2% (functions) and 72.9% (branches)
  • Tests: parser=3971, interpreter=866, cpal2x=1937