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)

    
    processdef Simple() {
      state Main {
        IO.println("relative deadline: %t", self.deadline); 
      }
    }
    
    process Simple: p1[10ms]();
    process Simple: p2[15ms]();
    
    @CPAL:sched {
      p1.deadline = 8ms;
      p2.deadline = 15ms;
    }
    
    • 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)

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

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

      
      const time64: min_jitter = 0ms;
      const time64: max_jitter = 10ms;
      const time64: period = 100ms;
      
      processdef Simple() {
        state Main {
          IO.println("%t %t", self.current_activation, self.previous_activation);
        }
      }
      
      process Simple: p1[period] ();
      @cpal:sched{
      	p1.jitter = time64.rand_uniform(min_jitter, max_jitter);
      }
      
    • 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