Version 1.15 – released on April 5, 2016

This release brings several improvements in the timing domain: tasks with variable jitters (for the purpose of simulation), process periods can now be specified in Herz and the addition of two new scheduling policies: non-preemptive Earliest Deadline First (NPEDF) and non-preemptive Fixed Priority (NPFP). It features also scientific notations for floating point constants and communication over UDP/Ethernet in real-time execution mode. Under the hood, the code of the execution engine has been partly rewritten to comply with the subset of the CERT C Coding Standard that is relevant to CPAL.

If you experience issues, or simply need help with CPAL, you are much welcome to contact us.

What is new

  • Added non-preemptive Earliest Deadline First (NPEDF) scheduling with interpreter option -p EDFNP (or --policy EDFNP). Relative deadlines are to be indicated in @CPAL:sched timing annotations (default value is the process period)

    x
     
    1
    2
    processdef Simple() {
    3
      state Main {
    4
        IO.println("relative deadline: %t", self.deadline); 
    5
      }
    6
    }
    7
    8
    process Simple: p1[10ms]();
    9
    process Simple: p2[15ms]();
    10
    11
    @CPAL:sched {
    12
      p1.deadline = 8ms;
    13
      p2.deadline = 15ms;
    14
    }
    15
    • Added non-preemptive Fixed Priority (NPFP) scheduling with interpreter option -p FPNP (or --policy FPNP). Priorities are specified through @CPAL:sched timing annotations (the default relative priority of the processes is their order of instanciation in the code)

      15
       
      1
      2
      processdef Simple() {
      3
        state Main {
      4
          IO.println("process priority: %u", self.priority); 
      5
        }
      6
      }
      7
      8
      process Simple: p1[10ms]();
      9
      process Simple: p2[15ms]();
      10
      11
      @CPAL:sched {
      12
        p1.priority = 1;
      13
        p2.priority = 2;
      14
      }
      15
    • Added new time unit Herz (Hz), quantities expressed in Herz are converted in picoseconds upon their assignment (#249)

      13
       
      1
      2
      const time64: frequency = 0.25Hz; /* converted to 4s */
      3
      const time64: max_frequency = 1000000000000.0Hz; /* 1ps */
      4
      const time64: min_frequency = 0.0000001Hz; /* more than 115 days */
      5
      6
      processdef Simple() {
      7
        state Main {
      8
          assert((self.period >= max_frequency) and (self.period <= min_frequency)); 
      9
        }
      10
      }
      11
      12
      process Simple: p1[frequency]();
      13
    • Added jitter timing annotation to enforce process activation jitters in simulation mode

      16
       
      1
      2
      const time64: min_jitter = 0ms;
      3
      const time64: max_jitter = 10ms;
      4
      const time64: period = 100ms;
      5
      6
      processdef Simple() {
      7
        state Main {
      8
          IO.println("%t %t", self.current_activation, self.previous_activation);
      9
        }
      10
      }
      11
      12
      process Simple: p1[period] ();
      13
      @cpal:sched{
      14
          p1.jitter = time64.rand_uniform(min_jitter, max_jitter);
      15
      }
      16
    • Added absolute value functions int8.abs(int8), int16.abs(int16), int32.abs(int32), int64.abs(int64) and float32.abs(float32) (#280)
    • Added scientific notations for floating point values. Supported formats are 3.14e5, 3.14E5, 3.14e+5, 3.14E+5, 3.14e-5, 3.14E-5 (#290)
    • Added command-line option -z (or --silent) to the interpreter to suppress all ouputs to the console during execution, including IO.print(ln) statements. This makes a huge difference in speed during simulations (#298)
    • Added send and receive messages over UDP/Ethernet on Linux64 real-time execution engine with simulation working on all platforms (#301)

    What has been fixed or improved

    • Fixed inconsistent scheduler behavior in overload conditions (#180)
    • Parser slow on large source files (#277)
    • Fixed wrong behavior with guarded executions (#284)
    • time taken by sleep() is not shown in the task execution Gantt chart of the CPAL-Editor (#295)

    Code metrics and overhead data

    • Test code coverage for the execution engine: 87.1% (lines of code), 90.8% (functions) and 73.3% (branches)
    • Tests: parser=3817, interpreter=786, embedded targets=381
    • Timing overhead (Cortex M4 at 120MHz with floating point unit): timer interrupt = 0.6us, scheduler overhead at process activation = 1.6us + n x 4.6 us where n is the number of active processes, process switching time = 2us