libinterp, actually works

master
Clyne Sullivan 7 years ago
parent 025ed8530c
commit 100cb2f84a

@ -6,7 +6,7 @@ OBJCOPY = objcopy
MCUFLAGS = -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16
AFLAGS = $(MCUFLAGS)
CFLAGS = $(MCUFLAGS) -Iinclude -fno-builtin -fsigned-char -ffreestanding -Wall -Werror -Wextra -Wno-discarded-qualifiers
CFLAGS = $(MCUFLAGS) -Iinclude -Iinclude/it -fno-builtin -fsigned-char -ffreestanding -Wall -Werror -Wextra -Wno-discarded-qualifiers -ggdb
LFLAGS =
OFLAGS = -O ihex
@ -21,10 +21,11 @@ HEX = main.hex
all: $(HEX)
$(HEX): $(OFILES)
$(HEX): $(OFILES) initrd/init
@echo " LINK " $(HEX)
@./mkinitrd.sh
@$(CROSS)$(OBJCOPY) -B arm -I binary -O elf32-littlearm initrd.img out/initrd.img.o
@$(CROSS)$(CC) $(CFLAGS) $(LFLAGS) -T link.ld out/*.o -o out/main.elf
@$(CROSS)$(CC) $(CFLAGS) $(LFLAGS) -T link.ld out/*.o -o out/main.elf -L. -linterp
@$(CROSS)$(OBJCOPY) $(OFLAGS) out/main.elf $(HEX)
$(OUTDIR)/%.o: src/%.c

@ -1,12 +1,12 @@
#ifndef HEAP_H_
#define HEAP_H_
#include <stdint.h>
//#include <stdint.h>
uint32_t heap_available(void);
//uint32_t heap_available(void);
void *malloc(uint32_t size);
void *calloc(uint32_t count, uint32_t size);
void free(void *buf);
//void *malloc(uint32_t size);
//void *calloc(uint32_t count, uint32_t size);
//void free(void *buf);
#endif // HEAP_H_

@ -0,0 +1 @@
../../interpreter

@ -1,34 +0,0 @@
#ifndef PARSER_H_
#define PARSER_H_
#include <variable.h>
typedef variable *stack_t;
typedef struct {
variable *vars;
char **vnames;
stack_t *stack;
uint32_t stidx;
char **lines;
uint32_t lnidx;
uint8_t indent;
} interpreter;
typedef int (*func_t)(interpreter *);
void iinit(interpreter *);
void inew_string(interpreter *, const char *, char *);
void inew_integer(interpreter *, const char *, int32_t);
void inew_float(interpreter *, const char *, float);
void inew_cfunc(interpreter *, const char *, func_t);
int idoline(interpreter *, const char *);
variable *igetarg(interpreter *, uint32_t);
char *igetarg_string(interpreter *, uint32_t);
int igetarg_integer(interpreter *, uint32_t);
float igetarg_float(interpreter *, uint32_t);
#endif // PARSER_H_

@ -1,21 +0,0 @@
#ifndef VARIABLE_H_
#define VARIABLE_H_
#include <stdint.h>
typedef struct {
uint8_t used :1;
uint8_t fromc :1;
uint8_t valtype :2;
uint32_t value;
char *svalue;
} variable;
enum valtype {
STRING = 0,
INTEGER,
FLOAT,
FUNC
};
#endif // VARIABLE_H_

@ -0,0 +1,10 @@
set a 0
do
set a (a + 1)
delay 1
while (a < 100)
if (a == 100)
print "All good!"
end

Binary file not shown.

@ -2,3 +2,6 @@
openocd -f /usr/share/openocd/scripts/board/st_nucleo_l476rg.cfg \
-c "init; reset halt; flash write_image erase main.hex; reset run; exit"
#openocd -f /usr/share/openocd/scripts/board/st_nucleo_l476rg.cfg > /dev/null &
#gdb-multiarch

@ -1,23 +1,35 @@
#include <heap.h>
#include <stm32l476xx.h>
#define HEAP_SIZE (16 * 1024)
static uint32_t offset = 0;
#define HEAP_SIZE (64 * 1024)
uint8_t heap[HEAP_SIZE];
void heap_init(void)
void *_sbrk(int inc)
{
// what to do...
}
static uint8_t *hend;
uint8_t *prev;
uint32_t heap_available(void)
{
return HEAP_SIZE - offset;
if (hend == 0)
hend = heap;
prev = hend;
hend += inc;
return prev;
}
void *malloc(uint32_t size)
//void heap_init(void)
//{
// what to do...
//}
//uint32_t heap_available(void)
//{
// return HEAP_SIZE - offset;
//}
/*void *malloc(uint32_t size)
{
void *alloc = &heap[offset];
offset += size;
@ -26,11 +38,11 @@ void *malloc(uint32_t size)
void *calloc(uint32_t count, uint32_t size)
{
/*uint32_t total = count * size;
void *alloc = hmalloc(total);
for (uint32_t i = 0; i < total; i++)
((uint8_t *)alloc)[i] = 0;
return alloc;*/
//uint32_t total = count * size;
//void *alloc = hmalloc(total);
//for (uint32_t i = 0; i < total; i++)
// ((uint8_t *)alloc)[i] = 0;
//return alloc;
// calloc broke
return malloc(count * size);
@ -39,4 +51,4 @@ void *calloc(uint32_t count, uint32_t size)
void free(void *ptr)
{
(void)ptr;
}
}*/

@ -128,8 +128,10 @@ void lcd_init(void)
* Task code
*/
static int bufpos = 0;
static char buf[64];
volatile int bufpos = 0;
volatile char buf[32];
volatile uint8_t using = 0;
void lcd_clearbuf(void)
{
bufpos = 0;
@ -140,9 +142,15 @@ void lcd_clearbuf(void)
void lcd_put(const char *s)
{
int len = strlen(s);
int off = (bufpos + len < 64) ? len : 64 - bufpos;
strncpy(buf + bufpos, s, off);
bufpos += off;
int i;
using = 1;
for (i = 0; i < len; bufpos++, i++) {
if (bufpos > 31)
bufpos = 0;
buf[bufpos] = s[i];
}
using = 0;
}
void lcd_handler(void)
@ -151,7 +159,7 @@ void lcd_handler(void)
lcd_clearbuf();
while (1) {
if (buf[0] != '\0') {
if (!using && buf[0] != '\0') {
lcd_puts(buf);
lcd_clearbuf();
}

@ -7,22 +7,13 @@
#include <initrd.h>
#include <serial.h>
#include <parser.h>
#include <stack.h>
#include <stdlib.h>
#include <string.h>
/**
* Accomplishments:
* - GPIO in/out
* - got to 80MHz clock
* - basic heap
* - multitask, can exit
* - gpio lib
* - lcd support
* - initrd support
* - lua? - no, something better, smaller
* - serial IO
*/
void pulse(uint8_t byte);
void kmain(void);
void task_interpreter(void);
int main(void)
{
@ -51,17 +42,58 @@ int main(void)
int script_puts(interpreter *it)
{
char *s = igetarg_string(it, 0);
//lcd_puts(s);
asm("mov r0, %0; svc 2" :: "r" (s));
return 0;
}
int script_delay(interpreter *it)
{
int ms = igetarg_integer(it, 0);
delay(ms);
return 0;
}
void task_interpreter(void)
{
interpreter it;
iinit(&it);
inew_cfunc(&it, "print", script_puts);
inew_cfunc(&it, "delay", script_delay);
char *s = initrd_getfile("init");
if (s == 0)
goto end;
char *linebuf = (char *)malloc(120);
uint32_t i = 0, prev = 0, lc;
uint32_t size = initrd_getfilesize("init");
int ret;
while (i < size) {
for (; s[i] != '\n' && s[i] != '\0'; i++);
lc = i - prev;
if (lc == 0) {
prev = ++i;
continue;
}
strncpy(linebuf, s + prev, lc + 1);
linebuf[lc] = '\0';
ret = idoline(&it, linebuf);
if (ret < 0)
break;
prev = ++i;
}
while (1);
if (ret < 0) {
lcd_puts("Error: ");
lcd_puts(itoa(ret, linebuf, 10));
}
free(linebuf);
//iend(&it); // nah
end:
while (1)
delay(10);
}
void kmain(void)
@ -70,7 +102,7 @@ void kmain(void)
task_start(lcd_handler, 128);
delay(200);
task_start(task_interpreter, 2048);
task_start(task_interpreter, 4096);
//char *s = initrd_getfile("test.txt");

@ -1,716 +0,0 @@
#include <parser.h>
#include <heap.h>
#include <ctype.h>
#include <string.h>
extern int atoi(char *);
float strtof(char *s, char **e)
{ (void)s; (void)e; return 0;}
#include <stdarg.h>
extern int ksnprintf(char *, int, const char *, ...);
#define MAX_VARS 32
#define MAX_STACK 32
#define INT(v) (*((int32_t *)&v->value))
#define FLOAT(v) (*((float *)&v->value))
static char *str_func = "(func)";
static char *str_undef = "(undefined)";
char *strclone(const char *s)
{
char *clone = (char *)malloc(strlen(s));
strcpy(clone, s);
return clone;
}
char *strnclone(const char *s, uint32_t n)
{
char *clone = (char *)malloc(n);
strncpy(clone, s, n);
return clone;
}
void fsetstr(variable *f)
{
if (f->svalue == 0)
f->svalue = (char *)malloc(16);
ksnprintf(f->svalue, 16, "%f", FLOAT(f));
}
void isetstr(variable *i)
{
if (i->svalue == 0)
i->svalue = (char *)malloc(12);
ksnprintf(i->svalue, 12, "%ld", INT(i));
}
uint8_t eol(int c)
{
return c == '\n' || c == '\0';
}
uint8_t eot(int c)
{
return eol(c) || c == ' ';
}
uint8_t eoe(int c)
{
return eol(c) || c == ')';
}
uint32_t findend(const char *s, char o, char c)
{
uint8_t indent = 0;
uint32_t i;
for (i = 1; !eol(s[i]); i++) {
if (s[i] == o) {
indent++;
} else if (s[i] == c) {
if (indent == 0)
break;
else
indent--;
}
}
return i;
}
int ifunc_set(interpreter *it);
int ifunc_jmp(interpreter *it);
int ifunc_label(interpreter *it);
int ifunc_end(interpreter *it);
variable *idoexpr(interpreter *interp, const char *line);
variable *itostring(variable *v);
variable *itoint(variable *v);
variable *itofloat(variable *v);
void iinit(interpreter *interp)
{
interp->vars = (variable *)calloc(MAX_VARS, sizeof(variable));
interp->vnames = (char **)calloc(MAX_VARS, sizeof(char *));
interp->stack = (stack_t *)calloc(MAX_STACK, sizeof(stack_t));
interp->stidx = 0;
interp->lines = (char **)calloc(20, sizeof(char *));
interp->lnidx = 0;
interp->indent = 0;
inew_cfunc(interp, "set", ifunc_set);
inew_cfunc(interp, "jmp", ifunc_jmp);
inew_cfunc(interp, "func", ifunc_label);
inew_cfunc(interp, "end", ifunc_end);
}
void ipush(interpreter *it, void *v)
{
it->stack[it->stidx++] = v;
}
void *ipop(interpreter *it)
{
return it->stack[--it->stidx];
}
variable *interpreter_get_variable(interpreter *interp, const char *name)
{
for (uint32_t i = 0; i < MAX_VARS; i++) {
if (!interp->vars[i].used) {
variable *v = &interp->vars[i];
v->used = 1;
v->fromc = 0;
v->valtype = STRING;
v->value = 0;
v->svalue = str_undef;
interp->vnames[i] = strclone(name);
return v;
} else if (interp->vnames[i] != 0 && !strcmp(interp->vnames[i], name)) {
return &interp->vars[i];
}
}
return 0;
}
char *interpreter_get_name(interpreter *interp, variable *v)
{
for (uint32_t i = 0; i < MAX_VARS; i++) {
if (v == &interp->vars[i])
return interp->vnames[i];
}
return str_undef;
}
void inew_string(interpreter *interp, const char *name, char *value)
{
variable *v = interpreter_get_variable(interp, name);
if (v != 0) {
v->valtype = STRING;
INT(v) = 0;
v->svalue = strclone(value);
}
}
void inew_integer(interpreter *interp, const char *name, int32_t value)
{
variable *v = interpreter_get_variable(interp, name);
if (v != 0) {
v->valtype = INTEGER;
INT(v) = value;
isetstr(v);
}
}
void inew_float(interpreter *interp, const char *name, float value)
{
variable *v = interpreter_get_variable(interp, name);
if (v != 0) {
v->valtype = FLOAT;
FLOAT(v) = value;
fsetstr(v);
}
}
void inew_cfunc(interpreter *interp, const char *name, func_t func)
{
variable *v = interpreter_get_variable(interp, name);
if (v != 0) {
v->fromc = 1;
v->valtype = FUNC;
v->value = (uint32_t)func;
v->svalue = str_func;
}
}
variable *make_var(interpreter *interp, const char *line, uint32_t *next)
{
if (line[0] == '\"') { // string literal
uint32_t end = 1;
while (!eol(line[end])) {
if (line[end] == '\"'/* && line[end - 1] != '\\'*/) {
if (!eot(line[end + 1]))
return 0;
// TODO string breakdown
variable *v = (variable *)malloc(sizeof(variable));
v->used = 0;
v->valtype = STRING;
v->svalue = strnclone(line + 1, end - 1);
*next = end + 1;
return v;
}
end++;
}
return 0;
} else if (line[0] == '(') { // equation literal
uint32_t end = findend(line, '(', ')');
if (eot(line[end]))
return 0;
*next = end + 1;
return idoexpr(interp, line + 1);
} else if (isalpha(line[0])) { // variable/func
uint32_t end = 1;
for (; isalnum(line[end]); end++);
if (!eot(line[end]))
return 0;
char *name = (char *)malloc(end + 1);
strncpy(name, line, end);
name[end] = '\0';
*next = end;
return interpreter_get_variable(interp, name);
} else if (isdigit(line[0])) { // number
uint32_t end = 1;
uint8_t dec = 0;
for (; !eot(line[end]); end++) {
if (!isdigit(line[end])) {
if (line[end] == '.') {
if (!dec)
dec = 1;
else
return 0;
} else {
return 0;
}
}
}
variable *v = (variable *)malloc(sizeof(variable));
v->used = 0;
if (dec) {
v->valtype = FLOAT;
FLOAT(v) = strtof(line, 0);
fsetstr(v);
} else {
v->valtype = INTEGER;
INT(v) = atoi(line);
isetstr(v);
}
*next = end;
return v;
}
return 0;
}
int idoline(interpreter *interp, const char *line)
{
variable *ops[8];
uint32_t ooffset, offset, next;
interp->lines[interp->lnidx] = strclone(line);
loop:
if (line[0] == '#') {
goto norun;
} else if (interp->indent > 0) {
if (!strcmp(line, "end"))
interp->indent--;
goto norun;
}
ooffset = 0;
offset = 0;
// step 1 - convert to tokens
while (!eol(line[offset])) {
ops[ooffset] = make_var(interp, line + offset, &next);
if (ops[ooffset] == 0) {
return -4;
} else {
ooffset++;
offset += next;
}
// skip whitespace
for (; line[offset] == ' ' && !eol(line[offset]); offset++);
}
// step 2 - execute
if (ooffset == 0)
return -1;
if (ops[0]->valtype != FUNC)
return -2;
if (ops[0]->value == 0)
return -3;
for (uint32_t i = ooffset; --i > 0;)
ipush(interp, ops[i]);
if (ops[0]->fromc) {
int ret = ((func_t)ops[0]->value)(interp);
if (ret != 0)
return ret;
} else {
ipush(interp, (void *)(interp->lnidx + 1));
interp->lnidx = ops[0]->value;
}
interp->stidx -= ooffset - 1;
if ((int32_t)interp->stidx < 0) {
interp->stidx = 0;
return -5;
}
for (uint32_t i = 0; i < ooffset; i++) {
if (!ops[i]->used)
free(ops[i]);
}
norun:
interp->lnidx++;
if (interp->lines[interp->lnidx] != 0) {
line = interp->lines[interp->lnidx];
goto loop;
}
return 0;
}
typedef void (*operation_t)(variable *, variable *, variable *);
#define IOPS_COUNT 15
static char *iops[IOPS_COUNT] = {
"+", "-", "*", "/", "&", "|", "^", ">>", "<<",
"==", "<", ">", "<=", ">=", "!="
};
void iop_add(variable *, variable *, variable *);
void iop_sub(variable *, variable *, variable *);
void iop_mult(variable *, variable *, variable *);
void iop_div(variable *, variable *, variable *);
void iop_and(variable *, variable *, variable *);
void iop_or(variable *, variable *, variable *);
void iop_xor(variable *, variable *, variable *);
void iop_shr(variable *, variable *, variable *);
void iop_shl(variable *, variable *, variable *);
void iop_eq(variable *, variable *, variable *);
void iop_lt(variable *, variable *, variable *);
void iop_gt(variable *, variable *, variable *);
void iop_lte(variable *, variable *, variable *);
void iop_gte(variable *, variable *, variable *);
void iop_ne(variable *, variable *, variable *);
static operation_t iopfuncs[IOPS_COUNT] = {
iop_add, iop_sub, iop_mult, iop_div, iop_and,
iop_or, iop_xor, iop_shr, iop_shl,
iop_eq, iop_lt, iop_gt, iop_lte, iop_gte, iop_ne
};
variable *idoexpr(interpreter *interp, const char *line)
{
variable *result = (variable *)malloc(sizeof(variable));
char *mline = line;
void *ops[16];
uint32_t ooffset = 0;
uint32_t offset = 0;
uint32_t next;
// step 1 - break apart line
// skip whitespace
for (; line[offset] == ' ' && !eol(line[offset]); offset++);
while (!eoe(line[offset])) {
if (line[offset] == '(') {
uint8_t indent = 0;
uint32_t i;
for (i = offset + 1; !eol(line[i]); i++) {
if (line[i] == '(') {
indent++;
} else if (line[i] == ')') {
if (indent == 0) {
break;
} else {
indent--;
}
}
}
if (eol(line[i]))
return 0;
ops[ooffset] = idoexpr(interp, line + offset + 1);
offset = i + 1;
} else {
uint32_t end = offset;
char cend = 0;
if (line[offset] != '\"') {
for (; isalnum(line[end]) || line[end] == '.'; end++);
cend = line[end];
mline[end] = ' ';
}
ops[ooffset] = make_var(interp, line + offset, &next);
if (end != 0)
mline[end] = cend;
}
if (ops[ooffset] == 0)
return 0;
ooffset++;
offset += next;
// skip whitespace
for (; line[offset] == ' ' && !eoe(line[offset]); offset++);
if (eoe(line[offset]))
break;
for (uint32_t i = 0; i < IOPS_COUNT; i++) {
int len = strlen(iops[i]);
if (!strncmp(iops[i], line + offset, len)) {
ops[ooffset] = (void *)(i + 1);
offset += len;
break;
}
}
if (ops[ooffset] == 0)
return 0;
ooffset++;
// skip whitespace
for (; line[offset] == ' ' && !eol(line[offset]); offset++);
}
if (ooffset % 2 == 0)
return 0;
// step 2 - do operations
result->valtype = ((variable *)ops[0])->valtype;
result->value = ((variable *)ops[0])->value;
for (uint32_t i = 1; i < ooffset; i += 2) {
iopfuncs[(uint32_t)ops[i] - 1](result, result, ops[i + 1]);
}
for (uint32_t i = 0; i < ooffset; i += 2) {
if (!((variable *)ops[i])->used)
free(ops[i]);
}
if (result->valtype == INTEGER)
isetstr(result);
else
fsetstr(result);
return result;
}
variable *igetarg(interpreter *interp, uint32_t index)
{
return interp->stack[interp->stidx - index - 1];
}
char *igetarg_string(interpreter *interp, uint32_t index)
{
if (index >= interp->stidx)
return 0;
variable *v = igetarg(interp, index);
return v->svalue;
}
int igetarg_integer(interpreter *interp, uint32_t index)
{
if (index >= interp->stidx)
return 0;
variable *v = igetarg(interp, index);
return INT(itoint(v));
}
float igetarg_float(interpreter *interp, uint32_t index)
{
if (index >= interp->stidx)
return 0;
variable *v = igetarg(interp, index);
return FLOAT(itofloat(v));
}
variable *itostring(variable *v)
{
switch (v->valtype) {
case INTEGER:
v->valtype = STRING;
isetstr(v);
break;
case FLOAT:
v->valtype = STRING;
fsetstr(v);
break;
}
return v;
}
variable *itoint(variable *v)
{
switch (v->valtype) {
case STRING:
v->valtype = INTEGER;
INT(v) = atoi(v->svalue);
isetstr(v);
break;
case FLOAT:
v->valtype = INTEGER;
INT(v) = (int32_t)FLOAT(v);
isetstr(v);
break;
}
return v;
}
variable *itofloat(variable *v)
{
switch (v->valtype) {
case STRING:
v->valtype = FLOAT;
FLOAT(v) = strtof(v->svalue, 0);
fsetstr(v);
break;
case INTEGER:
v->valtype = FLOAT;
FLOAT(v) = (float)INT(v);
fsetstr(v);
break;
}
return v;
}
/**
* Builtin functions
*/
int ifunc_set(interpreter *it)
{
variable *n = igetarg(it, 0);
variable *v = igetarg(it, 1);
if (n == 0)
return -1;
n->valtype = v->valtype;
n->value = v->value;
n->svalue = v->svalue;
return 0;
}
int ifunc_label(interpreter *it)
{
variable *n = igetarg(it, 0);
if (n == 0)
return -1;
n->valtype = FUNC;
n->value = it->lnidx;
n->svalue = str_func;
it->indent++;
return 0;
}
int ifunc_end(interpreter *it)
{
if (it->stidx > 0) {
uint32_t line = (uint32_t)ipop(it);
it->lnidx = line - 1;
}
return 0;
}
int ifunc_jmp(interpreter *it)
{
int newidx = igetarg_integer(it, 0);
ipop(it);
ipush(it, (void *)(it->lnidx + 1));
ipush(it, 0);
it->lnidx = newidx - 1;
return 0;
}
/**
* Builtin operations
*/
void iop_add(variable *r, variable *a, variable *b)
{
if (a->valtype == INTEGER && b->valtype == INTEGER) {
INT(r) = INT(a) + INT(b);
} else {
itofloat(a);
itofloat(b);
FLOAT(r) = FLOAT(a) + FLOAT(b);
}
}
void iop_sub(variable *r, variable *a, variable *b)
{
if (a->valtype == INTEGER && b->valtype == INTEGER) {
INT(r) = INT(a) - INT(b);
} else {
itofloat(a);
itofloat(b);
FLOAT(r) = FLOAT(a) - FLOAT(b);
}
}
void iop_mult(variable *r, variable *a, variable *b)
{
if (a->valtype == INTEGER && b->valtype == INTEGER) {
INT(r) = INT(a) * INT(b);
} else {
itofloat(a);
itofloat(b);
FLOAT(r) = FLOAT(a) * FLOAT(b);
}
}
void iop_div(variable *r, variable *a, variable *b)
{
if (a->valtype == INTEGER && b->valtype == INTEGER) {
INT(r) = INT(a) / INT(b);
} else {
itofloat(a);
itofloat(b);
FLOAT(r) = FLOAT(a) / FLOAT(b);
}
}
void iop_and(variable *r, variable *a, variable *b)
{
if (a->valtype == INTEGER && b->valtype == INTEGER) {
INT(r) = INT(a) & INT(b);
}
}
void iop_or(variable *r, variable *a, variable *b)
{
if (a->valtype == INTEGER && b->valtype == INTEGER) {
INT(r) = INT(a) | INT(b);
}
}
void iop_xor(variable *r, variable *a, variable *b)
{
if (a->valtype == INTEGER && b->valtype == INTEGER) {
INT(r) = INT(a) ^ INT(b);
}
}
void iop_shr(variable *r, variable *a, variable *b)
{
if (a->valtype == INTEGER && b->valtype == INTEGER) {
INT(r) = INT(a) >> INT(b);
}
}
void iop_shl(variable *r, variable *a, variable *b)
{
if (a->valtype == INTEGER && b->valtype == INTEGER) {
INT(r) = INT(a) << INT(b);
}
}
void iop_eq(variable *r, variable *a, variable *b)
{
if (a->valtype == INTEGER && b->valtype == INTEGER)
INT(r) = INT(a) == INT(b);
else
INT(r) = FLOAT(a) == FLOAT(b);
}
void iop_lt(variable *r, variable *a, variable *b)
{
if (a->valtype == INTEGER && b->valtype == INTEGER)
INT(r) = INT(a) < INT(b);
else
INT(r) = FLOAT(a) < FLOAT(b);
}
void iop_gt(variable *r, variable *a, variable *b)
{
if (a->valtype == INTEGER && b->valtype == INTEGER)
INT(r) = INT(a) > INT(b);
else
INT(r) = FLOAT(a) > FLOAT(b);
}
void iop_lte(variable *r, variable *a, variable *b)
{
if (a->valtype == INTEGER && b->valtype == INTEGER)
INT(r) = INT(a) <= INT(b);
else
INT(r) = FLOAT(a) <= FLOAT(b);
}
void iop_gte(variable *r, variable *a, variable *b)
{
if (a->valtype == INTEGER && b->valtype == INTEGER)
INT(r) = INT(a) >= INT(b);
else
INT(r) = FLOAT(a) >= FLOAT(b);
}
void iop_ne(variable *r, variable *a, variable *b)
{
if (a->valtype == INTEGER && b->valtype == INTEGER)
INT(r) = INT(a) != INT(b);
else
INT(r) = FLOAT(a) != FLOAT(b);
}

@ -62,7 +62,7 @@ defined in linker script */
/* end address for the .bss section. defined in linker script */
.word _ebss
//.equ BootRAM, 0xF1E0F85F
.equ BootRAM, 0xF1E0F85F
/**
* @brief This is the code that gets called when the processor first
* starts execution following a reset event. Only the absolutely

@ -1,44 +1,6 @@
#include <stdarg.h>
#include <stdint.h>
#include <string.h>
#include <heap.h>
extern char *itoa(int, char *, int);
void _exit(int code)
{
(void)code;
for (;;);
}
int ksnprintf(char *buf, unsigned int count, const char *format, ...)
{
(void)count;
va_list args;
va_start(args, format);
unsigned int i = 0, o = 0;
while (o < count && format[i] != '\0') {
if (format[i] == '%') {
if (format[i + 1] == 'd') {
char *s = itoa(va_arg(args, int), malloc(16), 10);
strncpy(buf + o, s, count - o);
o += strlen(s);
free(s);
} else if (format[i + 1] == 'f') {
strncpy(buf + o, "float", count - o);
o += 5;
}
i++;
} else {
buf[o++] = format[i];
}
i++;
}
return o;
}

@ -1,5 +1,5 @@
#include <task.h>
#include <heap.h>
#include <stdlib.h>
#include <stm32l476xx.h>
typedef struct {
@ -21,7 +21,7 @@ void task_init(void (*init)(void))
for (int i = 0; i < MAX_TASKS; i++)
tasks[i].use = 0;
task_start(init, 1024);
task_start(init, 4096);
asm("\
msr psp, %0; \
mrs r0, control; \

Loading…
Cancel
Save