New loadable style with big dispatcher table.

This commit is contained in:
Stefan `Sec` Zehl 2011-08-03 16:34:09 +02:00
parent 830ee24cb7
commit ce87f3b8f5
11 changed files with 677 additions and 0 deletions

View File

@ -9,6 +9,10 @@ LIBS =
VPATH +=
OBJS += main.o
ifeq "$(wildcard table.c)" "table.c"
OBJS += table.o
endif
LIBS += lcd/liblcd.a
LIBS += basic/libbasic.a
LIBS += core/libcore.a
@ -61,6 +65,9 @@ protect: $(OUTFILE).bin
loadables: $(OUTFILE).bin
@cd loadable && $(MAKE)
l0dables:
@cd l0dable && $(MAKE)
clean:
rm -f $(OBJS) $(LD_TEMP) $(OUTFILE).elf $(OUTFILE).bin $(OUTFILE).hex
for dir in $(SUBDIRS); do \

4
firmware/l0dable/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
*.elf
*.bin
*.h
loadable.ld

37
firmware/l0dable/EXPORTS Normal file
View File

@ -0,0 +1,37 @@
DoInt
DoIntX
DoString
GetLight
GetUUID32
GetVoltage
IntToStr
IntToStrX
_timectr
delayms
delayms_queue
getInputRaw
getInputWaitRelease
getSeconds
gpioGetValue
gpioSetValue
handleMenu
iapReadSerialNumber
isNight
lcdClear
lcdDisplay
lcdNl
lcdPrint
lcdPrintInt
lcdPrintIntHex
lcdPrintln
lcdRefresh
lcdSetPixel
lcdShift
meshbuffer
meshgen
meshincctr
mygmtime
push_queue
the_config
the_queue
work_queue

55
firmware/l0dable/Makefile Normal file
View File

@ -0,0 +1,55 @@
##########################################################################
# User configuration and firmware specific object files
##########################################################################
SRCS = $(wildcard *.c)
OBJS = $(foreach mod,$(SRCS),$(subst .c,.o,$(mod)))
ELFS = $(foreach mod,$(SRCS),$(subst .c,.elf,$(mod)))
BINS = $(foreach mod,$(SRCS),$(subst .c,.bin,$(mod)))
##########################################################################
# GNU GCC compiler flags
##########################################################################
ROOT_PATH?= ..
INCLUDE_PATHS = -I$(ROOT_PATH) -I$(ROOT_PATH)/core
include $(ROOT_PATH)/Makefile.inc
##########################################################################
# Compiler settings, parameters and flags
##########################################################################
LDSRCFILE=ram.ld
LDFILE=loadable.ld
CFLAGS+=-mlong-calls -fno-toplevel-reorder
all: $(OBJS) $(ELFS) $(BINS)
$(LDFILE):
-@echo "MEMORY" > $(LDFILE)
-@echo "{" >> $(LDFILE)
-@echo " sram(rwx): ORIGIN = 0x10002000 - $(RAMCODE), LENGTH = $(RAMCODE)" >> $(LDFILE)
-@echo "}" >> $(LDFILE)
-@echo "INCLUDE $(LDSRCFILE)" >> $(LDFILE)
%.o : %.c
$(CC) $(CFLAGS) -o $@ $<
%.elf: %.o $(FIRMWARE) $(LDFILE)
$(LD) $(LDFLAGS) -T $(LDFILE) -o $@ $<
$(SIZE) $@
%.bin: %.elf
$(OBJCOPY) $(OCFLAGS) -O binary $< $@
clean:
rm -f *.o *.elf *.bin
IDIR=/cygdrive/f
install:
for a in $(BINS) ; do f=$${a#*/};cp $$a $(IDIR)/$${f%.bin}.c0d ; done
$(OBJS): usetable.h
.SUFFIXES:
.PHONY: $(LDFILE)

12
firmware/l0dable/blink.c Normal file
View File

@ -0,0 +1,12 @@
#include <sysinit.h>
#include "basic/basic.h"
#include "usetable.h"
void ram(void){
for (int x=0;x<20;x++){
gpioSetValue (RB_LED1, x%2);
delayms(50);
};
};

230
firmware/l0dable/debug.c Normal file
View File

@ -0,0 +1,230 @@
#include <sysinit.h>
#include <string.h>
#include "basic/basic.h"
#include "basic/config.h"
#include "lcd/render.h"
#include "lcd/print.h"
#include "usb/usbmsc.h"
#include "core/iap/iap.h"
#include "funk/mesh.h"
#include "usetable.h"
/**************************************************************************/
void ChkFlame(void);
void ChkLight(void);
void ChkBattery(void);
void m_time(void);
void Qstatus(void);
void getsp(void);
void uptime(void);
void uuid(void);
static const struct MENU submenu_debug={ "debug", {
{ "ChkBattery", &ChkBattery},
// { "ChkFlame", &ChkFlame},
{ "ChkLight", &ChkLight},
{ "MeshInfo", &m_time},
{ "Qstatus", &Qstatus},
{ "ShowSP", &getsp},
{ "Uptime", &uptime},
{ "Uuid", &uuid},
{NULL,NULL}
}};
void ram(void) {
handleMenu(&submenu_debug);
};
//# MENU debug ChkLight
void ChkLight(void) {
int dx=0;
int dy=8;
dx=DoString(0,dy,"Light:");
DoString(0,dy+16,"Night:");
while ((getInputRaw())==BTN_NONE){
DoInt(dx,dy,GetLight());
DoInt(dx,dy+16,isNight());
DoInt(dx,dy+8,GLOBAL(daytrig));
lcdDisplay();
delayms_queue(100);
};
dx=DoString(0,dy+24,"Done.");
}
//# MENU debug ChkBattery
void ChkBattery(void) {
do{
lcdClear();
lcdPrintln("Voltage:");
lcdPrintln(IntToStr(GetVoltage(),5,0));
lcdNl();
lcdPrintln("Chrg_stat:");
if(gpioGetValue(RB_PWR_CHRG)){
lcdPrintln("1");
}else{
lcdPrintln("0");
};
lcdRefresh();
delayms_queue(100);
} while ((getInputRaw())==BTN_NONE);
}
//# MENU debug Uptime
void uptime(void) {
int t;
int h;
char flag;
while ((getInputRaw())==BTN_NONE){
lcdClear();
lcdPrintln("Uptime:");
t=(_timectr)/(1000/SYSTICKSPEED);
h=t/60/60;
flag=F_ZEROS;
if(h>0){
lcdPrint(IntToStr(h,2,flag));
lcdPrint("h");
flag|=F_LONG;
};
h=t/60%60;
if(h>0){
lcdPrint(IntToStr(h,2,flag));
lcdPrint("m");
flag|=F_LONG;
};
h=t%60;
if(h>0){
lcdPrint(IntToStr(h,2,flag));
lcdPrint("s");
};
lcdNl();
lcdNl();
lcdPrintln("Ticks:");
lcdPrint(IntToStr(_timectr,10,0));
lcdRefresh();
delayms_queue(222);
};
lcdPrintln("done.");
}
//# MENU debug Uuid
void uuid(void) {
IAP_return_t iap_return;
iap_return = iapReadSerialNumber();
lcdClear();
lcdPrintln("UUID:");
lcdPrintIntHex(iap_return.Result[0]); lcdNl();
lcdPrintIntHex(iap_return.Result[1]); lcdNl();
lcdPrintIntHex(iap_return.Result[2]); lcdNl();
lcdPrintIntHex(iap_return.Result[3]); lcdNl();
lcdNl();
lcdPrintln("Beacon ID:");
lcdPrintln(IntToStrX(GetUUID32(),4));
lcdRefresh();
}
//# MENU debug Qstatus
void Qstatus(void) {
int dx=0;
int dy=8;
lcdClear();
dx=DoString(0,dy+16,"Qdepth:");
while ((getInputRaw())!=BTN_ENTER){
DoInt(dx,dy+16,(the_queue.qend-the_queue.qstart+MAXQENTRIES)%MAXQENTRIES);
lcdDisplay();
if(getInputRaw()!=BTN_NONE)
work_queue();
else
delayms(10);
};
dy+=16;
dx=DoString(0,dy,"Done.");
};
void blink_led0(void){
gpioSetValue (RB_LED0, 1-gpioGetValue(RB_LED0));
};
void tick_alive(void){
static int foo=0;
if(GLOBAL(alivechk)==0)
return;
if(foo++>500/SYSTICKSPEED){
foo=0;
if(GLOBAL(alivechk)==2)
push_queue(blink_led0);
else
blink_led0();
};
return;
};
//# MENU debug ShowSP
void getsp(void) {
int dx=0;
int dy=8;
int x;
lcdClear();
dx=DoString(0,dy,"SP:");
while ((getInputRaw())==BTN_NONE){
__asm( "mov %0, sp\n" : "=r" (x) :);
DoIntX(0,dy+8,x);
lcdDisplay();
delayms_queue(50);
};
dy+=16;
dx=DoString(0,dy,"Done.");
};
void m_time(void){
struct tm* tm;
char c[2]={0,0};
getInputWaitRelease();
delayms(100);
do{
lcdClear();
tm= mygmtime(getSeconds());
lcdPrint(IntToStr(tm->tm_hour,2,F_LONG));
lcdPrint(":");
lcdPrint(IntToStr(tm->tm_min,2,F_LONG|F_ZEROS));
lcdPrint(":");
lcdPrint(IntToStr(tm->tm_sec,2,F_LONG|F_ZEROS));
lcdNl();
lcdPrint(IntToStr(tm->tm_mday,2,F_LONG));
lcdPrint(".");
lcdPrint(IntToStr(tm->tm_mon+1,2,0));
lcdPrint(".");
lcdPrint(IntToStr(tm->tm_year+YEAR0,4,F_LONG|F_ZEROS));
lcdNl();
lcdNl();
lcdPrint("<");
for(int i=0;i<MESHBUFSIZE;i++){
if(!meshbuffer[i].flags&MF_USED){
c[0]='_';
}else{
c[0]=meshbuffer[i].pkt[0];
};
lcdPrint(c);
};
lcdPrintln(">");
lcdPrint("Gen:");
lcdPrintInt(meshgen);
lcdNl();
lcdPrint("Inc:");
lcdPrintInt(meshincctr);
lcdNl();
lcdRefresh();
delayms_queue(50);
}while ((getInputRaw())==BTN_NONE);
};

View File

@ -0,0 +1,5 @@
MEMORY
{
sram(rwx): ORIGIN = 0x10002000 - 2048, LENGTH = 2048
}
INCLUDE ram.ld

173
firmware/l0dable/mandel.c Normal file
View File

@ -0,0 +1,173 @@
#include <sysinit.h>
#include "basic/basic.h"
#include "lcd/render.h"
#include "lcd/display.h"
#include "lcd/allfonts.h"
#include "usetable.h"
#define FIXSIZE 25
#define mul(a,b) ((((long long)a)*(b))>>FIXSIZE)
#define fixpt(a) ((long)(((a)*(1<<FIXSIZE))))
#define integer(a) (((a)+(1<<(FIXSIZE-1)))>>FIXSIZE)
#define ZOOM_RATIO 0.90
#define ITERATION_MAX 150
void mandelInit();
void mandelMove();
void mandelUpdate();
void ram(void) {
int key;
mandelInit();
while (1) {
lcdDisplay();
mandelMove();
mandelUpdate();
// Exit on enter+direction
key=getInputRaw();
if(key&BTN_ENTER && key>BTN_ENTER)
return;
}
return;
}
struct mb {
long rmin, rmax, imin, imax;
bool dirty, dup, ddown, dleft, dright;
} mandel;
void mandelInit() {
//mandel.rmin = -2.2*0.9;
//mandel.rmax = 1.0*0.9;
//mandel.imin = -2.0*0.9;
//mandel.imax = 2.0*0.9;
mandel.rmin = fixpt(-2);
mandel.rmax = fixpt(1);
mandel.imin = fixpt(-2);
mandel.imax = fixpt(2);
mandel.dirty = true;
mandel.dup = false;
mandel.ddown = false;
mandel.dleft = false;
mandel.dright = false;
}
void mandelMove() {
//long delta_r = (mandel.rmax - mandel.rmin)/10;
//long delta_i = (mandel.imax - mandel.imin)/10;
long rs =(mandel.rmax-mandel.rmin)/RESY;
long is =(mandel.imax-mandel.imin)/RESX;
char key = getInputRaw();
if (key == BTN_LEFT) {
mandel.imax -=is;
mandel.imin -=is;
mandel.dleft = true;
} else if (key == BTN_RIGHT) {
mandel.imax += is;
mandel.imin += is;
mandel.dright = true;
} else if (key == BTN_DOWN) {
mandel.rmax += rs;
mandel.rmin += rs;
mandel.ddown = true;
} else if (key == BTN_UP) {
mandel.rmax -= rs;
mandel.rmin -= rs;
mandel.dup = true;
} else if (key == (BTN_ENTER + BTN_UP)) {
mandel.imin = mandel.imin + (mandel.imax-mandel.imin)/10;
mandel.imax = mandel.imax - (mandel.imax-mandel.imin)/10;
mandel.rmin = mandel.rmin +(mandel.rmax-mandel.rmin)/10;
mandel.rmax = mandel.rmax -(mandel.rmax-mandel.rmin)/10;
mandel.dirty = true;
} else if (key == (BTN_ENTER + BTN_DOWN)) {
mandel.imin = mandel.imin - (mandel.imax-mandel.imin)/10;
mandel.imax = mandel.imax + (mandel.imax-mandel.imin)/10;
mandel.rmin = mandel.rmin -(mandel.rmax-mandel.rmin)/10;
mandel.rmax = mandel.rmax +(mandel.rmax-mandel.rmin)/10;
mandel.dirty = true;
}
}
void mandelPixel(int x, int y) {
long r0,i0,rn, p,q;
long rs,is;
int iteration;
rs=(mandel.rmax-mandel.rmin)/RESY;
is=(mandel.imax-mandel.imin)/RESX;
//p=fixpt(mandel.rmin+y*rs);
//q=fixpt(mandel.imin+x*is);
p=mandel.rmin+y*rs;
q=mandel.imin+x*is;
rn=0;
r0=0;
i0=0;
iteration=0;
while ((mul(rn,rn)+mul(i0,i0))<fixpt(4) && ++iteration<ITERATION_MAX) {
rn=mul((r0+i0),(r0-i0)) +p;
i0=mul(fixpt(2),mul(r0,i0)) +q;
r0=rn;
}
if (iteration==ITERATION_MAX) iteration=1;
bool pixel = ( iteration>1);
lcdSetPixel(x, y, pixel);
}
void mandelUpdate() {
int xmin,xmax,ymin,ymax;
if (mandel.dirty) {
xmin = 0;
xmax = RESX;
ymin = 0;
ymax = RESY;
mandel.dirty = false;
} else if (mandel.dleft) {
lcdShift(1,0,false);
xmin = 0;
xmax = 1;
ymin = 0;
ymax = RESY;
mandel.dleft = false;
} else if (mandel.dright) {
lcdShift(-1,0,false);
xmin = RESX-1;
xmax = RESX;
ymin = 0;
ymax = RESY;
mandel.dright = false;
} else if (mandel.dup) {
lcdShift(0,-1,true);
xmin=0;
xmax=RESX;
ymin=0;
ymax=1;
mandel.dup = false;
} else if (mandel.ddown) {
lcdShift(0,1,true);
xmin=0;
xmax=RESX;
ymin=RESY-1;
ymax=RESY;
mandel.ddown = false;
} else {
return;
}
for (int x = xmin; x<xmax; x++) {
for (int y = ymin; y<ymax; y++) {
mandelPixel(x,y);
}
}
}

105
firmware/l0dable/mktable.pl Executable file
View File

@ -0,0 +1,105 @@
#!/usr/bin/perl
#
# vim:set ts=4 sw=4:
use strict;
my $DIR="l0dable";
if( -d "../$DIR"){
chdir("..");
}
if ( ! -d $DIR ){
die "Can't find $DIR?";
};
my @symb;
open(Q,"<","l0dable/EXPORTS") || die "$!";
while(<Q>){
chomp;s/\r$//;
push @symb,$_;
};
close(Q);
$\="\n";
open (C,">","table.c")||die;
print C '#include "table.h"';
open (H,">","table.h")||die;
print H "#include <sysdefs.h>";
open (I,">","$DIR/usetable.h")||die;
print I "extern const void * TheTable[];";
print I "";
my %types;
my %files;
my %variable;
use File::Find ();
sub wanted {
my $id;
next unless /\.h$/;
open(F,"<",$_) || die;
while(<F>){
chomp;s/\r$//;
if(m!^[^(]* ([\w]+)\s*\(.*\);\s*(//.*)?$!){
$id=$1;
s/$id/(*)/;
s/;//;
s!//.*!!;
$types{$id}="*($_)";
$files{$id}=$File::Find::name;
}elsif (m!^\s*extern\s[^(]* ([\w]+)\s*(\[\w*\]\s*)?;\s*(//.*)?$!){
$id=$1;
s/extern //;
my $star="*";
if( s/\[\w*\]//){
$star="";
};
s/$id/*/;
s/;//;
s!//.*!!;
$types{$id}="$star($_)";
$variable{$id}=1;
$files{$id}=$File::Find::name;
};
};
close(F);
}
File::Find::find({wanted => \&wanted}, '.');
print C "";
print C qq!__attribute__ ((used, section("table"))) const void * TheTable[]={!;
my %defs;
for my $idx (0..$#symb){
$_=$symb[$idx];
if(!$types{$_}){
warn "Couldn't find $symb[$idx]";
};
if(!$defs{$files{$_}}){
print H qq!#include "$files{$_}"!;
$defs{$files{$_}}++;
};
if($variable{$_}){
print C "\&$_,";
}else{
print C "$_,";
};
print I "#define $_ ($types{$_}(TheTable[$idx]))";
};
print C "};";
close(I);
close(H);
close(C);

48
firmware/l0dable/ram.ld Normal file
View File

@ -0,0 +1,48 @@
sram_top = ORIGIN(sram) + LENGTH(sram);
TheTable = 0x00000124;
ENTRY(ram)
SECTIONS
{
.text :
{
*(.text*)
*(.rodata*)
} > sram
/*
* More information about Special Section Indexes is available in the
* free "ELF for the ARM Architecture" document from ARM Limited
* http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044d/IHI0044D_aaelf.pdf
*
*/
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } > sram
__exidx_start = .;
.ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > sram
__exidx_end = .;
_etext = .;
.data : AT (__exidx_end)
{
_data = .;
*(vtable)
*(.data*)
_edata = .;
} > sram
/* zero initialized data */
.bss :
{
_bss = .;
*(.bss*)
*(COMMON)
_ebss = .;
} > sram
end = .;
/* For GDB compatibility we decrease the top with 16 bytes */
stack_entry = sram_top - 16;
}

View File

@ -36,6 +36,7 @@ SECTIONS
.text :
{
KEEP(*(.irq_vectors))
KEEP(*(table))
*(.text*)
*(.rodata*)
} > flash