/** Default baud rate (set to 0 to disable) */
#define CONFIG_SER_DEFBAUDRATE 0
- /** Enable ser_gets() and ser_gets_echo() */
- #define CONFIG_SER_GETS 0
-
/** Enable second serial port in emulator. */
#define CONFIG_EMUL_UART1 0
/// Enable smooth scrolling in menus
#define CONFIG_MENU_SMOOTH 1
+/** Enable kfile_gets() and kfile_gets_echo() */
+#define CONFIG_KFILE_GETS 0
+
+/// Disable tests.
+#define CONFIG_TEST 0
+
+
#endif /* APPCONFIG_COMMON_H */
#include <io/arm.h>
Timer leds_timer;
+KFileSerial ser_fd;
static void leds_toggle(void)
{
proc_init();
ASSERT(!IRQ_ENABLED());
-
-
/* Open the main communication port */
- Serial *host_port = ser_open(0);
- ser_setbaudrate(host_port, 115200);
- ser_setparity(host_port, SER_PARITY_NONE);
+ ser_init(&ser_fd, 0);
+ ser_setbaudrate(&ser_fd, 115200);
+ ser_setparity(&ser_fd, SER_PARITY_NONE);
IRQ_ENABLE;
for(;;)
{
proc_test();
- ser_printf(host_port, "From serial 0: %s\r\n", msg);
+ kfile_printf(&ser_fd.fd, "From serial 0: %s\r\n", msg);
}
return 0;
}
#
#
-
# Set to 1 for debug builds
at91sam7s_DEBUG = 1
mware/event.c \
mware/formatwr.c \
mware/hex.c \
+ kern/kfile.c \
kern/proc.c \
kern/proc_test.c \
kern/monitor.c \
- kern/signal.c \
+ kern/signal.c
at91sam7s_CPPASRC = \
- cpu/arm/hw/crtat91sam7s256_rom.S \
+ cpu/arm/hw/crtat91sam7_rom.S \
kern/switch_arm.S
+at91sam7s_CROSS = arm-elf-
+
at91sam7s_CPPAFLAGS = -O0 -g -gdwarf-2 -g -gen-debug
at91sam7s_CPPFLAGS = -O0 -D'ARCH=0' -D__ARM_AT91SAM7S256__ -g3 -gdwarf-2 -fverbose-asm -Iapp/at91sam7s/hw -Iapp/at91sam7s -Icpu/arm
-at91sam7s_LDFLAGS = -nostartfiles -T cpu/arm/scripts/at91sam7s256_ram.ld -Wl,--no-warn-mismatch
+at91sam7s_LDFLAGS = -nostartfiles -T cpu/arm/scripts/at91sam7_256_ram.ld -Wl,--no-warn-mismatch
at91sam7s_CPU = arm7tdmi
#
# define some variables based on the AVR base path in $(AVR)
#
-CROSS = avr-
-CC = $(CROSS)gcc
-CXX = $(CROSS)g++
+#CROSS = avr-
+CC = gcc
+CXX = g++
AS = $(CC) -x assembler-with-cpp
LD = $(CC)
-OBJCOPY = $(CROSS)objcopy
-STRIP = $(CROSS)strip
+OBJCOPY = objcopy
+STRIP = strip
INSTALL = cp -a
RM = rm -f
RM_R = rm -rf
* usage.
*/
#define CONFIG_PROC_DEFSTACKSIZE \
- (CPU_SAVED_REGS_CNT * 2 * sizeof(cpu_stack_t) \
+ (CPU_SAVED_REGS_CNT * 2 * sizeof(cpustack_t) \
+ 32 * sizeof(int))
#endif
/* Memory fill codes to help debugging */
#if CONFIG_KERN_MONITOR
- #define CONFIG_KERN_STACKFILLCODE 0xA5A5
- #define CONFIG_KERN_MEMFILLCODE 0xDBDB
+ #include <cpu/types.h>
+ #if (SIZEOF_CPUSTACK_T == 1)
+ /* 8bit cpustack_t */
+ #define CONFIG_KERN_STACKFILLCODE 0xA5
+ #define CONFIG_KERN_MEMFILLCODE 0xDB
+ #elif (SIZEOF_CPUSTACK_T == 2)
+ /* 16bit cpustack_t */
+ #define CONFIG_KERN_STACKFILLCODE 0xA5A5
+ #define CONFIG_KERN_MEMFILLCODE 0xDBDB
+ #elif (SIZEOF_CPUSTACK_T == 4)
+ /* 16bit cpustack_t */
+ #define CONFIG_KERN_STACKFILLCODE 0xA5A5A5A5UL
+ #define CONFIG_KERN_MEMFILLCODE 0xDBDBDBDBUL
+ #else
+ #error No cpustack_t size supported!
+ #endif
#endif
/**
* Serial IRQ dispatcher for USART0.
*/
-static void uart0_irq_dispatcher(void) __attribute__ ((naked));
+static void uart0_irq_dispatcher(void) __attribute__ ((interrupt));
static void uart0_irq_dispatcher(void)
{
- IRQ_ENTRY();
-
if (US0_CSR & BV(US_RXRDY))
uart0_irq_rx();
if (US0_CSR & BV(US_TXRDY))
uart0_irq_tx();
- IRQ_EXIT();
+ /* Inform hw that we have served the IRQ */
+ AIC_EOICR = 0;
}
/**
/**
* Serial IRQ dispatcher for USART1.
*/
-static void uart1_irq_dispatcher(void) __attribute__ ((naked));
+static void uart1_irq_dispatcher(void) __attribute__ ((interrupt));
static void uart1_irq_dispatcher(void)
{
- IRQ_ENTRY();
-
if (US1_CSR & BV(US_RXRDY))
uart1_irq_rx();
if (US1_CSR & BV(US_TXRDY))
uart1_irq_tx();
- IRQ_EXIT();
+ /* Inform hw that we have served the IRQ */
+ AIC_EOICR = 0;
}
* various sources (system timer, etc..) and calls
* the corresponding handler.
*/
-static void sysirq_dispatcher(void) __attribute__ ((naked));
+static void sysirq_dispatcher(void) __attribute__ ((interrupt));
static void sysirq_dispatcher(void)
{
- IRQ_ENTRY();
for (unsigned i = 0; i < countof(sysirq_tab); i++)
{
if (sysirq_tab[i].enabled
sysirq_tab[i].handler();
}
- IRQ_EXIT();
+ /* Inform hw that we have served the IRQ */
+ AIC_EOICR = 0;
}
#define SYSIRQ_PRIORITY 0 ///< default priority for system irqs.
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2008 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Kernel scheduler macros.
+ *
+ * \version $Id$
+ *
+ * \author Francesco Sacchi <batt@develer.com>
+ * \author Stefano Fedrigo <aleph@develer.com>
+ */
+
+#ifndef CPU_ARM_HW_SWITCH_H
+#define CPU_ARM_HW_SWITCH_H
+
+#include <kern/proc_p.h>
+
+/**
+ * Interrupt entry point.
+ * Needed because AT91 uses an Interrupt Controller with auto-vectoring.
+ */
+#define SCHEDULER_IRQ_ENTRY \
+ asm volatile("sub lr, lr, #4 \n\t" /* Adjust LR */ \
+ "stmfd sp!, {r0} \n\t" /* Save r0 */ \
+ "stmfd sp, {sp}^ \n\t" /* Save user SP */ \
+ "sub sp, sp, #4 \n\t" /* Decrement irq SP, writeback is illegal */ \
+ "ldmfd sp!, {r0} \n\t" /* Restore user SP immedately in r0 */ \
+ "stmfd r0!, {lr} \n\t" /* Store system LR in user stack */ \
+ "stmfd r0, {r1-r12,lr}^ \n\t" /* Store registers on user stack (user LR too) */ \
+ "sub r0, r0, #52 \n\t" /* Decrement r0, writeback is illegal */ \
+ "ldmfd sp!, {r1} \n\t" /* Restore r0 */ \
+ "stmfd r0!, {r1} \n\t" /* Store r0 in user stack too */ \
+ "mrs r1, spsr \n\t" /* Save SPSR... */ \
+ "stmfd r0!, {r1} \n\t" /* ... in user stack */ \
+ "ldr r1, =CurrentProcess \n\t" /* Load in r1 &CurrentProcess->stack */ \
+ "ldr r1, [r1, %0] \n\t" \
+ "str r0, [r1] \n\t" /* Store the process SP */ \
+ "sub fp, sp, #4 \n\t" /* Store the process SP */ \
+ : /* no output */ \
+ : "n" (offsetof(Process, stack)) \
+ )
+
+
+#define SCHEDULER_IRQ_EXIT \
+ asm volatile("ldr lr, =CurrentProcess \n\t" /* Load &CurrentProcess->stack */ \
+ "ldr lr, [lr, %0] \n\t" \
+ "ldr lr, [lr] \n\t" /* Load current process SP */ \
+ "ldr r0, =0xFFFFF000 \n\t" /* End of interrupt for AT91 */ \
+ "str r0, [r0, #0x130] \n\t" /* */ \
+ "ldmfd lr!, {r0} \n\t" /* Pop status reg */ \
+ "msr spsr, r0 \n\t" /* ... */ \
+ "ldmfd lr, {r0-r12,lr}^ \n\t" /* Restore user regs */ \
+ "add lr, lr, #56 \n\t" /* 52 + irq link register (extracted below) */ \
+ "stmfd sp!, {lr} \n\t" /* Push user stack pointer in irq stack */ \
+ "ldmfd sp, {sp}^ \n\t" /* Restore user SP */ \
+ "sub sp, sp, #4 \n\t" /* Align irq SP */ \
+ "ldmdb lr, {pc}^ \n\t" /* And return to user space (We use ldmdb cause lr is sp+4) */ \
+ : /* no output */ \
+ : "n" (offsetof(Process, stack)) \
+ )
+
+#endif /* CPU_ARM_HW_SWITCH_H */
#define CPU_SAVED_REGS_CNT 9
#define CPU_STACK_GROWS_UPWARD 0
#define CPU_SP_ON_EMPTY_SLOT 0
- #define CPU_BYTE_ORDER (__BIG_ENDIAN__ ? CPU_BIG_ENDIAN : CPU_LITTLE_ENDIAN)
+ #warning Find a way to detect endianess at runtime
+ #define CPU_BYTE_ORDER CPU_LITTLE_ENDIAN
#define CPU_HARVARD 0
#ifdef __IAR_SYSTEMS_ICC__
#define IRQ_ENABLED() ((CPU_READ_FLAGS() & 0xc0) != 0xc0)
- /**
- * Interrupt entry point.
- * Needed because AT91 uses an Interrupt Controller with auto-vectoring.
- */
- #define IRQ_ENTRY() \
- asm volatile("sub lr, lr, #4" "\n\t" /* Adjust LR */ \
- "stmfd sp!, {r0-r12,lr}" "\n\t" /* Save registers on IRQ stack. */ \
- "mrs r1, spsr" "\n\t" /* Save SPSR */ \
- "stmfd sp!, {r1}" "\n\t") /* */
-
- /**
- * Interrupt exit.
- * Needed because AT91 uses an Interrupt Controller with auto-vectoring.
- */
- #define IRQ_EXIT() \
- asm volatile("ldmfd sp!, {r1}" "\n\t" /* Restore SPSR */ \
- "msr spsr_c, r1" "\n\t" /* */ \
- "ldr r0, =0xFFFFF000" "\n\t" /* End of interrupt. */ \
- "str r0, [r0, #0x130]" "\n\t" /* */ \
- "ldmfd sp!, {r0-r12, pc}^" "\n\t") /* Restore registers and return. */
-
#endif /* !__IAR_SYSTEMS_ICC_ */
#elif CPU_PPC
#define IRQ_ENABLE FIXME
#define IRQ_SAVE_DISABLE(x) FIXME
#define IRQ_RESTORE(x) FIXME
- #define IRQ_ENABLED() FIXME
+ #define IRQ_ENABLED() FIXME
#elif CPU_DSP56K
#if CONFIG_KERNEL
#include <config_kern.h>
+ #include <hw/switch.h>
#if CONFIG_KERN_SIGNALS
#include <kern/signal.h> /* sig_wait(), sig_check() */
#include <kern/proc.h> /* proc_current() */
*/
DEFINE_TIMER_ISR
{
+ SCHEDULER_IRQ_ENTRY;
+
/*
* With the Metrowerks compiler, the only way to force the compiler generate
* an interrupt service routine is to put a pragma directive within the function
* to ensure that IRQ is generated by timer source.
*/
if (!timer_hw_triggered())
- return;
+ SCHEDULER_IRQ_EXIT;
TIMER_STROBE_ON;
#endif /* CONFIG_TIMER_DISABLE_EVENTS */
TIMER_STROBE_OFF;
+
+ SCHEDULER_IRQ_EXIT;
}
MOD_DEFINE(timer)
p = MONITOR_NODE_TO_PROCESS(p->monitor.link.succ))
{
size_t free = monitor_checkStack(p->monitor.stack_base, p->monitor.stack_size);
- kprintf("%-24s%-8p%-8p%-8u%-8u\n",
+ kprintf("%-24s%-8p%-8p%-8lu%-8lu\n",
p->monitor.name, p, p->monitor.stack_base, p->monitor.stack_size, free);
}
}
$(1)_LDFLAGS += -Wl,-T$$($(1)_LDSCRIPT)
endif
+$(1)_CC = $$($(1)_CROSS)$$(CC)
+$(1)_CXX = $$($(1)_CROSS)$$(CXX)
+$(1)_AS = $$($(1)_CROSS)$$(AS)
+$(1)_OBJCOPY = $$($(1)_CROSS)$$(OBJCOPY)
+
$(1)_COBJ = $$(foreach file,$$($(1)_CSRC:%.c=%.o),$$(OBJDIR)/$(1)/$$(file))
$(1)_CXXOBJ = $$(foreach file,$$($(1)_CXXSRC:%.cpp=%.o),$$(OBJDIR)/$(1)/$$(file))
$(1)_PCOBJ = $$(foreach file,$$($(1)_PCSRC:%.c=%_P.o),$$(OBJDIR)/$(1)/$$(file))
$(1)_SRC := $$($(1)_CSRC) $$($(1)_CXXSRC) $$($(1)_PCSRC) $$($(1)_ASRC) $$($(1)_CPPASRC)
OBJ += $$($(1)_OBJ)
+ifneq ($$(strip $$($(1)_CXXSRC)),)
+$(1)_LD = $$($(1)_CROSS)$$(LDXX)
+else
+$(1)_LD = $$($(1)_CROSS)$$(LD)
+endif
+
# Compile: instructions to create assembler and/or object files from C source
$$($(1)_COBJ) : $$(OBJDIR)/$(1)/%.o : %.c
$L "$(1): Compiling $$< (C)"
@$$(MKDIR_P) $$(dir $$@)
- $Q $$(CC) -c $$(CFLAGS) $$($(1)_CFLAGS) $$($(1)_CPPFLAGS) $$(CPPFLAGS) $$< -o $$@
+ $Q $$($(1)_CC) -c $$(CFLAGS) $$($(1)_CFLAGS) $$($(1)_CPPFLAGS) $$(CPPFLAGS) $$< -o $$@
# Compile: instructions to create assembler and/or object files from C++ source
$$($(1)_CXXOBJ) : $$(OBJDIR)/$(1)/%.o : %.cpp
$L "$(1): Compiling $$< (C++)"
@$$(MKDIR_P) $$(dir $$@)
- $Q $$(CXX) -c $$(CXXFLAGS) $$($(1)_CXXFLAGS) $$($(1)_CPPFLAGS) $$(CPPFLAGS) $$< -o $$@
+ $Q $$($(1)_CXX) -c $$(CXXFLAGS) $$($(1)_CXXFLAGS) $$($(1)_CPPFLAGS) $$(CPPFLAGS) $$< -o $$@
# Generate assembly sources from C files (debug)
$$(OBJDIR)/$(1)/%.s : %.c
$L "$(1): Generating asm source $$<"
@$$(MKDIR_P) $$(dir $$@)
- $Q $$(CC) -S $$(CFLAGS) $$($(1)_CFLAGS) $$($(1)_CPPFLAGS) $$< -o $$@
+ $Q $$($(1)_CC) -S $$(CFLAGS) $$($(1)_CFLAGS) $$($(1)_CPPFLAGS) $$< -o $$@
# Generate special progmem variant of a source file
$$($(1)_PCOBJ) : $$(OBJDIR)/$(1)/%_P.o : %.c
$L "$(1): Compiling $$< (PROGMEM)"
@$$(MKDIR_P) $$(dir $$@)
- $Q $$(CC) -c -D_PROGMEM $$(CFLAGS) $$($(1)_CFLAGS) $$($(1)_CPPFLAGS) $$(CPPFLAGS) $$< -o $$@
+ $Q $$($(1)_CC) -c -D_PROGMEM $$(CFLAGS) $$($(1)_CFLAGS) $$($(1)_CPPFLAGS) $$(CPPFLAGS) $$< -o $$@
# Assemble: instructions to create object file from assembler files
$$($(1)_AOBJ): $$(OBJDIR)/$(1)/%.o : %.s
$L "$(1): Assembling $$<"
@$$(MKDIR_P) $$(dir $$@)
- $Q $$(AS) -c $$(ASFLAGS) $$($(1)_ASFLAGS) $$< -o $$@
+ $Q $$($(1)_AS) -c $$(ASFLAGS) $$($(1)_ASFLAGS) $$< -o $$@
$$($(1)_CPPAOBJ): $$(OBJDIR)/$(1)/%.o : %.S
$L "$(1): Assembling with CPP $$<"
@$$(MKDIR_P) $$(dir $$@)
- $Q $$(CC) -c $$(CPPAFLAGS) $$($(1)_CPPAFLAGS) $$($(1)_CPPFLAGS) $$(CPPFLAGS) $$< -o $$@
+ $Q $$($(1)_CC) -c $$(CPPAFLAGS) $$($(1)_CPPAFLAGS) $$($(1)_CPPFLAGS) $$(CPPFLAGS) $$< -o $$@
# Link: instructions to create elf output file from object files
$$(OUTDIR)/$(1).elf $$(OUTDIR)/$(1)_nostrip: bumprev $$($(1)_OBJ) $$($(1)_LDSCRIPT)
$L "$(1): Linking $$@"
@$$(MKDIR_P) $$(dir $$@)
- $Q $$(LD) $$($(1)_OBJ) $$(LIB) $$(LDFLAGS) $$($(1)_LDFLAGS) -o $$@
+ $Q $$($(1)_LD) $$($(1)_OBJ) $$(LIB) $$(LDFLAGS) $$($(1)_LDFLAGS) -o $$@
# Strip debug info
$$(OUTDIR)/$(1): $$(OUTDIR)/$(1)_nostrip
$L "$(1): Generating stripped executable $$@"
- $Q $$(STRIP) -o $$@ $$^
+ $Q $$($(1)_STRIP) -o $$@ $$^
# Compile and link (program-at-a-time)
$$(OUTDIR)/$(1)_whole.elf: bumprev $$($(1)_SRC) $$($(1)_LDSCRIPT)
$L "$(1): Compiling and Linking whole program $$@"
@$$(MKDIR_P) $$(dir $$@)
- $Q $$(CC) $$($(1)_SRC) $$(CFLAGS) $$($(1)_CFLAGS) $$(LIB) $$(LDFLAGS) $$($(1)_LDFLAGS) -o $$@
+ $Q $$($(1)_CC) $$($(1)_SRC) $$(CFLAGS) $$($(1)_CFLAGS) $$(LIB) $$(LDFLAGS) $$($(1)_LDFLAGS) -o $$@
# Flash target
# NOTE: we retry in case of failure because the STK500 programmer is crappy
$(AVRDUDE) $(DPROG) -p $$($(1)_MCU) -U lock:w:$$($(1)_lock):m ; \
fi \
fi
+
+$$(OUTDIR)/$(1).hex: $$(OUTDIR)/$(1).elf
+ $$($(1)_OBJCOPY) -O ihex $$< $$@
+
+$$(OUTDIR)/$(1).s19: $$(OUTDIR)/$(1).elf
+ $$($(1)_OBJCOPY) -O srec $$< $$@
+
+$$(OUTDIR)/$(1).bin: $$(OUTDIR)/$(1).elf
+ $$($(1)_OBJCOPY) -O binary $$< $$@
+
+$$(OUTDIR)/$(1).obj: $$(OUTDIR)/$(1).elf
+ $$($(1)_OBJCOPY) -O avrobj $$< $$@
+
+$$(OUTDIR)/$(1).rom: $$(OUTDIR)/$(1).elf
+ $$($(1)_OBJCOPY) -O $$(FORMAT) $$< $$@
+# $$($(1)_OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" -O $$(FORMAT) $$< $$(@:.rom=.eep)
+
endef
# Generate build rules for all targets
exit 1; \
fi
-%.hex: %.elf
- $(OBJCOPY) -O ihex $< $@
-
-%.s19: %.elf
- $(OBJCOPY) -O srec $< $@
-
-%.bin: %.elf
- $(OBJCOPY) -O binary $< $@
-
-%.obj: %.elf
- $(OBJCOPY) -O avrobj $< $@
-
-%.rom: %.elf
- $(OBJCOPY) -O $(FORMAT) $< $@
-# $(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" -O $(FORMAT) $< $(@:.rom=.eep)
%.cof: %.elf
$(COFFCONVERT) -O coff-ext-avr $< $@