#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
+#include <sys/time.h>
#include <unistd.h>
#include "mTaskSymbols.h"
#define STACKSIZE 1024
#define MSG_TASK 't'
+#define MSG_DELTASK 'd'
#define MSG_SDS 's'
#define DEBUG
struct task {
uint8_t bc[MAXTASKSIZE];
uint16_t tlen;
+ uint16_t interval;
+ long lastrun;
bool used;
};
+struct timeval tv1;
struct task tasks[MAXTASKS] = {0};
int sock_fd = -1;
int fd = -1;
return FD_ISSET(fd, &fds);
}
+long millis() {
+ if (gettimeofday(&tv1, NULL) == -1)
+ pdie("gettimeofday");
+ return tv1.tv_sec*1000 + tv1.tv_usec/1000;
+}
+
void read_message(int fd_in, int fd_out)
{
//Find next task
case MSG_SDS:
debug("Receiving an sds\n");
break;
+ case MSG_DELTASK:
+ debug("Receiving a delete task request\n");
+ //Read task number and set unused
+ read(fd_in, &c, 1);
+ tasks[ct].used = false;
+ break;
case MSG_TASK:
+ debug("Receiving a task\n");
+ bzero(&tasks[ct], sizeof(struct task));
+ //Read interval
+ read(fd_in, &c, 1);
+ tasks[ct].interval = 256*c;
+ read(fd_in, &c, 1);
+ tasks[ct].interval += c;
+ //Read tasklength
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);
+ //Read task bytecode
for(int i = 0; i<tasks[ct].tlen; i++){
debug("Read %d\n", i);
read(fd_in, tasks[ct].bc+i, 1);
while(pc != plen){
printf("program: %x\n", program[pc]);
switch(program[pc++]){
- case BCNOP:
- trace("nop\n");
+ case BCNOP: trace("nop\n");
break;
- case BCPUSH:
- trace("push %d\n", program[pc]);
+ case BCPUSH: trace("push %d\n", program[pc]);
stack[sp++] = program[pc++];
break;
- case BCPOP:
- trace("pop\n");
+ case BCPOP: trace("pop\n");
sp--;
break;
- case BCNOT:
- trace("not\n");
+ case BCSDSSTORE: trace("sds store\n");
+ break;
+ case BCSDSFETCH: trace("sds fetch\n");
+ break;
+ case BCSDSPUBLISH: trace("sds publish\n");
+ break;
+ case BCNOT: trace("not\n");
stack[sp] = stack[sp] > 0 ? 0 : 1;
break;
- case BCADD:
- trace("add\n");
+ case BCADD: trace("add\n");
stack[sp-1] = stack[sp] + stack[sp-1];
sp -= 1;
break;
- case BCSUB:
- trace("sub\n");
+ case BCSUB: trace("sub\n");
stack[sp-1] = stack[sp] - stack[sp-1];
sp -= 1;
break;
- case BCMUL:
- trace("mul\n");
+ case BCMUL: trace("mul\n");
stack[sp-1] = stack[sp] * stack[sp-1];
sp -= 1;
break;
- case BCDIV:
- trace("div\n");
+ case BCDIV: trace("div\n");
stack[sp-1] = stack[sp] / stack[sp-1];
sp -= 1;
break;
- case BCAND:
- trace("and\n");
+ case BCAND: trace("and\n");
stack[sp-1] = stack[sp] && stack[sp-1];
sp -= 1;
break;
- case BCOR:
- trace("or\n");
+ case BCOR: trace("or\n");
stack[sp-1] = stack[sp] || stack[sp-1];
sp -= 1;
break;
- case BCEQ:
- trace("eq\n");
+ case BCEQ: trace("eq\n");
stack[sp-1] = stack[sp] == stack[sp-1];
sp -= 1;
break;
- case BCNEQ:
- trace("neq\n");
+ case BCNEQ: trace("neq\n");
stack[sp-1] = stack[sp] != stack[sp-1];
sp -= 1;
break;
- case BCLES:
- trace("les\n");
+ case BCLES: trace("les\n");
stack[sp-1] = stack[sp] < stack[sp-1];
sp -= 1;
break;
- case BCGRE:
- trace("gre\n");
+ case BCGRE: trace("gre\n");
stack[sp-1] = stack[sp] > stack[sp-1];
sp -= 1;
break;
- case BCLEQ:
- trace("leq\n");
+ case BCLEQ: trace("leq\n");
stack[sp-1] = stack[sp] <= stack[sp-1];
sp -= 1;
break;
- case BCGEQ:
- trace("geq\n");
+ 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]);
+ case BCJMP: trace("jmp to %d\n", program[pc]);
pc = pc + program[pc];
break;
- case BCJMPT:
- trace("jmpt to %d\n", program[pc]);
+ 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]);
+ case BCJMPF: trace("jmpf to %d\n", program[pc]);
pc += stack[sp] ? 1 : program[pc];
break;
- case BCSERIALAVAIL:
- trace("SerialAvailable()\n");
+ case BCSERIALAVAIL: trace("SerialAvailable()\n");
break;
- case BCSERIALPRINT:
- trace("SerialPrint()\n");
+ case BCSERIALPRINT: trace("SerialPrint()\n");
break;
- case BCSERIALPRINTLN:
- trace("SerialPrintln()\n");
+ case BCSERIALPRINTLN: trace("SerialPrintln()\n");
break;
- case BCSERIALREAD:
- trace("SerialRead()\n");
+ case BCSERIALREAD: trace("SerialRead()\n");
break;
- case BCSERIALPARSEINT:
- trace("SerialParseInt()\n");
+ case BCSERIALPARSEINT: trace("SerialParseInt()\n");
break;
- case BCANALOGREAD:
- trace("AnalogRead(%d)\n", program[pc]);
+ case BCANALOGREAD: trace("AnalogRead(%d)\n", program[pc]);
pc++;
break;
- case BCANALOGWRITE:
- trace("AnalogWrite(%d)\n", program[pc]);
+ case BCANALOGWRITE: trace("AnalogWrite(%d)\n", program[pc]);
pc++;
break;
- case BCDIGITALREAD:
- trace("DigitalRead(%d)\n", program[pc]);
+ case BCDIGITALREAD: trace("DigitalRead(%d)\n", program[pc]);
pc++;
break;
- case BCDIGITALWRITE:
- trace("DigitalWrite(%d)\n", program[pc]);
+ case BCDIGITALWRITE: trace("DigitalWrite(%d)\n", program[pc]);
pc++;
break;
default:
open_filedescriptors();
+ long cyclestart;
while(true){
//Check for new tasks
if(input_available(fd))
read_message(fd, fd);
//Run tasks
+ cyclestart = millis();
for(ct = 0; ct<MAXTASKS; ct++){
+ //See whether the task is even in use
if(!tasks[ct].used){
debug("Task %d not implemented\n", ct);
continue;
}
+ //See whether the task interval has passed
+ if(cyclestart-tasks[ct].lastrun < tasks[ct].interval){
+ debug("Task %d not scheduled\n", ct);
+ continue;
+ }
#ifdef DEBUG
printf("Current task to run: %d\n", ct);
printf("Enter to continue, s to step\n");