CLEAN_HOME?=/opt/clean
CLM:=clm
-override CLMFLAGS+=-dynamics -h 200M -nt
+override CLMFLAGS+=-dynamics -h 200M -nt -l -no-pie
CLMLIBS:=\
-I $(CLEAN_HOME)/lib/iTasks-SDK/Patches/Dynamics\
-I $(CLEAN_HOME)/lib/iTasks-SDK/Patches/Generics\
-CFLAGS:=-g -Wall -Wextra -Werror -std=c99
+CPPFLAGS:=-g -Wall -Wextra -Werror -DDEBUG
PROG:=main
-OBJS:=interpret.o sds.o task.o
+OBJS:=interpret.o sds.o task.o main.o
all: mTaskSymbols.h $(PROG)
-$(PROG): $(PROG).c $(OBJS) misc.h
- $(LINK.c) $(LDLIBS) $^ $(OUTPUT_OPTION)
+%.o: %.cpp
+ g++ $(CPPFLAGS) -c $< -o $@
+
+$(PROG): $(OBJS) misc.h
+ g++ $(LDFLAGS) -o $@ $(OBJS)
mTaskSymbols.h:
CLMFLAGS=-nr make -BC .. mTaskInterpret
--- /dev/null
+BOARD_TAG = uno
+ARDUINO_LIBS = LiquidCrystal
+CPPFLAGS += -std=gnu11
+
+include /usr/share/arduino/Arduino.mk
+
#include "task.h"
#include "sds.h"
-void run_task(struct task *t, int fd)
+#ifdef ARDUINO
+#define trace(op, ...) ;
+#else
+#define trace(op, ...) printf("pc: %d, sp: %d, op: " op, pc, sp, ##__VA_ARGS__);
+#endif
+
+void run_task(struct task *t)
{
uint8_t *program = t->bc;
int plen = t->tlen;
stack[sp++] = sds_fetch(program[pc++]);
break;
case BCSDSPUBLISH: trace("sds publish %d\n", program[pc]);
- sds_publish(program[pc++], fd);
+ sds_publish(program[pc++]);
break;
case BCNOT: trace("not\n");
stack[sp] = stack[sp] > 0 ? 0 : 1;
#include "task.h"
-void run_task(struct task *task, int fd);
+void run_task(struct task *task);
#endif
-#define _BSD_SOURCE
+#define _DEFAULT_SOURCE
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef ARDUINO
+#include <Arduino.h>
+#include <HardwareSerial.h>
+#else
+#include <stdbool.h>
#include <netdb.h>
#include <netinet/in.h>
#include <signal.h>
-#include <stdbool.h>
-#include <stdint.h>
#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include <sys/socket.h>
-#include <sys/types.h>
#include <sys/time.h>
+#include <sys/types.h>
#include <unistd.h>
+#endif
#include "interpret.h"
#include "mTaskSymbols.h"
#define MSG_SDS_SPEC 's'
#define MSG_SDS_UPD 'u'
+//Globals
+#ifndef ARDUINO
struct timeval tv1;
int sock_fd = -1;
int fd = -1;
-int port = 8123;
+int *argc;
+char **argv;
+char bt;
+#endif
-void killHandler(int i)
-{
- printf("%i caught, Bye...\n", i);
- exit(1);
+#ifndef ARDUINO
+long millis() {
+ if (gettimeofday(&tv1, NULL) == -1)
+ pdie("gettimeofday");
+ return tv1.tv_sec*1000 + tv1.tv_usec/1000;
}
+#endif
-bool input_available(int fd){
+bool input_available(){
+#ifdef ARDUINO
+ return Serial.available();
+#else
struct timeval tv;
fd_set fds;
tv.tv_sec = 0;
if (select(fd+1, &fds, NULL, NULL, &tv) == -1)
pdie("select");
return FD_ISSET(fd, &fds);
+#endif
}
-long millis() {
- if (gettimeofday(&tv1, NULL) == -1)
- pdie("gettimeofday");
- return tv1.tv_sec*1000 + tv1.tv_usec/1000;
+uint8_t read_byte()
+{
+#ifdef ARDUINO
+ return Serial.read();
+#else
+ read(fd, &bt, 1);
+ return bt;
+#endif
}
-void read_message(int fd_in, int fd_out)
+void write_byte(uint8_t b)
{
- uint8_t c;
- //Find next task
+#ifdef ARDUINO
+ Serial.write(b);
+#else
+ write(fd, &b, 1);
+#endif
+}
+
+void sleep(int ms)
+{
+#ifdef ARDUINO
+ delay(ms);
+#else
+ usleep(ms*1000);
+#endif
+}
+
+#ifndef ARDUINO
+void killHandler(int i)
+{
+ printf("%i caught, Bye...\n", i);
+ exit(1);
+}
+#endif
- read(fd_in, &c, 1);
+void read_message()
+{
+ //Find next task
+ uint8_t c = read_byte();
debug("Receiving input: %c\n", c);
switch(c){
case MSG_SDS_SPEC:
debug("Receiving an sds\n");
- sds_register(fd_in);
+ sds_register();
break;
case MSG_SDS_UPD:
debug("Receiving an sds\n");
//TODO do something with the return value
- sds_update(fd_in);
+ sds_update();
break;
case MSG_DEL_TASK:
debug("Receiving a delete task request\n");
- task_delete(fd);
+ task_delete();
break;
case MSG_GET_TASK:
debug("Receiving a task\n");
- c = task_register(fd_in);
+ c = task_register();
// write(fd_out, &c, 1);
// write(fd_out,
break;
default:
debug("Unknown message: %X\n", c);
}
- (void) fd_out;
}
void open_filedescriptors()
{
- struct sockaddr_in sa;
-
- memset(&sa, 0, 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");
- if(listen(sock_fd, 10) == -1)
- pdie("listen");
-
- 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){
, arg0);
}
-int main(int argc, char *argv[])
+void setup()
{
- int ct;
-
+#ifdef ARDUINO
+ Serial.begin(9600);
+#else
+ int port = 8123, opti = 1;
//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 opti = 1;
- while(opti < argc){
- if(strcmp(argv[opti], "-h") == 0){
+ while(opti < *argc){
+ if(strcmp((*argv)+opti, "-h") == 0){
usage(stdout, argv[0]);
exit(EXIT_SUCCESS);
- } else if(strcmp(argv[opti], "-p") == 0 && opti+1<argc){
+ } else if(strcmp(argv[opti], "-p") == 0 && opti+1<*argc){
port = atoi(argv[++opti]);
if(port < 1)
die("Port numbers are > 1\n");
opti++;
}
+ //Open file descriptors
+ struct sockaddr_in sa;
+
+ memset(&sa, 0, 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");
+ if(listen(sock_fd, 10) == -1)
+ pdie("listen");
+
+ printf("Listening on %d\n", port);
+ fflush(stdout);
+ if((fd = accept(sock_fd, (struct sockaddr*)NULL, NULL)) == -1)
+ pdie("accept");
+#endif
+
//Initialize systems
sds_init();
task_init();
+}
- //Open communication
- open_filedescriptors();
- write(fd, "\n", 1);
-
+void loop()
+{
+ int ct;
long cyclestart;
struct task *curtask;
- 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((curtask = task_get(ct)) == NULL){
-// debug("Task %d not implemented\n", ct);
- continue;
- }
- //See whether the task interval has passed
- if(cyclestart-curtask->lastrun < curtask->interval){
-// debug("Task %d not scheduled\n", ct);
- continue;
- }
+ if(input_available())
+ read_message();
+ //Run tasks
+ cyclestart = millis();
+ for(ct = 0; ct<MAXTASKS; ct++){
+ //See whether the task is even in use
+ if((curtask = task_get(ct)) == NULL){
+// debug("Task %d not implemented\n", ct);
+ continue;
+ }
+ //See whether the task interval has passed
+ if(cyclestart-curtask->lastrun < curtask->interval){
+// debug("Task %d not scheduled\n", ct);
+ continue;
+ }
#ifdef DEBUG
- printf("Current task to run: %d\n", ct);
- getchar();
+ printf("Current task to run: %d\n", ct);
+ getchar();
#endif
- run_task(curtask, fd);
- }
- debug("Waiting for 500ms\n");
- usleep(500000);
- debug("done waiting\n");
- write(fd, "\n", 1);
+ run_task(curtask);
+ }
+ debug("Waiting for 500ms\n");
+ sleep(500);
+ debug("done waiting\n");
+ write_byte('\n');
+}
+
+int main(int ac, char *av[])
+{
+#ifndef ARDUINO
+ argc = ∾
+ argv = av;
+#endif
+ setup();
+
+ write_byte('\n');
+
+ while(true){
+ //Check for new tasks
}
return 0;
}
--- /dev/null
+#ifndef MAIN_H
+#define MAIN_H
+
+#include <stdint.h>
+
+uint8_t read_byte();
+void write_byte(uint8_t b);
+#endif
#ifndef MISC_H
#define MISC_H
+#include "main.h"
-#define DEBUG
+#define read16() 256*read_byte() + read_byte()
+#ifdef ARDUINO
+#define debug(s, ...) ;
+#define pdie(s) ;
+#define die(s, ...) ;
+#else
#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-1, sp, op) ;
#endif
#define pdie(s) {perror(s); exit(1);}
#define die(s, ...) {fprintf(stderr, s, ##__VA_ARGS__); exit(1);}
-
-#define read16(fd, c, i) {\
- read(fd, &c, 1); \
- i = 256*c; \
- read(fd, &c, 1); \
- i += c; \
- }
+#endif
#endif
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+
+#ifndef ARDUINO
#include <unistd.h>
+#include <stdio.h>
+#endif
-#include "mTaskSymbols.h"
+#include "main.h"
#include "interpret.h"
#include "misc.h"
#include "sds.h"
memset(&sdss, 0, sizeof(struct sds)*MAXSDSS);
}
-void sds_register(int fd)
+void sds_register()
{
uint8_t cs;
for(cs = 0; cs<MAXSDSS; cs++)
memset(&sdss[cs], 0, sizeof(struct sds));
//Read identifier
- read16(fd, c, sdss[cs].id);
+ sdss[cs].id = read16();
//Read value
- read16(fd, c, sdss[cs].value);
+ sdss[cs].value = read16();
debug("\nReceived sds %d: %d\n", sdss[cs].id, sdss[cs].value);
sdss[cs].used = true;
}
-bool sds_update(int fd)
+bool sds_update()
{
uint8_t cs, id;
//Read identifier
- read(fd, &id, 1);
+ id = read_byte();
for(cs = 0; cs<MAXSDSS; cs++){
if(!sdss[cs].used)
continue;
if(sdss[cs].id == id){
//Read value
- read16(fd, c, sdss[cs].value);
+ sdss[cs].value = read16();
return true;
}
}
return false;
}
-void sds_publish(int id, int fd)
+void sds_publish(int id)
{
uint8_t cs;
- char msg[6];
for(cs = 0; cs<MAXSDSS; cs++){
if(sdss[cs].used && sdss[cs].id == id){
debug("Publish %d=%d\n", sdss[cs].id, sdss[cs].value);
- sprintf(msg, "u%c%c%c%c\n",
- 0,
- sdss[cs].id,
- sdss[cs].value/265,
- sdss[cs].value%265);
- write(fd, msg, 6);
+ write_byte('u');
+ write_byte(0);
+ write_byte(sdss[cs].id);
+ write_byte(sdss[cs].value/265);
+ write_byte(sdss[cs].value%265);
return;
}
}
};
void sds_init();
-void sds_register(int fd);
-bool sds_update(int fd);
-void sds_publish(int id, int fd);
+void sds_register();
+bool sds_update();
+void sds_publish(int id);
int sds_fetch(int id);
void sds_store(int id, int val);
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+
+#ifdef ARDUINO
+#include <Arduino.h>
+#include <HardwareSerial.h>
+#else
#include <unistd.h>
+#include <stdio.h>
+#endif
#include "misc.h"
#include "task.h"
struct task tasks[MAXTASKS];
-uint8_t c;
void task_init()
{
memset(&tasks, 0, sizeof(struct task)*MAXTASKS);
}
-int task_register(int fd)
+int task_register()
{
uint8_t ct;
memset(&tasks[ct], 0, sizeof(struct task));
//Read interval
- read16(fd, c, tasks[ct].interval);
+ tasks[ct].interval = read16();
//Read tasklength
- read16(fd, c, tasks[ct].tlen);
+ tasks[ct].tlen = read16();
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++){
- read(fd, tasks[ct].bc+i, 1);
+ for(unsigned int i = 0; i<tasks[ct].tlen; i++){
+ tasks[ct].bc[i] = read_byte();
debug("t[][%i]: 0x%02x %d\n", i,
tasks[ct].bc[i], tasks[ct].bc[i]);
}
return ct;
}
-void task_delete(int fd)
+void task_delete()
{
- read(fd, &c, 1);
- tasks[c].used = false;
+ tasks[read_byte()].used = false;
}
struct task *task_get(int num)
};
void task_init();
-int task_register(int fd);
-void task_delete(int fd);
+int task_register();
+void task_delete();
struct task *task_get(int num);
#endif