From: ian Date: Sun, 10 Sep 2006 19:27:49 +0000 (+0000) Subject: new hostside compiles but has several bits missing X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=3bc63a0879850d9d6e3c5ba10fe31fc723327e1e;p=trains.git new hostside compiles but has several bits missing --- diff --git a/hostside/Makefile b/hostside/Makefile index caca325..0c0bc2d 100644 --- a/hostside/Makefile +++ b/hostside/Makefile @@ -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 \ diff --git a/hostside/README b/hostside/README index bf67f48..39d1695 100644 --- a/hostside/README +++ b/hostside/README @@ -32,14 +32,15 @@ To test: Protocol over new hostside stdin: Example (always the same msg): - P> nmra [*] [...]] nmra speed28 3 13 1 - P> nmra [*] [=] nmra =0348 - P> nmra [*] [:] nmra :03484b - P> nmra [*] [_] nmra _7f7f00644197 - in each case * indicates that the message should be put in - the retransmission cycle, and cancels any previous message with the - same *. may be empty. - P> nmra * + P> nmra [] [...]] nmra speed28 3 13 1 + P> nmra [] [=] nmra =0348 + P> nmra [] [:] nmra :03484b + P> nmra [] [_] nmra _7f7f00644197 + in each case (if present) is * or % and + indicates that the message should be put in the retransmission + cycle, and cancels any previous message with the same . + may be empty. * indicates urgent + P> nmra cancels the relevant retransmission. Example (always the same msg): diff --git a/hostside/TODO b/hostside/TODO index a9b4fa2..1c8443e 100644 --- a/hostside/TODO +++ b/hostside/TODO @@ -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 diff --git a/hostside/commands.c b/hostside/commands.c index 2dccc25..369e7aa 100644 --- a/hostside/commands.c +++ b/hostside/commands.c @@ -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 } +}; diff --git a/hostside/realtime.h b/hostside/realtime.h index 197efc6..59db14c 100644 --- a/hostside/realtime.h +++ b/hostside/realtime.h @@ -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); diff --git a/hostside/retransmit.c b/hostside/retransmit.c index ce6a0da..5372751 100644 --- a/hostside/retransmit.c +++ b/hostside/retransmit.c @@ -39,14 +39,15 @@ */ #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) diff --git a/hostside/startup.c b/hostside/startup.c index a580280..04d844a 100644 --- a/hostside/startup.c +++ b/hostside/startup.c @@ -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 } -}; diff --git a/hostside/utils.c b/hostside/utils.c index ce4bee9..5e08244 100644 --- a/hostside/utils.c +++ b/hostside/utils.c @@ -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);