Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.arch.embedded > #29311

Re: Cortex-M: share an int between two tasks

From Niklas Holsti <niklas.holsti@tidorum.invalid>
Newsgroups comp.arch.embedded
Subject Re: Cortex-M: share an int between two tasks
Date 2020-03-19 12:27 +0200
Organization Tidorum Ltd
Message-ID <hdgvpeF4ktdU1@mid.individual.net> (permalink)
References (1 earlier) <r4slk8$1cb$1@dont-email.me> <r4sobf$gk9$1@dont-email.me> <r4srd8$2i9$1@dont-email.me> <r4suan$keu$1@dont-email.me> <r4v447$4ms$1@dont-email.me>

Show all headers | View raw


On 2020-03-19 8:40, pozz wrote:

    [snip long discussion]

> I simply wanted a management taskB to stop and restart sensor sampling 
> done by taskA. taskA uses vTaskDelay() for sampling at precise timings.

    [snip]

> After many years using cooperative schedulers, it appears to me 
> incredible how difficult, error prone and resource consuming is to 
> implement even simple mechanisms like this one with a preemptive scheduler.

It's not so hard once you absorb a set of high-level solution patterns 
and apply them consistently and with a high-level design approach.

I realize that this response may not be helpful, but here is how it can 
be done in Ada, as an example of a high-level approach.

The SW will have a subsystem that does "sampling", and you want some 
other "managing" subsystem to be able to set the sampling period and to 
start/stop sampling. The sampling subsystem interface (API) is then:

    package Sampling is
       procedure Set_Period (To : in Duration);
       procedure Start;
       procedure Stop;
    end Sampling;

That Ada text is put in its own file (by current convention named 
sampling.ads).

The body (implementation) of the sampling subsystem is put in its own 
file (conventionally named sampling.adb) and will start with

    package body Sampling is

The rest of this post will add the parts of the package body one by one.

The sampling package will have a concurrent task, called Sampler for 
example, and declared as:

    task Sampler;

The task body is shown later below.

The data to be communicated to the Sampler task will be the sampling 
period and whether sampling should be active. These shared data are 
placed in a "protected object" to ensure mutually exclusive access. The 
actions on these shared data are the following:

- Actions from the "manager" (exterior to the Sampling package):

    -- set the sampling period
    -- start sampling
    -- stop sampling.

- Actions from the Sampler task:

    -- get the current sampling period-

Moreover, the Sampler task should be suspended when sampling is stopped, 
which is convenient to implement with an Ada "entry" operation that 
suspends the caller if its "guard" expression is false. The declaration 
of the protected object is then:

    protected Sampling_Control is
       procedure Set_Period (To : in Duration);
       procedure Start;
       procedure Stop;
       entry Get_Period (Giving : out Duration);
    private
       Running : Boolean := False;
       Period : Duration := 1.0;
    end Sampling_Control;

The shared but protected data are thus the Running flag, which will be 
the guard for the Get_Period entry, and the current sampling Period.
Note that sampling is initially stopped (Running is initially False) and 
the initial sampling period is one second.

The implementation is rather trivial:

    protected body Sampling_Control is

       procedure Set_Period (To : in Duration) is
       begin
          Period := To;
       end Set_Period;

       procedure Start is
       begin
          Running := True;
       end Start;

       procedure Stop is
       begin
          Running := False;
       end Stop;

       entry Get_Period (Giving : out Duration)
       when Running
       is
       begin
          Giving := Period;
       end Get_Period;

    end Sampling_Control;

Note the guard "when Running" on the Get_Period entry. This means that a 
task that calls Get_Period when Running is False is suspended, at the 
point of the call, until Running becomes True. If Running is True, the 
call succeeds at once.

Note that Set_Period does not automatically start sampling. If that is 
desired, add the statement "Running := True" in Set_Period.

The Sampler task body can now be implemented simply:

    task body Sampler is
       Period : Duration;
    begin
       loop
          Sampling_Control.Get_Period (Giving => Period);
          -- Take the sample, etc.
          delay Period;
        end loop;
    end Sampler;

(This code is a bit sloppy, because the use of a "relative" delay 
statement brings lag and jitter into sample timing. It is better to use 
the "absolute" delay statement ("delay until"), but this complication is 
not relevant to the task interactions so I skipped it.)

The public (API) operations of the Sampling package just call the 
corresponding operations of Sampling_Control (this circumlocation can of 
course be avoided by making Sampling_Control itself public, but that 
would harm encapsulation and increase inter-module coupling):

    procedure Set_Period (To : in Duration) is
    begin
       Sampling_Control.Set_Period (To);
    end Set_Period;

    procedure Start is
    begin
       Sampling_Control.Start;
    end Start;

    procedure Stop is
    begin
       Sampling_Control.Stop;
    end Stop;

The implementation of the Sampling subsystem is now complete, and the 
file sampling.adb ends with:

    end Sampling;

The "manager" part of the SW accesses the Sampling subsystem by saying

    with Sampling;

and can then use the Sampling interface, for example as

    Sampling.Set_Period (To => 0.1);  -- 10 Hz
    Sampling.Start;
    ...
    Sampling.Set_Period (To => 2.5);
    ...
    Sampling.Stop;

and so on.

To map this Ada code into some C+RTOS combination, one should use a 
mutex to make the executions of the protected operations 
(Sampling_Control.Set_Period, .Start, .Stop, .Get_Period) mutually 
exclusive, and use some "condition" variable or semaphore to implement 
the guard (caller suspension) of Sampling_Control.Get_Period.

That last point (caller suspension) has some subtleties that depend on 
the actual set of RTOS primitives available. But I recommend a simpler 
solution: instead of suspending/resuming the sampling task, just let it 
run normally at the sampling period, but make the actual sampling (and 
sample processing, I assume) conditional on a "Running" flag (by 
returning this flag, too, from Get_Period). Usually the processor effort 
saved by actually suspending tasks that normally run periodically is not 
significant.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .

Back to comp.arch.embedded | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

Cortex-M: share an int between two tasks pozz <pozzugno@gmail.com> - 2020-03-13 15:38 +0100
  Re: Cortex-M: share an int between two tasks David Brown <david.brown@hesbynett.no> - 2020-03-13 17:49 +0100
    Re: Cortex-M: share an int between two tasks pozz <pozzugno@gmail.com> - 2020-03-18 09:09 +0100
      Re: Cortex-M: share an int between two tasks David Brown <david.brown@hesbynett.no> - 2020-03-18 09:17 +0100
      Re: Cortex-M: share an int between two tasks Hans-Bernhard Bröker <HBBroeker@t-online.de> - 2020-03-18 17:37 +0100
        Re: Cortex-M: share an int between two tasks David Brown <david.brown@hesbynett.no> - 2020-03-18 19:23 +0100
    Re: Cortex-M: share an int between two tasks Les Cargill <lcargill99@comcast.com> - 2020-03-22 13:42 -0500
      Re: Cortex-M: share an int between two tasks David Brown <david.brown@hesbynett.no> - 2020-03-22 21:45 +0100
      Re: Cortex-M: share an int between two tasks Richard Damon <Richard@Damon-Family.org> - 2020-03-22 20:50 -0400
        Re: Cortex-M: share an int between two tasks David Brown <david.brown@hesbynett.no> - 2020-03-23 09:09 +0100
          Re: Cortex-M: share an int between two tasks Richard Damon <Richard@Damon-Family.org> - 2020-03-23 08:00 -0400
            Re: Cortex-M: share an int between two tasks David Brown <david.brown@hesbynett.no> - 2020-03-23 14:21 +0100
              Re: Cortex-M: share an int between two tasks Clifford Heath <no.spam@please.net> - 2020-03-25 09:55 +1100
                Re: Cortex-M: share an int between two tasks David Brown <david.brown@hesbynett.no> - 2020-03-30 16:07 +0200
                Re: Cortex-M: share an int between two tasks Clifford Heath <no.spam@please.net> - 2020-03-31 09:02 +1100
                Re: Cortex-M: share an int between two tasks David Brown <david.brown@hesbynett.no> - 2020-03-31 10:57 +0200
                Re: Cortex-M: share an int between two tasks Clifford Heath <no.spam@please.net> - 2020-04-01 12:05 +1100
                Re: Cortex-M: share an int between two tasks Tauno Voipio <tauno.voipio@notused.fi.invalid> - 2020-03-30 17:49 +0300
                Re: Cortex-M: share an int between two tasks kegs@provalid.com (Kent Dickey) - 2020-05-19 00:34 -0500
                Re: Cortex-M: share an int between two tasks Clifford Heath <no.spam@please.net> - 2020-05-19 17:40 +1000
                Re: Cortex-M: share an int between two tasks David Brown <david.brown@hesbynett.no> - 2020-05-19 12:00 +0200
                Re: Cortex-M: share an int between two tasks Tom Gardner <spamjunk@blueyonder.co.uk> - 2020-05-19 13:48 +0100
  Re: Cortex-M: share an int between two tasks pozz <pozzugno@gmail.com> - 2020-03-18 09:20 +0100
    Re: Cortex-M: share an int between two tasks David Brown <david.brown@hesbynett.no> - 2020-03-18 10:06 +0100
      Re: Cortex-M: share an int between two tasks pozz <pozzugno@gmail.com> - 2020-03-18 10:59 +0100
        Re: Cortex-M: share an int between two tasks David Brown <david.brown@hesbynett.no> - 2020-03-18 11:48 +0100
          Re: Cortex-M: share an int between two tasks upsidedown@downunder.com - 2020-03-18 20:37 +0200
            Re: Cortex-M: share an int between two tasks David Brown <david.brown@hesbynett.no> - 2020-03-18 21:24 +0100
              Re: Cortex-M: share an int between two tasks Tauno Voipio <tauno.voipio@notused.fi.invalid> - 2020-03-19 14:05 +0200
                Re: Cortex-M: share an int between two tasks David Brown <david.brown@hesbynett.no> - 2020-03-19 13:16 +0100
                Re: Cortex-M: share an int between two tasks Tauno Voipio <tauno.voipio@notused.fi.invalid> - 2020-03-19 14:27 +0200
                Re: Cortex-M: share an int between two tasks David Brown <david.brown@hesbynett.no> - 2020-03-19 14:13 +0100
            Re: Cortex-M: share an int between two tasks pozz <pozzugno@gmail.com> - 2020-03-19 08:03 +0100
              Re: Cortex-M: share an int between two tasks David Brown <david.brown@hesbynett.no> - 2020-03-19 09:10 +0100
              Re: Cortex-M: share an int between two tasks upsidedown@downunder.com - 2020-03-19 12:51 +0200
          Re: Cortex-M: share an int between two tasks pozz <pozzugno@gmail.com> - 2020-03-19 07:40 +0100
            Re: Cortex-M: share an int between two tasks David Brown <david.brown@hesbynett.no> - 2020-03-19 09:38 +0100
              Re: Cortex-M: share an int between two tasks pozz <pozzugno@gmail.com> - 2020-03-19 11:26 +0100
                Re: Cortex-M: share an int between two tasks David Brown <david.brown@hesbynett.no> - 2020-03-19 12:12 +0100
                Re: Cortex-M: share an int between two tasks pozz <pozzugno@gmail.com> - 2020-03-19 15:31 +0100
                Re: Cortex-M: share an int between two tasks pozz <pozzugno@gmail.com> - 2020-03-23 09:22 +0100
                Re: Cortex-M: share an int between two tasks Richard Damon <Richard@Damon-Family.org> - 2020-03-23 08:10 -0400
                Re: Cortex-M: share an int between two tasks pozz <pozzugno@gmail.com> - 2020-03-23 13:47 +0100
                Re: Cortex-M: share an int between two tasks David Brown <david.brown@hesbynett.no> - 2020-03-23 14:31 +0100
                Re: Cortex-M: share an int between two tasks Richard Damon <Richard@Damon-Family.org> - 2020-03-23 13:50 -0400
            Re: Cortex-M: share an int between two tasks Niklas Holsti <niklas.holsti@tidorum.invalid> - 2020-03-19 12:27 +0200
              Re: Cortex-M: share an int between two tasks pozz <pozzugno@gmail.com> - 2020-03-19 11:45 +0100
                Re: Cortex-M: share an int between two tasks upsidedown@downunder.com - 2020-03-19 13:27 +0200
    Re: Cortex-M: share an int between two tasks antispam@math.uni.wroc.pl - 2020-03-18 16:24 +0000

csiph-web