Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.arch.embedded > #21402
| From | Don Y <this@is.not.me.com> |
|---|---|
| Newsgroups | comp.arch.embedded |
| Subject | Re: Design pattern: refresh-based or event-based? |
| Date | 2015-07-21 03:16 -0700 |
| Organization | Aioe.org NNTP Server |
| Message-ID | <mol643$vc0$1@speranza.aioe.org> (permalink) |
| References | <moku8e$6sf$1@dont-email.me> |
On 7/21/2015 1:02 AM, pozz wrote:
> Suppose you have a complex dashboard with tenth of LEDs, gauges, values, labels
> and so on. It could be a full-futured high-resolution TFT display. The values
> shown on the dashboard come from remote controllers connected through a bus. I
> think it's a very common scenario in my systems.
>
> When I design the firmware of the dashboard controller, I always have many
> doubts on the design better to choose: refresh-based or event-based?
>
> Refresh-based is very simple: every 20ms, 100ms, 500ms or 1s a refresh function
> is called. This function redraws *everything* on the dashboard based on the
> current values collected on the bus.
> The thing I don't like with this approach is that it could be time consuming.
> If the values change slowly, most probably only 1-5 values really change since
> the last refresh. Why do I redraw everything?
> I could improve this by defining a variable with the old displayed value for
> each graphical element:
>
> bool ledX_displayed;
> if (ledX_displayed != ledX_currentvalue()) {
> ledX_displayed = ledX_currentvalue();
> ledX_refresh();
> }
>
> However this method uses a double RAM space (current values and displayed
> values) and the code isn't so clear.
>
> Another approach is event-based. IMHO, it is very attractive and elegant,
> because it remembers state-machines. The drawing operations are performed only
> when necessary.
It's not really anything more than remembering the current state of each
*individual* display item. I.e., it is many "simple" state machines with
a common "conditional": if value is no longer what it was previously,
then display new value and remember this value.
> int X, Y, ...;
> void bus_rx(const char *msg, size_t msglen) {
> int new_value;
> ...
> new_value = <something related to msg> /* X value */
> if (X != new_value) {
> X = new_value;
> event_handler(X_CHANGED);
> }
> ...
> }
> void event_handler(enum EVENT_TYPE evtype) {
> if (X_CHANGED == evtype)
> ledX_refresh();
> else ...
> }
>
> The event X_CHANGED is triggered by the bus task: when a new value for X is
> received, it is compared with the current value and, if it is different, the
> event is triggered (a callback is called).
So, you're keeping a copy of the "currently displayed" value in "numeric form"
as well as in "graphical form".
> Even this design patter have some drawbacks.
> IMHO it is dangerous and error-prone, because you could ignore a certain
> sequence of events that brings to a wrong state (you will have a wrong value
> displayed on the dashboard).
> The startup must be designed with great care. Should a "virtual startup event"
> be triggered during initialization for each value, so the current/init value is
> correctly displayed?
> How to distinguish a "virtual startup event" from a "normal event"? It's
> important, if I have to make soma actions only if a "normal event" occurs.
You can force a "change" simply by ensuring the initial state for
every displayed value is "UNDEFINED". So, the first value that
you receive for each displayed value is seen as "different" and
forces that portion of the display to be repainted.
Your initialization routine simply sends an "update display" event
to every registered "display item" (widget, control, etc. -- whatever
you want to call them). Part of that process for each display
item is a means of displaying "UNDEFINED".
> What is you preferred method?
This depends on whether parameters are routinely *reported* (from the
"field") or, only when they change.
If the latter, then how do you know what the initial value to
"display" should be (in your refresh scenario)? In the former,
you are effectively continuously "refreshing" the display -- but
at a rate determined by each "control/widget" and the frequency
of its reporting event(s).
This can work for or against you. E.g., if a parameter is being reported
at a very high frequency, then you are needlessly repainting the display
faster than the user can perceive its changes. (i.e., you'd have to
add an intermediary filter to present values that "make sense" from
the many values coming in).
OTOH, you can choose to update certain portions of the display at
different rates. E.g., engine temperature changes much more slowly
than vehicular velocity; why repaint the temperature gauge if
you know it isn't changing very quickly??
You also have to have a mechanism for ensuring that messages aren't
lost; AND, identifying when they *have* been lost -- perhaps
causing you to manually query each parameter and synthesize
corresponding "events" (i.e., as if the parameters had been
*reported* instead of *queried*).
For example, you may want to demultiplex incoming events to
device specific "handlers". Each of these can then impose
whatever sanity checks they deem necessary on the *data*
AND the *reporting rate*! So, if the "temperature handler"
doesn't get a report/event indicating current engine temperature
in X seconds (where X is greater than the reporting interval
that the *design* was supposed to satisfy), then *it* (the
temperature handler) can schedule a "temperature query".
Eventually, that query will be passed to the appropriate subsystem
and, if all is well, a "temperature event" will be returned.
This will percolate through the demultiplexor to the "temperature
handler" (which is the entity that effectively requested it!)
and be processed as if it had arrived in the course of normal
operation.
If, OTOH, no such message arrives, the temperature handler knowws
that something is broke and can take corrective actions (signal
"check engine", log an error code to black box, place a reduced
limit on the maximum engine speed that can be commanded, etc.)
As well as updating the display, as appropriate!
Back to comp.arch.embedded | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
Design pattern: refresh-based or event-based? pozz <pozzugno@gmail.com> - 2015-07-21 10:02 +0200
Re: Design pattern: refresh-based or event-based? upsidedown@downunder.com - 2015-07-21 11:37 +0300
Re: Design pattern: refresh-based or event-based? pozz <pozzugno@gmail.com> - 2015-07-21 11:00 +0200
Re: Design pattern: refresh-based or event-based? Dimiter_Popoff <dp@tgi-sci.com> - 2015-07-22 01:34 +0300
Re: Design pattern: refresh-based or event-based? pozz <pozzugno@gmail.com> - 2015-07-22 06:57 +0200
Re: Design pattern: refresh-based or event-based? Paul Rubin <no.email@nospam.invalid> - 2015-07-21 23:02 -0700
Re: Design pattern: refresh-based or event-based? pozz <pozzugno@gmail.com> - 2015-07-22 09:17 +0200
Re: Design pattern: refresh-based or event-based? Paul Rubin <no.email@nospam.invalid> - 2015-07-22 00:23 -0700
Re: Design pattern: refresh-based or event-based? upsidedown@downunder.com - 2015-07-22 10:02 +0300
Re: Design pattern: refresh-based or event-based? Dimiter_Popoff <dp@tgi-sci.com> - 2015-07-22 19:48 +0300
Re: Design pattern: refresh-based or event-based? pozz <pozzugno@gmail.com> - 2015-07-23 09:04 +0200
Re: Design pattern: refresh-based or event-based? Dimiter_Popoff <dp@tgi-sci.com> - 2015-07-23 10:29 +0300
Re: Design pattern: refresh-based or event-based? raimond.dragomir@gmail.com - 2015-07-31 02:34 -0700
Re: Design pattern: refresh-based or event-based? Don Y <this@is.not.me.com> - 2015-07-21 03:16 -0700
Re: Design pattern: refresh-based or event-based? Hans-Bernhard Bröker <HBBroeker@t-online.de> - 2015-07-21 14:40 +0200
Re: Design pattern: refresh-based or event-based? pozz <pozzugno@gmail.com> - 2015-07-22 07:01 +0200
Re: Design pattern: refresh-based or event-based? Stefan Reuther <stefan.news@arcor.de> - 2015-07-22 18:30 +0200
Re: Design pattern: refresh-based or event-based? Paul Rubin <no.email@nospam.invalid> - 2015-07-22 10:55 -0700
Re: Design pattern: refresh-based or event-based? Paul Rubin <no.email@nospam.invalid> - 2015-07-21 08:26 -0700
Re: Design pattern: refresh-based or event-based? pozz <pozzugno@gmail.com> - 2015-07-22 07:04 +0200
Re: Design pattern: refresh-based or event-based? Paul Rubin <no.email@nospam.invalid> - 2015-07-21 23:13 -0700
Re: Design pattern: refresh-based or event-based? pozz <pozzugno@gmail.com> - 2015-07-22 09:24 +0200
Re: Design pattern: refresh-based or event-based? Paul Rubin <no.email@nospam.invalid> - 2015-07-22 08:26 -0700
Re: Design pattern: refresh-based or event-based? pozz <pozzugno@gmail.com> - 2015-07-23 09:00 +0200
Re: Design pattern: refresh-based or event-based? hamilton <hamilton@nothere.com> - 2015-07-21 14:07 -0600
Re: Design pattern: refresh-based or event-based? Don Y <this@is.not.me.com> - 2015-07-21 13:12 -0700
Re: Design pattern: refresh-based or event-based? Andrew Smallshaw <andrews@sdf.lonestar.org> - 2015-07-22 00:19 +0000
Re: Design pattern: refresh-based or event-based? Paul Rubin <no.email@nospam.invalid> - 2015-07-21 18:09 -0700
Re: Design pattern: refresh-based or event-based? Andrew Smallshaw <andrews@sdf.lonestar.org> - 2015-07-22 21:18 +0000
Re: Design pattern: refresh-based or event-based? Paul Rubin <no.email@nospam.invalid> - 2015-07-22 23:17 -0700
Re: Design pattern: refresh-based or event-based? pozz <pozzugno@gmail.com> - 2015-07-22 07:20 +0200
Re: Design pattern: refresh-based or event-based? upsidedown@downunder.com - 2015-07-22 10:53 +0300
Re: Design pattern: refresh-based or event-based? pozz <pozzugno@gmail.com> - 2015-07-22 07:32 +0200
csiph-web