diff --git a/ports/arm/platforms/qemu_integratorcp/Makefile b/ports/arm/platforms/qemu_integratorcp/Makefile index 86c13ba..dd76588 100644 --- a/ports/arm/platforms/qemu_integratorcp/Makefile +++ b/ports/arm/platforms/qemu_integratorcp/Makefile @@ -22,11 +22,11 @@ OBJCOPY=arm-none-eabi-objcopy BUILD_DIR=build # Platform-specific object files -PLATFORM_OBJECTS = main.o modules.o syscalls.o +PLATFORM_OBJECTS = modules.o syscalls.o PLATFORM_ASM_OBJECTS = startup.o # Port-specific object files -PORT_OBJECTS = atomport.o +PORT_OBJECTS = atomport.o tests-main.o PORT_ASM_OBJECTS = atomport-asm.o # Kernel object files diff --git a/ports/arm/platforms/qemu_integratorcp/main.c b/ports/arm/platforms/qemu_integratorcp/main.c deleted file mode 100644 index 3699c38..0000000 --- a/ports/arm/platforms/qemu_integratorcp/main.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2012, Natie van Rooyen. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. No personal names or organizations' names associated with the - * Atomthreads project may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#include -#include "modules.h" -#include "atom.h" -#include "atomtests.h" - - -#define TEST_STACK_BYTE_SIZE 1024 -#define IDLE_STACK_BYTE_SIZE 512 - -static unsigned char test_stack[TEST_STACK_BYTE_SIZE] ; -static unsigned char idle_stack[IDLE_STACK_BYTE_SIZE] ; -ATOM_TCB test_tcb ; - - -/** - * \b test_thread - * - * Function calling the test function of the Atomthreads test suite. - * - */ -void -test_thread (uint32_t param) -{ - uint32_t failures ; - - failures = test_start () ; - printf ("%s\r\n", failures ? "FAIL" : "PASS") ; - - return; -} - -/** - * \b main - * - * Initialize atomthreads and start a test_thread to run the Atomthreads test suite. - * - */ -int -main (void) -{ - printf ("atomthreads starting... ") ; - - atomOSInit(&idle_stack[0], IDLE_STACK_BYTE_SIZE, TRUE) ; - atomThreadCreate ((ATOM_TCB *)&test_tcb, TEST_THREAD_PRIO, test_thread, 0, &test_stack[0], TEST_STACK_BYTE_SIZE, TRUE); - atomOSStart() ; - - return 0 ; -} diff --git a/ports/arm/tests-main.c b/ports/arm/tests-main.c new file mode 100644 index 0000000..f79bb10 --- /dev/null +++ b/ports/arm/tests-main.c @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2013, Kelvin Lawson. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#include "atom.h" +#include "atomport-private.h" +#include "atomtests.h" +#include "atomtimer.h" + + +/* Constants */ + +/* + * Idle thread stack size + * + * This needs to be large enough to handle any interrupt handlers + * and callbacks called by interrupt handlers (e.g. user-created + * timer callbacks) as well as the saving of all context when + * switching away from this thread. + */ +#define IDLE_STACK_SIZE_BYTES 512 + + +/* + * Main thread stack size + * + * Note that this is not a required OS kernel thread - you will replace + * this with your own application thread. + * + * In this case the Main thread is responsible for calling out to the + * test routines. Once a test routine has finished, the test status is + * printed out on the UART and the thread remains running in a loop. + * + * The Main thread stack generally needs to be larger than the idle + * thread stack, as not only does it need to store interrupt handler + * stack saves and context switch saves, but the application main thread + * will generally be carrying out more nested function calls and require + * stack for application code local variables etc. + */ +#define MAIN_STACK_SIZE_BYTES 1024 + + +/* Local data */ + +/* Application threads' TCBs */ +static ATOM_TCB main_tcb; + +/* Main thread's stack area */ +static uint8_t main_thread_stack[MAIN_STACK_SIZE_BYTES]; + +/* Idle thread's stack area */ +static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES]; + + +/* Forward declarations */ +static void main_thread_func (uint32_t data); + + +/** + * \b main + * + * Program entry point. + * + * Creates an application thread and starts the OS. + */ + +int main ( void ) +{ + int8_t status; + + /** + * Note: to protect OS structures and data during initialisation, + * interrupts must remain disabled until the first thread + * has been restored. They are reenabled at the very end of + * the first thread restore, at which point it is safe for a + * reschedule to take place. + */ + + /** + * Initialise the OS before creating our threads. + */ + status = atomOSInit(&idle_thread_stack[0], IDLE_STACK_SIZE_BYTES, TRUE); + if (status == ATOM_OK) + { + /* Create an application thread */ + status = atomThreadCreate(&main_tcb, + TEST_THREAD_PRIO, main_thread_func, 0, + &main_thread_stack[0], + MAIN_STACK_SIZE_BYTES, + TRUE); + if (status == ATOM_OK) + { + /** + * First application thread successfully created. It is + * now possible to start the OS. Execution will not return + * from atomOSStart(), which will restore the context of + * our application thread and start executing it. + * + * Note that interrupts are still disabled at this point. + * They will be enabled as we restore and execute our first + * thread in archFirstThreadRestore(). + */ + atomOSStart(); + } + } + + while (1) + ; + + /* There was an error starting the OS if we reach here */ + return (0); +} + + +/** + * \b main_thread_func + * + * Entry point for main application thread. + * + * This is the first thread that will be executed when the OS is started. + * + * @param[in] data Unused (optional thread entry parameter) + * + * @return None + */ +static void main_thread_func (uint32_t data) +{ + uint32_t test_status; + + /* Put a message out on the UART */ + printf ("Go\n"); + + /* Start test. All tests use the same start API. */ + test_status = test_start(); + + /* Check main thread stack usage (if enabled) */ +#ifdef ATOM_STACK_CHECKING + if (test_status == 0) + { + uint32_t used_bytes, free_bytes; + + /* Check idle thread stack usage */ + if (atomThreadStackCheck (&main_tcb, &used_bytes, &free_bytes) == ATOM_OK) + { + /* Check the thread did not use up to the end of stack */ + if (free_bytes == 0) + { + printf ("Main stack overflow\n"); + test_status++; + } + + /* Log the stack usage */ +#ifdef TESTS_LOG_STACK_USAGE + printf ("MainUse:%d\n", used_bytes); +#endif + } + + } +#endif + + /* Log final status */ + if (test_status == 0) + { + printf ("Pass\n"); + } + else + { + printf ("Fail(%d)\n", (int)test_status); + } + +}