-#include <stdio.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <signal.h>
#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
#include <stdlib.h>
-#include <signal.h>
#include <string.h>
+#include <sys/socket.h>
+#include <sys/types.h>
#include <unistd.h>
-#include <stdint.h>
#include "mTaskSymbols.h"
#define MAXSDS 50
#define STACKSIZE 1024
+#define MSG_TASK 't'
+#define MSG_SDS 's'
+
#define DEBUG
+
#ifdef DEBUG
#define debug(s, ...) printf(s, ##__VA_ARGS__);
+#define trace(op, ...) printf("pc: %d, sp: %d, op: " op, pc, sp, ##__VA_ARGS__);
#else
#define debug(s, ...) ;
+#define trace(pc, sp, op) ;
#endif
#define pdie(s) {perror(s); exit(1);}
#define die(s, ...) {fprintf(stderr, s, ##__VA_ARGS__); exit(1);}
-char tasks[MAXTASKS][MAXTASKSIZE] = {0};
+struct task {
+ uint8_t bc[MAXTASKSIZE];
+ uint16_t tlen;
+ bool used;
+};
+
+struct task tasks[MAXTASKS] = {0};
+int sock_fd = -1;
+int fd = -1;
+int port = 8123;
void killHandler(int i)
{
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(fd, &fds);
- if(select(fd+1, &fds, NULL, NULL, &tv) == -1){
+ if (select(fd+1, &fds, NULL, NULL, &tv) == -1)
pdie("select");
- }
return FD_ISSET(fd, &fds);
}
-int main(void)
+void read_message(int fd_in, int fd_out)
{
- uint8_t c;
-// char taskindex = 0;
-// int pl, sp, pc;
-//
- int fd_in = 0;
- int next_free_new_task = 0;
- uint16_t tasklen = 0;
+ //Find next task
+ uint8_t c, ct;
- //Register signal handler
- if(signal(SIGINT, killHandler) == SIG_ERR){
- die("Couldn't register signal handler...\n");
- }
- if(signal(SIGTERM, killHandler) == SIG_ERR){
- die("Couldn't register signal handler...\n");
- }
+ for(ct = 0; ct<MAXTASKS; ct++)
+ if(!tasks[ct].used)
+ break;
+ if(ct == MAXTASKS)
+ die("Trying to add too much tasks...\n");
- while(true){
- if(input_available(fd_in)){
- printf("Receiving input\n");
- read(fd_in, &c, 1);
- if((char) c == 's'){
- debug("Receiving an sds\n");
- } else if((char) c == 't'){
- read(fd_in, &c, 1);
- tasklen = 256*c;
- read(fd_in, &c, 1);
- tasklen += c;
- if(tasklen > MAXTASKSIZE){
- die("Task is too long: %d\n", tasklen);
- }
- for(int i = 0; i<tasklen; i++){
- debug("Read %d\n", i);
- read(fd_in, tasks[next_free_new_task]+i, 1);
- read(fd_in, tasks[next_free_new_task]+i, 1);
- debug("t[][%i]: %d\n", i, tasks[next_free_new_task][i]);
- }
- debug("Receiving a task of length %d\n", tasklen);
- } else {
- die("Unknown message: %c?\n", c);
- }
- exit(1);
+ debug("Receiving input for task %d\n", ct);
+ read(fd_in, &c, 1);
+ switch(c){
+ case MSG_SDS:
+ debug("Receiving an sds\n");
+ break;
+ case MSG_TASK:
+ read(fd_in, &c, 1);
+ tasks[ct].tlen = 256*c;
+ read(fd_in, &c, 1);
+ tasks[ct].tlen += c;
+ if(tasks[ct].tlen > MAXTASKSIZE)
+ die("Task is too long: %d\n", tasks[ct].tlen);
+ for(int i = 0; i<tasks[ct].tlen; i++){
+ debug("Read %d\n", i);
+ read(fd_in, tasks[ct].bc+i, 1);
+ debug("t[][%i]: %d\n", i,
+ tasks[ct].bc[i]);
}
- usleep(1);
+ //Return the task number for later removal
+ write(fd_out, (void *)&ct, 1);
+ debug("Received a task of length %d\n", tasks[ct].tlen);
+ tasks[ct].used = true;
+ break;
+ default:
+ debug("Unknown message: %X?\n", c);
}
+}
-/* //Read program
- pc = 0;
- while ((c = getchar()) != EOF && pc < PROGRAMSIZE)
- program[pc++] = c;
- if (pc >= PROGRAMSIZE)
- die("Max program size: %d\n", PROGRAMSIZE);
- pl = pc;
- debug("Done reading, program length: %d\n", pl);
-
- //Evaluate program
- //Reset program counter and stack counter
- pc = 0;
- sp = 0;
- while(pc != pl){
+void run_task(int tasknum)
+{
+ uint8_t *program = tasks[tasknum].bc;
+ int plen = tasks[tasknum].tlen;
+ int pc = 0;
+ int sp = 0;
+ char stack[STACKSIZE] = {0};
+ printf("Running task: %d\nWith length: %d\n", tasknum, plen);
+ while(pc != plen){
+ printf("program: %x\n", program[pc]);
switch(program[pc++]){
- case BCNOP:;
+ case BCNOP:
+ trace("nop\n");
break;
case BCPUSH:
+ trace("push %d\n", program[pc]);
stack[sp++] = program[pc++];
break;
case BCPOP:
+ trace("pop\n");
sp--;
break;
case BCNOT:
+ trace("not\n");
stack[sp] = stack[sp] > 0 ? 0 : 1;
break;
case BCADD:
+ trace("add\n");
stack[sp-1] = stack[sp] + stack[sp-1];
sp -= 1;
break;
case BCSUB:
+ trace("sub\n");
stack[sp-1] = stack[sp] - stack[sp-1];
sp -= 1;
break;
case BCMUL:
+ trace("mul\n");
stack[sp-1] = stack[sp] * stack[sp-1];
sp -= 1;
break;
case BCDIV:
+ trace("div\n");
stack[sp-1] = stack[sp] / stack[sp-1];
sp -= 1;
break;
case BCAND:
+ trace("and\n");
stack[sp-1] = stack[sp] && stack[sp-1];
sp -= 1;
break;
case BCOR:
+ trace("or\n");
stack[sp-1] = stack[sp] || stack[sp-1];
sp -= 1;
break;
case BCEQ:
+ trace("eq\n");
stack[sp-1] = stack[sp] == stack[sp-1];
sp -= 1;
break;
case BCNEQ:
+ trace("neq\n");
stack[sp-1] = stack[sp] != stack[sp-1];
sp -= 1;
break;
- case BCLES: stack[sp-1] = stack[sp] < stack[sp-1];
+ case BCLES:
+ trace("les\n");
+ stack[sp-1] = stack[sp] < stack[sp-1];
sp -= 1;
break;
case BCGRE:
+ trace("gre\n");
stack[sp-1] = stack[sp] > stack[sp-1];
sp -= 1;
break;
case BCLEQ:
+ trace("leq\n");
stack[sp-1] = stack[sp] <= stack[sp-1];
sp -= 1;
break;
case BCGEQ:
+ trace("geq\n");
stack[sp-1] = stack[sp] >= stack[sp-1];
sp -= 1;
break;
case BCJMP:
+ trace("jmp to %d\n", program[pc]);
pc = pc + program[pc];
break;
case BCJMPT:
+ trace("jmpt to %d\n", program[pc]);
pc += stack[sp] ? program[pc] : 1;
break;
case BCJMPF:
+ trace("jmpf to %d\n", program[pc]);
pc += stack[sp] ? 1 : program[pc];
break;
case BCSERIALAVAIL:
- printf("SerialAvailable()\n");
+ trace("SerialAvailable()\n");
break;
case BCSERIALPRINT:
- printf("SerialPrint()\n");
+ trace("SerialPrint()\n");
break;
case BCSERIALPRINTLN:
- printf("SerialPrintln()\n");
+ trace("SerialPrintln()\n");
break;
case BCSERIALREAD:
- printf("SerialRead()\n");
+ trace("SerialRead()\n");
break;
case BCSERIALPARSEINT:
- printf("SerialParseInt()\n");
+ trace("SerialParseInt()\n");
break;
case BCANALOGREAD:
- printf("AnalogRead()\n");
+ trace("AnalogRead(%d)\n", program[pc]);
+ pc++;
break;
case BCANALOGWRITE:
- printf("AnalogWrite()\n");
+ trace("AnalogWrite(%d)\n", program[pc]);
+ pc++;
+ break;
+ case BCDIGITALREAD:
+ trace("DigitalRead(%d)\n", program[pc]);
+ pc++;
+ break;
+ case BCDIGITALWRITE:
+ trace("DigitalWrite(%d)\n", program[pc]);
+ pc++;
+ break;
default:
- die("Unrecognized command: %X\n", program[--pc]);
+ die("Unrecognized command: %d\n", program[--pc]);
+ }
+ }
+ debug("Task %d terminated\n", tasknum);
+}
+
+void open_filedescriptors()
+{
+ struct sockaddr_in sa;
+
+ bzero((char *) &sa, sizeof(sa));
+ sa.sin_family = AF_INET;
+ sa.sin_addr.s_addr = INADDR_ANY;
+ sa.sin_port = htons(port);
+
+ if((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
+ pdie("socket");
+ if(bind(sock_fd, (struct sockaddr*)&sa, sizeof(sa)) == -1)
+ pdie("bind\n");
+ if(listen(sock_fd, 10) == -1)
+ pdie("bind\n");
+
+ printf("Listening on %d\n", port);
+ fflush(stdout);
+ if((fd = accept(sock_fd, (struct sockaddr*)NULL, NULL)) == -1)
+ pdie("accept");
+}
+
+void usage(FILE *o, char *arg0){
+ fprintf(o,
+ "Usage: %s [opts]\n"
+ "\n"
+ "Options\n"
+ "-p PORT Custom port number, default: 8123\n"
+ , arg0);
+}
+
+int main(int argc, char *argv[])
+{
+ int ct;
+
+ //Register signal handler
+ if(signal(SIGINT, killHandler) == SIG_ERR){
+ die("Couldn't register signal handler...\n");
+ }
+ if(signal(SIGTERM, killHandler) == SIG_ERR){
+ die("Couldn't register signal handler...\n");
+ }
+
+ //Command line arguments
+ int opt;
+ while((opt = getopt(argc, argv, "hp:")) != -1){
+ switch(opt){
+ case 'p':
+ port = atoi(optarg);
+ if(port < 1)
+ die("Port numbers are > 1\n");
+ break;
+ case 'h':
+ usage(stdout, argv[0]);
+ exit(EXIT_SUCCESS);
+ default:
+ usage(stderr, argv[0]);
+ exit(EXIT_FAILURE);
+ }
+
+ }
+
+ open_filedescriptors();
+
+ while(true){
+ //Check for new tasks
+ if(input_available(fd))
+ read_message(fd, fd);
+ //Run tasks
+ for(ct = 0; ct<MAXTASKS; ct++){
+ if(!tasks[ct].used){
+ debug("Task %d not implemented\n", ct);
+ continue;
+ }
+#ifdef DEBUG
+ printf("Current task to run: %d\n", ct);
+ printf("Enter to continue, s to step\n");
+ switch(getchar()){
+ case 'd':
+ die("Killed\n");
+ case 's':
+ printf("step\n");
+ break;
+ default:
+ break;
+ }
+#endif
+ run_task(ct);
}
+ usleep(10);
}
-*/
return 0;
}