2 #include <netinet/in.h>
9 #include <sys/socket.h>
10 #include <sys/types.h>
14 #include "mTaskSymbols.h"
17 #define MAXTASKSIZE 1024
19 #define STACKSIZE 1024
22 #define MSG_DELTASK 'd'
28 #define debug(s, ...) printf(s, ##__VA_ARGS__);
29 #define trace(op, ...) printf("pc: %d, sp: %d, op: " op, pc, sp, ##__VA_ARGS__);
31 #define debug(s, ...) ;
32 #define trace(pc, sp, op) ;
35 #define pdie(s) {perror(s); exit(1);}
36 #define die(s, ...) {fprintf(stderr, s, ##__VA_ARGS__); exit(1);}
39 uint8_t bc
[MAXTASKSIZE
];
47 struct task tasks
[MAXTASKS
] = {0};
52 void killHandler(int i
)
54 printf("%s caught, Bye...\n", strsignal(i
));
58 bool input_available(int fd
){
65 if (select(fd
+1, &fds
, NULL
, NULL
, &tv
) == -1)
67 return FD_ISSET(fd
, &fds
);
71 if (gettimeofday(&tv1
, NULL
) == -1)
73 return tv1
.tv_sec
*1000 + tv1
.tv_usec
/1000;
76 void read_message(int fd_in
, int fd_out
)
81 for(ct
= 0; ct
<MAXTASKS
; ct
++)
85 die("Trying to add too much tasks...\n");
87 debug("Receiving input for task %d\n", ct
);
91 debug("Receiving an sds\n");
94 debug("Receiving a delete task request\n");
95 //Read task number and set unused
97 tasks
[ct
].used
= false;
100 debug("Receiving a task\n");
101 bzero(&tasks
[ct
], sizeof(struct task
));
104 tasks
[ct
].interval
= 256*c
;
106 tasks
[ct
].interval
+= c
;
109 tasks
[ct
].tlen
= 256*c
;
112 if(tasks
[ct
].tlen
> MAXTASKSIZE
)
113 die("Task is too long: %d\n", tasks
[ct
].tlen
);
115 for(int i
= 0; i
<tasks
[ct
].tlen
; i
++){
116 debug("Read %d\n", i
);
117 read(fd_in
, tasks
[ct
].bc
+i
, 1);
118 debug("t[][%i]: %d\n", i
,
121 //Return the task number for later removal
122 write(fd_out
, (void *)&ct
, 1);
123 debug("Received a task of length %d\n", tasks
[ct
].tlen
);
124 tasks
[ct
].used
= true;
127 debug("Unknown message: %X?\n", c
);
131 void run_task(int tasknum
)
133 uint8_t *program
= tasks
[tasknum
].bc
;
134 int plen
= tasks
[tasknum
].tlen
;
137 char stack
[STACKSIZE
] = {0};
138 printf("Running task: %d\nWith length: %d\n", tasknum
, plen
);
140 printf("program: %x\n", program
[pc
]);
141 switch(program
[pc
++]){
142 case BCNOP
: trace("nop\n");
144 case BCPUSH
: trace("push %d\n", program
[pc
]);
145 stack
[sp
++] = program
[pc
++];
147 case BCPOP
: trace("pop\n");
150 case BCSDSSTORE
: trace("sds store\n");
152 case BCSDSFETCH
: trace("sds fetch\n");
154 case BCSDSPUBLISH
: trace("sds publish\n");
156 case BCNOT
: trace("not\n");
157 stack
[sp
] = stack
[sp
] > 0 ? 0 : 1;
159 case BCADD
: trace("add\n");
160 stack
[sp
-1] = stack
[sp
] + stack
[sp
-1];
163 case BCSUB
: trace("sub\n");
164 stack
[sp
-1] = stack
[sp
] - stack
[sp
-1];
167 case BCMUL
: trace("mul\n");
168 stack
[sp
-1] = stack
[sp
] * stack
[sp
-1];
171 case BCDIV
: trace("div\n");
172 stack
[sp
-1] = stack
[sp
] / stack
[sp
-1];
175 case BCAND
: trace("and\n");
176 stack
[sp
-1] = stack
[sp
] && stack
[sp
-1];
179 case BCOR
: trace("or\n");
180 stack
[sp
-1] = stack
[sp
] || stack
[sp
-1];
183 case BCEQ
: trace("eq\n");
184 stack
[sp
-1] = stack
[sp
] == stack
[sp
-1];
187 case BCNEQ
: trace("neq\n");
188 stack
[sp
-1] = stack
[sp
] != stack
[sp
-1];
191 case BCLES
: trace("les\n");
192 stack
[sp
-1] = stack
[sp
] < stack
[sp
-1];
195 case BCGRE
: trace("gre\n");
196 stack
[sp
-1] = stack
[sp
] > stack
[sp
-1];
199 case BCLEQ
: trace("leq\n");
200 stack
[sp
-1] = stack
[sp
] <= stack
[sp
-1];
203 case BCGEQ
: trace("geq\n");
204 stack
[sp
-1] = stack
[sp
] >= stack
[sp
-1];
207 case BCJMP
: trace("jmp to %d\n", program
[pc
]);
208 pc
= pc
+ program
[pc
];
210 case BCJMPT
: trace("jmpt to %d\n", program
[pc
]);
211 pc
+= stack
[sp
] ? program
[pc
] : 1;
213 case BCJMPF
: trace("jmpf to %d\n", program
[pc
]);
214 pc
+= stack
[sp
] ? 1 : program
[pc
];
216 case BCSERIALAVAIL
: trace("SerialAvailable()\n");
218 case BCSERIALPRINT
: trace("SerialPrint()\n");
220 case BCSERIALPRINTLN
: trace("SerialPrintln()\n");
222 case BCSERIALREAD
: trace("SerialRead()\n");
224 case BCSERIALPARSEINT
: trace("SerialParseInt()\n");
226 case BCANALOGREAD
: trace("AnalogRead(%d)\n", program
[pc
]);
229 case BCANALOGWRITE
: trace("AnalogWrite(%d)\n", program
[pc
]);
232 case BCDIGITALREAD
: trace("DigitalRead(%d)\n", program
[pc
]);
235 case BCDIGITALWRITE
: trace("DigitalWrite(%d)\n", program
[pc
]);
239 die("Unrecognized command: %d\n", program
[--pc
]);
242 debug("Task %d terminated\n", tasknum
);
245 void open_filedescriptors()
247 struct sockaddr_in sa
;
249 bzero((char *) &sa
, sizeof(sa
));
250 sa
.sin_family
= AF_INET
;
251 sa
.sin_addr
.s_addr
= INADDR_ANY
;
252 sa
.sin_port
= htons(port
);
254 if((sock_fd
= socket(AF_INET
, SOCK_STREAM
, 0)) == -1)
256 if(bind(sock_fd
, (struct sockaddr
*)&sa
, sizeof(sa
)) == -1)
258 if(listen(sock_fd
, 10) == -1)
261 printf("Listening on %d\n", port
);
263 if((fd
= accept(sock_fd
, (struct sockaddr
*)NULL
, NULL
)) == -1)
267 void usage(FILE *o
, char *arg0
){
272 "-p PORT Custom port number, default: 8123\n"
276 int main(int argc
, char *argv
[])
280 //Register signal handler
281 if(signal(SIGINT
, killHandler
) == SIG_ERR
){
282 die("Couldn't register signal handler...\n");
284 if(signal(SIGTERM
, killHandler
) == SIG_ERR
){
285 die("Couldn't register signal handler...\n");
288 //Command line arguments
290 while((opt
= getopt(argc
, argv
, "hp:")) != -1){
295 die("Port numbers are > 1\n");
298 usage(stdout
, argv
[0]);
301 usage(stderr
, argv
[0]);
307 open_filedescriptors();
311 //Check for new tasks
312 if(input_available(fd
))
313 read_message(fd
, fd
);
315 cyclestart
= millis();
316 for(ct
= 0; ct
<MAXTASKS
; ct
++){
317 //See whether the task is even in use
319 debug("Task %d not implemented\n", ct
);
322 //See whether the task interval has passed
323 if(cyclestart
-tasks
[ct
].lastrun
< tasks
[ct
].interval
){
324 debug("Task %d not scheduled\n", ct
);
328 printf("Current task to run: %d\n", ct
);
329 printf("Enter to continue, s to step\n");