diff --git a/ports/arm7a/Makefile b/ports/arm7a/Makefile index ade2dce..a066851 100644 --- a/ports/arm7a/Makefile +++ b/ports/arm7a/Makefile @@ -1,24 +1,32 @@ -############ -# Settings # -############ +########################################## +# Toplevel makefile for all ARM7a boards # +########################################## -# Build all test applications: -# make -# -# Program a test application using UISP (appname => test app e.g. sems1): -# make program app=appname +# Build directory +ifdef O + build_dir=$(shell readlink -f $(O)) +else + build_dir=$(CURDIR)/build +endif -# Location of build tools and atomthreads sources -kernel_dir=../../kernel -tests_dir=../../tests - -# Directory for built objects -build_dir=build +# Source directory +src_dir=$(CURDIR) +# Configuration CPU=cortex-a8 BOARD=pb-a8 CC=$(CROSS_COMPILE)gcc OBJCOPY=$(CROSS_COMPILE)objcopy +# Enable stack-checking. WARNING: the full automated test suite currently +# requires a little over 1KB RAM with stack-checking enabled. If you are +# using a device with 1KB internal SRAM and no external SRAM then you +# must disable stack-checking to run all of the automated tests. +#STACK_CHECK=true + +# Location of atomthreads sources +board_dir=$(src_dir)/$(BOARD) +kernel_dir=$(src_dir)/../../kernel +tests_dir=$(src_dir)/../../tests # Check if verbosity is ON for build process VERBOSE_DEFAULT := 0 @@ -38,45 +46,36 @@ else V := $(CMD_PREFIX_DEFAULT) endif -# Enable stack-checking. WARNING: the full automated test suite currently -# requires a little over 1KB RAM with stack-checking enabled. If you are -# using a device with 1KB internal SRAM and no external SRAM then you -# must disable stack-checking to run all of the automated tests. -#STACK_CHECK=true +# object files +objs = arm_irq.o +objs += arm_main.o +objs += atomport.o +objs += arm_entry.o +objs += atomport-asm.o -# Port/application object files -APP_OBJECTS = arm_irq.o -APP_OBJECTS += arm_gic.o -APP_OBJECTS += arm_timer.o -APP_OBJECTS += arm_uart.o -APP_OBJECTS += arm_main.o -APP_OBJECTS += atomport.o -APP_OBJECTS += printk.o -APP_OBJECTS += string.o -APP_OBJECTS += vsprintf.o -APP_ASM_OBJECTS = arm_entry.o -APP_ASM_OBJECTS += atomport-asm.o +# include board makefile for board specific objects +-include $(board_dir)/Makefile + +# library object files +objs += printk.o +objs += string.o +objs += vsprintf.o # Kernel object files -KERNEL_OBJECTS = atomkernel.o -KERNEL_OBJECTS += atomsem.o -KERNEL_OBJECTS += atommutex.o -KERNEL_OBJECTS += atomtimer.o -KERNEL_OBJECTS += atomqueue.o +objs += atomkernel.o +objs += atomsem.o +objs += atommutex.o +objs += atomtimer.o +objs += atomqueue.o # Collection of built objects (excluding test applications) -ALL_OBJECTS = $(APP_ASM_OBJECTS) $(APP_OBJECTS) $(KERNEL_OBJECTS) -BUILT_OBJECTS = $(patsubst %,$(build_dir)/%,$(ALL_OBJECTS)) - -# Test object files (dealt with separately as only one per application build) -TEST_OBJECTS = $(notdir $(patsubst %.c,%.o,$(wildcard $(tests_dir)/*.c))) +build_objs = $(foreach obj,$(objs),$(build_dir)/$(obj)) # Target application filenames .elf for each test object -TEST_ELFS = $(patsubst %.o,%.elf,$(TEST_OBJECTS)) - -# Search build/output directory for dependencies -#vpath %.o ./$(build_dir) -#vpath %.elf ./$(build_dir) +tobjs = $(notdir $(patsubst %.c,%.o,$(wildcard $(tests_dir)/*.c))) +telfs = $(patsubst %.o,%.elf,$(tobjs)) +build_tobjs = $(foreach tobj,$(tobjs),$(build_dir)/$(tobj)) +build_telfs = $(foreach telf,$(telfs),$(build_dir)/$(telf)) # GCC flags CFLAGS= -g \ @@ -86,63 +85,54 @@ CFLAGS= -g \ -nostdinc \ -nostdlib \ -nodefaultlibs \ - -fno-builtin + -fno-builtin \ + -I$(src_dir) \ + -I$(board_dir) \ + -I$(kernel_dir) \ + -I$(tests_dir) # Enable stack-checking (disable if not required) ifeq ($(STACK_CHECK),true) CFLAGS += -DATOM_STACK_CHECKING endif -################# -# Build targets # -################# +# All +.PHONY: all +all: $(build_telfs) $(build_tobjs) $(build_objs) Makefile -# All tests -all: $(TEST_ELFS) Makefile - -# Test ELF files (one application build for each test) -$(TEST_ELFS): %.elf: %.o $(APP_ASM_OBJECTS) $(KERNEL_OBJECTS) $(APP_OBJECTS) - $(V)mkdir -p `dirname $(build_dir)/$@` - $(if $(V), @echo " (ELF) $(subst $(build_dir)/,,$@)") - $(V)$(CC) $(CFLAGS) $(build_dir)/$(notdir $<) $(BUILT_OBJECTS) -static-libgcc -lgcc --output $(build_dir)/$@ -Wl -T linker.ld - -# Kernel objects builder -$(KERNEL_OBJECTS): %.o: $(kernel_dir)/%.c - $(V)mkdir -p `dirname $(build_dir)/$(notdir $@)` - $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") - $(V)$(CC) -c $(CFLAGS) -I. -I$(kernel_dir) $< -o $(build_dir)/$(notdir $@) - -# Test objects builder -$(TEST_OBJECTS): %.o: $(tests_dir)/%.c - $(V)mkdir -p `dirname $(build_dir)/$(notdir $@)` - $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") - $(V)$(CC) -c $(CFLAGS) -I. -I$(kernel_dir) $< -o $(build_dir)/$(notdir $@) - -# Application C objects builder -$(APP_OBJECTS): %.o: ./%.c - $(V)mkdir -p `dirname $(build_dir)/$(notdir $@)` - $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") - $(V)$(CC) -c $(CFLAGS) -I. -I$(kernel_dir) -I$(tests_dir) $< -o $(build_dir)/$(notdir $@) - -# Application asm objects builder -$(APP_ASM_OBJECTS): %.o: ./%.s - $(V)mkdir -p `dirname $(build_dir)/$(notdir $@)` - $(if $(V), @echo " (AS) $(subst $(build_dir)/,,$@)") - $(V)$(CC) -c $(CFLAGS) -D__ASSEMBLY__ -x assembler-with-cpp -I. -I$(kernel_dir) $< -o $(build_dir)/$(notdir $@) - -# .lst file builder -%.lst: %.c +$(build_dir)/%.elf: $(build_dir)/%.o $(build_objs) $(V)mkdir -p `dirname $@` - $(if $(V), @echo " (LST) $(subst $(build_dir)/,,$@)") - $(V)$(CC) $(CFLAGS) -I. -I$(kernel_dir) -I$(tests_dir) -Wa,-al $< > $@ + $(if $(V), @echo " (ELF) $(subst $(build_dir)/,,$@)") + $(V)$(CC) $(CFLAGS) $(build_objs) $< -static-libgcc -lgcc -Wl -T linker.ld -o $@ + +$(build_dir)/%.o: $(src_dir)/%.S + $(V)mkdir -p `dirname $@` + $(if $(V), @echo " (AS) $(subst $(build_dir)/,,$@)") + $(V)$(CC) $(CFLAGS) -D__ASSEMBLY__ -I`dirname $<` -c $< -o $@ + +$(build_dir)/%.o: $(src_dir)/%.c + $(V)mkdir -p `dirname $@` + $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") + $(V)$(CC) $(CFLAGS) $(CFLAGS) -I`dirname $<` -c $< -o $@ + +$(build_dir)/%.o: $(kernel_dir)/%.c + $(V)mkdir -p `dirname $@` + $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") + $(V)$(CC) $(CFLAGS) $(CFLAGS) -I`dirname $<` -c $< -o $@ + +$(build_dir)/%.o: $(tests_dir)/%.c + $(V)mkdir -p `dirname $@` + $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") + $(V)$(CC) $(CFLAGS) $(CFLAGS) -I`dirname $<` -c $< -o $@ # Clean +.PHONY: clean clean: - $(V)rm -f *.o *.elf *.map *.bin *.lst rm -rf doxygen-kernel rm -rf doxygen-avr rm -rf $(build_dir) - +# Docs +.PHONY: doxygen doxygen: doxygen $(kernel_dir)/Doxyfile doxygen ./Doxyfile diff --git a/ports/arm7a/arm_entry.s b/ports/arm7a/arm_entry.S similarity index 100% rename from ports/arm7a/arm_entry.s rename to ports/arm7a/arm_entry.S diff --git a/ports/arm7a/arm_irq.c b/ports/arm7a/arm_irq.c index 1aec38c..cc9290d 100644 --- a/ports/arm7a/arm_irq.c +++ b/ports/arm7a/arm_irq.c @@ -29,7 +29,7 @@ #include #include -#include +#include #include arm_irq_handler_t irq_hndls[NR_IRQS_PBA8]; @@ -82,7 +82,7 @@ void do_not_used(pt_regs_t *regs) void do_irq(pt_regs_t *uregs) { int rc = 0; - int irq = arm_gic_active_irq(0); + int irq = arm_pic_active_irq(); /* Call the interrupt entry routine */ atomIntEnter(); @@ -94,7 +94,7 @@ void do_irq(pt_regs_t *uregs) while (1); } } - rc = arm_gic_ack_irq(0, irq); + rc = arm_pic_ack_irq(irq); if (rc) { while (1); } @@ -113,7 +113,7 @@ void do_fiq(pt_regs_t *uregs) atomIntExit(TRUE); } -void arm_irq_setup(void) +void arm_irq_init(void) { extern uint32_t _start_vect[]; uint32_t *vectors = (uint32_t *)NULL; @@ -150,12 +150,7 @@ void arm_irq_setup(void) /* * Initialize Generic Interrupt Controller */ - vec = arm_gic_dist_init(0, REALVIEW_PBA8_GIC_DIST_BASE, - IRQ_PBA8_GIC_START); - if (vec) { - while(1); - } - vec = arm_gic_cpu_init(0, REALVIEW_PBA8_GIC_CPU_BASE); + vec = arm_pic_init(); if (vec) { while(1); } @@ -167,7 +162,7 @@ void arm_irq_register(uint32_t irq, arm_irq_handler_t hndl) if (irq < NR_IRQS_PBA8) { irq_hndls[irq] = hndl; if (irq_hndls[irq]) { - rc = arm_gic_unmask(0, irq); + rc = arm_pic_unmask(irq); if (rc) { while (1); } diff --git a/ports/arm7a/arm_irq.h b/ports/arm7a/arm_irq.h index 89f963f..3defb6d 100644 --- a/ports/arm7a/arm_irq.h +++ b/ports/arm7a/arm_irq.h @@ -47,7 +47,7 @@ typedef int (*arm_irq_handler_t) (uint32_t irq_no, pt_regs_t * regs); #define ARM_EXTERNAL_IRQ 6 #define ARM_EXTERNAL_FIQ 7 -void arm_irq_setup(void); +void arm_irq_init(void); void arm_irq_register(uint32_t irq_no, arm_irq_handler_t hndl); void arm_irq_enable(void); void arm_irq_disable(void); diff --git a/ports/arm7a/arm_main.c b/ports/arm7a/arm_main.c index ec42025..b0242ff 100644 --- a/ports/arm7a/arm_main.c +++ b/ports/arm7a/arm_main.c @@ -169,9 +169,9 @@ int main ( void ) IDLE_STACK_SIZE_BYTES, 0); if (status == ATOM_OK) { - arm_irq_setup(); + arm_irq_init(); - arm_timer_init((1000000 / SYSTEM_TICKS_PER_SEC), 1); + arm_timer_init(SYSTEM_TICKS_PER_SEC); arm_uart_init(); diff --git a/ports/arm7a/atomport-asm.s b/ports/arm7a/atomport-asm.S similarity index 93% rename from ports/arm7a/atomport-asm.s rename to ports/arm7a/atomport-asm.S index 667dea9..9208fc4 100644 --- a/ports/arm7a/atomport-asm.s +++ b/ports/arm7a/atomport-asm.S @@ -1,5 +1,6 @@ /* - * Copyright (c) 2010, Atomthreads Project. All rights reserved. + * Copyright (c) 2011, Anup Patel for Atomthreads Project. + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,14 +32,6 @@ .section .text -/** - * uint32_t archGetCPSR(void) - */ - .globl archGetCPSR -archGetCPSR: - mrs r0, cpsr_all - bx lr - /** * int archSetJump(pt_regs_t *regs) */ diff --git a/ports/arm7a/atomport.c b/ports/arm7a/atomport.c index 08bb591..de52b49 100644 --- a/ports/arm7a/atomport.c +++ b/ports/arm7a/atomport.c @@ -70,7 +70,6 @@ void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, extern int archSetJump(pt_regs_t *regs, uint32_t *tmp); extern void archLongJump(pt_regs_t *regs); -extern uint32_t archGetCPSR(void); /** * archFirstThreadRestore(ATOM_TCB *new_tcb) diff --git a/ports/arm7a/atomport.h b/ports/arm7a/atomport.h index debf68a..487df12 100644 --- a/ports/arm7a/atomport.h +++ b/ports/arm7a/atomport.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2011, Anup Patel. All rights reserved. + * Copyright (c) 2011, Anup Patel for Atomthreads Project. + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,7 +32,7 @@ #define __ATOM_PORT_H /* Required number of system ticks per second (normally 100 for 10ms tick) */ -#define SYSTEM_TICKS_PER_SEC 100 +#define SYSTEM_TICKS_PER_SEC 1000 typedef signed int int32_t; typedef signed short int16_t; diff --git a/ports/arm7a/pb-a8/Makefile b/ports/arm7a/pb-a8/Makefile new file mode 100644 index 0000000..f44b66c --- /dev/null +++ b/ports/arm7a/pb-a8/Makefile @@ -0,0 +1,9 @@ +########################## +# Board specific objects # +########################## + +# board object files +objs += pb-a8/arm_pic.o +objs += pb-a8/arm_timer.o +objs += pb-a8/arm_uart.o + diff --git a/ports/arm7a/arm_config.h b/ports/arm7a/pb-a8/arm_config.h similarity index 100% rename from ports/arm7a/arm_config.h rename to ports/arm7a/pb-a8/arm_config.h diff --git a/ports/arm7a/arm_gic.c b/ports/arm7a/pb-a8/arm_pic.c similarity index 90% rename from ports/arm7a/arm_gic.c rename to ports/arm7a/pb-a8/arm_pic.c index 773d869..d17ef1b 100644 --- a/ports/arm7a/arm_gic.c +++ b/ports/arm7a/pb-a8/arm_pic.c @@ -29,7 +29,7 @@ #include #include -#include +#include #define max(a,b) ((a) < (b) ? (b) : (a)) @@ -206,3 +206,42 @@ int arm_gic_cpu_init(uint32_t gic_nr, virtual_addr_t base) return 0; } + +int arm_pic_active_irq(void) +{ + return arm_gic_active_irq(0); +} + +int arm_pic_ack_irq(uint32_t irq) +{ + return arm_gic_ack_irq(0, irq); +} + +int arm_pic_mask(uint32_t irq) +{ + return arm_gic_mask(0, irq); +} + +int arm_pic_unmask(uint32_t irq) +{ + return arm_gic_unmask(0, irq); +} + +int arm_pic_init(void) +{ + int rc = 0; + + rc = arm_gic_dist_init(0, REALVIEW_PBA8_GIC_DIST_BASE, + IRQ_PBA8_GIC_START); + if (rc) { + return rc; + } + rc = arm_gic_cpu_init(0, REALVIEW_PBA8_GIC_CPU_BASE); + if (rc) { + while(1); + } + + return rc; +} + + diff --git a/ports/arm7a/arm_gic.h b/ports/arm7a/pb-a8/arm_pic.h similarity index 87% rename from ports/arm7a/arm_gic.h rename to ports/arm7a/pb-a8/arm_pic.h index cca8c77..d3485f0 100644 --- a/ports/arm7a/arm_gic.h +++ b/ports/arm7a/pb-a8/arm_pic.h @@ -52,11 +52,10 @@ #define GIC_DIST_CONFIG 0xc00 #define GIC_DIST_SOFTINT 0xf00 -int arm_gic_active_irq(uint32_t gic_nr); -int arm_gic_ack_irq(uint32_t gic_nr, uint32_t irq); -int arm_gic_mask(uint32_t gic_nr, uint32_t irq); -int arm_gic_unmask(uint32_t gic_nr, uint32_t irq); -int arm_gic_dist_init(uint32_t gic_nr, virtual_addr_t base, uint32_t irq_start); -int arm_gic_cpu_init(uint32_t gic_nr, virtual_addr_t base); +int arm_pic_active_irq(void); +int arm_pic_ack_irq(uint32_t irq); +int arm_pic_mask(uint32_t irq); +int arm_pic_unmask(uint32_t irq); +int arm_pic_init(void); #endif diff --git a/ports/arm7a/arm_plat.h b/ports/arm7a/pb-a8/arm_plat.h similarity index 100% rename from ports/arm7a/arm_plat.h rename to ports/arm7a/pb-a8/arm_plat.h diff --git a/ports/arm7a/arm_timer.c b/ports/arm7a/pb-a8/arm_timer.c similarity index 92% rename from ports/arm7a/arm_timer.c rename to ports/arm7a/pb-a8/arm_timer.c index ed5b359..e3f753f 100644 --- a/ports/arm7a/arm_timer.c +++ b/ports/arm7a/pb-a8/arm_timer.c @@ -70,16 +70,15 @@ int arm_timer_irqhndl(uint32_t irq_no, pt_regs_t * regs) return 0; } -int arm_timer_init(uint32_t usecs, uint32_t ensel) +int arm_timer_init(uint32_t ticks_per_sec) { uint32_t val; /* * set clock frequency: - * REALVIEW_REFCLK is 32KHz * REALVIEW_TIMCLK is 1MHz */ - val = arm_readl((void *)REALVIEW_SCTL_BASE) | (REALVIEW_TIMCLK << ensel); + val = arm_readl((void *)REALVIEW_SCTL_BASE) | (REALVIEW_TIMCLK << 0x1); arm_writel(val, (void *)REALVIEW_SCTL_BASE); /* Register interrupt handler */ @@ -89,8 +88,10 @@ int arm_timer_init(uint32_t usecs, uint32_t ensel) val &= ~TIMER_CTRL_ENABLE; val |= (TIMER_CTRL_32BIT | TIMER_CTRL_PERIODIC | TIMER_CTRL_IE); arm_writel(val, (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_CTRL)); - arm_writel(usecs, (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_LOAD)); - arm_writel(usecs, (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_VALUE)); + arm_writel((1000000 / ticks_per_sec), + (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_LOAD)); + arm_writel((1000000 / ticks_per_sec), + (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_VALUE)); return 0; } diff --git a/ports/arm7a/arm_timer.h b/ports/arm7a/pb-a8/arm_timer.h similarity index 97% rename from ports/arm7a/arm_timer.h rename to ports/arm7a/pb-a8/arm_timer.h index 45bf35c..23c921c 100644 --- a/ports/arm7a/arm_timer.h +++ b/ports/arm7a/pb-a8/arm_timer.h @@ -51,6 +51,6 @@ void arm_timer_enable(void); void arm_timer_disable(void); void arm_timer_clearirq(void); -int arm_timer_init(uint32_t usecs, uint32_t ensel); +int arm_timer_init(uint32_t ticks_per_sec); #endif /* __ARM_TIMER_H */ diff --git a/ports/arm7a/arm_uart.c b/ports/arm7a/pb-a8/arm_uart.c similarity index 100% rename from ports/arm7a/arm_uart.c rename to ports/arm7a/pb-a8/arm_uart.c diff --git a/ports/arm7a/arm_uart.h b/ports/arm7a/pb-a8/arm_uart.h similarity index 100% rename from ports/arm7a/arm_uart.h rename to ports/arm7a/pb-a8/arm_uart.h diff --git a/tests/kern3.c b/tests/kern3.c index a149d72..d54312f 100644 --- a/tests/kern3.c +++ b/tests/kern3.c @@ -45,9 +45,9 @@ static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE]; static volatile int running_flag[2]; static volatile int sleep_request[2]; - /* Forward declarations */ static void test_thread_func (uint32_t param); +static int test_iter = 0; /** @@ -93,23 +93,29 @@ uint32_t test_start (void) running_flag[0] = running_flag[1] = FALSE; sleep_request[0] = sleep_request[1] = FALSE; - /* Create low priority thread */ - if (atomThreadCreate (&tcb[0], 253, test_thread_func, 0, - &test_thread_stack[0][0], - TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) - { - ATOMLOG (_STR("Bad thread create\n")); - failures++; + /* Create threads in first iteration only */ + if (test_iter == 0) { + /* Create low priority thread */ + if (atomThreadCreate (&tcb[0], 253, test_thread_func, 0, + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) + { + ATOMLOG (_STR("Bad thread create\n")); + failures++; + } + + /* Create high priority thread */ + else if (atomThreadCreate (&tcb[1], 252, test_thread_func, 1, + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) + { + ATOMLOG (_STR("Bad thread create\n")); + failures++; + } } - /* Create high priority thread */ - else if (atomThreadCreate (&tcb[1], 252, test_thread_func, 1, - &test_thread_stack[1][0], - TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) - { - ATOMLOG (_STR("Bad thread create\n")); - failures++; - } + /* Increment test iteration count */ + test_iter++; /* Repeat test a few times */ for (i = 0; i < 8; i++) diff --git a/tests/kern4.c b/tests/kern4.c index 23ed33b..253b05a 100644 --- a/tests/kern4.c +++ b/tests/kern4.c @@ -51,7 +51,7 @@ static int volatile test_started; /* Forward declarations */ static void test_thread_func (uint32_t param); - +static int test_iter = 0; /** * \b test_start @@ -89,42 +89,48 @@ uint32_t test_start (void) /* Set test as not started until all threads are ready to go */ test_started = FALSE; - /* - * Create all four threads at the same priority as each other. - * They are given a lower priority than this thread, however, - * to ensure that once this thread wakes up to stop the test it - * can do so without confusing the scheduling tests by having - * a spell in which this thread was run. - */ - if (atomThreadCreate (&tcb[0], TEST_THREAD_PRIO + 1, test_thread_func, 0, - &test_thread_stack[0][0], - TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) - { - ATOMLOG (_STR("Bad thread create\n")); - failures++; - } - else if (atomThreadCreate (&tcb[1], TEST_THREAD_PRIO + 1, test_thread_func, 1, - &test_thread_stack[1][0], - TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) - { - ATOMLOG (_STR("Bad thread create\n")); - failures++; - } - else if (atomThreadCreate (&tcb[2], TEST_THREAD_PRIO + 1, test_thread_func, 2, - &test_thread_stack[2][0], - TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) - { - ATOMLOG (_STR("Bad thread create\n")); - failures++; - } - else if (atomThreadCreate (&tcb[3], TEST_THREAD_PRIO + 1, test_thread_func, 3, - &test_thread_stack[3][0], - TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) - { - ATOMLOG (_STR("Bad thread create\n")); - failures++; + /* Create threads in first iteration only */ + if (test_iter == 0) { + /* + * Create all four threads at the same priority as each other. + * They are given a lower priority than this thread, however, + * to ensure that once this thread wakes up to stop the test it + * can do so without confusing the scheduling tests by having + * a spell in which this thread was run. + */ + if (atomThreadCreate (&tcb[0], TEST_THREAD_PRIO + 1, test_thread_func, 0, + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) + { + ATOMLOG (_STR("Bad thread create\n")); + failures++; + } + else if (atomThreadCreate (&tcb[1], TEST_THREAD_PRIO + 1, test_thread_func, 1, + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) + { + ATOMLOG (_STR("Bad thread create\n")); + failures++; + } + else if (atomThreadCreate (&tcb[2], TEST_THREAD_PRIO + 1, test_thread_func, 2, + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) + { + ATOMLOG (_STR("Bad thread create\n")); + failures++; + } + else if (atomThreadCreate (&tcb[3], TEST_THREAD_PRIO + 1, test_thread_func, 3, + &test_thread_stack[3][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) + { + ATOMLOG (_STR("Bad thread create\n")); + failures++; + } } + /* Increment test iteration count */ + test_iter++; + /* Start the test */ test_started = TRUE;