Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.arch.embedded > #29311
| 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> |
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
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