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


Groups > comp.arch.embedded > #24329 > unrolled thread

Common name for a "Task Loop"

Started byTim Wescott <seemywebsite@myfooter.really>
First post2016-06-24 13:37 -0500
Last post2016-07-14 20:44 +0000
Articles 20 on this page of 196 — 27 participants

Back to article view | Back to comp.arch.embedded


Contents

  Common name for a "Task Loop" Tim Wescott <seemywebsite@myfooter.really> - 2016-06-24 13:37 -0500
    Re: Common name for a "Task Loop" Lanarcam <lanarcam1@yahoo.fr> - 2016-06-24 21:04 +0200
      Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-06-24 15:21 -0500
    Re: Common name for a "Task Loop" Tauno Voipio <tauno.voipio@notused.fi.invalid> - 2016-06-24 22:46 +0300
    Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-06-24 14:51 -0500
      Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-06-24 15:10 -0500
    Re: Common name for a "Task Loop" Rob Gaddi <rgaddi@highlandtechnology.invalid> - 2016-06-24 20:11 +0000
      Re: Common name for a "Task Loop" gtwrek@sonic.net (Mark Curry) - 2016-06-24 20:31 +0000
    Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-24 13:21 -0700
      Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-06-24 18:31 -0500
        Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-24 17:03 -0700
          Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-06-25 10:52 +0300
            Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-25 01:07 -0700
              Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-06-25 14:00 +0300
                Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-25 08:27 -0700
                  Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-06-25 15:50 -0500
                    Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-25 14:45 -0700
                      Re: Common name for a "Task Loop" Tim Wescott <seemywebsite@myfooter.really> - 2016-06-25 17:28 -0500
                        Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-26 00:40 -0700
                      Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-06-26 12:41 +0300
              Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-06-25 15:46 -0500
                Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-25 14:42 -0700
          Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-06-25 15:43 -0500
            Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-25 14:36 -0700
              Re: Common name for a "Task Loop" Tim Wescott <seemywebsite@myfooter.really> - 2016-06-25 17:25 -0500
                Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-26 00:14 -0700
    Re: Common name for a "Task Loop" Paul Rubin <no.email@nospam.invalid> - 2016-06-24 14:00 -0700
      Re: Common name for a "Task Loop" Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> - 2016-06-25 15:27 +0000
        Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-25 09:41 -0700
          Re: Common name for a "Task Loop" Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> - 2016-06-25 17:59 +0000
            Re: Common name for a "Task Loop" Tim Wescott <seemywebsite@myfooter.really> - 2016-06-25 16:24 -0500
              Re: Common name for a "Task Loop" Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> - 2016-06-26 23:36 +0000
                Re: Common name for a "Task Loop" Tim Wescott <seemywebsite@myfooter.really> - 2016-06-26 19:00 -0500
                Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-06-27 05:53 +0300
                  Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-06-27 09:43 -0500
                    Re: Common name for a "Task Loop" Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> - 2016-06-28 02:39 +0000
            Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-25 15:08 -0700
              Re: Common name for a "Task Loop" Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> - 2016-06-26 23:54 +0000
                Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-26 18:12 -0700
                  Re: Common name for a "Task Loop" Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> - 2016-06-28 02:54 +0000
                    Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-06-28 06:20 +0300
                      Re: Common name for a "Task Loop" raimond.dragomir@gmail.com - 2016-06-27 22:57 -0700
                      Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-06-28 09:40 -0500
                        Re: Common name for a "Task Loop" Mel Wilson <mwilson@the-wire.com> - 2016-06-28 15:38 +0000
                          Re: Common name for a "Task Loop" raimond.dragomir@gmail.com - 2016-06-28 08:57 -0700
                        Re: Common name for a "Task Loop" Rob Gaddi <rgaddi@highlandtechnology.invalid> - 2016-06-28 16:49 +0000
                          Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-06-28 15:35 -0500
                          Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-28 13:54 -0700
                            Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-28 14:04 -0700
                              Re: Common name for a "Task Loop" Rob Gaddi <rgaddi@highlandtechnology.invalid> - 2016-06-28 21:09 +0000
                                Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-28 15:14 -0700
                                  Re: Common name for a "Task Loop" Rob Gaddi <rgaddi@highlandtechnology.invalid> - 2016-06-28 22:30 +0000
                                    Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-28 16:06 -0700
                                      Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-28 16:18 -0700
                                    Re: Common name for a "Task Loop" Hans-Bernhard Bröker <HBBroeker@t-online.de> - 2016-06-29 01:32 +0200
                        Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-06-29 01:00 +0300
                          Re: Common name for a "Task Loop" Hans-Bernhard Bröker <HBBroeker@t-online.de> - 2016-06-29 00:20 +0200
                            Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-06-29 02:07 +0300
                          Re: Common name for a "Task Loop" Rob Gaddi <rgaddi@highlandtechnology.invalid> - 2016-06-28 22:21 +0000
                            Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-06-29 02:20 +0300
                          Re: Common name for a "Task Loop" Tim Wescott <seemywebsite@myfooter.really> - 2016-06-28 17:39 -0500
                            Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-06-29 02:29 +0300
                              Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-06-29 09:50 -0500
                          Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-28 15:43 -0700
                            Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-06-29 02:40 +0300
                              Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-28 16:56 -0700
                            Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-06-29 08:04 +0300
                              Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-28 23:22 -0700
                                Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-06-30 09:02 +0300
                                  Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-30 02:33 -0700
                                    Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-02 14:27 +0300
                                      Re: Common name for a "Task Loop" Wouter van Ooijen <wouter@voti.nl> - 2016-07-02 14:50 +0200
                                        Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-02 20:18 +0300
                                      Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-02 07:36 -0700
                                        Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-02 21:44 +0300
                                          Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-02 14:36 -0700
                                            Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-07-03 06:23 +0300
                                              Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-03 00:43 -0700
                          Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-06-29 11:36 -0500
                            Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-29 09:55 -0700
                              Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-06-29 12:53 -0500
                                Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-29 11:29 -0700
                                  Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-06-29 13:41 -0500
                                    Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-29 11:49 -0700
                                Re: Common name for a "Task Loop" Richard Damon <Richard@Damon-Family.org> - 2016-07-02 20:48 -0700
                                  Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-07-03 03:07 -0500
                                    Re: Common name for a "Task Loop" Richard Damon <Richard@Damon-Family.org> - 2016-07-03 08:06 -0700
                                      Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-07-03 12:39 -0500
                                        Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-03 21:44 +0300
                                        Re: Common name for a "Task Loop" Richard Damon <Richard@Damon-Family.org> - 2016-07-03 16:39 -0700
                                          Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-07-03 23:57 -0500
                                            Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-07-04 14:39 -0500
                                            Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-07-05 06:04 +0300
                                              Re: Common name for a "Task Loop" Tim Wescott <seemywebsite@myfooter.really> - 2016-07-05 11:58 -0500
                                                Re: Common name for a "Task Loop" Reinhardt Behm <rbehm@hushmail.com> - 2016-07-06 10:39 +0800
                                                  Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-07-06 10:11 -0500
                                              Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-05 21:57 +0300
                                                Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-05 12:20 -0700
                                            Re: Common name for a "Task Loop" Richard Damon <Richard@Damon-Family.org> - 2016-07-04 10:08 -0700
                                          Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-05 11:59 -0700
                                            Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-05 22:51 +0300
                                              Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-05 13:16 -0700
                                                Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-06 11:31 +0300
                                                  Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-06 03:06 -0700
                                                    Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-06 21:37 +0300
                                                      Re: Common name for a "Task Loop" George Neuner <gneuner2@comcast.net> - 2016-07-07 00:50 -0400
                                                        Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-06 23:16 -0700
                                                          Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-07 21:36 +0300
                                                            Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-07 12:06 -0700
                                                              Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-07 23:09 +0300
                                                                Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-07-08 11:06 -0500
                                                                  Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-07-08 12:50 -0500
                                                                    Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-08 23:33 +0300
                                                                      Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-07-08 16:40 -0500
                                                                    Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-08 23:47 +0300
                                                                      Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-07-08 16:48 -0500
                                                                        Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-09 21:37 +0300
                                                                          Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-07-09 14:26 -0500
                                                                            Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-10 00:48 +0300
                                                                              Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-07-10 03:29 -0500
                                                                                Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-11 06:51 +0300
                                                                                  Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-11 16:11 +0300
                                                                                    Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-07-11 12:04 -0500
                                                                                    Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-12 11:31 +0300
                                                                                      Re: Common name for a "Task Loop" mac <acolvin@efunct.com> - 2016-07-12 15:08 +0000
                                                                                        Re: Common name for a "Task Loop" Robert Wessel <robertwessel2@yahoo.com> - 2016-07-12 21:24 -0500
                                                                                      Memory scrubbing [Was Re: Common name for a "Task Loop"] Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-12 21:11 +0300
                                                                                    Re: Common name for a "Task Loop" Robert Wessel <robertwessel2@yahoo.com> - 2016-07-12 21:11 -0500
                                                                  Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-08 23:35 +0300
                                                                    Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-07-08 23:54 +0300
                                                                      Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-09 09:34 +0300
                                                                        Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-07-09 10:28 +0300
                                                                        Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-07-09 14:39 -0500
                                                                    Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-07-08 16:56 -0500
                                                                      Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-09 15:46 +0300
                                                                        Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-10 02:41 -0700
                                                                          Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-10 17:55 +0300
                                                                            Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-16 16:34 -0700
                                                                            Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-17 09:56 +0300
                                                                              Re: Common name for a "Task Loop" George Neuner <gneuner2@comcast.net> - 2016-07-18 00:08 -0400
                                                                                Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-18 21:16 +0300
                                                                                  Re: Common name for a "Task Loop" George Neuner <gneuner2@comcast.net> - 2016-07-18 23:54 -0400
                                                                                    Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-19 10:02 +0300
                                                                                  Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-25 02:56 -0700
                                                                                Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-25 02:40 -0700
                                                                                  Re: Common name for a "Task Loop" George Neuner <gneuner2@comcast.net> - 2016-07-25 17:32 -0400
                                                                                    Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-25 16:56 -0700
                                                                                      Re: Common name for a "Task Loop" George Neuner <gneuner2@comcast.net> - 2016-07-26 06:27 -0400
                                                                                        Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-26 15:59 +0300
                                                                                          Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-26 06:55 -0700
                                                                                          Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-07-26 17:14 +0300
                                                                                          Re: Common name for a "Task Loop" George Neuner <gneuner2@comcast.net> - 2016-07-26 12:50 -0400
                                                                                            Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-26 22:07 -0700
                                                                                              Re: Common name for a "Task Loop" George Neuner <gneuner2@comcast.net> - 2016-07-27 14:22 -0400
                                                                                                Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-08-03 04:58 -0700
                                                                                        Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-26 06:38 -0700
                                                                    Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-07-09 01:28 +0300
                                                                      Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-07-09 09:25 +0300
                                                                        Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-09 21:47 +0300
                                                                      Re: Common name for a "Task Loop" Mike Perkins <spam@spam.com> - 2016-07-09 11:18 +0100
                                                                      Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-09 21:41 +0300
                                                                    Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-07-09 20:52 -0500
                                                                Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-07-10 02:01 -0700
                                                                  Re: Common name for a "Task Loop" Niklas Holsti <niklas.holsti@tidorum.invalid> - 2016-07-10 17:34 +0300
                                                                    Re: Common name for a "Task Loop" [long] Don Y <blockedofcourse@foo.invalid> - 2016-07-17 01:17 -0700
                                                            Re: Common name for a "Task Loop" Tim Wescott <seemywebsite@myfooter.really> - 2016-07-07 16:02 -0500
                            Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-06-30 04:14 +0300
                              Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-06-30 17:07 -0500
                                Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-07-01 02:28 +0300
                      Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-28 12:02 -0700
                        Re: Common name for a "Task Loop" Hans-Bernhard Bröker <HBBroeker@t-online.de> - 2016-06-28 23:19 +0200
                    Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-28 11:51 -0700
                      Re: Common name for a "Task Loop" Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> - 2016-07-01 06:54 +0000
          Re: Common name for a "Task Loop" Dimiter_Popoff <dp@tgi-sci.com> - 2016-06-25 21:08 +0300
            Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-25 15:24 -0700
          Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-06-25 21:52 +0300
            Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-26 01:04 -0700
              Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-06-26 13:46 +0300
                Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-26 05:11 -0700
                  Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-06-26 15:35 +0300
                    Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-26 06:57 -0700
                  Re: Common name for a "Task Loop" Reinhardt Behm <rbehm@hushmail.com> - 2016-06-26 21:18 +0800
                    Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-26 07:07 -0700
                      Re: Common name for a "Task Loop" upsidedown@downunder.com - 2016-06-26 17:35 +0300
                        Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-26 07:50 -0700
                      Re: Common name for a "Task Loop" Reinhardt Behm <rbehm@hushmail.com> - 2016-06-26 22:37 +0800
                        Re: Common name for a "Task Loop" Don Y <blockedofcourse@foo.invalid> - 2016-06-26 08:18 -0700
    Re: Common name for a "Task Loop" Dave Nadler <drn@nadler.com> - 2016-06-25 22:00 -0700
      Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-06-26 11:01 -0500
      Re: Common name for a "Task Loop" Les Cargill <lcargill99@comcast.com> - 2016-06-26 19:28 -0500
    Re: Common name for a "Task Loop" FreeRTOS info <noemail@given.com> - 2016-06-27 08:33 +0100
      Re: Common name for a "Task Loop" Tim Wescott <tim@seemywebsite.com> - 2016-06-28 09:48 -0500
        Re: Common name for a "Task Loop" raimond.dragomir@gmail.com - 2016-06-28 08:25 -0700
    Re: Common name for a "Task Loop" Chris <xxx.syseng.yyy@gfsys.co.uk> - 2016-07-03 17:39 +0000
    Re: Common name for a "Task Loop" WangoTango <Asgard24@mindspring.com> - 2016-07-14 16:27 -0400
      Re: Common name for a "Task Loop" Rob Gaddi <rgaddi@highlandtechnology.invalid> - 2016-07-14 20:44 +0000

Page 2 of 10 — ← Prev page 1 [2] 3 4 … 10  Next page →


#24357

FromTim Wescott <tim@seemywebsite.com>
Date2016-06-25 15:46 -0500
Message-ID<5qqdnVRzu88OcPPKnZ2dnUU7-VGdnZ2d@giganews.com>
In reply to#24348
On Sat, 25 Jun 2016 01:07:41 -0700, Don Y wrote:

> On 6/25/2016 12:52 AM, upsidedown@downunder.com wrote:
>> On Fri, 24 Jun 2016 17:03:07 -0700, Don Y <blockedofcourse@foo.invalid>
>> wrote:
>>
>>> On 6/24/2016 4:31 PM, Tim Wescott wrote:
>>>> I don't think your "prioritization" scheme really works, though -- if
>>>> a high-priority task happens to miss it's cue right before the loop
>>>> iterates then all the low- and mid-priority tasks get executed before
>>>> the high-priority stuff.
>>>
>>> Priority is a misnomer.  It's a "relatively short word" that suggests
>>> "larger quantum".  The "low_latency" task (list) tries to address
>>> those tasks that need to "wake up more often".
>>
>> What does quantum has to do with priority in a real time environment ?
> 
> Who mentioned "real-time"?
>       "... I'm _not_ using an RTOS..."

Who ever said that using an RTOS makes a system real-time (or at least 
correctly real-time)?  Who ever said that not using an RTOS kept a system 
from being real-time?

An RTOS is a tool that makes certain real-time systems easier to code -- 
but it by no means guarantees that real-time constraints will 
automatically be met.

-- 
Tim Wescott
Control systems, embedded software and circuit design
I'm looking for work!  See my website if you're interested
http://www.wescottdesign.com

[toc] | [prev] | [next] | [standalone]


#24361

FromDon Y <blockedofcourse@foo.invalid>
Date2016-06-25 14:42 -0700
Message-ID<nkmtr4$h9j$1@dont-email.me>
In reply to#24357
On 6/25/2016 1:46 PM, Tim Wescott wrote:
> On Sat, 25 Jun 2016 01:07:41 -0700, Don Y wrote:
>
>> On 6/25/2016 12:52 AM, upsidedown@downunder.com wrote:
>>> On Fri, 24 Jun 2016 17:03:07 -0700, Don Y <blockedofcourse@foo.invalid>
>>> wrote:
>>>
>>>> On 6/24/2016 4:31 PM, Tim Wescott wrote:
>>>>> I don't think your "prioritization" scheme really works, though -- if
>>>>> a high-priority task happens to miss it's cue right before the loop
>>>>> iterates then all the low- and mid-priority tasks get executed before
>>>>> the high-priority stuff.
>>>>
>>>> Priority is a misnomer.  It's a "relatively short word" that suggests
>>>> "larger quantum".  The "low_latency" task (list) tries to address
>>>> those tasks that need to "wake up more often".
>>>
>>> What does quantum has to do with priority in a real time environment ?
>>
>> Who mentioned "real-time"?
---^^^^^^^^^^^^^^^^^^^^^^^^^^
>>        "... I'm _not_ using an RTOS..."
>
> Who ever said that using an RTOS makes a system real-time (or at least
> correctly real-time)?  Who ever said that not using an RTOS kept a system
> from being real-time?

Reread your original post.  Where did you mention a "real-time environment"?
    "I'm doing some small thing in a small processor"
For all I know, task_1 may be "compute first fibonacci number" and
task_2 "compute second fibonacci number".  Presumably, the first being
a prerequisite for the second...

> An RTOS is a tool that makes certain real-time systems easier to code --
> but it by no means guarantees that real-time constraints will
> automatically be met.

Of course not!  But, it is a measurable entity that can be characterized
like any other component.  So the *designer* can state with authority
that particular SPECIFIED constraints of the real-time application
can or can't be met.

[toc] | [prev] | [next] | [standalone]


#24356

FromTim Wescott <tim@seemywebsite.com>
Date2016-06-25 15:43 -0500
Message-ID<5qqdnVVzu89jcfPKnZ2dnUU7-VGdnZ2d@giganews.com>
In reply to#24346
On Fri, 24 Jun 2016 17:03:07 -0700, Don Y wrote:

> On 6/24/2016 4:31 PM, Tim Wescott wrote:
>> I don't think your "prioritization" scheme really works, though -- if a
>> high-priority task happens to miss it's cue right before the loop
>> iterates then all the low- and mid-priority tasks get executed before
>> the high-priority stuff.
> 
> Priority is a misnomer.  It's a "relatively short word" that suggests
> "larger quantum".  The "low_latency" task (list) tries to address those
> tasks that need to "wake up more often".
> 
> As all of this relies on active tasks voluntarily relinquishing control
> of the processor "quickly", it's a tough system to tune if performance
> is an issue.
> 
> But, the overhead of the "executive" can be almost negligible: a couple
> of microseconds (literally) -- because it isn't really *doing* anything!
> 
>> That's why my "if (flag)" folderol.
>>
>> You could also do "if (task_n()) {continue;}", I suppose.
> 
> The problem comes when all task_n are "ready" (eligible to run).
> If you *don't* want to add some overhead in a scheduler, then the
> individual tasks have to assume responsibility for this fairness.

Well, that's exactly what I'm trying to say about _your_ approach.  In 
your scheme, if everything comes ready all at once and at the wrong time, 
then the execution has to plow through all of the low-priority tasks and 
all of the mid-priority tasks before it gets to execute a high-priority 
task.  In mine, it just needs to finish up whatever task it's on and then 
the highest-priority task automatically gets executed.

This still depends on the low-priority stuff being broken into bits short 
enough that they never get in the way of the high-priority stuff.  To me, 
this situation is the big advantage of an RTOS -- if you have stuff to do 
on very dissimilar time scales, you can just write the damned slow stuff 
without having to think hard about breaking it into bite-sized chunks.

> When I use this sort of approach, my code looks like:
> 
>       ... // do something ... // do something else ... // do still more
>       yield()
>       ... // do some other stuff ... // do some more other stuff ... //
>       do still more other stuff 
>       yield()
>       ...
> 

When you have no RTOS you have a yield() function call???  How?

> For someone unaccustomed to it, it looks like you're spending a helluva
> lot of time (relatively speaking) "yield()-ing" and rather little "doing
> something".
> 
> But, when you look at the implementation of yield and see how little it
> costs, you think nothing about injecting even more yield()'s in the
> code.
> 
> [This works best when coding in ASM as you have far more control over
> how much machine state you preserve -- which can be as little as the
> program counter!]

-- 
Tim Wescott
Control systems, embedded software and circuit design
I'm looking for work!  See my website if you're interested
http://www.wescottdesign.com

[toc] | [prev] | [next] | [standalone]


#24360

FromDon Y <blockedofcourse@foo.invalid>
Date2016-06-25 14:36 -0700
Message-ID<nkmthf$gc1$1@dont-email.me>
In reply to#24356
On 6/25/2016 1:43 PM, Tim Wescott wrote:
> On Fri, 24 Jun 2016 17:03:07 -0700, Don Y wrote:
>
>> On 6/24/2016 4:31 PM, Tim Wescott wrote:
>>> I don't think your "prioritization" scheme really works, though -- if a
>>> high-priority task happens to miss it's cue right before the loop
>>> iterates then all the low- and mid-priority tasks get executed before
>>> the high-priority stuff.
>>
>> Priority is a misnomer.  It's a "relatively short word" that suggests
>> "larger quantum".  The "low_latency" task (list) tries to address those
>> tasks that need to "wake up more often".
>>
>> As all of this relies on active tasks voluntarily relinquishing control
>> of the processor "quickly", it's a tough system to tune if performance
>> is an issue.
>>
>> But, the overhead of the "executive" can be almost negligible: a couple
>> of microseconds (literally) -- because it isn't really *doing* anything!
>>
>>> That's why my "if (flag)" folderol.
>>>
>>> You could also do "if (task_n()) {continue;}", I suppose.
>>
>> The problem comes when all task_n are "ready" (eligible to run).
>> If you *don't* want to add some overhead in a scheduler, then the
>> individual tasks have to assume responsibility for this fairness.
>
> Well, that's exactly what I'm trying to say about _your_ approach.  In
> your scheme, if everything comes ready all at once and at the wrong time,
> then the execution has to plow through all of the low-priority tasks and
> all of the mid-priority tasks before it gets to execute a high-priority

It's a fundamentally different approach.  No one task is more "urgent"
than another (in terms of latency).  You assign "importance" by
deciding on how much of the processor's resources (execution time)
you want to allocate to each task -- in a very loose sense.

You can't count on a preemptive scheduler yanking the processor
back from you if you get greedy.  So, you have to be acutely aware that
every opcode you fetch comes at the expense of some other task.
It's time that the other task(s) don't have AND time that is imposed
BEFORE the other tasks can execute.

So, you "yield often".  And, since all the other tasks are equally
considerate, you don't worry about being starved out.

OTOH, if the developer decides that you need a proportionately larger
piece of the pie, you don't have to selectively elide individual
yield()'s -- your "job" just runs twice for each time the other
jobs are run!  Your "cpu" is effectively twice as fast.

> task.  In mine, it just needs to finish up whatever task it's on and then
> the highest-priority task automatically gets executed.

And it gets *exclusive* use of the processor while it is executing!
So, anything of lower priority starves.  Your scheduling algorithm
is "highest priority first".

Few systems are this cut and dry.  In practice, you want to give more
resources to "more important" tasks -- and still let other tasks
continue to run.  You don't want a big loop of "try this, then try that"
but, rather, to be able to code "this" and "that" in isolation and
then tie them back together (because they all must work in a single
environment).

In a foreground-background approach, the interrupt system takes
priority over the background.  And, within the interrupt system,
the interrupt having the highest priority can preempt those of
lower priorities -- allowing them to resume when it has
completed.

Extending those priorities to the background in any meaningful
way distributes the scheduling mechanisms among the tasks.
I.e., if highest_priority gets half way through and then needs to
*wait* for something else, it needs to mark itself as "not ready"
and hope that someone will mark it as ready when that something
else happens.  And, that whichever executing task happens to
finish up (along with any "higher priority" tasks) so that the
if-tree will transfer control to it.

How do you deal with two tasks of equal priority?  One has to come
first in your scheme as they can't share a priority level (because one
"if" precedes the other).

If I have to flash the display and "blink" a noise maker, do I
have to put those activities in the same task?  Why can't they
coexist alongside each other at equal "priorities" so BOTH can
happen without one starving the other?

The scheme I illustrated shows everything as "the same priority"
but with differing degrees of "importance".  Or, alternatively,
with differing resource requirements to achieve similar levels
of performance.

Should servicing UART0 have priority over UART1 (note I'm not talking about
ISRs but, rather, the handlers that the ISR's feed and are fed by).  I.e.,
if I allow two clients to connect to a device using two different UARTs
on the device, should I give preference to traffic from one over the
other?  Is one, somehow, more "important" than the other?

Where do you put the task that manages system timers?  (or, do you require
each individual task to examine a hardware counter-timer and do their
own timekeeping?)

Where does the keyboard fit into your priority scheme?  If too low, then
keys get dropped.  If too high, then the operator's actions can jeopardize
some other aspect of the application (maybe the UARTs drop characters
because you're busy debouncing keys?)

And, of course, if power fails, THAT should be noticed ASAP.  But, will
the power fail task have to assume responsibility for doing all the
housekeeping as the system goes down?  The priorities that would apply
may be exactly the opposite of what they were when the system was
running normally (and the system doesn't even know, yet, that it will
no longer be running normally!).

When you pick (somewhat arbitrary) priorities, you invariably end up having
to juggle them.  Then, refactor because the assignment doesn't work in all
operating conditions (e.g., power fail).  In practical systems, this results
in a flattening of priorities -- which means SHARING the processor
concurrently.

> This still depends on the low-priority stuff being broken into bits short
> enough that they never get in the way of the high-priority stuff.  To me,
> this situation is the big advantage of an RTOS -- if you have stuff to do
> on very dissimilar time scales, you can just write the damned slow stuff
> without having to think hard about breaking it into bite-sized chunks.

But then you incur the costs of a formal scheduler -- not an ad hoc
loop of code.  How will task_lowest() ever have any guarantees of
meeting its requirements?  You've cast the scheduling decisions in
concrete, at compile time.

>> When I use this sort of approach, my code looks like:
>>
>>        ... // do something ... // do something else ... // do still more
>>        yield()
>>        ... // do some other stuff ... // do some more other stuff ... //
>>        do still more other stuff
>>        yield()
>>        ...
>
> When you have no RTOS you have a yield() function call???  How?

All yield() has to do is save the state of the current task and
advance to the next task in the "queue".  In the big loop example,
the "queue" is fixed.

task() {
      ...
      ... // do something
      ... // do something else
      ... // do still more
      yield()
      ... // do some other stuff
      ... // do some more other stuff
      ... // do still more other stuff
      yield()
      ...
}

imagine if yield() was:
    save current state (whatever that may be and however you want to save it)
    discard top stack frame (i.e., the frame that invoked yield())
    ret  (i.e., return FROM task() to whatever invoked it!)

The magic you're failing to see is you can fudge the preamble to task()
(and all task's) to effectively be:
    restore state (whatever it was and however it was saved)
    jump thru saved PC to the location after most recent yield()

This is what a simple scheduler would do "in one "reschedule()"
routine.  But, a scheduler would have to examine a queue of
"ready" tasks to select the next to execute.  Here, the loop
has made it clear which will be the next task to execute.

Which will *always* be the next to execute!

[In an ASM environment, yield can be a couple of opcodes!]

[toc] | [prev] | [next] | [standalone]


#24365

FromTim Wescott <seemywebsite@myfooter.really>
Date2016-06-25 17:25 -0500
Message-ID<NradnWLD6PFMmfLKnZ2dnUU7-RednZ2d@giganews.com>
In reply to#24360
On Sat, 25 Jun 2016 14:36:58 -0700, Don Y wrote:

> On 6/25/2016 1:43 PM, Tim Wescott wrote:
> 
>> task.  In mine, it just needs to finish up whatever task it's on and
>> then the highest-priority task automatically gets executed.
> 
> And it gets *exclusive* use of the processor while it is executing!
> So, anything of lower priority starves.  Your scheduling algorithm is
> "highest priority first".

Whoa!  No S**t!  Just like the well-known and successful real-time design 
rules say!  Dayum -- a method that does what it should.  What a concept.

> Few systems are this cut and dry.  In practice, you want to give more
> resources to "more important" tasks -- and still let other tasks
> continue to run.  You don't want a big loop of "try this, then try that"
> but, rather, to be able to code "this" and "that" in isolation and then
> tie them back together (because they all must work in a single
> environment).

Well, that would be why the higher-priority tasks only run when they're 
_ready_.

> In a foreground-background approach, the interrupt system takes priority
> over the background.  And, within the interrupt system,
> the interrupt having the highest priority can preempt those of lower
> priorities -- allowing them to resume when it has completed.
> 
> Extending those priorities to the background in any meaningful way
> distributes the scheduling mechanisms among the tasks.
> I.e., if highest_priority gets half way through and then needs to *wait*
> for something else, it needs to mark itself as "not ready"
> and hope that someone will mark it as ready when that something else
> happens.  And, that whichever executing task happens to finish up (along
> with any "higher priority" tasks) so that the if-tree will transfer
> control to it.

Well, yes -- did you happen to know that the sky is blue and that water 
is wet, or do you need to have that pointed out?

> How do you deal with two tasks of equal priority?  One has to come first
> in your scheme as they can't share a priority level (because one "if"
> precedes the other).
>
> If I have to flash the display and "blink" a noise maker, do I have to
> put those activities in the same task?  Why can't they coexist alongside
> each other at equal "priorities" so BOTH can happen without one starving
> the other?

You seem to be confusing assigned priority with how important something 
is to the programmer.  If it's a hard-real-time system and you have a 
fast enough processor, you can just arbitrarily assign "equal priority" 
tasks as being adjacent to each other in order and it'll work.  If you 
_don't_ have a fast-enough processor then nothing will work.

> The scheme I illustrated shows everything as "the same priority"
> but with differing degrees of "importance".  Or, alternatively,
> with differing resource requirements to achieve similar levels of
> performance.
> 
> Should servicing UART0 have priority over UART1 (note I'm not talking
> about ISRs but, rather, the handlers that the ISR's feed and are fed
> by).  I.e., if I allow two clients to connect to a device using two
> different UARTs on the device, should I give preference to traffic from
> one over the other?  Is one, somehow, more "important" than the other?

That depends on so many different system-wide considerations that the 
question is practically meaningless.  If it's really a real-time system, 
see my answer above.  If you want some sort of graceful degradation in 
the face of processor overload, then yes, you need to do something 
different.

> Where do you put the task that manages system timers?  (or, do you
> require each individual task to examine a hardware counter-timer and do
> their own timekeeping?)
> 
> Where does the keyboard fit into your priority scheme?  If too low, then
> keys get dropped.  If too high, then the operator's actions can
> jeopardize some other aspect of the application (maybe the UARTs drop
> characters because you're busy debouncing keys?)
> 
> And, of course, if power fails, THAT should be noticed ASAP.  But, will
> the power fail task have to assume responsibility for doing all the
> housekeeping as the system goes down?  The priorities that would apply
> may be exactly the opposite of what they were when the system was
> running normally (and the system doesn't even know, yet, that it will no
> longer be running normally!).
> 
> When you pick (somewhat arbitrary) priorities, you invariably end up
> having to juggle them.  Then, refactor because the assignment doesn't
> work in all operating conditions (e.g., power fail).  In practical
> systems, this results in a flattening of priorities -- which means
> SHARING the processor concurrently.

In PRACTICAL systems that have well-defined deadlines, then the 
priorities are obvious, and ignoring them leads to a system that for all 
PRACTICAL purposes is useless.  Yes, things may be different in a power-
down situation, but that's such an extreme example that it's probably 
best handled entirely in an NMI.

>> This still depends on the low-priority stuff being broken into bits
>> short enough that they never get in the way of the high-priority stuff.
>>  To me,
>> this situation is the big advantage of an RTOS -- if you have stuff to
>> do on very dissimilar time scales, you can just write the damned slow
>> stuff without having to think hard about breaking it into bite-sized
>> chunks.
> 
> But then you incur the costs of a formal scheduler -- not an ad hoc loop
> of code.  How will task_lowest() ever have any guarantees of meeting its
> requirements?  You've cast the scheduling decisions in concrete, at
> compile time.

How will task_lowest() ever have any guarantees of meeting it's 
requirements?  Oh, garsh -- maybe because some guy on the team who's 
called an "engineer" knows that engineering means "applied science and 
math", and has _justified his pay_ by applying the science of processor 
speed and resource requirements to the math of rate-monotonic scheduling 
or one of the other well-known scheduling algorithms to make sure?

Where did you learn your TRADE????

>>> When I use this sort of approach, my code looks like:
>>>
>>>        ... // do something ... // do something else ... // do still
>>>        more yield()
>>>        ... // do some other stuff ... // do some more other stuff ...
>>>        //
>>>        do still more other stuff yield()
>>>        ...
>>
>> When you have no RTOS you have a yield() function call???  How?
> 
> All yield() has to do is save the state of the current task and advance
> to the next task in the "queue".  In the big loop example,
> the "queue" is fixed.
> 
> task() {
>       ...
>       ... // do something ... // do something else ... // do still more
>       yield()
>       ... // do some other stuff ... // do some more other stuff ... //
>       do still more other stuff yield()
>       ...
> }
> 
> imagine if yield() was:
>     save current state (whatever that may be and however you want to
>     save it)
>     discard top stack frame (i.e., the frame that invoked yield())
>     ret  (i.e., return FROM task() to whatever invoked it!)
> 
> The magic you're failing to see is you can fudge the preamble to task()
> (and all task's) to effectively be:
>     restore state (whatever it was and however it was saved)
>     jump thru saved PC to the location after most recent yield()
> 
> This is what a simple scheduler would do "in one "reschedule()"
> routine.  But, a scheduler would have to examine a queue of "ready"
> tasks to select the next to execute.  Here, the loop has made it clear
> which will be the next task to execute.
> 
> Which will *always* be the next to execute!
> 
> [In an ASM environment, yield can be a couple of opcodes!]

So, you don't want to implement the useful part of a scheduler, but you 
do want to implement the esoteric and prone-to-bugs part.

Well, it's different, I suppose.

I can only assume from how you think the world should work that you 
simply do not work on products that need to have tasks of markedly 
different time-scales working at the same time.  Because your approach 
would crash and burn immediately on most of the stuff that I work on.

-- 

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com

I'm looking for work -- see my website!

[toc] | [prev] | [next] | [standalone]


#24369

FromDon Y <blockedofcourse@foo.invalid>
Date2016-06-26 00:14 -0700
Message-ID<nknvbj$c93$1@dont-email.me>
In reply to#24365
On 6/25/2016 3:25 PM, Tim Wescott wrote:
> I can only assume from how you think the world should work that you
> simply do not work on products that need to have tasks of markedly
> different time-scales working at the same time.  Because your approach
> would crash and burn immediately on most of the stuff that I work on.

You seem to have selective amnesia.  Here's what I said when introducing
my version of the "big loop":

     "I've used (*really* slim!) multitasking executives that used the
     loop as a general framework for 'scheduling' tasks -- but allowed
     voluntary rescheduling directives to be invoked by the individual
     'function calls' invoked from that loop: "

Yet, from that, you CONCLUDE that I "simply do not work on products that
need to have tasks of markedly different time-scales working at the same
time."  I guess I fail to see the logic in that conclusion.

And, the fact that *this* approach "would crash and burn immediately on
most of the stuff that I work on" is equally useless to draw conclusions
of the types of projects that *I* have applied it to.

Here's the "Job list" (main loop) from a product I designed with this
approach ~35 years ago:

Jobs:   Debugger        // interactive debugger, when present
         Timekeeping     // Timer service
         PowerMonitor    // AC, battery backup and line frequency clock
         Display         // Display and Indicator update
         Keypad          // keypad scanning
         Barcode         // Barcode decoding
         Sensor          // sensor array scanning
         Operator        // Console operator user interface FSM
         Diagnostic      // Diagnostic Mode user interface FSM
         Supervisor      // Supervisor Mode user interface FSM
         Port0           // Port0 comm channel user dialog
         Port1           // Port1 comm channel user dialog
	ret		// done

The Debugger task lets a developer plug a proprietary piece
of hardware into the running (production!) system to examine
and control the system at all levels (i.e., live patches to
memory, stepping individual tasks, altering register contents).
Most of the time, it's just refreshing the display on *that*
device and polling for keystrokes.  When it encounters one, it
implements the command associated with it altering the device's
operation in "real time".  After deployment, it's dead code
(and can be elided)

Timekeeping updates the system timers made available to any
task that needs them.  So, no need to watch a hardware
counter/timer to determine elapsed time, delays, etc.
     "Wait 3 seconds"
and your code will block for 3 seconds,
     "Test KeystrokeTimeout"
and your code will check to see if the "KeystrokeTimeout"
has expired.

PowerMonitor monitors the AC "line frequency clock" (essentially
the 50/60Hz mains) so the unit can adjust sampling intervals and
display refresh to frequency lock to the mains voltage.  It also
provides an indication of absence of primary power.  And, whether
that is due to the user manually flipping the power switch "off" *or*
a power outage.  The device can then either shutdown as "intended"
or alert the user (via the "Operator" interface task) that he's
now working on borrowed time -- perhaps wise to unload the
database stored in system RAM, now.  And, eventually, bring about
an orderly shutdown when the battery actually is ready to fail.  Or,
alerting the user when power returns!

At the same time, it informs the timekeeping software that the
"stable" AC mains line frequency reference is no longer available
and the most recent "crystal calibration" must be used to create
synthetic time.  So, the timescales are 50/60hz as well as the
fractional hour the device can run on battery.

The Display task ensures the display is updated synchronous with
the AC mains (so you don't see a beating in the display) as
well as ensuring the "content update" is synchronized with the
"scan line refresh" to eliminate visual artifacts.  It implements
features like "blink" (in-phase and out-of-phase), "reverse", etc.
so you can say:

DisplayCenteredMessage:
                                // copy pointer to message into "message"

         Send to Video          // select device and wait to obtain lock
         SetAttributes(NORMAL+REPLACEMENT+FORWARD+SHOWIT+SOLID+INPHASE)
         CarriageReturn         // leftmost column in line 0
         Call(SkipOverLeadIn)   // skip leading whitepace

         SetAttributes(NORMAL+REPLACEMENT+BACKWARD+SHOWIT+SOLID+INPHASE)
         ClearToEol             // clear all LEADING whitespace!
                                // display cursor now at LEFTMOST column

         Call(SkipOverLeadIn)   // skip leading whitepace

         SetAttributes(NORMAL+REPLACEMENT+FORWARD+SHOWIT+SOLID+INPHASE)
         CarriageReturn         // leftmost column in line 0
         Print(message)         // show error message

         ClearToEol             // clear all TRAILING whitespace!
	Done                   // release the lock on the device

SystemError:
         EnableAttribute(FLASH)
         "System Error"
         DisableAttribute(FLASH)
         " Detected!"
         End

Initializing:
         "Initializing..."
         End

FailedToInit:
         "Unable to Initialize"
         End

SensorShorted:
         "Sensor Shorted"
         End

The audio annunciator (handled as part of the Display "job") emits tones.
So, you can say:
         Send To Audio          // select device and wait to acquire lock
         Print(DropOfBlood)     // "play" the annunciator
         Quit                   // end of output -- but retain lock on device
         ...                    // do other stuff while annunciator is playing
         Send To Audio          // select device, already have the lock!
         Flush                  // block until output queue is empty
         Done                   // release the lock on the device

DropOfBlood:
         Rate 150*60 Beats per Minute  // underlying timebase

         Flush                  // ensure any previously queued are done

         Gather                 // queue data, don't play, yet

         // default glissando so it sounds "fluid"!
         Play C_Natural(4) for 3 Beats
         Play D_Natural(4) for 2 Beats
         Play E_Natural(4) for 1 Beats
         Play F_Natural(4) for 1 Beats
         Play G_Natural(4) for 1 Beats
         Play A_Natural(4) for 1 Beats
         Play B_Natural(4) for 1 Beats

         Play C_Natural(5) for 1 Beats
         Play D_Natural(5) for 1 Beats
         Play E_Natural(5) for 1 Beats
         Play F_Natural(5) for 1 Beats
         Play G_Natural(5) for 1 Beats
         Play A_Natural(5) for 1 Beats
         Play B_Natural(5) for 1 Beats

         Release                // release queued data for playing
         End

So, the timescales there are 1/150ths of seconds.

The Keypad task scans the key matrix and debounces keys providing
rollover etc.  It feeds "events" to the Operator FSM in much the same
way that the AC line monitor fed POWER_FAIL, POWER_OFF, POWER_RESTORE
and BATTERY_FAIL events.

The Barcode task continually monitors for the user's presentation
of a barcoded label to the device.  The user protocol doesn't
require the operator to inform the device of his desire to do so;
that would be an inefficient use of the operator's time!  Instead,
the operator can swipe a barcode at ANY time.  The barcode
hardware consists of a photodetector feeding an edge triggered
interrupt pin, through an XOR.  The other input of the XOR allows
the ISR to indicate that it is looking for the black-to-white
edge (of a bar) or the white-to-black edge (of a space) as the
times between them are the "data".  The ISR simply stores the
contents of a freerunning counter along with another value
(from the same counter) that effectively tells how long *ago*
the edge occurred.  I.e., the barcode *handler* will be able to
adjust the observed counter value to reflect this interrupt
latency to yield the *actual* time between successive "edges".

At 100 ips, a minimal bar/space of 0.007" can pass the detector
(i.e., time between edges) in 70 microseconds.  Even smaller
if you allow for ink spread (which causes space shrinking).
You'll see an entire set of ~100 transitions in a bit less than
a second -- an "entire code".  I.e., the ISR is *really* fast
cuz it has to catch each edge and reprogram the XOR for the
NEXT edge.  All this on a 1980-vintage machine processing 1.5M
8b opcodes per second.

The Barcode task implements the "handler" -- that retrieves the
raw data from the circular buffer managed by the ISR as it
arrives (and taking note if it is ever too sluggish revisiting
the buffer before it overflows!), does the latency compensation
and then begins the analysis of the actual bar/space widths to
create a code -- which it then verifies as legitimate or not.

If the ratios of bar/space widths don't fit a defined pattern,
the "oldest" bar and accompanying space are discarded and the
process repeats -- until a set of bar/space widths consistent
with a "legitimate character encoding" are discovered.  Then,
the bars and spaces that follow are analyzed to (hopefully)
arrive at another "valid character".

Once *a* character is available, we hesitate to discard anything
until we know if that character -- and any that might follow -- are
representative of a valid label (which might be "followed" by crud).

;Validity       ::=     Valid_ID | Alpha_ID | Null_ID
;
;Valid_ID       ::=     NumericID
;Alpha_ID       ::=     AlphaID
;Null_ID        ::=     NullID

      Wildcard NumericID      for Validity    is keyed with Valid_ID
      Wildcard AlphaID        for Validity    is keyed with Alpha_ID
      Wildcard NullID         for Validity    is keyed with Null_ID

;IDVals         ::=     NumericID | AlphaID | NullID
;
;NumericID      ::=     PADDING DIGIT DIGITS
;AlphaID        ::=     PADDING ALPHAPART NUMERICPART
;NullID         ::=     PADDING

      Grammar for NumericID   is <<PADDING,DIGIT,DIGITS>>
      Grammar for AlphaID     is <<PADDING,ALPHAPART,NUMERICPART>>
      Grammar for NullID      is <<PADDING>>

      Wildcard PADDING        for IDVals      is keyed with 'p'
      Wildcard DIGIT          for IDVals      is keyed with '#'
      Wildcard DIGIT?         for IDVals      is keyed with 'e'
      Wildcard DIGITS         for IDVals      is keyed with 'd'
      Wildcard ALPHAPART      for IDVals      is keyed with 'a'
      Wildcard NUMERICPART    for IDVals      is keyed with 'n'

;PADDING        ::=     ASCNUL PADDING | ''
;DIGITS         ::=     DIGIT DIGITS | ''
;DIGIT?         ::=     DIGIT | ''

etc.  I.e., a grammar for what constitutes a "valid" label in terms
of "recognized characters" -- so the handler can reject any PROCESSED
data that might LOOK like (and may even *be*!) a set of legal characters
but that doesn't ACTUALLY satisfy the criteria for a label.

Once *a* code/label has been read, it has to note if another VALID
label is encountered within a "half inch" of the end of the previous
label (of course, it can't measure distances, only *times* -- what's
a half inch at the scan rate that is apparent from the bar/space
times in the data already recognized?).  If the start code of the next
label is compatible with the end code of the previous, seamlessly glue
these labels together AS IF they had been a single, continuous label.
Up to three labels can be concatenated like this *in* the Barcode
handler so the rest of the system is unaware of this capability
(the adjoining start and end codes are elided when the label's contents
are reported to the application)

When valid, it signals a BARCODE_AVAILABLE event to the Operator
FSM task.  Which can then interpret the event as applicable to the
current user context (is a barcode valid at this stage in the protocol?
is *this* barcode valid, here?)

So, times from 70 microseconds through a second or more to ensure the
label has completely passed the scanner (can't control how fast the
user moves his arm!)

The Sensor task scans an array of 60 RC oscillators at a rate that is
frequency locked to the AC mains with the same sort of interrupt latency
compensation that was applied to the barcode detector.  In addition to
noting the current frequency of each oscillator, it also has to detect
an "open" cap (the caps are formed from large, widely spaced plates that
allow changes in frequency to be used to detect the presence of 10 microliter
blood samples placed between any pair; if a plate breaks off, that detector
is obviously unreliable), a shorted cap (if the user bridges the gap between
the plates with something of "relatively" low impedance the sensor is
unreliable) or a disconnected sensor assembly.

These data are signaled to the Operator FSM as well so the FSM knows what
the operator has done in his "interaction" with the sensor array.  So, you're
sampling at some multiple of AC mains clock periods (the sampling interval
changes based on what the Operator FSM is expecting from the sensor; faster
intervals for reduced resolution, etc.  A user typically pipettes samples
(or reagents!) at a few second interval -- sort of like tapping on a keyboard.

The Operator FSM task is a giant state machine that processes events
and conditions sourced from other tasks.  It steers the user interaction
accordingly.  Events can be sourced at varying timescales: as often as
a user presses a key or scans a barcode, as often as he pipettes blood
samples into the array, as often as the power fails/recovers, etc.

It runs forever (as do all of these other jobs)

The Diagnostic and Supervisor FSM's are other operating modes for the
device.  Typically, only one of these three modes are engaged at a
time.  Splitting them into three FSM's allows them to operate concurrently
as well as reducing the complexity of the "user interface" FSM.

Port0 and Port1 are handlers that service the two UARTs.  Each talks to
a respective UART ISR to retrieve incoming data and status (from software
FIFO's with overflow protection -- this predates UARTs with big internal
buffers).  They also implement the hardware handshaking and character
"pacing" (so the ISR's can remain lean -- just read the data and status
registers... don't bother with the handshaking in the foreground!).
As such, they deal with "character times" -- too sluggish and the
remote device can be overrun *or* overrun the local device.

Additionally, they feed two instances of the same state machine that
implements the interface language specification by which external
devices can query and control the device and the data that it maintains.

The system is resilient enough that you can take a barcode label and
rub it vigorously back and forth over the detector -- keeping in mind that
each black/white transition triggers an interrupt -- and not crash the
device *or* corrupt its execution.  And, when you get tired of
waving the barcode labels in front of the detector, the system will
respond with the *correctly* decoded barcode -- despite the overload
that it experienced.

Of course, it *has* to be -- else you'll report the wrong diagnosis for
some patient!

What "priorities" would you like me to assign to these tasks?  Maybe force
the user to press a "Read A Barcode" key so the barcode task can be
made ready?  Then, once it has seen a barcode (or, perhaps, timed out?),
it can make itself NOT ready until manually called upon, again?

Maybe the Port0 servicing should only run when the user isn't busy
interacting with the device?  And, Port1 should wait until Port0
is no longer active?

Maybe ignore the power subsystem while the user is in the middle of
a sampling cycle and only worry about power availability BETWEEN
those cycles?  (e.g., POLL it?).  Unless, of course, he takes too
long and we have to abort his action lest we starve the power
monitor task.  And, we can just use a higher quality crystal oscillator
instead of calibrating it against the (reliable) AC mains.  And, only
check the line frequency each time we power up (hey, if it's 50Hz,
it's gonna stay 50Hz, right?).  If the line frequency drifts, we can
always live with a low frequency "beat" in the display.  And, errors in
the sensor array, right?

As I said elsewhere, everything ends up running at essentially the same
"priority" -- because everything CAN happen at the same time!  Those
activities that have truly tight timeliness constraints move into the
foreground.  And, ONLY do what they absolutely *must* while there.
E.g., the barcode ISR doesn't waste foreground time computing the "time
since the previous edge"; the UART ISR's don't waste time twiddling
with handshaking/pacing features; etc.

And, the *background* routines aren't piggish, either!  They do enough to
have justify their invocation "this time around the loop" but not too
much that they delay the other tasks (who are ALL "ready").  So, the barcode
handler quickly tries to empty any "edge times" from the barcode ISR's
FIFO -- and converting them to widths.  This allows 4 bytes of FIFO data
to be reduced to a two byte "width" -- in the *handler's* "width FIFO".
So, the ISR FIFO can stay small and still accommodate the amount of
activity likely to be encountered BEFORE THE HANDLER COMES AROUND, AGAIN,
to empty it.

Likewise, the higher layers in the barcode handler try to aggressively
discard "widths" that are incompatible with "valid character codes".
Again, trying to keep as much space available in the *width* FIFO so
there is always room for the raw "edge" data from the ISR FIFO.

And, even higher layers try to invalidate individual characters as
being incompatible with a valid *label* format -- again, so some widths
can be removed from the width FIFO.

And, ultimately, concatenated labels that fail to satisfy the criteria
for a "glued together" label can be discarded.  Always keeping the door
open to harvest as much data from the ISR as possible.  Because a FIFO
overrun (anywhere) wedges the label in question.  And, that means the user
has to rescan the label (this is not a Good Thing).

[toc] | [prev] | [next] | [standalone]


#24341

FromPaul Rubin <no.email@nospam.invalid>
Date2016-06-24 14:00 -0700
Message-ID<87bn2qqp44.fsf@nightsong.com>
In reply to#24329
Tim Wescott <seemywebsite@myfooter.really> writes:
> So, this is the third time in a month or so that I've needed to tell 
> someone "use a task loop" -- but I'm not sure if I can say "just Google 
> it".

I'd call that a polling loop, since it polls each task to see if it's
ready.  But I don't know if that's a standard term.  There's a DSL for
generating these things (see "Atom" under http://tomahawkins.org) and
the slide presentation doesn't seem to use any particular name for the
main loop.

[toc] | [prev] | [next] | [standalone]


#24350

FromSimon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP>
Date2016-06-25 15:27 +0000
Message-ID<nkm7te$3oc$1@dont-email.me>
In reply to#24341
On 2016-06-24, Paul Rubin <no.email@nospam.invalid> wrote:
> Tim Wescott <seemywebsite@myfooter.really> writes:
>> So, this is the third time in a month or so that I've needed to tell 
>> someone "use a task loop" -- but I'm not sure if I can say "just Google 
>> it".
>
> I'd call that a polling loop, since it polls each task to see if it's
> ready.  But I don't know if that's a standard term.

Until I read your reply, this was _exactly_ what I was going to say.

It _is_ a polling loop (or polling architecture if you want to
distinguish it from an interrupt architecture.)

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

[toc] | [prev] | [next] | [standalone]


#24352

FromDon Y <blockedofcourse@foo.invalid>
Date2016-06-25 09:41 -0700
Message-ID<nkmc7u$jvj$1@dont-email.me>
In reply to#24350
On 6/25/2016 8:27 AM, Simon Clubley wrote:
> On 2016-06-24, Paul Rubin <no.email@nospam.invalid> wrote:
>> Tim Wescott <seemywebsite@myfooter.really> writes:
>>> So, this is the third time in a month or so that I've needed to tell
>>> someone "use a task loop" -- but I'm not sure if I can say "just Google
>>> it".
>>
>> I'd call that a polling loop, since it polls each task to see if it's
>> ready.  But I don't know if that's a standard term.
>
> Until I read your reply, this was _exactly_ what I was going to say.
>
> It _is_ a polling loop (or polling architecture if you want to
> distinguish it from an interrupt architecture.)

No.  Why does any "polling" have to occur?  Why can't every task be
treated as active/ready?  Why can't it coexist with an active foreground?

How do you address task_N's whose ready conditions can't be simply
externalized as "task_N_ready"?  (Or, are you ONLY addressing implementations
where this is the case -- ignoring any other sort of implementation that
can ALSO exploit a "big loop"?)

// The Big Loop
while (FOREVER) {
    verify_all_windows_closed();
    verify_all_doors_locked();
    verify_no_water_leaks();
    handle_annunciator();
}

verify_all_windows_closed() {
    while (FOREVER) {
       windowID = get_head(window_list);
       ASSERT(windowID != 0)

       open = get_window_state(windowID);   // reschedule
       window_cracked = open ? windowID : 0;
       append(window_list, windowID);
    }
}

verify_all_doors_locked() {
    while (FOREVER) {
       doorID = get_head(door_list);
       ASSERT(doorID != 0)

       open = get_door_state(doorID);   // reschedule
       door_ajar = open ? doorID : 0;
       append(door_list, doorID);
    }
}

handle_annunciator() {
    // simple state machine
    while (FOREVER) {
off:
       while !(window_cracked || door_ajar ... ) {
          yield();   // all is well
       }

       annunciator(ON);   // bad things!

on:
       while (window_cracked || door_ajar ... ) {
          yield();      // problem persists
       }

       annunciator(OFF);   // all is well

//off:
       yield();
    }
}

Note that every task is always "ready".  And, the get_XXXX_state()
functions can typically interface to a communication system that
is running in the foreground (so that it doesn't drop packets).

[Note that these can implicitly reschedule/yield while performing
their intended functions -- esp if "getting the state" is time
consuming]

There's no mention of "time" in any of this code -- it runs as fast
as the resources available permit.  If the window_list grows,
then the time between "checks" of a particular window will similarly
lengthen.  If this gets to be too long, allocate a larger quantum
to the "verify_all_windows_closed()" task (put it in the loop TWICE
so you don't have to rewrite the task's implementation!)

If you later decide to add "check_all_smoke_detectors()" to the main
loop, then all tasks will slow down a bit (in their relative frequency).
If you decide the smoke detectors must be checked "more promptly",
then inject the "check_all_smoke_detectors()" task between every
other task listed in the big loop (i.e., do_something, check_smoke,
do_something_else, check_smoke, do_yet_another_thing, check_smoke)

[toc] | [prev] | [next] | [standalone]


#24353

FromSimon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP>
Date2016-06-25 17:59 +0000
Message-ID<nkmgpi$3vq$1@dont-email.me>
In reply to#24352
On 2016-06-25, Don Y <blockedofcourse@foo.invalid> wrote:
> On 6/25/2016 8:27 AM, Simon Clubley wrote:
>> On 2016-06-24, Paul Rubin <no.email@nospam.invalid> wrote:
>>> Tim Wescott <seemywebsite@myfooter.really> writes:
>>>> So, this is the third time in a month or so that I've needed to tell
>>>> someone "use a task loop" -- but I'm not sure if I can say "just Google
>>>> it".
>>>
>>> I'd call that a polling loop, since it polls each task to see if it's
>>> ready.  But I don't know if that's a standard term.
>>
>> Until I read your reply, this was _exactly_ what I was going to say.
>>
>> It _is_ a polling loop (or polling architecture if you want to
>> distinguish it from an interrupt architecture.)
>
> No.  Why does any "polling" have to occur?  Why can't every task be
> treated as active/ready?  Why can't it coexist with an active foreground?
>

Hello Don,

I define a polling architecture in the general sense as one or more loops
actively going out and asking {X}, {Y} or {Z} on an ongoing basis if they
have anything to tell you or if they need you to give them some processing
time.

I define an interrupt architecture as an architecture as something where
no code runs until some state change occurs, maybe in an external door
sensor, or maybe in an I/O device which completes an operation and has
some results to deliver. In either case, there's an interrupt and only
then are CPU cycles consumed by the CPU deciding what needs to run next.

{X}, {Y} and {Z} can be anything; either some software construct such as
a task or some physical construct such as an external sensor. What matters
is whether you are asking {X}, {Y} and {Z} for their current state
(polling architecture) or if you are waiting for them to tell you
(interrupt architecture).

In the example you post below, I therefore consider that to be a classic
polling architecture because the code is going out and asking the sensors
on a continuous basis if something has happened.

If your code were to setup a range of interrupts from external sensors
and then got on with something else or just stuck around in some Wait
For Interrupt state, then I would instead consider that to be an
interrupt architecture.

Simon.

PS: The reason I've left your message fully intact below is so others can
see your full example without them having to go to your original message.

> How do you address task_N's whose ready conditions can't be simply
> externalized as "task_N_ready"?  (Or, are you ONLY addressing implementations
> where this is the case -- ignoring any other sort of implementation that
> can ALSO exploit a "big loop"?)
>
> // The Big Loop
> while (FOREVER) {
>     verify_all_windows_closed();
>     verify_all_doors_locked();
>     verify_no_water_leaks();
>     handle_annunciator();
> }
>
> verify_all_windows_closed() {
>     while (FOREVER) {
>        windowID = get_head(window_list);
>        ASSERT(windowID != 0)
>
>        open = get_window_state(windowID);   // reschedule
>        window_cracked = open ? windowID : 0;
>        append(window_list, windowID);
>     }
> }
>
> verify_all_doors_locked() {
>     while (FOREVER) {
>        doorID = get_head(door_list);
>        ASSERT(doorID != 0)
>
>        open = get_door_state(doorID);   // reschedule
>        door_ajar = open ? doorID : 0;
>        append(door_list, doorID);
>     }
> }
>
> handle_annunciator() {
>     // simple state machine
>     while (FOREVER) {
> off:
>        while !(window_cracked || door_ajar ... ) {
>           yield();   // all is well
>        }
>
>        annunciator(ON);   // bad things!
>
> on:
>        while (window_cracked || door_ajar ... ) {
>           yield();      // problem persists
>        }
>
>        annunciator(OFF);   // all is well
>
> //off:
>        yield();
>     }
> }
>
> Note that every task is always "ready".  And, the get_XXXX_state()
> functions can typically interface to a communication system that
> is running in the foreground (so that it doesn't drop packets).
>
> [Note that these can implicitly reschedule/yield while performing
> their intended functions -- esp if "getting the state" is time
> consuming]
>
> There's no mention of "time" in any of this code -- it runs as fast
> as the resources available permit.  If the window_list grows,
> then the time between "checks" of a particular window will similarly
> lengthen.  If this gets to be too long, allocate a larger quantum
> to the "verify_all_windows_closed()" task (put it in the loop TWICE
> so you don't have to rewrite the task's implementation!)
>
> If you later decide to add "check_all_smoke_detectors()" to the main
> loop, then all tasks will slow down a bit (in their relative frequency).
> If you decide the smoke detectors must be checked "more promptly",
> then inject the "check_all_smoke_detectors()" task between every
> other task listed in the big loop (i.e., do_something, check_smoke,
> do_something_else, check_smoke, do_yet_another_thing, check_smoke)


-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

[toc] | [prev] | [next] | [standalone]


#24359

FromTim Wescott <seemywebsite@myfooter.really>
Date2016-06-25 16:24 -0500
Message-ID<NradnWHD6PETa_PKnZ2dnUU7-RednZ2d@giganews.com>
In reply to#24353
On Sat, 25 Jun 2016 17:59:15 +0000, Simon Clubley wrote:

> On 2016-06-25, Don Y <blockedofcourse@foo.invalid> wrote:
>> On 6/25/2016 8:27 AM, Simon Clubley wrote:
>>> On 2016-06-24, Paul Rubin <no.email@nospam.invalid> wrote:
>>>> Tim Wescott <seemywebsite@myfooter.really> writes:
>>>>> So, this is the third time in a month or so that I've needed to tell
>>>>> someone "use a task loop" -- but I'm not sure if I can say "just
>>>>> Google it".
>>>>
>>>> I'd call that a polling loop, since it polls each task to see if it's
>>>> ready.  But I don't know if that's a standard term.
>>>
>>> Until I read your reply, this was _exactly_ what I was going to say.
>>>
>>> It _is_ a polling loop (or polling architecture if you want to
>>> distinguish it from an interrupt architecture.)
>>
>> No.  Why does any "polling" have to occur?  Why can't every task be
>> treated as active/ready?  Why can't it coexist with an active
>> foreground?
>>
>>
> Hello Don,
> 
> I define a polling architecture in the general sense as one or more
> loops actively going out and asking {X}, {Y} or {Z} on an ongoing basis
> if they have anything to tell you or if they need you to give them some
> processing time.
> 
> I define an interrupt architecture as an architecture as something where
> no code runs until some state change occurs, maybe in an external door
> sensor, or maybe in an I/O device which completes an operation and has
> some results to deliver. In either case, there's an interrupt and only
> then are CPU cycles consumed by the CPU deciding what needs to run next.
> 
> {X}, {Y} and {Z} can be anything; either some software construct such as
> a task or some physical construct such as an external sensor. What
> matters is whether you are asking {X}, {Y} and {Z} for their current
> state (polling architecture) or if you are waiting for them to tell you
> (interrupt architecture).
> 
> In the example you post below, I therefore consider that to be a classic
> polling architecture because the code is going out and asking the
> sensors on a continuous basis if something has happened.
> 
> If your code were to setup a range of interrupts from external sensors
> and then got on with something else or just stuck around in some Wait
> For Interrupt state, then I would instead consider that to be an
> interrupt architecture.
> 
> Simon.

Except that -- for my code at least -- if you add a command at the end to 
sleep if no tasks are ready, then it's no longer a polling by your 
definition architecture.

(Yes, "sleep if no tasks are ready" is a bit challenging, but it can 
certainly be done if you're careful).

-- 

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com

I'm looking for work -- see my website!

[toc] | [prev] | [next] | [standalone]


#24386

FromSimon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP>
Date2016-06-26 23:36 +0000
Message-ID<nkpoua$h8b$1@dont-email.me>
In reply to#24359
On 2016-06-25, Tim Wescott <seemywebsite@myfooter.really> wrote:
>
> Except that -- for my code at least -- if you add a command at the end to 
> sleep if no tasks are ready, then it's no longer a polling by your 
> definition architecture.
>

Yes, I would agree with that; it's no longer a purely polling
architecture in that case. If you only come out of sleep as a result
of, say, an external interrupt causing a task to become ready then I
would call that more of an interrupt architecture.

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

[toc] | [prev] | [next] | [standalone]


#24388

FromTim Wescott <seemywebsite@myfooter.really>
Date2016-06-26 19:00 -0500
Message-ID<7amdnVkeRZwY8e3KnZ2dnUU7-I2dnZ2d@giganews.com>
In reply to#24386
On Sun, 26 Jun 2016 23:36:43 +0000, Simon Clubley wrote:

> On 2016-06-25, Tim Wescott <seemywebsite@myfooter.really> wrote:
>>
>> Except that -- for my code at least -- if you add a command at the end
>> to sleep if no tasks are ready, then it's no longer a polling by your
>> definition architecture.
>>
>>
> Yes, I would agree with that; it's no longer a purely polling
> architecture in that case. If you only come out of sleep as a result of,
> say, an external interrupt causing a task to become ready then I would
> call that more of an interrupt architecture.
> 
> Simon.

Everything I do ends up being event driven, as long as you allow that a 
hardware timer popping off in an "event".

And for the least mods in the code that I originally presented, the 
"sleep until interrupt" opcode (whatever it's called in your context) 
should go _before_ the string of if statements.

-- 

Tim Wescott
Wescott Design Services
http://www.wescottdesign.com

I'm looking for work -- see my website!

[toc] | [prev] | [next] | [standalone]


#24391

Fromupsidedown@downunder.com
Date2016-06-27 05:53 +0300
Message-ID<8l41nb5levom7ook0s1hntolspaem199eb@4ax.com>
In reply to#24386
On Sun, 26 Jun 2016 23:36:43 -0000 (UTC), Simon Clubley
<clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:

>On 2016-06-25, Tim Wescott <seemywebsite@myfooter.really> wrote:
>>
>> Except that -- for my code at least -- if you add a command at the end to 
>> sleep if no tasks are ready, then it's no longer a polling by your 
>> definition architecture.
>>
>
>Yes, I would agree with that; it's no longer a purely polling
>architecture in that case. If you only come out of sleep as a result
>of, say, an external interrupt causing a task to become ready then I
>would call that more of an interrupt architecture.
>
>Simon.

Even if a timer interrupt is used ??

Just before entering the sleep, program the timer to expire say, at
the next full millisecond, i.e. generating exactly 1000 polls/second ?

[toc] | [prev] | [next] | [standalone]


#24396

FromTim Wescott <tim@seemywebsite.com>
Date2016-06-27 09:43 -0500
Message-ID<PumdnRG7lpHjpuzKnZ2dnUU7-fmdnZ2d@giganews.com>
In reply to#24391
On Mon, 27 Jun 2016 05:53:53 +0300, upsidedown wrote:

> On Sun, 26 Jun 2016 23:36:43 -0000 (UTC), Simon Clubley
> <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
> 
>>On 2016-06-25, Tim Wescott <seemywebsite@myfooter.really> wrote:
>>>
>>> Except that -- for my code at least -- if you add a command at the end
>>> to sleep if no tasks are ready, then it's no longer a polling by your
>>> definition architecture.
>>>
>>>
>>Yes, I would agree with that; it's no longer a purely polling
>>architecture in that case. If you only come out of sleep as a result of,
>>say, an external interrupt causing a task to become ready then I would
>>call that more of an interrupt architecture.
>>
>>Simon.
> 
> Even if a timer interrupt is used ??
> 
> Just before entering the sleep, program the timer to expire say, at the
> next full millisecond, i.e. generating exactly 1000 polls/second ?

_I_ would call that event-driven.  The important thing (in my definition) 
is that you're responding to the world external to the software in a 
timely manner; marching in step with the clocks in the rest of the world 
counts for that for me.

-- 
Tim Wescott
Control systems, embedded software and circuit design
I'm looking for work!  See my website if you're interested
http://www.wescottdesign.com

[toc] | [prev] | [next] | [standalone]


#24399

FromSimon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP>
Date2016-06-28 02:39 +0000
Message-ID<nkso03$o68$1@dont-email.me>
In reply to#24396
On 2016-06-27, Tim Wescott <tim@seemywebsite.com> wrote:
> On Mon, 27 Jun 2016 05:53:53 +0300, upsidedown wrote:
>
>> On Sun, 26 Jun 2016 23:36:43 -0000 (UTC), Simon Clubley
>> <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
>> 
>>>On 2016-06-25, Tim Wescott <seemywebsite@myfooter.really> wrote:
>>>>
>>>> Except that -- for my code at least -- if you add a command at the end
>>>> to sleep if no tasks are ready, then it's no longer a polling by your
>>>> definition architecture.
>>>>
>>>Yes, I would agree with that; it's no longer a purely polling
>>>architecture in that case. If you only come out of sleep as a result of,
>>>say, an external interrupt causing a task to become ready then I would
>>>call that more of an interrupt architecture.
>>>
>> 
>> Even if a timer interrupt is used ??
>> 
>> Just before entering the sleep, program the timer to expire say, at the
>> next full millisecond, i.e. generating exactly 1000 polls/second ?
>
> _I_ would call that event-driven.  The important thing (in my definition) 
> is that you're responding to the world external to the software in a 
> timely manner; marching in step with the clocks in the rest of the world 
> counts for that for me.
>

Actually if the external event is a timer and not, say, an interrupt
from an external sensor, I would still call that a polling loop.
I would consider that to be no different from (for example) a PID loop
which runs at a fixed rate.

For me, a polling architecture is where you reach out to the sensors and
ask them if they have something to tell you. An interrupt architecture
for me is where you don't do anything until the sensors contact you.

To me, it doesn't matter if that polling loop is a fixed rate polling
loop or an "as fast as possible" polling loop; it's still a polling loop.

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

[toc] | [prev] | [next] | [standalone]


#24363

FromDon Y <blockedofcourse@foo.invalid>
Date2016-06-25 15:08 -0700
Message-ID<nkmvd4$q7m$1@dont-email.me>
In reply to#24353
Hi Simon,

On 6/25/2016 10:59 AM, Simon Clubley wrote:

> I define a polling architecture in the general sense as one or more loops
> actively going out and asking {X}, {Y} or {Z} on an ongoing basis if they
> have anything to tell you or if they need you to give them some processing
> time.

But, that is a very specific type of application.  What would you call:

     while (FOREVER) {
        V=readADC();
        writeDAC(V);
     }

Imagine I had written it as:

     value-t V;

     while (FOREVER) {
        task1();
        task2(V);
     }

I.e., I'm sure there's a piece of code in my car that is reading
the accelerator pedal position and using that to control ignition.
Over and over again.  It doesn't "ask" to see if my foot is on the
pedal and read the position only when that's found to be true.

When does "polling" stop being polling?  I.e., when all tasks
are ALWAYS "ready", what are you "asking"/polling?

> I define an interrupt architecture as an architecture as something where
> no code runs until some state change occurs, maybe in an external door
> sensor, or maybe in an I/O device which completes an operation and has
> some results to deliver. In either case, there's an interrupt and only
> then are CPU cycles consumed by the CPU deciding what needs to run next.

Again, another very specific class of applications.  Few systems sit
(in HALT) waiting for an interrupt -- and then returning to HALT.

In practice, most systems are AT LEAST "foreground-background" -- some
set of interrupts happening "at will" that feed some set of operations
that are happening "when not handling an interrupt".

This is the "poor man's" way of addressing timeliness constraints:
move anything with timing constraints into an ISR (foreground) and
deal with everything else in the background.  This ensures that you
don't "miss" anything by being too slow to "look for it" (polling
interval).

And, inevitably, you clutter up the foreground with all those "important"
things:  handling UART interrupts, NIC interrupts, timer/jiffy IRQ's,
display refresh IRQ, keyboard scanning, sound synthesis, etc.

And, if you're lucky, the hardware priorities associated with the
interrupts align with your "intrinsic" priority assessment for each
of these things (is a UART overrun IRQ as important as a UART
receive IRQ?  After all, the character has already been OVERRUN,
why rush to address that fact??!).

But, often, they don't.  Or, need to change (but the hardware might
not allow reassigning priorities dynamically -- or, may impose some
arcane restrictions on these choices).

And, as more things compete for the foreground (which is a limited
resource), you find the background starving.  So, you are tempted to
move more code into ISR's to "ensure" they get handled.

Which, of course, makes the foreground even more bloated...  etc.

[This is why you encounter desktop systems that "lose time" when
heavily loaded.  Or, drop network packets, etc.  They often have
to deal with a variety of hardware configurations -- interrupt
priorities! -- that they couldn't address when the system was
built.  So, you find remedies like "Increase the clock speed"
when the problem might be correctible with a different hardware
configuration]

> {X}, {Y} and {Z} can be anything; either some software construct such as
> a task or some physical construct such as an external sensor. What matters
> is whether you are asking {X}, {Y} and {Z} for their current state
> (polling architecture) or if you are waiting for them to tell you
> (interrupt architecture).
>
> In the example you post below, I therefore consider that to be a classic
> polling architecture because the code is going out and asking the sensors
> on a continuous basis if something has happened.

So, generating fibonacci numbers would be...?
Processing paychecks?  (or, would you see "asking for hours worked
and wage rate" as "polling" for current state?)
Generating a shipping manifest from the barcoded labels on
items passing a conveyor?

> If your code were to setup a range of interrupts from external sensors
> and then got on with something else or just stuck around in some Wait
> For Interrupt state, then I would instead consider that to be an
> interrupt architecture.

Without changing the example, if I claim that get_window_state()
takes the ID argument provided, looks it up to determine the CAN
address of a node that can read the state of that window sensor,
crafts and sends a message to that node inquiring as to the current
state, then waits for the reply (all of those comms actions involving
some amount of interrupt activity), then what do I have?

[Note that the code can continue to execute while these things
are happening]

This is why I lump all of these in "foreground-background".

> Simon.
>
> PS: The reason I've left your message fully intact below is so others can
> see your full example without them having to go to your original message.

>> // The Big Loop
>> while (FOREVER) {
>>      verify_all_windows_closed();
>>      verify_all_doors_locked();
>>      verify_no_water_leaks();
>>      handle_annunciator();
>> }
>>
>> verify_all_windows_closed() {
>>      while (FOREVER) {
>>         windowID = get_head(window_list);
>>         open = get_window_state(windowID);   // reschedule
>>         window_cracked = open ? windowID : 0;
>>         append(window_list, windowID);
>>      }
>> }
>>
>> verify_all_doors_locked() {
>>      while (FOREVER) {
>>         doorID = get_head(door_list);
>>         open = get_door_state(doorID);   // reschedule
>>         door_ajar = open ? doorID : 0;
>>         append(door_list, doorID);
>>      }
>> }
>>
>> handle_annunciator() {
>>      // simple state machine
>>      while (FOREVER) {
>> off:
>>         while !(window_cracked || door_ajar ... ) {
>>            yield();   // all is well
>>         }
>>         annunciator(ON);   // bad things!
>>
>> on:
>>         while (window_cracked || door_ajar ... ) {
>>            yield();      // problem persists
>>         }
>>         annunciator(OFF);   // all is well
>>
>>         yield();
>>      }
>> }

[toc] | [prev] | [next] | [standalone]


#24387

FromSimon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP>
Date2016-06-26 23:54 +0000
Message-ID<nkpq03$knl$1@dont-email.me>
In reply to#24363
On 2016-06-25, Don Y <blockedofcourse@foo.invalid> wrote:
> Hi Simon,
>
> On 6/25/2016 10:59 AM, Simon Clubley wrote:
>
>> I define a polling architecture in the general sense as one or more loops
>> actively going out and asking {X}, {Y} or {Z} on an ongoing basis if they
>> have anything to tell you or if they need you to give them some processing
>> time.
>
> But, that is a very specific type of application.  What would you call:
>
>      while (FOREVER) {
>         V=readADC();
>         writeDAC(V);
>      }
>

Polling.

> Imagine I had written it as:
>
>      value-t V;
>
>      while (FOREVER) {
>         task1();
>         task2(V);
>      }
>

Polling unless task1() consumes no CPU cycles until an external event
wakes it up to process some data.

> I.e., I'm sure there's a piece of code in my car that is reading
> the accelerator pedal position and using that to control ignition.
> Over and over again.  It doesn't "ask" to see if my foot is on the
> pedal and read the position only when that's found to be true.
>
> When does "polling" stop being polling?  I.e., when all tasks
> are ALWAYS "ready", what are you "asking"/polling?
>

No it stops being polling when you can insert a WFI opcode in your
main loop and still have your application work. If part of a larger
system, it stops being polling when the scheduler doesn't have to
schedule any time for your loop until some external event happens.

>
>> {X}, {Y} and {Z} can be anything; either some software construct such as
>> a task or some physical construct such as an external sensor. What matters
>> is whether you are asking {X}, {Y} and {Z} for their current state
>> (polling architecture) or if you are waiting for them to tell you
>> (interrupt architecture).
>>
>> In the example you post below, I therefore consider that to be a classic
>> polling architecture because the code is going out and asking the sensors
>> on a continuous basis if something has happened.
>
> So, generating fibonacci numbers would be...?
> Processing paychecks?  (or, would you see "asking for hours worked
> and wage rate" as "polling" for current state?)

Are you trolling ? :-)

Neither of those have anything to do with reading sensor data.

> Generating a shipping manifest from the barcoded labels on
> items passing a conveyor?
>

Interrupt if the scanner delivers an interrupt upon scanning a parcel's
barcode or polling otherwise.

>> If your code were to setup a range of interrupts from external sensors
>> and then got on with something else or just stuck around in some Wait
>> For Interrupt state, then I would instead consider that to be an
>> interrupt architecture.
>
> Without changing the example, if I claim that get_window_state()
> takes the ID argument provided, looks it up to determine the CAN
> address of a node that can read the state of that window sensor,
> crafts and sends a message to that node inquiring as to the current
> state, then waits for the reply (all of those comms actions involving
> some amount of interrupt activity), then what do I have?
>

It's still inquiring for the current state so it's a polling
architecture.

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

[toc] | [prev] | [next] | [standalone]


#24390

FromDon Y <blockedofcourse@foo.invalid>
Date2016-06-26 18:12 -0700
Message-ID<nkpuhc$vgr$1@dont-email.me>
In reply to#24387
On 6/26/2016 4:54 PM, Simon Clubley wrote:
>>> In the example you post below, I therefore consider that to be a classic
>>> polling architecture because the code is going out and asking the sensors
>>> on a continuous basis if something has happened.
>>
>> So, generating fibonacci numbers would be...?
>> Processing paychecks?  (or, would you see "asking for hours worked
>> and wage rate" as "polling" for current state?)
>
> Are you trolling ? :-)
>
> Neither of those have anything to do with reading sensor data.

I'm trying to finely identify the criteria that you consider qualifies
something as a "polling loop".

Savitzky (see reference elsewhere) defines this as:
    "... the program examines (polls) each of its inputs in turn to
    determine whether an event has occurred which requires a response.
    If it has, the program takes the required action before proceeding
    to the next input".

This is similar to your description.

But, makes the explicit mention of a *conditional* in the code:
    if (event_has_occurred) {
        generate_response();
    }

This is also similar to Tim's "big loop" structure -- except he
moves the responsibility for "signaling" the "events" to
something "set offstage (in an ISR, or by one of the
task_n_update functions) and reset within the tasks".

The example:
    while (FOREVER) {
        V=readADC();
        writeDAC(V);
    }
you termed as "polling" -- despite the fact that there are no
visible conditionals.  (I don't consider the hardwired while()
to be a conditional -- it could be implemented with a goto.)

However, to guard against the possibility that you are
considering the "readADC" function to *contain* some conditional
logic (i.e., start conversion, wait for result, acquire result,
return value to caller) instead of a "flash A/DC" sort of
implementation (i.e., just an UNCONDITIONAL *read* of a memory
location/IO port), I pose the Fibonacci example -- there is NO
conditional logic contained therein; the "inputs" are ALWAYS
available and this is known *in* the algorithm.  I.e.,
there isn't even an "if (1) ..."

There's no "polling" in the sense of "asking if something
needs to be done".  The code runs "forever" (as the sequence
never ends so you don't even have to see "if done"!)

I.e., *my* example shows no conditionals (at least not in the
context of the "big loop").  And, unless you look under the hood,
you won't realize that tasks are producing events (even Fibonacci
numbers) and *conditionally* consuming them:
     if (another_fibonacci_number_available) {
         // do something
     }

So far, your distinguishing criteria is "if interrupts are used,
then interrupt driven; else polling (even if no conditional logic
involved)"  ??

[toc] | [prev] | [next] | [standalone]


#24400

FromSimon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP>
Date2016-06-28 02:54 +0000
Message-ID<nksotv$rsk$1@dont-email.me>
In reply to#24390
On 2016-06-27, Don Y <blockedofcourse@foo.invalid> wrote:
>
> The example:
>     while (FOREVER) {
>         V=readADC();
>         writeDAC(V);
>     }
> you termed as "polling" -- despite the fact that there are no
> visible conditionals.  (I don't consider the hardwired while()
> to be a conditional -- it could be implemented with a goto.)
>

It is an interesting example. I still think that's a polling loop
because you are reaching out to the sensor and asking it for it's
current value.

It's possible to have polling loops in which there is no conditional
logic, but instead a pure mathematical transformation of an input
to an output is performed. While there's no obvious maths going on
in the above loop, you are still driving a second device based on
the current value of the first device.

>
> So far, your distinguishing criteria is "if interrupts are used,
> then interrupt driven; else polling (even if no conditional logic
> involved)"  ??

To me, it's more like if you have to reach out to the sensors and ask
them what their current status is, then it's polling. If you don't do
anything until the sensor tells you via some mechanism that there's
been a change in the sensor then to me it's an interrupt architecture.

Simon.

-- 
Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
Microsoft: Bringing you 1980s technology to a 21st century world

[toc] | [prev] | [next] | [standalone]


Page 2 of 10 — ← Prev page 1 [2] 3 4 … 10  Next page →

Back to top | Article view | comp.arch.embedded


csiph-web