omgooien taken
authorMart Lubbers <mart@martlubbers.net>
Fri, 18 Nov 2016 09:42:32 +0000 (10:42 +0100)
committerMart Lubbers <mart@martlubbers.net>
Fri, 18 Nov 2016 09:42:32 +0000 (10:42 +0100)
1  2 
README.md
gCons.dcl
gCons.icl
int/int.c
int/mTaskSymbols.h
mTaskMakeSymbols.icl

diff --cc README.md
index 0000000,17602cc..3872733
mode 000000,100644..100644
--- /dev/null
+++ b/README.md
@@@ -1,0 -1,60 +1,59 @@@
 -The engine starts with no tasks. To send a new task the following protocol must
 -be adhered.
+ # mTask
+ ### Introduction
+ *mTasks* are small imperative tasks that can be run on an embedded device like
+ arduino/ESPxxx/Nucleo arm boards. They are communicated to the device in
+ bytecode which is interpreted by the engine that has to be programmed on the
+ device.
+ The devices suitable for *mTasks* are not limited to embedded devices. In the
+ `int` folder is a `C` reference implementation available for intel machines.
+ *mTasks* are written in [clean][clean] and specifically using the
+ [iTasks][itasks] library.
+ ### Workings of an *mTask* system
+ *mTasks* are routines that are executed in a round robin fashion
+ ### Communication back to the server via shared data sources
+ When a shared data source is updated the *mTask* can publish this data back to
+ the server. This is usefull when for example a temperature reaches a certain
+ threshhold. How this communication will be done is yet to be researched.
+ **TODO**
+ ### Usage
+ All programs can be built by running `make`. Note that you need the latest
+ `clm` version if you want to use the `Makefile` since hierarchical modules are
+ used. This version can be found [here][clm].
+ The following programs are available as of now:
+ - `mTaskExamples`
+       This compiles a list of mTask examples to `C` code.
+ - `mTaskMakeSymbols`
+       This creates the `mTaskSymbols.h` header file
+ - `mTaskInterpret`
+       This compiles a subset of *mTasks* to bytecode.
+ ### Protocol
 -Since the system consists only of stores and tasks they are send in different
 -ways.
 -**TODO**
++The server can send task specifications to the microcontroller by sending:
++| id  | length 
++| 's' | n | n bytes | newline
++Where n is a 16bit integer.
+ ### Bytecode operations
+ The header file for the interpreter with the corresponding bytevalues can be
+ generated by running `mTaskMakeSymbols`.
+ ### Author(s)
+ Initial work has been done by Pieter Koopman. Extensions have been made by Mart
+ Lubbers.
+ [clm]: https://svn.cs.ru.nl/repos/clean-tools/trunk/clm
+ [clean]: clean.cs.ru.nl
+ [itasks]: clean.cs.ru.nl/ITasks
diff --cc gCons.dcl
+++ b/gCons.dcl
@@@ -15,5 -15,6 +15,5 @@@ derive consName CONS of {gcd_name},UNIT
  generic consIndex a :: a -> Int
  derive consIndex CONS of {gcd_index},UNIT,PAIR,EITHER,OBJECT,Int,Bool,Char,String
  
 -conses :: [a] | gconses{|*|} a
 -generic gconses a :: Bool -> [a]
 -derive gconses CONS,UNIT,PAIR,EITHER,OBJECT,FIELD,RECORD,Int,Bool,Char,Real,String,(),{},{!},[],[! ],[ !],[!!],(->)
 +generic conses a :: [a]
- derive conses CONS,UNIT,PAIR,EITHER,OBJECT,FIELD,RECORD,Int,Bool,Char,Real,String,(),{},{!},[],[! ],[ !],[!!]
++derive conses CONS,UNIT,PAIR,EITHER,OBJECT,FIELD,RECORD,Int,Bool,Char,Real,String,(),{},{!},[],[! ],[ !],[!!],(->)
diff --cc gCons.icl
+++ b/gCons.icl
@@@ -36,25 -36,28 +36,24 @@@ consIndex{|Bool|} b = if b 1 
  consIndex{|Char|} c = toInt c
  consIndex{|String|} _ = 0
  
- import StdMisc, StdDebug
 -conses :: [a] | gconses{|*|} a
 -conses = gconses{|*|} True
--
 -generic gconses a :: Bool -> [a]
 -gconses{|CONS|} f True = map CONS (f False)
 -gconses{|CONS|} f b = [CONS (hd (f b))]
 -gconses{|UNIT|} _ = [UNIT]
 -gconses{|PAIR|} f g _ = []
 -gconses{|EITHER|} f g b = map LEFT (f b) ++ map RIGHT (g b)
 -gconses{|OBJECT|} f b = map OBJECT (f b)
 -gconses{|RECORD|} f b = map RECORD (f b)
 -gconses{|FIELD|} f b = map FIELD (f b)
 -gconses{|Int|} _ = [0]
 -gconses{|Bool|} _ = [True]
 -gconses{|Char|} _ = ['\0']
 -gconses{|Real|} _ = [0.0]
 -gconses{|String|} _ = [""]
 -gconses{|[]|} _ _ = [[ ]]
 -gconses{|[!]|} _ _ = [[!]]
 -gconses{|[ !]|} _ _ = [[ !]]
 -gconses{|[!!]|} _ _ = [[!!]]
 -gconses{|{}|} _ _ = [{}]
 -gconses{|{!}|} _ _ = [{!}]
 -gconses{|()|} _ = [()]
 -gconses{|(->)|} _ _ _ = [const undef]
 +generic conses a :: [a]
- conses{|CONS|} f = map CONS f
++conses{|CONS|} f = [CONS (hd f)]
 +conses{|UNIT|} = [UNIT]
 +conses{|PAIR|} f g = []
 +conses{|EITHER|} f g = map LEFT f ++ map RIGHT g
 +conses{|OBJECT|} f = map OBJECT f
 +conses{|RECORD|} f = map RECORD f
 +conses{|FIELD|} f = map FIELD f
 +conses{|Int|} = [0]
 +conses{|Bool|} = [True]
 +conses{|Char|} = ['\0']
 +conses{|Real|} = [0.0]
 +conses{|String|} = [""]
 +conses{|[]|} _ = [[ ]]
 +conses{|[!]|} _ = [[!]]
 +conses{|[ !]|} _ = [[ !]]
 +conses{|[!!]|} _ = [[!!]]
 +conses{|{}|} _ = [{}]
 +conses{|{!}|} _ = [{!}]
 +conses{|()|} = [()]
++conses{|(->)|} _ _ = [const undef]
diff --cc int/int.c
+++ b/int/int.c
@@@ -1,10 -1,9 +1,17 @@@
  #include <stdio.h>
 +#include <stdbool.h>
++#include <stdlib.h>
++#include <signal.h>
++#include <string.h>
++#include <unistd.h>
++#include <stdint.h>
  
  #include "mTaskSymbols.h"
  
++#define MAXTASKS 5
++#define MAXTASKSIZE 1024
++#define MAXSDS 50
  #define STACKSIZE 1024
--#define PROGRAMSIZE 1024
  
  #define DEBUG
  #ifdef DEBUG
  #define debug(s, ...) ;
  #endif
  
--#define die(s, ...) {fprintf(stderr, s, ##__VA_ARGS__); return 1;}
++#define pdie(s) {perror(s); exit(1);}
++#define die(s, ...) {fprintf(stderr, s, ##__VA_ARGS__); exit(1);}
  
--char program[PROGRAMSIZE+1] = {0};
--int stack[STACKSIZE+1] = {0};
++char tasks[MAXTASKS][MAXTASKSIZE] = {0};
 +
- bool input_available(){
++void killHandler(int i)
++{
++      printf("%s caught, Bye...\n", strsignal(i));
++      exit(1);
++}
++
++bool input_available(int fd){
 +      struct timeval tv;
 +      fd_set fds;
 +      tv.tv_sec = 0;
 +      tv.tv_usec = 0;
 +      FD_ZERO(&fds);
-       FD_SET(0, &fds);
-       select(1, &fds, NULL, NULL, &tv);
-       return FD_ISSET(0, &fds);
++      FD_SET(fd, &fds);
++      if(select(fd+1, &fds, NULL, NULL, &tv) == -1){
++              pdie("select");
++      }
++      return FD_ISSET(fd, &fds);
 +}
  
  int main(void)
  {
--      char c;
--      int pl, sp, pc;
++      uint8_t c;
++//    char taskindex = 0;
++//    int pl, sp, pc;
++//
++      int fd_in = 0;
++      int next_free_new_task = 0;
++      uint16_t tasklen = 0;
++
++      //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");
++      }
++
++      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);
++              }
++              usleep(1);
++      }
  
--      //Read program
++/*    //Read program
        pc = 0;
        while ((c = getchar()) != EOF && pc < PROGRAMSIZE)
                program[pc++] = c;
        sp = 0;
        while(pc != pl){
                switch(program[pc++]){
--              case BCNop:;
++              case BCNOP:;
                        break;
--              case BCPush:
++              case BCPUSH:
                        stack[sp++] = program[pc++];
                        break;
--              case BCPop:
++              case BCPOP:
                        sp--;
                        break;
--              case BCNot:
++              case BCNOT:
                        stack[sp] = stack[sp] > 0 ? 0 : 1;
                        break;
--              case BCAdd:
++              case BCADD:
                        stack[sp-1] = stack[sp] + stack[sp-1];
                        sp -= 1;
                        break;
--              case BCSub:
++              case BCSUB:
                        stack[sp-1] = stack[sp] - stack[sp-1];
                        sp -= 1;
                        break;
--              case BCMul:
++              case BCMUL:
                        stack[sp-1] = stack[sp] * stack[sp-1];
                        sp -= 1;
                        break;
--              case BCDiv:
++              case BCDIV:
                        stack[sp-1] = stack[sp] / stack[sp-1];
                        sp -= 1;
                        break;
--              case BCAnd:
++              case BCAND:
                        stack[sp-1] = stack[sp] && stack[sp-1];
                        sp -= 1;
                        break;
--              case BCOr:
++              case BCOR:
                        stack[sp-1] = stack[sp] || stack[sp-1];
                        sp -= 1;
                        break;
--              case BCEq:
++              case BCEQ:
                        stack[sp-1] = stack[sp] == stack[sp-1];
                        sp -= 1;
                        break;
--              case BCNeq:
++              case BCNEQ:
                        stack[sp-1] = stack[sp] != stack[sp-1];
                        sp -= 1;
                        break;
--              case BCLes:
--                      stack[sp-1] = stack[sp] < stack[sp-1];
++              case BCLES: stack[sp-1] = stack[sp] < stack[sp-1];
                        sp -= 1;
                        break;
--              case BCGre:
++              case BCGRE:
                        stack[sp-1] = stack[sp] > stack[sp-1];
                        sp -= 1;
                        break;
--              case BCLeq:
++              case BCLEQ:
                        stack[sp-1] = stack[sp] <= stack[sp-1];
                        sp -= 1;
                        break;
--              case BCGeq:
++              case BCGEQ:
                        stack[sp-1] = stack[sp] >= stack[sp-1];
                        sp -= 1;
                        break;
--              case BCJmp:
++              case BCJMP:
                        pc = pc + program[pc];
                        break;
--              case BCJmpT:
++              case BCJMPT:
                        pc += stack[sp] ? program[pc] : 1;
                        break;
--              case BCJmpF:
++              case BCJMPF:
                        pc += stack[sp] ? 1 : program[pc];
                        break;
                case BCSERIALAVAIL:
                        die("Unrecognized command: %X\n", program[--pc]);
                }
        }
++*/
        return 0;
  }
@@@ -1,37 -1,31 +1,32 @@@
  #ifndef MTASK_H
  #define MTASK_H
- #define BCNOP 0
- #define BCPUSH 1
- #define BCPOP 2
- #define BCNOT 3
- #define BCADD 4
- #define BCSUB 5
- #define BCMUL 6
- #define BCDIV 7
- #define BCAND 8
- #define BCOR 9
- #define BCEQ 10
- #define BCNEQ 11
- #define BCLES 12
- #define BCGRE 13
- #define BCLEQ 14
- #define BCGEQ 15
- #define BCJMP 16
- #define BCJMPT 17
- #define BCJMPF 18
- #define BCSERIALAVAIL 19
- #define BCSERIALPRINT 20
- #define BCSERIALPRINTLN 21
- #define BCSERIALREAD 22
- #define BCSERIALPARSEINT 23
- #define BCANALOGREAD 24
- #define BCANALOGWRITE 25
- #define BCDIGITALREAD 26
- #define BCDIGITALWRITE 27
- #define BCTEST 28
+ #define BCNOP 1
+ #define BCPUSH 2
+ #define BCPOP 3
+ #define BCNOT 4
+ #define BCADD 5
+ #define BCSUB 6
+ #define BCMUL 7
+ #define BCDIV 8
+ #define BCAND 9
+ #define BCOR 10
+ #define BCEQ 11
+ #define BCNEQ 12
+ #define BCLES 13
+ #define BCGRE 14
+ #define BCLEQ 15
+ #define BCGEQ 16
+ #define BCJMP 17
+ #define BCJMPT 18
+ #define BCJMPF 19
+ #define BCSERIALAVAIL 20
+ #define BCSERIALPRINT 21
+ #define BCSERIALPRINTLN 22
+ #define BCSERIALREAD 23
+ #define BCSERIALPARSEINT 24
+ #define BCANALOGREAD 25
+ #define BCANALOGWRITE 26
+ #define BCDIGITALREAD 27
+ #define BCDIGITALWRITE 28
 +#define BCTEST 29
- #define BCTEST 30
- #define BCTEST 31
- #define BCTEST 32
- #define BCTEST 33
  #endif
@@@ -30,7 -31,7 +31,7 @@@ toDefine i b = "#define " <+ toUpperCas
  Start w
  # (io, w) = stdio w
  # io = io <<< "#ifndef MTASK_H\n#define MTASK_H\n"
- # io = io <<< join "\n" (map (uncurry toDefine) (zip2 [0..] conses{|*|}))
 -# io = io <<< join "\n" $ zipWith toDefine [1..] conses
++# io = io <<< join "\n" (zipWith toDefine [1..] conses{|*|})
  # (ok, w) = fclose (io <<< "\n#endif\n") w
  | not ok = abort "Couldn't close stdio"
  = w