2 * main program for realtime control
7 const char *progname= "realtime";
9 /*---------- global variables ----------*/
13 static const char *device;
15 /*---------- general event handling ----------*/
17 static void comms_error(const char *ch, const char *e1,
18 const char *e2 /* may be 0 */) {
19 if (!e1 && !e2) e1= "end of file";
20 die("communications error: %s: %s%s%s", ch, e1, e2?": ":"", e2?e2:"");
23 static void *read_exception(oop_source *evts, int fd,
24 oop_event evt, void *cl_v) {
29 ch= (fd==UPO->fd ? UPO->desc :
30 fd==serial_fd ? "serial port" :
33 r= read(fd, &bufc, 1);
34 if (r==-1) comms_error(ch, "read error", strerror(errno));
35 else if (r==0) comms_error(ch, "reports exception, reads EOF", 0);
36 else comms_error(ch, "reports exception, but readable", 0);
41 /*---------- command channel handling (oop_read, obc) ----------*/
43 static void command_doline(ParseState *ps, CommandInput *cmdi) {
45 ci= some_needword_lookup(ps, toplevel_cmds, "command");
46 if (ci) ci->fn(ps,ci);
49 void oupicio(const char *dirn, const PicInsnInfo *pii, int objnum) {
51 oprintf(UPO, "picio %s %s\n", dirn, pii->name);
53 oprintf(UPO, "picio %s %s %u\n", dirn, pii->name, objnum);
56 void vbadcmd(ParseState *ps, const char *fmt, va_list al) {
60 static void obc_error(OutBufferChain *ch, const char *e1, const char *e2) {
61 comms_error(ch->desc, e1, e2);
64 void ouhex(const char *word, const Byte *command, int length) {
65 oprintf(UPO, "%s", word);
67 oprintf(UPO, " %02x", *command++);
76 if (e) fprintf(stderr,"(unwritten command output: %s)\n",strerror(e));
79 /*---------- serial input (via oop) ----------*/
81 static PicInsn serial_buf;
83 static void *serial_readable(oop_source *evts, int fd,
84 oop_event evt, void *u0) {
87 r= read(serial_fd, &serial_buf.d, sizeof(serial_buf.d) - serial_buf.l);
88 if (r==0) die("serial port - eof");
90 if (errno == EWOULDBLOCK || errno == EINTR)
92 diee("serial port - read error");
96 buf_used= serial_buf.l;
100 serial_buf.l= buf_used;
101 serial_moredata(&serial_buf);
102 if (!serial_buf.l) break;
103 buf_used -= serial_buf.l;
104 memmove(serial_buf.d, serial_buf.d + serial_buf.l, buf_used);
105 if (!buf_used) break;
107 serial_buf.l= buf_used;
111 /*---------- serial port output (not via liboop) ----------*/
113 void serial_transmit(const PicInsn *pi) {
114 const PicInsnInfo *pii;
117 fixme decode polarity
118 picinsn_decode(pi, pic_command_infos, &pii, &objnum);
121 oprintf(UPO, "picio out unknown\n");
123 oupicio("out",pii,objnum);
125 ouhex("picioh out", pi->d, pi->l);
127 /* note that the serial port is still in nonblocking mode. if
128 * we ever buffer up far enough that the kernel wants to make us
129 * block, we should die! */
130 serial_transmit_now(pi->d, pi->l);
133 /*---------- initialisation ----------*/
135 int main(int argc, const char **argv) {
136 oop_source_sys *sys_events;
140 if (!device) device= "/dev/ttya0";
142 sys_events= oop_sys_new(); if (!sys_events) diee("oop_sys_new");
143 events= oop_sys_source(sys_events); massert(events);
145 cmdi.out.desc= (char*)"command";
147 cmdi.out.error= obc_error;
148 cmdi.doline= command_doline;
153 r= oop_fd_nonblock(serial_fd, 1); if (r) diee("nonblock(serial_fd,1)");
155 events->on_fd(events, serial_fd, OOP_READ, serial_readable, 0);
156 events->on_fd(events, serial_fd, OOP_EXCEPTION, read_exception, 0);
159 oop_sys_run(sys_events);