chiark / gitweb /
new hostside compiles but has several bits missing
authorian <ian>
Sun, 10 Sep 2006 19:27:49 +0000 (19:27 +0000)
committerian <ian>
Sun, 10 Sep 2006 19:27:49 +0000 (19:27 +0000)
hostside/Makefile
hostside/README
hostside/TODO
hostside/commands.c
hostside/realtime.h
hostside/retransmit.c
hostside/startup.c
hostside/utils.c

index caca32556bfbcae00184eddfe15da75d28a302d7..0c0bc2d6b297b9d0c89ba281b3b08d6d07f95f45 100644 (file)
@@ -27,7 +27,7 @@ on-bessar:    $(TARGETS)
 
 realtime:      realtime.o startup.o cdumgr.o safety.o trackloc.o       \
                 speed.o actual.o retransmit.o                          \
-                cmdinput.o obc.o eventhelp.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          \
                 nmra.o encode.o                                        \
index bf67f482b42c0a184e57e20ea13df4aa3353a9f3..39d169536a2777d9acd4cde4d37e73fa70a55117 100644 (file)
@@ -32,14 +32,15 @@ To test:
 
 Protocol over new hostside stdin:
                                             Example (always the same msg):
- P> nmra [*<slot>] [<nmra-command [<nmra-args>...]]    nmra speed28 3 13 1
- P> nmra [*<slot>] [=<nmra-bytes>]                     nmra =0348
- P> nmra [*<slot>] [:<nmra-bytes-with-csum>]           nmra :03484b
- P> nmra [*<slot>] [_<pic-literal-bytes>]              nmra _7f7f00644197
-   in each case *<slot> indicates that the message should be put in
-   the retransmission cycle, and cancels any previous message with the
-   same *<slot>.  <slot> may be empty.
- P> nmra *<slot>
+ P> nmra [<slot>] [<nmra-command [<nmra-args>...]]    nmra speed28 3 13 1
+ P> nmra [<slot>] [=<nmra-bytes>]                     nmra =0348
+ P> nmra [<slot>] [:<nmra-bytes-with-csum>]           nmra :03484b
+ P> nmra [<slot>] [_<pic-literal-bytes>]              nmra _7f7f00644197
+   in each case <slot> (if present) is *<slotname> or %<slotname> and
+   indicates that the message should be put in the retransmission
+   cycle, and cancels any previous message with the same <slotname>.
+   <slotname> may be empty.  * indicates urgent
+ P> nmra <slot>
    cancels the relevant retransmission.
 
                                             Example (always the same msg):
index a9b4fa2a21a83fcdffb3a4dcba98519b3002d5e9..1c8443e6bb59351a094f627e7bc11a5872ce3fff 100644 (file)
@@ -1,6 +1,16 @@
+before can test
+       commands for speed manager
+       create data files containing some train data
+       write trivial initial settlement to get data array right
+       write out layout data on crash
+       check that everything in Train and Segment is init'd
+
+dunno but maybe before can test
+       train speed curve measurements
+       wiring to gui display
+
 things not yet considered at all in safety code
-       polarity
+       coming up against points the wrong way
        min. curve specifications
 
-put correct data in dummy-trains.c
 initialise safety_state with appropriate stuff
index 2dccc253ba76740ccbd0fe882bb028d260dba2ff..369e7aa3e591c44e3a6549327ea752034547eac8 100644 (file)
@@ -16,7 +16,7 @@ struct ManualRetransmitNode {
   ManualRetransmitNode *back, *next;
   char *name;
   int lname;
-  RetransmitNode rn;
+  RetransmitUrgentNode rn;
 };
 
 #define bogus_volatile /*empty*/
@@ -46,7 +46,7 @@ void nmra_problem(NmraParseEncodeCaller *pec, const char *problem) {
   longjmp(pec->jb, 1);
 }
 
-static int cmd_nmra_command(ParseState *ps, RetransmitNode *rn) {
+static int cmd_nmra_command(ParseState *ps, PicInsn *pi) {
   int hex;
   const char *cmdarg;
   int lcmdarg;
@@ -57,7 +57,7 @@ static int cmd_nmra_command(ParseState *ps, RetransmitNode *rn) {
 
   assert(ps->remain);
   switch (ps->remain[0]) {
-  case '_':  ps->remain++; return ps_needhextoend(ps, rn->pi.d, &rn->pi.l);
+  case '_':  ps->remain++; return ps_needhextoend(ps, pi->d, &pi->l);
   case '=':  hex=1;  checksum=1;  break;
   case ':':  hex=1;  checksum=0;  break;
   default:   hex=0;  checksum=1;  break;
@@ -93,17 +93,22 @@ static int cmd_nmra_command(ParseState *ps, RetransmitNode *rn) {
   if (checksum)
     nmra_addchecksum(&nmra);
 
-  nmra_encodeforpic(&nmra, &rn->pi);
+  nmra_encodeforpic(&nmra, pi);
   return 1;
 }
   
 static void cmd_nmra(ParseState *ps, const CmdInfo *ci) {
   static struct { ManualRetransmitNode *head, *tail; } mrns;
   
-  ManualRetransmitNode *mrn;
-  RetransmitNode *rn, rn_buf;
+  PicInsn *pi, pi_buf;
+  ManualRetransmitNode *mrn=0;
+  void (*retrans)(RetransmitUrgentNode *urg, const Nmra *n)= 0;
   
-  if (ps->remain && ps->remain[0]=='*') {
+  if (ps->remain) {
+    if (ps->remain[0]=='*') retrans= retransmit_urgent_queue;
+    else if (ps->remain[0]=='%') retrans= retransmit_urgent_queue_relaxed;
+  }
+  if (retrans) {
     const char *mrname;
     int lmrname;
 
@@ -116,19 +121,17 @@ static void cmd_nmra(ParseState *ps, const CmdInfo *ci) {
           !memcmp(mrn->name, mrname, lmrname));
         mrn= mrn->next);
     if (mrn) {
-      retransmit_cancel(&mrn->rn);
+      retransmit_urgent_cancel(&mrn->rn);
     } else {
       mrn= mmalloc(sizeof(*mrn));
       mrn->name= mmalloc(lmrname);
       memcpy(mrn->name, mrname, lmrname);
       mrn->lname= lmrname;
     }
-  } else {
-    mrn= 0;
   }
 
   if (!ps->remain) {
-    if (!mrn) {
+    if (!retrans) {
       badcmd(ps,"nmra must have slot to cancel or data to send");
       return;
     }
@@ -138,18 +141,17 @@ static void cmd_nmra(ParseState *ps, const CmdInfo *ci) {
     return;
   }
 
-  rn= mrn ? &mrn->rn : &rn_buf;
-  rn->pi.l= sizeof(rn->pi.d);
+  pi= retrans ? &mrn->rn.pi : &pi_buf;
   
-  if (!cmd_nmra_command(ps, rn)) {
-    if (mrn) { free(mrn->name); free(mrn); }
+  if (!cmd_nmra_command(ps, pi)) {
+    if (retrans) { free(mrn->name); free(mrn); }
     return;
   }
 
-  if (mrn)
-    retransmit_queue(&mrn->rn);
+  if (retrans)
+    retrans(&mrn->rn, 0);
   else
-    serial_transmit(&rn->pi);
+    serial_transmit(pi);
   ouack(ci);
 }
 
@@ -179,8 +181,15 @@ static void cmd_pic(ParseState *ps, const CmdInfo *ci) {
     }
     if (!ps_neednoargs(ps))
       return;
-    enco_pic_anyinsn(&pi, pii, arg);
+    enco_pic_pii(&pi, pii, arg);
   }
   serial_transmit(&pi);
   ouack(ci);
 }
+
+const CmdInfo toplevel_cmds[]= {
+  { "pic",        cmd_pic         },
+  { "nmra",       cmd_nmra,       },
+  { "noop",       cmd_noop        },
+  { 0 }
+};
index 197efc68fa38f4198c9ed06db6c3bc70ec5c73f6..59db14c4a6f127f1449bbc05b1caff7842109f7c 100644 (file)
@@ -31,11 +31,16 @@ typedef struct RetransmitRelaxedNode RetransmitRelaxedNode;
 typedef union RetransmitUrgentNode RetransmitUrgentNode;
 typedef unsigned Retransmit__Time;
 
-struct RetransmitRelaxedNode { /* all for use by retransmit.c only */
+  /* Contents of the retransmission nodes is generally all for use by
+   * retransmit.c only; as a special exception, caller may edit pi
+   * directly.  Normally, though, pi is set by supplying an NMRA
+   * command to one of the _queue functions; _queue will update pi
+   * iff the Nmra* is non-null */
+struct RetransmitRelaxedNode {
   PicInsn pi;
   DLIST_NODE(RetransmitRelaxedNode) rr;
 };
-union RetransmitUrgentNode { /* all for use by retransmit.c only */
+union RetransmitUrgentNode {
   PicInsn pi;
   struct {
     RetransmitRelaxedNode relaxed;
@@ -45,6 +50,9 @@ union RetransmitUrgentNode { /* all for use by retransmit.c only */
   } u;
 };
 
+void retransmit_start(void);
+void retransmit_something(void);
+
 void retransmit_relaxed_queue(RetransmitRelaxedNode *rn, const Nmra *n);
 void retransmit_relaxed_requeue(RetransmitRelaxedNode *rn, const Nmra *n);
 void retransmit_relaxed_cancel(RetransmitRelaxedNode *rn);
index ce6a0da2e7c945cb56bdb7890d9c08855d2c0f44..5372751ecda3ceb2c17c8338fd0982d272010887 100644 (file)
  */
 
 #include "realtime.h"
+#include "nmra.h"
 #include "retransmit-table.h"
 
 #define RETRANSMIT_TIME_SIGNED_MAX ((~(Retransmit__Time)0) >> 1)
 
-static const PicInsn linefill= { { 0xff, 0x7f }, 2 };
+static PicInsn linefill;
 
 static DLIST2_HEAD(RetransmitRelaxedNode) relaxed;
-static elapsed;
+static Retransmit__Time elapsed;
 static PerSpeedyTrans speedies[] = SPEEDIESINIT;
 
 static void retransmit_this(const PicInsn *pi) {
@@ -54,21 +55,33 @@ static void retransmit_this(const PicInsn *pi) {
   elapsed++;
 }
 
-static void retransmit_something(void) {
+void retransmit_start(void) {
+  Nmra n;
+
+  enco_nmra_idle(&n);
+  nmra_encodeforpic(&n, &linefill);
+
+  retransmit_something();
+  retransmit_something();
+  retransmit_something();
+}
+
+void retransmit_something(void) {
   PerSpeedyTrans *spd;
   RetransmitUrgentNode *urg;
   RetransmitRelaxedNode *rlx;
+  int ix;
   
   for (ix=0, spd=speedies;
-       ix < RETRANS_SPEEDYCOUNT;
+       ix < SPEEDYCOUNT;
        ix++, spd++) {
-    urg= spd->head;
+    urg= spd->queue.head;
     if (!urg) continue;
     if (elapsed - urg->u.when > RETRANSMIT_TIME_SIGNED_MAX) continue;
 
     /* found one to transmit: */
     DLIST2_REMOVE(spd->queue,urg,u.queue);
-    if (++ix < RETRANS_SPEEDYCOUNT) {
+    if (++ix < SPEEDYCOUNT) {
       urg->u.ix= ix;
       urg->u.when= elapsed + spd->interval;
       spd++;
@@ -80,7 +93,7 @@ static void retransmit_something(void) {
     return;
   }
 
-  rlx= relaxed.head) {
+  rlx= relaxed.head;
   if (rlx) {
     DLIST2_REMOVE(relaxed,rlx,rr);
     DLIST2_APPEND(relaxed,rlx,rr);
@@ -91,34 +104,32 @@ static void retransmit_something(void) {
   serial_transmit(&linefill);
 }
 
-void retransmit_relaxed_queue(RetransmitRelaxedNode *rlx, const Nmra *n) {
-  nmra_encodeforpic(n, &rlx->pi);
+void retransmit_relaxed_queue(RetransmitRelaxedNode *rn, const Nmra *n) {
+  if (n) nmra_encodeforpic(n, &rn->pi);
   DLIST2_PREPEND(relaxed,rn,rr);
 }
 void retransmit_relaxed_requeue(RetransmitRelaxedNode *rn, const Nmra *n) {
-  retransmit_relaxed_cancel(rlx);
-  retransmit_relaxed_queue(rlx, n);
+  retransmit_relaxed_cancel(rn);
+  retransmit_relaxed_queue(rn, n);
 }
 void retransmit_relaxed_cancel(RetransmitRelaxedNode *rlx) {
   DLIST2_REMOVE(relaxed,rlx,rr);
 }
 
 void retransmit_urgent_queue(RetransmitUrgentNode *urg, const Nmra *n) {
-  nmra_encodeforpic(n, &urg->pi);
+  retransmit_relaxed_queue(&urg->u.relaxed, n);
   urg->u.ix= 0;
   urg->u.when= elapsed;
   DLIST2_APPEND(speedies[0].queue,urg,u.queue);
-  retransmit_relaxed_queue(&urg->u.relaxed);
 }
 void retransmit_urgent_queue_relaxed(RetransmitUrgentNode *urg, const Nmra *n){
-  nmra_encodeforpic(n, &urg->pi);
+  retransmit_relaxed_queue(&urg->u.relaxed, n);
   urg->u.ix= -1;
   urg->u.when= elapsed;
-  retransmit_relaxed_queue(&urg->u.relaxed);
 }
 void retransmit_urgent_requeue(RetransmitUrgentNode *rn, const Nmra *n) {
-  retransmit_urgent_cancel(urg);
-  retransmit_urgent_queue(urg, n);
+  retransmit_urgent_cancel(rn);
+  retransmit_urgent_queue(rn, n);
 }
 void retransmit_urgent_cancel(RetransmitUrgentNode *urg) {
   if (urg->u.ix >= 0)
index a580280009072271cef3056428a99a1c6ca1db89..04d844a46d68334345d5bb0e2e5a22742424e11f 100644 (file)
@@ -78,7 +78,7 @@ static void sta_goto(StartupState new_state) {
   case Sta_Fault:                                                  break;
   case Sta_Settling:                        enco_pic_off(&piob);   break;
   case Sta_Resolving:                       enco_pic_on(&piob);    break;
-  case Sta_Run:                                                    break;
+  case Sta_Run:         retransmit_start();                        break;
   }
   if (piob.l) serial_transmit(&piob);
 
@@ -200,8 +200,9 @@ void on_pic_detect1(const PicInsnInfo *pii, const PicInsn *pi, int segn) {
 void on_pic_nmradone(const PicInsnInfo *pii, const PicInsn *pi, int objnum) {
   if (sta_state <= Sta_Settling) return;
   if (sta_state != Sta_Run) die("PIC sent NMRADONE in Resolving");
-  
-  /* fixme transmit something else (move this to another file?) */
+
+  while (objnum--)
+    retransmit_something();
 }
 
 void on_pic_detect0(const PicInsnInfo *pii, const PicInsn *pi, int objnum) {
@@ -210,12 +211,3 @@ void on_pic_detect0(const PicInsnInfo *pii, const PicInsn *pi, int objnum) {
 void abandon_run(void) {
   /* fixme do something here */
 }
-
-const CmdInfo toplevel_cmds[]= {
-#if 0
-  { "pic",        cmd_pic         },
-  { "nmra",       cmd_nmra,       },
-  { "noop",       cmd_noop        },
-#endif
-  { 0 }
-};
index ce4bee93ef3c1162f5ab5b8dd03deeaa1a0cde3c..5e0824432d014d31ed90ab4403cc5f3678d752e3 100644 (file)
@@ -53,6 +53,14 @@ void *mmalloc(size_t sz) {
   return p;
 }
                  
+void *mrealloc(void *o, size_t sz) {
+  void *r;
+  if (!sz) { free(o); return 0; }
+  r= realloc(o,sz);
+  if (!r) diem();
+  return r;
+}
+                 
 char *mstrdupl(const char *s, int l) {
   char *p;
   p= mmalloc(l+1);