rtimer implementation (not well tested)

sprintf that use strformat, so there's no need to pull in the newlib
implementation.
Build system improvements.
This commit is contained in:
ksb 2007-08-21 09:03:55 +00:00
parent 1ca82694f5
commit 792eae91c6
15 changed files with 294 additions and 67 deletions

View file

@ -123,7 +123,7 @@ SECTIONS
_end = .;
PROVIDE (end = .);
.stack ORIGIN(DATA) + LENGTH(DATA) - 0x0c0c :
.stack ORIGIN(DATA) + LENGTH(DATA) - 0x0a0c :
{
__stack_start__ = . ;
*(.stack)

View file

@ -1,32 +1,28 @@
# Adapted from Makefile.msp430
### Check if we are running under Windows
ifndef WINDIR
ifdef OS
ifneq (,$(findstring Windows,$(OS)))
WINDIR := Windows
endif
endif
endif
ifdef nodeid
CFLAGS += -DNODEID=$(nodeid)
endif
### Define the CPU directory
### Defin the CPU directory
CONTIKI_CPU=$(CONTIKI)/cpu/at91sam7s
### Define the source files we have in the MSP430 port
### Define the source files we have in the AT91SAM7S port
AT91SAM7S = clock.c debug-uart.c interrupt_utils.c newlib-syscalls.c sys-interrupt.c
CONTIKI_CPU_DIRS = . dbg-io loader
CONTIKI_TARGET_SOURCEFILES += $(AT91SAM7S)
AT91SAM7S = clock.c debug-uart.c interrupt-utils.c newlib-syscalls.c sys-interrupt.c rtimer-arch.c rtimer-arch-interrupt.c uip-log.c
SYSAPPS = codeprop-otf.c
APPDIRS += $(CONTIKI)/cpu/at91sam7s/loader
ELFLOADER = elfloader-otf.c elfloader-arm.c symtab.c cfs-ram.c
TARGETLIBS = random.c dbg-printf.c dbg-puts.c dbg-putchar.c dbg-sprintf.c strformat.c
CONTIKI_TARGET_SOURCEFILES += $(AT91SAM7S) $(SYSAPPS) $(ELFLOADER) \
$(TARGETLIBS) $(UIPDRIVERS)
CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES)
CONTIKIDIRS=$(CONTIKI)/core/sys:$(CONTIKI)/core/dev:$(CONTIKI)/core/cfs:$(CONTIKI)/core/loader:$(CONTIKI)/core/net:$(CONTIKI)/core/lib
THREADS =
### Compiler definitions
CC = arm-elf-gcc
@ -37,9 +33,11 @@ NM = arm-elf-nm
OBJCOPY = arm-elf-objcopy
STRIP = arm-elf-strip
PROJECT_OBJECTFILES += ${addprefix $(OBJECTDIR)/,$(CONTIKI_TARGET_MAIN:.c=.o)}
LINKERSCRIPT = $(CONTIKI_CPU)/AT91SAM7S64-ROM.ld
STARTUP=startup-SAM7S.o
STARTUP=${addprefix $(OBJECTDIR)/,startup-SAM7S.o}
# JTAG program upload
OPENOCD = openocd
@ -50,9 +48,9 @@ OPENOCD_RESET = arm7_wig_reset.cfg
SAMIAM=Sam_I_Am
SAMIAM_TTY=/dev/ttyACM0
ARCH_FLAGS= -mcpu=arm7tdmi
THUMB_FLAGS=-mthumb -mthumb-interwork
ARM_FLAGS=-mthumb-interwork
ARCH_FLAGS= -mcpu=arm7tdmi -mthumb-interwork
THUMB_FLAGS=-mthumb
ARM_FLAGS=
CFLAGSNO = -I. -I$(CONTIKI)/core -I$(CONTIKI_CPU) -I$(CONTIKI_CPU)/loader \
@ -63,58 +61,94 @@ CFLAGSNO = -I. -I$(CONTIKI)/core -I$(CONTIKI_CPU) -I$(CONTIKI_CPU)/loader \
-Wall $(ARCH_FLAGS) -g
CFLAGS += $(CFLAGSNO) -O -DRUN_AS_SYSTEM -DROM_RUN
LDFLAGS += $(ARCH_FLAGS) -T $(LINKERSCRIPT)
LDFLAGS += -T $(LINKERSCRIPT) -nostartfiles
CDEPFLAGS = $(CFLAGS) -D __MAKING_DEPS__
PROJECT_OBJECTFILES += ${addprefix $(OBJECTDIR)/,$(CONTIKI_TARGET_MAIN:.c=.o)}
### Setup directory search path for source files
CONTIKI_TARGET_DIRS_CONCAT = ${addprefix $(CONTIKI)/platform/$(TARGET)/, \
$(CONTIKI_TARGET_DIRS)}
vpath %.c $(PROJECTDIRS) \
$(CONTIKIDIRS) $(APPDIRS) $(CONTIKI_TARGET_DIRS_CONCAT) \
$(CONTIKI_CPU) $(CONTIKI_CPU)/loader $(CONTIKI_CPU)/dbg-io
vpath %.S $(CONTIKI_CPU)
CUSTOM_RULE_C_TO_OBJECTDIR_O=yes
CUSTOM_RULE_C_TO_O=yes
%-interrupt.o: %-interrupt.c
$(CC) $(CFLAGS) $(ARM_FLAGS) $< -c
$(OBJECTDIR)/%-interrupt.o: %-interrupt.c
$(CC) $(CFLAGS) $(ARM_FLAGS) -c $< -o $@
%-arm.o: %-arm.c
$(CC) $(CFLAGS) $(ARM_FLAGS) $< -c
interrupt-utils.o: interrupt-utils.c
$(CC) $(CFLAGS) $(ARM_FLAGS) $< -c
$(OBJECTDIR)/%-arm.o: %-arm.c
$(CC) $(CFLAGS) $(ARM_FLAGS) -c $< -o $@
$(OBJECTDIR)/interrupt-utils.o: interrupt-utils.c
$(CC) $(CFLAGS) $(ARM_FLAGS) $< -c -o $@
%.o: %.c
$(CC) $(CFLAGS) $(THUMB_FLAGS) $< -c
$(OBJECTDIR)/%.o: %.c
$(CC) $(CFLAGS) $(THUMB_FLAGS) -c $< -o $@
%.o: %.S
$(CC) $(CFLAGS) $(ARM_FLAGS) $< -c
%.ko: %.o
$(LD) --relocatable -T $(CONTIKI_CPU)/merge-rodata.ld $< -o $@
$(OBJECTDIR)/%.o: %.S
$(CC) $(CFLAGS) $(ARM_FLAGS) $< -c -o $@
CUSTOM_RULE_C_TO_CO=yes
%.co: %.c
$(CC) $(CFLAGS) $(THUMB_FLAGS) $< -c -o $@
CUSTOM_RULE_C_TO_CE=yes
%.ce: %.o
$(LD) $(LDFLAGS) --relocatable -T $(CONTIKI_CPU)/merge-rodata.ld $< -o $@
$(STRIP) -K _init -K _fini --strip-unneeded -g -x $@
CUSTOM_RULE_LINK=yes
# Add a namelist to the kernel
%-syms.elf: $^ $(STARTUP)
: | awk -f $(CONTIKI)/tools/mknmlist > $*-tmp.c && mv $*-tmp.c $*-nm.c
$(CC) $(LDFLAGS) $(CFLAGS) $(THUMB_FLAGS) -nostartfiles -o $@ $^ $*-nm.c
$(NM) $@ | awk -f $(CONTIKI)/tools/mknmlist > $*-tmp.c && mv $*-tmp.c $*-nm.c
-test -r $*.exclude && grep -v -f $*.exclude $*-nm.c >$*-tmp.c && mv $*-tmp.c $*-nm.c
$(CC) $(LDFLAGS) $(CFLAGS) $(THUMB_FLAGS) -nostartfiles -o $*-syms.elf $^ $*-nm.c
%-stripped.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
$(STRIP) --strip-unneeded -g -x $@
%.elf: $^ $(STARTUP)
$(CC) $(LDFLAGS) $(CFLAGS) $(THUMB_FLAGS) -nostartfiles -o $@ $^
%-stripped.o: %.o
$(STRIP) --strip-unneeded -g -x -o $@ $<
%.ihx: %.elf
$(OBJCOPY) -O ihex $< $@
%.o: ${CONTIKI_TARGET}/loader/%.S
$(AS) -o $(notdir $(<:.S=.o)) $<
%.bin: %.elf
%-nosyms.$(TARGET): %.co $(PROJECT_OBJECTFILES) contiki-$(TARGET).a $(STARTUP) $(OBJECTDIR)/empty-symbols.o
$(CC) $(LDFLAGS) $(CFLAGS) -nostartfiles -o $@ $(filter-out %.a,$^) $(filter %.a,$^) -lc $(filter %.a,$^)
%.ihex: %.$(TARGET)
$(OBJCOPY) $^ -O ihex $@
%.bin: %.$(TARGET)
$(OBJCOPY) -O binary $< $@
.PHONY: symbols.c
ifdef CORE
%.$(TARGET): %.co $(PROJECT_OBJECTFILES) contiki-$(TARGET).a $(STARTUP) $(OBJECTDIR)/symbols.o
$(CC) $(LDFLAGS) $(CFLAGS) -nostartfiles -o $@ $(filter-out %.a,$^) $(filter %.a,$^) -lc $(filter %.a,$^)
symbols.c: $(CORE)
$(NM) $< | awk -f ../../tools/mknmlist > symbols.c
else
%.$(TARGET): %-nosyms.$(TARGET)
ln -sf $< $@
endif
empty-symbols.c:
@${CONTIKI}/tools/make-empty-symbols
upload_ocd_%: %.bin
cp $< /tmp/openocd_write.bin
@ -123,7 +157,7 @@ upload_ocd_%: %.bin
-rm /tmp/openocd_write.bin
upload_%: %.ihx
upload_%: %.ihex
# Clear lock bits
$(SAMIAM) "open $(SAMIAM_TTY) , writew 0xffffff64 5a000004"
$(SAMIAM) "open $(SAMIAM_TTY) , writew 0xffffff64 5a002004"
@ -132,10 +166,8 @@ upload_%: %.ihx
ocd_reset:
cd $(CONTIKI_CPU)/openocd;$(OPENOCD) -f $(OPENOCD_RESET)
clean:
-rm *.o
-rm *.elf
-rm *.ihx
-rm *.bin
-rm *-nm.c
-rm *.ko
# Don't use core/loader/elfloader.c, use elfloader-otf.c instead
$(OBJECTDIR)/elfloader.o:
echo -n >$@
.PRECIOUS: %-nosyms.$(TARGET)

View file

@ -47,6 +47,8 @@ clock_time(void)
#define SPIN_TIME 2 /* us */
#define SPIN_COUNT (((MCK*SPIN_TIME/1000000)-5)/4)
#ifndef __MAKING_DEPS__
void
clock_delay(unsigned int t)
{
@ -56,3 +58,5 @@ clock_delay(unsigned int t)
#error Must be compiled in thumb mode
#endif
}
#endif /* __MAKING_DEPS__ */

View file

@ -3,7 +3,7 @@
#include <string.h>
#include <strformat.h>
StrFormatResult
static StrFormatResult
write_str(void *user_data, const char *data, unsigned int len)
{
dbg_send_bytes((unsigned char*)data, len);
@ -19,10 +19,12 @@ static StrFormatContext ctxt =
int
printf(const char *fmt, ...)
{
int res;
va_list ap;
va_start(ap, fmt);
return format_str_v(&ctxt, fmt, ap);
res = format_str_v(&ctxt, fmt, ap);
va_end(ap);
return res;
}

View file

@ -0,0 +1,26 @@
#include <stdio.h>
#include <strformat.h>
#include <string.h>
static StrFormatResult
buffer_str(void *user_data, const char *data, unsigned int len)
{
memcpy(*(char**)user_data, data, len);
(*(char**)user_data) += len;
return STRFORMAT_OK;
}
int
sprintf(char *str, const char *format, ...)
{
StrFormatContext ctxt;
int res;
va_list ap;
va_start(ap, format);
ctxt.write_str = buffer_str;
ctxt.user_data = &str;
res = format_str_v(&ctxt, format, ap);
*str = '\0';
va_end(ap);
return res;
}

View file

@ -74,7 +74,10 @@ dbg_send_bytes(const unsigned char *seq, unsigned int len)
unsigned short current_count;
unsigned short left;
unsigned int save = disableIRQ();
if (mutex) return 0; /* Buffer being updated */
if (mutex) {
restoreIRQ(save);
return 0; /* Buffer being updated */
}
mutex = 1; /* Prevent interrupts from messing up the transmission */
*AT91C_DBGU_PTCR =AT91C_PDC_TXTDIS; /* Stop transmitting */
while(*AT91C_DBGU_PTSR & AT91C_PDC_TXTEN); /* Wait until stopped */

View file

@ -1,3 +1,4 @@
#include <stdlib.h>
#include <malloc.h>
#include <loader/elfloader-arch-otf.h>

View file

@ -1,7 +1,7 @@
/******************************************************************************
*
* $RCSfile: interrupt-utils.c,v $
* $Revision: 1.1 $
* $Revision: 1.2 $
*
* This module provides the interface routines for setting up and
* controlling the various interrupt modes present on the ARM processor.
@ -26,7 +26,7 @@ static inline unsigned __get_cpsr(void)
static inline void __set_cpsr(unsigned val)
{
asm volatile (" msr cpsr, %0" : /* no outputs */ : "r" (val) );
asm volatile (" msr cpsr_c, %0" : /* no outputs */ : "r" (val) );
}
unsigned disableIRQ(void)

View file

@ -0,0 +1,3 @@
#include "symbols.h"
const int symbols_nelts = 0;
const struct symbols symbols[] = {{0,0}};

View file

@ -94,3 +94,30 @@ fsync(int fd)
errno = EBADF;
return -1;
}
void
_exit(int status)
{
while(1);
}
void
_abort()
{
while(1);
}
void
_kill()
{
while(1);
}
pid_t
_getpid(void)
{
return 1;
}
const unsigned long
bkpt_instr = 0xe1200070;

View file

@ -0,0 +1,34 @@
#include "rtimer-arch-interrupt.h"
#include "rtimer-arch.h"
#include <interrupt-utils.h>
#include <AT91SAM7S64.h>
#define DEBUG 1
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
/* Here we have a proper stack frame and can use local variables */
static void rtimer_int_safe() __attribute((noinline));
static void
rtimer_int_safe()
{
unsigned int status;
status = RTIMER_ARCH_TIMER_BASE->TC_SR;
if (status & AT91C_TC_CPAS) {
rtimer_run_next();
}
*AT91C_AIC_EOICR = 0;
}
void NACKEDFUNC
rtimer_interrupt (void) {
ISR_STORE();
ISR_ENABLE_NEST();
rtimer_int_safe();
ISR_DISABLE_NEST();
ISR_RESTORE();
}

View file

@ -0,0 +1,6 @@
#ifndef __RTIMER_ARCH_INTERRUPT_H__P0PXG70757__
#define __RTIMER_ARCH_INTERRUPT_H__P0PXG70757__
void rtimer_interrupt (void);
#endif /* __RTIMER_ARCH_INTERRUPT_H__P0PXG70757__ */

View file

@ -0,0 +1,49 @@
#include "rtimer-arch.h"
#include <AT91SAM7S64.h>
#include "rtimer-arch-interrupt.h"
#define DEBUG 1
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
static rtimer_clock_t offset;
void
rtimer_arch_init(void)
{
offset = 0;
RTIMER_ARCH_TIMER_BASE->TC_CMR =
(AT91C_TC_WAVE | AT91C_TC_WAVESEL_UP | AT91C_TC_CLKS_TIMER_DIV5_CLOCK);
RTIMER_ARCH_TIMER_BASE->TC_RA = 0xffff;
RTIMER_ARCH_TIMER_BASE->TC_IER = AT91C_TC_CPAS;
*AT91C_PMC_PCER = (1 << RTIMER_ARCH_TIMER_ID);
AT91C_AIC_SMR[RTIMER_ARCH_TIMER_ID] =
AT91C_AIC_SRCTYPE_INT_POSITIVE_EDGE | 6;
AT91C_AIC_SVR[RTIMER_ARCH_TIMER_ID] = (unsigned long)rtimer_interrupt;
*AT91C_AIC_IECR = (1 << RTIMER_ARCH_TIMER_ID);
RTIMER_ARCH_TIMER_BASE->TC_CCR = AT91C_TC_SWTRG | AT91C_TC_CLKEN;
PRINTF("rtimer_arch_init: Done\n");
}
void
rtimer_arch_schedule(rtimer_clock_t t)
{
RTIMER_ARCH_TIMER_BASE->TC_RA = t + offset;
PRINTF("rtimer_arch_schedule: %d\n",t);
}
void
rtimer_arch_set(rtimer_clock_t t)
{
offset = t - RTIMER_ARCH_TIMER_BASE->TC_CV;
}
rtimer_clock_t
rtimer_arch_now(void)
{
return RTIMER_ARCH_TIMER_BASE->TC_CV + offset;
}

View file

@ -0,0 +1,21 @@
/**
* \file
* Header file for the AT91SAM7S-specific rtimer code
* \author
* Simon Berg <ksb@users.sourceforge.net>
*/
#ifndef __RTIMER_ARCH_H__
#define __RTIMER_ARCH_H__
#include "sys/rtimer.h"
#define RTIMER_ARCH_TIMER_ID AT91C_ID_TC1
#define RTIMER_ARCH_TIMER_BASE AT91C_BASE_TC1
#define RTIMER_ARCH_SECOND (MCK/1024)
void rtimer_arch_set(rtimer_clock_t t);
#endif /* __RTIMER_ARCH_H__ */

View file

@ -71,7 +71,7 @@
*/
.equ Top_Stack, 0x00204000
.equ UND_Stack_Size, 0x00000004
.equ SVC_Stack_Size, 0x00000400
.equ SVC_Stack_Size, 0x00000200
.equ ABT_Stack_Size, 0x00000004
.equ FIQ_Stack_Size, 0x00000004
.equ IRQ_Stack_Size, 0x00000400
@ -207,6 +207,11 @@ UND_Stack_End:
.equ RSTC_MR_Val, 0xa5000001 /* Enable user reset */
/* Advanced interrupt controller */
.equ AIC_SETUP, 1
.equ AIC_BASE, 0xfffff000
.equ AIC_EOICR, 0x130
.equ AIC_SPU, 0x134
#if (defined(VECTORS_IN_RAM) && defined(ROM_RUN)) || defined(USE_SAMBA)
@ -299,7 +304,16 @@ DAbt_Handler: B DAbt_Handler
IRQ_Handler: B IRQ_Handler
FIQ_Handler: B FIQ_Handler
#endif
#endif
// Spurious interrupt handler
SPU_Handler:
STMDB SP!, {R0}
LDR R0, =AIC_BASE
STR R0, [R0, #AIC_EOICR]
LDMIA SP!, {R0}
SUBS PC, LR, #4
// Starupt Code must be linked first at Address at which it expects to run.
@ -395,7 +409,7 @@ PLL_Loop: LDR R2, [R0, #PMC_SR]
LDR SP, =SVC_Stack_End
// Enter User Mode and set its Stack Pointer
#ifndef RUN_AS_SYSTEM
#ifdef RUN_AS_SYSTEM
MSR CPSR_c, #Mode_SYS
#else
MSR CPSR_c, #Mode_USR
@ -453,6 +467,11 @@ LoopVectCopy: CMP R2, R3
BLO LoopVectCopy
#endif
.if AIC_SETUP
LDR R1, =AIC_BASE
LDR R0, = SPU_Handler
STR R0, [R1, #AIC_SPU]
.endif
/*
Call C++ constructors (for objects in "global scope")