#include "auproto-pic.h"
#include "dliste.h"
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <stddef.h>
-#include <ctype.h>
-#include <math.h>
-
-#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/mman.h>
-#include <sys/wait.h>
-#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
+#include <inttypes.h>
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include "../.git-revid-autoversion.h"
#include "../layout/layout-data.h"
+#include "realtime+dflags.h"
-typedef struct Segment Segment;
-typedef struct Train Train;
+typedef struct Segment Segment; /* from safety.h */
+typedef struct Train Train; /* from safety.h */
+typedef struct TimeoutEvent TimeoutEvent;
/*---------- from retransmit.c ----------*/
* 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; iff the Nmra* is
- * non-null, _queue will add an NMRA checksum and update pi.
+ * non-null, _queue will add an NMRA checksum (modifying *n)
+ * and update pi (which always results in a nonzero pi.l).
*/
struct RetransmitRelaxedNode {
PicInsn pi;
void retransmit_start(void);
void retransmit_something(void);
-void retransmit_relaxed_queue(RetransmitRelaxedNode *rn, Nmra *n);
-void retransmit_relaxed_requeue(RetransmitRelaxedNode *rn, Nmra *n);
-void retransmit_relaxed_cancel(RetransmitRelaxedNode *rn);
-
void retransmit_urgent_queue(RetransmitUrgentNode *rn, Nmra *n);
void retransmit_urgent_queue_relaxed(RetransmitUrgentNode *urg, Nmra *n);
void retransmit_urgent_requeue(RetransmitUrgentNode *rn, Nmra *n);
void retransmit_urgent_cancel(RetransmitUrgentNode *rn);
- /* ... NB: these are NOT idempotent. Use _requeue it's queued;
- * _requeue is just _cancel followed by queue. */
+void retransmit_relaxed_queue(RetransmitRelaxedNode *rn, Nmra *n);
+void retransmit_relaxed_cancel(RetransmitRelaxedNode *rn);
+
+ /* ... NB: these are NOT idempotent and NOT interchangeable. Use
+ * urgent_requeue if it's queued and has changed and must get a new
+ * quota of urgency; _requeue is just _cancel followed by queue. */
-/*---------- features, filled in by record, used by features.c ----------*/
+/*---------- adjuncts, filled in by record, used by adjuncts.c ----------*/
-#define FEATURESADDR_TRANSMITS 4
+#define ADJUNCTSADDR_TRANSMITS 4
/* 0..2 are func0to4 func5to8 func9to12 and speed cmd
* pi.l is 0 if not transmitting */
-typedef struct FeaturesAddr {
- struct FeaturesAddr *next;
- int addr, cbitmap;
- RetransmitRelaxedNode rn[FEATURESADDR_TRANSMITS];
-} FeaturesAddr;
+#define ADJS_SPEEDSTEP_BIT 0x4000u /* a->{current,all,permit}, f->bits */
+#define ADJS_SPEEDSTEP_REVERSE 0x8000u /* in a->all */
+
+typedef struct AdjunctsAddr {
+ struct AdjunctsAddr *next;
+ int addr, speedstep;
+ unsigned current, permit, all;
+ RetransmitRelaxedNode rn[ADJUNCTSADDR_TRANSMITS];
+} AdjunctsAddr;
typedef struct {
- FeaturesAddr *a;
- int bitval; /* may have no or several bits set */
- int speedstep; /* -ve means backwards; 0 means not to use motor for feat */
-} FeaturesFeature;
-
-typedef struct FeaturesTarget {
- struct FeaturesTarget *next;
- char *pname;
- char *featchs; /* null-terminated */
- FeaturesFeature **feats; /* same order as featchs */
-} FeaturesTarget;
+ char *pname; /* first, for pname1st_compar */
+ AdjunctsAddr *a;
+ unsigned bits; /* may have no or several bits set */
+} AdjunctsAdjunct;
+
+typedef struct AdjunctsTarget {
+ char *pname; /* first, for pname1st_compar */
+ int n_adjs;
+ AdjunctsAdjunct *adjs;
+} AdjunctsTarget;
extern int n_trains;
extern Train *trains;
extern Segment *segments;
-extern FeaturesTarget *feattargs;
-extern FeaturesAddr *feataddrs;
+extern int n_adjtargs, n_adjaddrs;
+extern AdjunctsTarget *adjtargs;
+extern AdjunctsAddr **adjaddrs;
/*---------- global variables, in realtime.c ----------*/
extern CommandInput cmdi;
extern int picio_send_noise;
+extern int disable_watchdog;
-#define UPO (&(cmdi.out))
+#define CIXF_U 0x0000ffffu
+#define CIXF_FORCE 0x00010000u
+#define CIXF_ANYSTA 0x00020000u
/*---------- from/for startup.c ----------*/
extern StartupState sta_state;
extern const char *const stastatelist[];
+void cmdi_output_bufferempty(OutBufferChain *obc);
void resolve_begin(void); /* from resolve.c */
int resolve_complete(void);
void resolve_motioncheck(void);
+void waggle_settle(void); /* from movpos.c */
+void waggle_startup_manual(void);
+
/*---------- from/for record.c and persist.c ----------*/
void records_parse(const char **argv);
/*---------- from/for realtime.c ----------*/
-void oupicio(const char *dirn, const PicInsnInfo *pii, int objnum);
+void oupicio(const char *dirn, const PicInsnInfo *pii, int obj, int v,
+ void (*qprintf)(const char *fmt, ...));
void ouhex(const char *word, const Byte *command, int length);
+void ouhex_nosim(const char *word, const Byte *command, int length);
void serial_transmit(const PicInsn *pi);
+void command_doline(ParseState *ps, CommandInput *cmdi_arg);
+const CmdInfo *current_cmd;
+
+void check_rusage_baseline(void);
+void check_rusage_check(int always_report);
+
+/*---------- for/from simulate.c ----------*/
+
+void serial_indata_process(int buf_used);
+
+void sim_initialise(const char *logduplicate);
+void sim_run(void);
+
+void simlog_ccb(char *m, size_t l, void *u);
+void simlogv(const char *fmt, va_list al);
+void simlog(const char *fmt, ...);
+void simlog_serial(const Byte *data, int length);
+void simlog_flush(void);
+void simlog_open(const char *fn);
+
+void mgettimeofday(struct timeval *tv); /* contains magic for simulation */
+void *toev_callback(oop_source *source, struct timeval tv, void *t_v);
+
+void sim_toev_start(TimeoutEvent *toev);
+void sim_toev_stop(TimeoutEvent *toev);
+void sim_mgettimeofday(struct timeval *tv);
+
+extern int simlog_full;
+extern const char *simulate;
+
+extern PicInsn serial_buf;
/*---------- from actual.c ----------*/
/* this belongs in {au,skel}proto-pic.[ch] really but it's
* more convenient here. */
+void adjuncts_start_xmit(void);
+void adjuncts_updated(AdjunctsAddr *a);
+
/*---------- from movpos.c ----------*/
void points_turning_on(void);
-void points_all_abandon(void);
+void motions_all_abandon(void);
+void movpos_reportall(void);
+
+/*---------- from eventhelp.c ----------*/
+
+extern const char toev_fast_pclass[];
+
+typedef void TimeoutEventFn(TimeoutEvent*);
+struct TimeoutEvent { /* Undefined Idle Running set by */
+ int running; /* any 0 1 toev_ */
+ int duration; /*ms*/ /* any any[1] any[1] caller */
+ TimeoutEventFn *callback; /* any any valid[2] caller */
+ struct timeval abs; /* any any valid toev_ */
+ const char *pclass, *pinst; /* any any valid caller */
+}; /* [1] duration must be >=0 or -1 when toev_start is called;
+ * [2] callback may be modified while timeout is running;
+ * value used is that prevailing when timeout happens
+ * when the timeout happens, TimeoutEvent's state goes from R to I
+ * and then callback member is read and the function called
+ */
+
+void toev_init(TimeoutEvent*); /* U -> I */
+void toev_start(TimeoutEvent*); /* IR -> R; reads duration */
+ /* if duration is -1 then is same as toev_stop */
+void toev_stop(TimeoutEvent*); /* IR -> I */
+
+/*---------- from rtprio.c ----------*/
+
+void realtime_priority(void);
+
+#define RTFEAT_DEFAULTS 0100u /* turns things on iff not sim */
+#define RTFEAT_MEM 0001u /* mlock */
+#define RTFEAT_CPU 0002u /* hard CPU scheduling priority */
+#define RTFEAT_RUSAGE 0004u /* check up on faults etc. in getrusage */
+
+#define RTFEAT_ALL_SHIFT 16
+#define RTFEAT_ALL(x) (RTFEAT_##x << RTFEAT_ALL_SHIFT)
+ /* RTFEAT_ALL(FOO) is relevant only if RTFEAT_FOO selected, and means
+ * not to apply the normal limit to the grabbing of FOO */
+
+extern unsigned rtfeats_use;
+
+void ouvprintf(const char *fmt, va_list al)
+ __attribute__((format(printf,1,0)));
+void ouprintf(const char *fmt, ...)
+ __attribute__((format(printf,1,2)));
+
+void ouvprintf_only(const char *fmt, va_list al)
+ __attribute__((format(printf,1,0)));
+void ouprintf_only(const char *fmt, ...)
+ __attribute__((format(printf,1,2)));
+
+extern unsigned long eventcounter; /* for debugging use only ! */
+void debug_count_event(const char *what);
+
+#define DEBUGP(a,k) (dflags_##a & DBIT_##a##_##k)
+
+#define DPRINTFA ouprintf_only
+
+#define COND_DPRINTF(cond, a,k, fmt, ...) \
+ ((cond) ? DPRINTFA("debug " #a "/" #k " : " fmt,##__VA_ARGS__) : (void)0)
+
+#define DPRINTF(a,k,f,...) COND_DPRINTF(DEBUGP(a,k),a,k,f,##__VA_ARGS__)
+#define DPRINTF1(a,k,f,...) COND_DPRINTF((DP)=DEBUGP(a,k), a,k,f,##__VA_ARGS__)
+#define DPRINTF2(f,...) ((DP) ? DPRINTFA(f,##__VA_ARGS__) : (void)0)
/*---------- tbi ----------*/
void choreographers_all_abandon(void);
-
#include "record.h"
#define PERSIST_CONVERT_OPTION "--persist-convert-entrails"
#include "safety.h"
-#define CTYPE(isfoobar,ch) (isfoobar((unsigned char)(ch)))
#endif /*REALTIME_H*/