case MSG_SDS_UPD:
debug("Receiving an sds update");
//TODO do something with the return value
- sds_update();
+ c = read16();
+ sds_update(c);
break;
case MSG_SDS_DEL:
debug("Receiving a delete SDS request");
- sds_delete();
+ c = read16();
+ sds_delete(c);
+ write_byte('a');
+ write16(c);
+ write_byte('\n');
break;
case MSG_DEL_TASK:
debug("Receiving a delete task request");
gargv = argv;
#endif
- //Initialize systems
+ //Initialize device independant functionality
real_setup();
- sds_init();
- task_init();
- debug("sending device spec");
#ifndef ARDUINO_ESP8266_NODEMCU
while(true){
CFLAGS:=-DLINUX -g -Wall -Wextra -DDEBUG
PROG:=client
-OBJS:=interpret.o sds.o task.o client.o interface.o spec.o
+OBJS:=interpret.o sds.o task.o client.o interface.o spec.o mem.o
all: $(PROG)
--- /dev/null
+../mem.c
\ No newline at end of file
--- /dev/null
+../mem.h
\ No newline at end of file
#include <stdlib.h>
+#include <stdint.h>
-struct task *task_head = NULL;
+#include "mem.h"
+
+uint8_t mem[MEMSIZE] = {0};
+
+uint8_t *mem_top = &mem[MEMSIZE-1];
+uint8_t *mem_bottom = &mem[0];
+uint8_t *mem_task = &mem[0];
+uint8_t *mem_sds = &mem[MEMSIZE-1];
+
+uint16_t mem_free(void)
+{
+ return mem_sds-mem_task;
+}
--- /dev/null
+#ifndef MEM_H
+#define MEM_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#define MEMSIZE 1024
+
+uint8_t *mem_top;
+uint8_t *mem_bottom;
+uint8_t *mem_task;
+uint8_t *mem_sds;
+
+uint16_t mem_free(void);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
#include <stdlib.h>
#include <string.h>
-
-#ifndef STM
-#include <unistd.h>
#include <stdio.h>
-#endif
#include "interface.h"
-#include "interpret.h"
#include "sds.h"
+#include "mem.h"
-struct sds sdss[MAXSDSS];
-uint8_t c;
+extern uint8_t *mem_top;
+extern uint8_t *mem_bottom;
+extern uint8_t *mem_task;
+extern uint8_t *mem_sds;
-void sds_init(void)
+struct sds *sds_head(void)
{
- memset(&sdss, 0, sizeof(struct sds)*MAXSDSS);
+ return mem_sds == mem_top ? NULL
+ : (struct sds *)(mem_top-sizeof(struct sds));
}
-void sds_register(void)
+struct sds *sds_next(struct sds *s)
{
- uint8_t cs;
- for(cs = 0; cs<MAXSDSS; cs++)
- if(!sdss[cs].used)
+ uint8_t *next = (uint8_t *)s - sizeof(struct sds);
+ return next < mem_sds ? NULL : (struct sds *)next;
+}
+
+struct sds *sds_get(uint8_t id)
+{
+ struct sds *s = sds_head();
+ while(s != NULL){
+ if(s->id == id){
break;
+ }
+ s = sds_next(s);
+ }
+ return s;
+}
- if(cs == MAXSDSS)
- die("Trying to add too much sdss...");
+void sds_register(void)
+{
+ debug("free memory: %lu", mem_free());
+
+ if(mem_sds-sizeof(struct sds) < mem_task){
+ die("Out of memory... Not enough to allocate sds struct");
+ }
+
+ struct sds *s = (struct sds *)(mem_sds-sizeof(struct sds));
- memset(&sdss[cs], 0, sizeof(struct sds));
//Read identifier
- sdss[cs].id = read16();
- //Read value
- sdss[cs].type = read_byte();
- sdss[cs].value = read16();
+ s->id = read16();
- debug("Received sds %d: %d", sdss[cs].id, sdss[cs].value);
- sdss[cs].used = true;
+ //Read value
+ s->type = read_byte();
+ s->value = read16();
write_byte('s');
- write16(sdss[cs].id);
+ write16(s->id);
write_byte('\n');
+
+ mem_sds -= sizeof(struct sds);
}
-void sds_delete(void)
+void sds_delete(uint8_t c)
{
- uint8_t cs;
- cs = read16();
- sdss[cs].used = false;
- write_byte('a');
- write16(sdss[cs].id);
- write_byte('\n');
+ struct sds *s = sds_get(c);
+
+ if(s != NULL){
+ //We found the sds, now we move verything from the end of the sds up to
+ //the pointer to the right
+ uint8_t *end = (uint8_t *)s;
+ uint8_t *start = end + sizeof(struct sds) - 1;
+ for(int i = 0; i<end-mem_sds; i++){
+ *(start - i) = *(end - i-1);
+ }
+ mem_sds += start-end+1;
+ }
}
-bool sds_update(void)
+bool sds_update(uint8_t id)
{
- uint8_t cs, id;
//Read identifier
- id = read16();
-
- for(cs = 0; cs<MAXSDSS; cs++){
- if(!sdss[cs].used)
- continue;
- if(sdss[cs].id == id){
- //Read value
- sdss[cs].value = read16();
- debug("Received sds update %d: %d",
- sdss[cs].id, sdss[cs].value);
- write_byte('u');
- write16(sdss[cs].id);
- write_byte('\n');
- return true;
- }
+ struct sds *s = sds_get(id);
+ if(s != NULL){
+ s->value = read16();
+ debug("Received sds update %d: %d", s->id, s->value);
+ write_byte('u');
+ write16(s->id);
+ write_byte('\n');
+ return true;
}
return false;
}
void sds_publish(int id)
{
- uint8_t cs;
- for(cs = 0; cs<MAXSDSS; cs++){
- if(sdss[cs].used && sdss[cs].id == id){
- debug("Publish %d=%d", sdss[cs].id, sdss[cs].value);
- write_byte('p');
- write16(sdss[cs].id);
- write_byte(sdss[cs].type);
-
- switch(sdss[cs].type){
- //Long
- case 'l':
- //Int
- case 'i':
- write16(sdss[cs].value);
- break;
- case 'b': //Bool
- case 'c': //Character
- case 'B': //Button
- case 'L': //UserLED
- write_byte(sdss[cs].value);
- break;
- }
- write_byte('\n');
- return;
+ struct sds *s = sds_get(id);
+ if(s != NULL){
+ debug("Publish %d=%d", s->id, s->value);
+ write_byte('p');
+ write16(s->id);
+ write_byte(s->type);
+
+ switch(s->type){
+ //Long
+ case 'l':
+ //Int
+ case 'i':
+ write16(s->value);
+ break;
+ case 'b': //Bool
+ case 'c': //Character
+ case 'B': //Button
+ case 'L': //UserLED
+ write_byte(s->value);
+ break;
}
+ write_byte('\n');
+ return;
+
+ } else {
+ debug("SDS identifier unknown: %d", id);
+ die("");
}
- debug("SDS identifier unknown: %d", id);
- die("");
}
int sds_fetch(int id)
{
- uint8_t cs;
- for(cs = 0; cs<MAXSDSS; cs++)
- if(sdss[cs].used && sdss[cs].id == id)
- return sdss[cs].value;
+ struct sds *s = sds_get(id);
+ if(s != NULL){
+ return s->value;
+ }
debug("SDS identifier unknown: %d", id);
die("");
return 0;
void sds_store(int id, int val)
{
- uint8_t cs;
- for(cs = 0; cs<MAXSDSS; cs++) {
- if(sdss[cs].used && sdss[cs].id == id){
- sdss[cs].value = val;
- return;
- }
+ struct sds *s = sds_get(id);
+ if(s != NULL){
+ s->value = val;
+ } else {
+ debug("SDS identifier unknown: %d", id);
+ die("");
}
- debug("SDS identifier unknown: %d", id);
- die("");
}
struct sds {
int id;
- bool used;
- char type;
int value;
+ char type;
};
-void sds_init(void);
void sds_register(void);
-void sds_delete(void);
-bool sds_update(void);
+void sds_delete(uint8_t cs);
+bool sds_update(uint8_t id);
void sds_publish(int id);
int sds_fetch(int id);
void sds_store(int id, int val);
#include "spec.h"
#include "interface.h"
+#include "mem.h"
void spec_send(void)
{
write_byte('c');
write_byte(0 | (HAVELED << 0) | (HAVEAIO << 1) | (HAVEDIO << 2));
- write16(MAXTASKS);
- write16(MAXSDSS);
+ write16(MEMSIZE);
write_byte('\n');
write_byte('\n');
}
#include "task.h"
#include "spec.h"
#include "interface.h"
+#include "mem.h"
-#define TASKSPACE 128
+extern uint8_t *mem_top;
+extern uint8_t *mem_bottom;
+extern uint8_t *mem_task;
+extern uint8_t *mem_sds;
-uint8_t taskspace[TASKSPACE] = {0};
-uint8_t *spacepointer = (uint8_t *)&taskspace;
uint8_t taskid = 0;
-void task_init(void)
-{
- memset(&taskspace, 0, TASKSPACE);
-}
-
void task_register(void)
{
- debug("free memory: %lu\n", ((uint8_t *)taskspace)-spacepointer+TASKSPACE);
+ debug("free memory: %lu\n", mem_free());
int i;
- if(spacepointer+sizeof(struct task) > taskspace+TASKSPACE){
+ if(mem_task+sizeof(struct task) > mem_sds){
die("Out of memory... Not enough to allocate taskstruct");
}
- //We haven't had a task before, therefore we initialize head
- struct task *t = (struct task *)spacepointer;
+ struct task *t = (struct task *)mem_task;
//Read interval
t->interval = read16();
t->tasklength = read16();
debug("task interval: %d, length: %d\n", t->interval, t->tasklength);
- if(spacepointer+t->tasklength > taskspace+TASKSPACE){
+ if(mem_task+t->tasklength > mem_sds){
die("Out of memory... Not enough to allocate bytes");
}
- spacepointer += sizeof(struct task);
- t->bc = spacepointer;
- spacepointer += t->tasklength;
+ mem_task += sizeof(struct task);
+ t->bc = mem_task;
+ mem_task += t->tasklength;
//Read task bytecode
for(i = 0; i<t->tasklength; i++){
write_byte('t');
write16(t->taskid);
write_byte('\n');
- debug("free memory: %lu\n", ((uint8_t *)taskspace)+TASKSPACE-spacepointer);
+ debug("free memory: %lu\n", mem_free());
}
bool is_interrupt_task(struct task *t)
struct task *task_head(void)
{
- return spacepointer == (uint8_t *)&taskspace ? NULL
- : (struct task *)&taskspace;
+ return mem_task == mem_bottom ? NULL : (struct task *)mem_bottom;
}
struct task *task_next(struct task *t)
{
- uint8_t *next = (uint8_t *)t;
- next += sizeof(struct task);
- next += t->tasklength;
-
- return next >= spacepointer ? NULL : (struct task *)next;
+ uint8_t *next = (uint8_t *)t + sizeof(struct task) + t->tasklength;
+ return next >= mem_task ? NULL : (struct task *)next;
}
void task_delete(uint8_t c)
{
debug("Going to delete task: %i", c);
- debug("spacepointer: %p", spacepointer);
+ debug("mem_task: %p", mem_task);
struct task *t = task_head();
while(t != NULL){
if(t->taskid == c){
//to the spacepointer right
uint8_t *start = (uint8_t *)t;
uint8_t *end = start + sizeof(struct task) + t->tasklength;
- debug("Moving %lu bytes\n", spacepointer-end);
- for(int i = 0; i<spacepointer-end; i++){
+ debug("Moving %lu bytes\n", mem_task-end);
+ for(int i = 0; i<mem_task-end; i++){
start[i] = end[i];
}
//Decrement the spacepointer
- spacepointer -= end-start;
+ mem_task -= end-start;
}
- debug("spacepointer: %p", spacepointer);
+ debug("mem_task: %p", mem_task);
}
struct task *task_head(void);
struct task *task_next(struct task *t);
-void task_init(void);
+
void task_register(void);
void task_delete(uint8_t num);
{haveLed :: Bool
,haveAio :: Bool
,haveDio :: Bool
- ,maxTask :: Int //Should be number of bytes reserved in total for shares, tasks and functions
- ,maxSDS :: Int
+ ,bytesMemory :: Int
}
:: BCValue = E.e: BCValue e & mTaskType e
|haveLed=(c bitand 1) > 0
,haveAio=(c bitand 2) > 0
,haveDio=(c bitand 4) > 0
- ,maxTask=from16bit $ s % (1,3)
- ,maxSDS=from16bit $ s % (3,5)
+ ,bytesMemory=from16bit $ s % (1,3)
}
derive gPrint Long, UserLED, Button, AnalogPin, DigitalPin, PinMode, Pin, BC, MTaskDeviceSpec