chiark / gitweb /
new FOR_TRA etc. macros; initial hooks for resolver
authorian <ian>
Wed, 13 Feb 2008 22:22:18 +0000 (22:22 +0000)
committerian <ian>
Wed, 13 Feb 2008 22:22:18 +0000 (22:22 +0000)
hostside/Makefile
hostside/persist.c
hostside/realtime.c
hostside/realtime.h
hostside/record.c
hostside/resolve.c [new file with mode: 0644]
hostside/safety.c
hostside/safety.h
hostside/startup.c

index 9c75a7806e8bd6450e3d762752f5458392836c4d..ab6d59c503be8b030e83ac3e9905b727f054a6a1 100644 (file)
@@ -29,7 +29,7 @@ on-bessar:    $(TARGETS)
                RSYNC_RSH=fsh rsync $^ $(BESSAR)
 
 realtime:      realtime.o startup.o cdumgr.o safety.o trackloc.o       \
-                speed.o actual.o retransmit.o persist.o                \
+                speed.o actual.o retransmit.o persist.o resolve.o      \
                 cmdinput.o commands.o obc.o eventhelp.o                \
                 record.o record-l.o record-y.o                         \
                 utils.o serialio.o parseutils.o auproto-pic.o          \
index fcf0be2e319409450e14e374b6b5ef85e1107994..e7faccf833c601fccbe9f47cefed676c57c609a7 100644 (file)
@@ -362,12 +362,12 @@ static void persist_mapread(void) {
 }
 
 void persist_entrails_run_converter(void) {
-  Train *tra; int tran;
-  Segment *seg; const SegmentInfo *segi; int segn;
+  TRA_IV;
+  SEG_IV;
 
   persist_mapread();
 
-  for (tran=0, tra=trains; tran<n_trains; tran++, tra++) {
+  FOR_TRA {
     if (!tra->pname || !tra->foredetect ||
        !tra->foredetect->i || !tra->foredetect->i->pname)
       continue;
@@ -375,9 +375,7 @@ void persist_entrails_run_converter(void) {
           tra->pname, tra->backwards ? "-" : "",
           tra->foredetect->i->pname, tra->maxinto, tra->uncertainty);
   }
-  for (segn=0, seg=segments, segi=info_segments; segn<info_nsegments;
-       segn++, seg++, segi++) {
-    
+  FOR_SEG {
     if (seg->i != segi || !segi->pname ||
        !seg->owner || !seg->owner->pname)
       continue;
index c20ce3819c8f76653bc9eab758ab9afb54d081ce..1f36162ba8dcf7be1464fe4e1a8f4ceacedd87f4 100644 (file)
@@ -294,14 +294,12 @@ void serial_transmit(const PicInsn *pi) {
   int objnum, suppress=0;
 
   if ((pi->d[0] & 0xf8) == 0x90) {
-    SegmentNum segn;
-    const SegmentInfo *segi;
+    SEG_IV;
     const char *delim;
     
     oprintf(UPO,"picio out polarity <");
-    for (segn=0, segi=info_segments, delim="";
-        segn < info_nsegments;
-        segn++, segi++) {
+    delim="";
+    FOR_SEG {
       if (!segi->invertible) continue;
       if (!picinsn_polarity_testbit(pi,segi)) continue;
       oprintf(UPO,"%s%s", delim, segi->pname);
index aff15cb61e4190dabfe0861cf663d9f59aa39d18..fecb36bf4eaad411c215ac3e2c94d941c44c7cd4 100644 (file)
@@ -90,6 +90,8 @@ void serial_moredata(PicInsn *buf);
 extern StartupState sta_state;
 extern const char *const stastatelist[];
 
+int resolve_failed(void); /* from resolve.c */
+
 /*---------- from/for record.c and persist.c ----------*/
 
 void records_parse(const char **argv);
index 074135b657d027c2884d024ad29b80566935bf11..e247e2fddfa2688cac9128b6cf36c936f4832a39 100644 (file)
@@ -49,14 +49,11 @@ found:
 }
 
 Segment *record_pname2seg(const char *pname) {
-  int i;
-  const SegmentInfo *segi;
-  
-  for (i=0, segi=info_segments;
-       i<NUM_SEGMENTS;
-       i++, segi++)
+  SEG_IV;
+
+  FOR_SEG
     if (!strcmp(segi->pname, pname))
-      return segments + i;
+      return seg;
   
   return 0; /* silently discard data for segments no longer in the layout */
 }
@@ -138,17 +135,17 @@ void record_seg_has(Segment *seg, int backw, Train *tra) {
 
 void record_seg_at(Segment *seg, const char *movposcombpname) {
   const SegPosCombInfo *spci;
-  int i;
+  int poscomb;
   
-  for (i=0, spci=seg->i->poscombs;
-       i<seg->i->n_poscombs;
-       i++, spci++)
+  for (poscomb=0, spci=seg->i->poscombs;
+       poscomb < seg->i->n_poscombs;
+       poscomb++, spci++)
     if (!strcmp(spci->pname, movposcombpname))
       goto found;
   return;
   
 found:
-  seg->movposcomb= i;
+  seg->movposcomb= poscomb;
 }
 
 /*---------- speed curves ----------*/
@@ -211,12 +208,9 @@ static int speedcurveentry_compare(const void *av, const void *bv) {
 }
 
 static void sort_curves(void) {
-  int i;
-  Train *tra;
-  
-  for (i=0, tra=trains;
-       i<n_trains;
-       i++, tra++) {
+  TRA_IV;
+
+  FOR_TRA {
     if (tra->accel.curve) {
       if (tra->accel.curvesz < 2)
        die("config: speed curve too short for %s", tra->pname);
@@ -250,10 +244,11 @@ static void *alloc_some(void *mapbase, int *offset, size_t sz, int count) {
 }
 
 static void alloc(void) {
-  Train *tra; Segment *seg; const SegmentInfo *segi;
+  TRA_IV;
+  SEG_IV;
   void *mapbase=0;
   char **trap;
-  int i, phase, offset, datalen=0;
+  int phase, offset, datalen=0;
 
 #define ALLOC(array,count) \
   ((array)= alloc_some(mapbase,&offset,sizeof(*(array)),(count)))
@@ -281,9 +276,7 @@ static void alloc(void) {
       break;
 
     ALLOC(trains, n_trains);
-    for (i=0, tra=trains, trap=train_pnames;
-        i<n_trains;
-        i++, tra++, trap++) {
+    FOR_TRAIN(tra, trap=train_pnames, trap++) {
       char *pname;
       ALLOC(pname, strlen(*trap)+1);
       if (phase) {
@@ -297,9 +290,7 @@ static void alloc(void) {
 
     ALLOC(segments, info_nsegments);
     if (phase)
-      for (i=0, seg=segments, segi=info_segments;
-          i<NUM_SEGMENTS;
-          i++, seg++, segi++) {
+      FOR_SEG {
        seg->owner= 0;
        seg->movposcomb= -1;
        seg->i= segi;
diff --git a/hostside/resolve.c b/hostside/resolve.c
new file mode 100644 (file)
index 0000000..73bb763
--- /dev/null
@@ -0,0 +1,9 @@
+/*
+ * resolve detected trains into initial state
+ */
+
+#include "realtime.h"
+
+int resolve_failed(void) {
+  return 0;
+}
index 179f0e4bbdaed52285d3a8dceeb42058719d1603..c01e94022c9464e514b8d2ecf5fb3102db29c0b4 100644 (file)
@@ -99,9 +99,7 @@ static void lay_train_pass(LayTrainState *l,
 }
 
 static void lay_train_inversions(LayTrainState *l) {
-  SegmentNum segn;
-  Segment *seg;
-  const SegmentInfo *segi;
+  SEG_IV;
   int train_be_inverted, seg_be_inverted;
  
   if (l->ec) return;
@@ -110,10 +108,8 @@ static void lay_train_inversions(LayTrainState *l) {
   assert(l->invert_count[train_be_inverted] >= 0);
 
   actual_inversions_start();
-  
-  for (segn=0, seg=segments, segi=info_segments;
-       segn <= NUM_SEGMENTS;
-       segn++, seg++, segi++) {
+
+  FOR_SEG {
     if (!seg->tr_updated) continue;
     assert(seg->owner == l->tra);
     seg_be_inverted= train_be_inverted ^ seg->tr_backwards;
@@ -125,12 +121,9 @@ static void lay_train_inversions(LayTrainState *l) {
 }
 
 static void lay_train_done(LayTrainState *l) {
-  SegmentNum segn;
-  Segment *seg;
+  SEG_IV;
   
-  for (segn=0, seg=segments;
-       segn <= NUM_SEGMENTS;
-       segn++, seg++) {
+  FOR_SEG {
     if (seg->owner == l->tra) {
       if (!seg->tr_updated) seg_clear_stale(seg);
       seg->tr_updated= 0;
index d7dd84718400c28dab36c262de5ebfe3daa78bd7..df975447bdbabab17b8df287f04b9f39c3ed3e8a 100644 (file)
@@ -73,7 +73,8 @@ struct Segment {
     movfeat_moving:1, /* feature(s) have been told to change to movposcomb */
     cm_autostop:1, /* train should stop on detection */
     seg_inverted:1, /* polarity is inverted */
-    tr_updated:1; /* for use by safety.c:lay_train etc.; otherwise 0 */
+    tr_updated:1, /* for use by safety.c:lay_train etc.; otherwise 0 */
+    res_detect:1; /* detection noticed here during resolution */
   TimeInterval until_here, /* ) nonnegative; */  /* ) always valid but      */
     until_detect;          /* ) 0 if already */  /* )  meaningful iff owner */
   MovPosComb movposcomb;
@@ -196,6 +197,33 @@ const SegmentLinkInfo *trackloc_segmentlink(const TrackLocation *tloc,
 
 /*========== useful macros and declarations ==========*/
 
+/*---------- looping over trains and segments ----------*/
+
+#define SEGMENT_ITERVARS(seg)                  \
+  SegmentNum seg##n;                           \
+  Segment *seg;                                        \
+  const SegmentInfo *seg##i
+
+#define TRAIN_ITERVARS(tra)                    \
+  Train *tra;                                  \
+  int tra##n
+
+#define FOR_SEGMENT(seg, initx, stepx)                 \
+  for (seg##n=0, seg=segments, seg##i=info_segments;   \
+       seg##n <= NUM_SEGMENTS;                         \
+       seg##n++, seg++, seg##i++, stepx)
+
+#define FOR_TRAIN(tra, initx, stepx)           \
+  for (tra##n=0, tra=trains;                   \
+       tra##n < n_trains;                      \
+       tra##n++, tra++, stepx)
+
+#define SEG_IV SEGMENT_ITERVARS(seg)
+#define FOR_SEG FOR_SEGMENT(seg,(void)0,(void)0)
+  
+#define TRA_IV TRAIN_ITERVARS(tra)
+#define FOR_TRA FOR_TRAIN(tra,(void)0,(void)0)
+
 /*---------- calculations with fixed point speeds ----------*/
 
 #define DIVIDE_ROUNDING_UP(num,den)   (((num) + (den) - 1) / (den))
index 25b67505db8d707952b7f26c5263a66b0d844731..b2822094848828e2b39541e88a3150d00a083732 100644 (file)
@@ -49,6 +49,8 @@ static void initial_ping(void) {
 void sta_startup(void) { sta_goto(Sta_Flush); }
 
 static void sta_goto(StartupState new_state) {
+  SEG_IV;
+  
   toev_stop(&sta_toev);
   sta_toev.callback= timedout_onward;
   sta_toev.duration= -1;
@@ -78,8 +80,17 @@ static void sta_goto(StartupState new_state) {
   case Sta_Ping:                                                   break;
   case Sta_Fault:                                                  break;
   case Sta_Settling:                        enco_pic_off(&piob);   break;
-  case Sta_Resolving:                       enco_pic_on(&piob);    break;
-  case Sta_Run:   persist_install(); retransmit_start();           break;
+  case Sta_Resolving:
+    FOR_SEG seg->res_detect= 0;
+    enco_pic_on(&piob);
+    break;
+  case Sta_Run:
+    if (resolve_failed)
+      /* in this case, we get stuck - user has to power cycle the layout */
+      return;
+    persist_install();
+    retransmit_start();
+    break;
   }
   if (piob.l) serial_transmit(&piob);
 
@@ -190,13 +201,23 @@ void on_pic_aaargh(const PicInsnInfo *pii, const PicInsn *pi, int objnum)
   { abort(); }
 
 void on_pic_detect1(const PicInsnInfo *pii, const PicInsn *pi, int segn) {
+  Segment *seg;
   if (segn >= NUM_SEGMENTS) die("PIC sent detect @#%d out of range",segn);
-  if (sta_state < Sta_Run) {
+
+  seg= &segments[segn];
+  
+  switch (sta_state) {
+  case Sta_Flush:
+  case Sta_Off:
+  case Sta_Ping:
+  case Sta_Fault:
+  case Sta_Settling:
     oprintf(UPO, "warning fixme ignored non-Run detection @%s\n",
            info_segments[segn].pname);
-    return;
+    break;
+  case Sta_Resolving:  seg->res_detect= 1;             break;
+  case Sta_Run:        safety_notify_detection(seg);   break;
   }
-  safety_notify_detection(&segments[segn]);
 }
 
 /*---------- fixme move these to where they want to go ----------*/