mirror of
https://github.com/kelvinlawson/atomthreads.git
synced 2026-01-11 18:33:16 +01:00
Add stack usage analysis. Used for all automated test modules (if enabled) such that the automated tests can now trap some classes of thread stack overflow. ATmega port now tested on both ATMega16 and ATmega32. STM8 port not yet modified to support the new stack-checking API.
This commit is contained in:
@@ -60,6 +60,12 @@ typedef struct atom_tcb
|
||||
uint8_t suspend_wake_status; /* Status returned to woken suspend calls */
|
||||
ATOM_TIMER *suspend_timo_cb; /* Callback registered for suspension timeouts */
|
||||
|
||||
/* Details used if thread stack-checking is required */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
POINTER stack_top; /* Pointer to top of stack allocation */
|
||||
uint32_t stack_size; /* Size of stack allocation in bytes */
|
||||
#endif
|
||||
|
||||
} ATOM_TCB;
|
||||
|
||||
|
||||
@@ -92,7 +98,7 @@ extern uint8_t atomOSStarted;
|
||||
|
||||
|
||||
/* Function prototypes */
|
||||
extern uint8_t atomOSInit (void *idle_thread_stack_top);
|
||||
extern uint8_t atomOSInit (void *idle_thread_stack_top, uint32_t stack_size);
|
||||
extern void atomOSStart (void);
|
||||
|
||||
extern void atomSched (uint8_t timer_tick);
|
||||
@@ -107,7 +113,8 @@ extern ATOM_TCB *tcbDequeuePriority (ATOM_TCB **tcb_queue_ptr, uint8_t priority)
|
||||
|
||||
extern ATOM_TCB *atomCurrentContext (void);
|
||||
|
||||
extern uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_point)(uint32_t), uint32_t entry_param, void *stack_top);
|
||||
extern uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_point)(uint32_t), uint32_t entry_param, void *stack_top, uint32_t stack_size);
|
||||
extern uint8_t atomThreadStackCheck (ATOM_TCB *tcb_ptr, uint32_t *used_bytes, uint32_t *free_bytes);
|
||||
|
||||
extern void archContextSwitch (ATOM_TCB *old_tcb_ptr, ATOM_TCB *new_tcb_ptr);
|
||||
extern void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, void (*entry_point)(uint32_t), uint32_t entry_param);
|
||||
|
||||
@@ -187,6 +187,12 @@ static ATOM_TCB idle_tcb;
|
||||
static int atomIntCnt = 0;
|
||||
|
||||
|
||||
/* Constants */
|
||||
|
||||
/** Bytecode to fill thread stacks with for stack-checking purposes */
|
||||
#define STACK_CHECK_BYTE 0x5A
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
static void atomThreadSwitch(ATOM_TCB *old_tcb, ATOM_TCB *new_tcb);
|
||||
static void atomIdleThread (uint32_t data);
|
||||
@@ -363,22 +369,27 @@ static void atomThreadSwitch(ATOM_TCB *old_tcb, ATOM_TCB *new_tcb)
|
||||
* scheduler. If the priority is higher than the current priority, then the
|
||||
* new thread may be scheduled in before the function returns.
|
||||
*
|
||||
* Optionally prefills the thread stack with a known value to enable stack
|
||||
* usage checking (if the ATOM_STACK_CHECKING macro is defined).
|
||||
*
|
||||
* @param[in] tcb_ptr Pointer to the thread's TCB storage
|
||||
* @param[in] priority Priority of the thread (0 to 255)
|
||||
* @param[in] entry_point Thread entry point
|
||||
* @param[in] entry_param Parameter passed to thread entry point
|
||||
* @param[in] stack_top Top of the stack area
|
||||
* @param[in] stack_size Size of the stack area in bytes
|
||||
*
|
||||
* @retval ATOM_OK Success
|
||||
* @retval ATOM_ERR_PARAM Bad parameters
|
||||
* @retval ATOM_ERR_QUEUE Error putting the thread on the ready queue
|
||||
*/
|
||||
uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_point)(uint32_t), uint32_t entry_param, void *stack_top)
|
||||
uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_point)(uint32_t), uint32_t entry_param, void *stack_top, uint32_t stack_size)
|
||||
{
|
||||
CRITICAL_STORE;
|
||||
uint8_t status;
|
||||
|
||||
if ((tcb_ptr == NULL) || (entry_point == NULL) || (stack_top == NULL))
|
||||
if ((tcb_ptr == NULL) || (entry_point == NULL) || (stack_top == NULL)
|
||||
|| (stack_size == 0))
|
||||
{
|
||||
/* Bad parameters */
|
||||
status = ATOM_ERR_PARAM;
|
||||
@@ -401,6 +412,34 @@ uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_poin
|
||||
tcb_ptr->entry_point = entry_point;
|
||||
tcb_ptr->entry_param = entry_param;
|
||||
|
||||
/**
|
||||
* Additional processing only required if stack-checking is
|
||||
* enabled. Incurs a slight overhead on each thread creation
|
||||
* and uses some additional storage in the TCB, but can be
|
||||
* compiled out if not desired.
|
||||
*/
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
|
||||
/* Store the stack details for use by the stack-check function */
|
||||
tcb_ptr->stack_top = stack_top;
|
||||
tcb_ptr->stack_size = stack_size;
|
||||
|
||||
/**
|
||||
* Prefill the stack with a known value. This is used later in
|
||||
* calls to atomThreadStackCheck() to get an indication of how
|
||||
* much stack has been used during runtime.
|
||||
*/
|
||||
while (stack_size > 0)
|
||||
{
|
||||
/* Initialise all stack bytes from bottom up to 0x5A */
|
||||
*((uint8_t *)stack_top - (stack_size - 1)) = STACK_CHECK_BYTE;
|
||||
stack_size--;
|
||||
}
|
||||
#else
|
||||
/* Avoid compiler warnings due to unused stack_size variable */
|
||||
stack_size = stack_size;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Call the arch-specific routine to set up the stack. This routine
|
||||
* is responsible for creating the context save area necessary for
|
||||
@@ -445,6 +484,82 @@ uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_poin
|
||||
}
|
||||
|
||||
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
/**
|
||||
* \b atomThreadStackCheck
|
||||
*
|
||||
* Check the stack usage of a thread.
|
||||
*
|
||||
* If the ATOM_STACK_CHECKING macro is defined, thread stacks are filled
|
||||
* with a known value before the thread is started. This function can be
|
||||
* called at runtime to examine the stack and find the high water mark
|
||||
* (the furthest modified byte from the start of the stack).
|
||||
*
|
||||
* This gives an indication of how much stack the thread has used. It is
|
||||
* useful but not absolutely precise because the thread may legitimately
|
||||
* have the known value on its stack. The thread's stack pointer may also
|
||||
* have strayed outside of the allowable stack area while leaving some of
|
||||
* the known-value bytes unmodified. This simple method cannot trap stack
|
||||
* usage outside of the thread's allocated stack, for which you could use
|
||||
* additional guard areas (still limited in scope) or compiler/CPU/MMU
|
||||
* features.
|
||||
*
|
||||
* The function takes a thread's TCB and returns both the number of stack
|
||||
* bytes used, and the free stack bytes.
|
||||
*
|
||||
* @param[in] tcb_ptr Pointer to the TCB of the thread to stack-check
|
||||
* @param[in,out] used_bytes Pointer into which the used byte count is copied
|
||||
* @param[in,out] free_bytes Pointer into which the free byte count is copied
|
||||
*
|
||||
* @retval ATOM_OK Success
|
||||
* @retval ATOM_ERR_PARAM Bad parameters
|
||||
* @retval ATOM_ERR_QUEUE Error putting the thread on the ready queue
|
||||
*/
|
||||
uint8_t atomThreadStackCheck (ATOM_TCB *tcb_ptr, uint32_t *used_bytes, uint32_t *free_bytes)
|
||||
{
|
||||
uint8_t status;
|
||||
uint8_t *stack_ptr;
|
||||
int i;
|
||||
|
||||
if ((tcb_ptr == NULL) || (used_bytes == NULL) || (free_bytes == NULL))
|
||||
{
|
||||
/* Bad parameters */
|
||||
status = ATOM_ERR_PARAM;
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* Starting at the far end, count the unmodified areas until a
|
||||
* modified byte is found.
|
||||
*/
|
||||
stack_ptr = (uint8_t *)tcb_ptr->stack_top - (tcb_ptr->stack_size - 1);
|
||||
for (i = 0; i < tcb_ptr->stack_size; i++)
|
||||
{
|
||||
/* Loop until a modified byte is found */
|
||||
if (*stack_ptr++ != STACK_CHECK_BYTE)
|
||||
{
|
||||
/* Found a modified byte */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* We quit the loop above on the count of the free bytes */
|
||||
*free_bytes = (uint32_t)i;
|
||||
|
||||
/* Calculate used bytes using our knowledge of the stack size */
|
||||
*used_bytes = tcb_ptr->stack_size - *free_bytes;
|
||||
|
||||
/* No error */
|
||||
status = ATOM_OK;
|
||||
|
||||
}
|
||||
|
||||
return (status);
|
||||
|
||||
}
|
||||
#endif /* ATOM_STACK_CHECKING */
|
||||
|
||||
|
||||
/**
|
||||
* \b atomIntEnter
|
||||
*
|
||||
@@ -534,11 +649,12 @@ ATOM_TCB *atomCurrentContext (void)
|
||||
* enabled by the archFirstThreadRestore() routine in the architecture port.
|
||||
*
|
||||
* @param[in] idle_thread_stack_top Ptr to top of stack area for idle thread
|
||||
* @param[in] idle_thread_stack_size Size of idle thread stack in bytes
|
||||
*
|
||||
* @retval ATOM_OK Success
|
||||
* @retval ATOM_ERROR Initialisation error
|
||||
*/
|
||||
uint8_t atomOSInit (void *idle_thread_stack_top)
|
||||
uint8_t atomOSInit (void *idle_thread_stack_top, uint32_t idle_thread_stack_size)
|
||||
{
|
||||
uint8_t status;
|
||||
|
||||
@@ -552,7 +668,8 @@ uint8_t atomOSInit (void *idle_thread_stack_top)
|
||||
IDLE_THREAD_PRIORITY,
|
||||
atomIdleThread,
|
||||
0,
|
||||
idle_thread_stack_top);
|
||||
idle_thread_stack_top,
|
||||
idle_thread_stack_size);
|
||||
|
||||
/* Return status */
|
||||
return (status);
|
||||
|
||||
@@ -13,10 +13,21 @@ KERNEL_DIR=../../kernel
|
||||
TESTS_DIR=../../tests
|
||||
CC=/usr/bin/avr-gcc
|
||||
OBJCOPY=/usr/bin/avr-objcopy
|
||||
SIZE=/usr/bin/avr-size
|
||||
UISP=/usr/bin/uisp
|
||||
|
||||
# Modify this to the device name of the UART used for UISP
|
||||
UISP_DEV=/dev/ttyUSB0
|
||||
|
||||
# Modify this to the CPU you are using
|
||||
PART=atmega16
|
||||
|
||||
# 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
|
||||
|
||||
# Directory for built objects
|
||||
BUILD_DIR=build
|
||||
|
||||
@@ -46,6 +57,11 @@ vpath %.hex ./$(BUILD_DIR)
|
||||
# GCC flags
|
||||
CFLAGS=-g -mmcu=$(PART) -Wall -Werror
|
||||
|
||||
# Enable stack-checking (disable if not required)
|
||||
ifeq ($(STACK_CHECK),true)
|
||||
CFLAGS += -DATOM_STACK_CHECKING
|
||||
endif
|
||||
|
||||
|
||||
#################
|
||||
# Build targets #
|
||||
@@ -96,8 +112,9 @@ clean:
|
||||
|
||||
# Send to STK500
|
||||
program : $(BUILD_DIR)/$(app).hex
|
||||
$(SIZE) -C $(BUILD_DIR)/$(app).elf
|
||||
$(UISP) -dprog=stk500 -dserial=$(UISP_DEV) -dpart=$(PART) --erase --upload --verify if=$(BUILD_DIR)/$(app).hex
|
||||
|
||||
doxygen:
|
||||
doxygen $(KERNEL_DIR)/Doxyfile
|
||||
doxygen ./Doxyfile
|
||||
doxygen ./Doxyfile
|
||||
|
||||
131
ports/avr/README
131
ports/avr/README
@@ -39,11 +39,11 @@ functionality, and can be used with any architecture ports. This port
|
||||
provides an easy mechanism for building, downloading and running the test
|
||||
suite to prove the OS on your target.
|
||||
|
||||
The port was carried out and tested on an ATmega16 running within an
|
||||
STK500 board, utilising the gcc-avr tools. It is possible to use it with
|
||||
other processors in the ATmega range, as well as other hardware platforms
|
||||
and compilers, with minimal changes. Platform and compiler specific code
|
||||
has been kept to an absolute minimum.
|
||||
The port was carried out and tested on both an ATmega16 and ATmega32
|
||||
running within an STK500 board, utilising the gcc-avr tools. It is possible
|
||||
to use it with other processors in the ATmega range, as well as other
|
||||
hardware platforms and compilers, with minimal changes. Platform and
|
||||
compiler specific code has been kept to an absolute minimum.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
@@ -124,7 +124,11 @@ PD0/1 to "RS232 SPARE RXD/TXD" respectively using a two-wire link.
|
||||
RUNNING THE AUTOMATED TESTS
|
||||
|
||||
Atomthreads contains a set of generic kernel tests which can be run on any
|
||||
port to prove that all core functionality is working on your target.
|
||||
port to prove that all core functionality is working on your target. In
|
||||
order to accommodate a full testing regime, a large number of test threads
|
||||
are spawned which on ATmega platforms requires at least 1KB and possibly
|
||||
more RAM. Bear this in mind if you wish to run all of the automated tests
|
||||
on your target platform.
|
||||
|
||||
The full set of tests can be found in the top-level 'tests' folder. Each of
|
||||
these tests is built as an independent application in the 'build' folder.
|
||||
@@ -136,6 +140,10 @@ For example to run the 'kern1.c' test use:
|
||||
|
||||
* make program app=kern1
|
||||
|
||||
Before running the program and data size for the application is printed
|
||||
out on the terminal. You can use this to verify that your platform has
|
||||
enough program and data space to run the application.
|
||||
|
||||
To view the test results, connect a serial debug cable to your target
|
||||
platform. On starting, the test applications print out "Go" on the UART.
|
||||
Once the test is complete they will print out "Pass" or "Fail", along
|
||||
@@ -143,11 +151,23 @@ with other information if the test failed. Most of the tests complete
|
||||
within a few seconds, but some (particularly the stress tests) can take
|
||||
minutes, so be patient.
|
||||
|
||||
The test application also toggles a bit on PORTB once per second if the
|
||||
test was successful. On the STK500 this can be connected to the LEDs for
|
||||
a visual indication of a passed test without the UART. If you do not wish to
|
||||
use the UART you may use this to indicate passed tests, a UART is not
|
||||
a requirement for running the tests.
|
||||
Note that some tests utilise four test threads, which together with the
|
||||
idle thread and main test thread can consume significant RAM resource.
|
||||
Those tests which utilise four threads will generally only run on
|
||||
platforms with greater than 1KB RAM. They do currently run on a system
|
||||
with 1KB RAM but only with stack-checking disabled and this may change
|
||||
in future as the RAM usage changes. For platforms with only 1KB internal
|
||||
SRAM you should disable stack-checking by disabling STACK_CHECK in the
|
||||
Makefile, or ensuring that the ATOM_STACK_CHECKING macro is not defined.
|
||||
Platforms with only 512 bytes RAM will be unable to run many of the
|
||||
automated tests.
|
||||
|
||||
The test application also toggles a bit on PORTB to indicate test success
|
||||
or failure (once per second if the test was successful and once every
|
||||
1/8 second if the test failed). On the STK500 this can be connected to an
|
||||
LED for a visual indication of a passed test without the UART. If you do
|
||||
not wish to use the UART you may use the LED to indicate passed tests; a
|
||||
UART is not a requirement for running the tests.
|
||||
|
||||
The full suite of tests endeavours to exercise as much of the kernel code
|
||||
as possible, and can be used for quick confirmation of core OS
|
||||
@@ -206,9 +226,9 @@ up.
|
||||
|
||||
A good rule of thumb when using Atomthreads on the AVR architecture is that
|
||||
a minimum of 1KB RAM is required in order to support an application with 4
|
||||
or 5 threads and the idle thread. If approximately 128 bytes per thread
|
||||
stack is acceptable then you will benefit from the easy-to-read, portable
|
||||
implementation of an RTOS herein.
|
||||
or 5 threads and the idle thread. If a minimum of approximately 128 bytes
|
||||
per thread stack is acceptable then you will benefit from the easy-to-read,
|
||||
portable implementation of an RTOS herein.
|
||||
|
||||
The major consumer of RAM when using Atomthreads is your thread stacks.
|
||||
Functionality that is shared between several kernel modules is farmed out
|
||||
@@ -224,53 +244,56 @@ application code does, and what memory model is used etc, but generally
|
||||
you should find that 128 bytes is enough to allow for the thread to be
|
||||
switched out (and thus save its registers) while deep within a kernel
|
||||
or application call stack, and similarly enough to provide stack for
|
||||
interrupt handlers interrupting while the thread is deep within a
|
||||
kernel or application call stack. We have seen a little more than 128
|
||||
bytes being used, however, when the application code itself is made up
|
||||
of several subroutines.
|
||||
interrupt handlers interrupting while the thread is deep within a kernel
|
||||
or application call stack. You will need to increase this depending on
|
||||
what level of stack the application code in question requires.
|
||||
|
||||
At this time the maximum stack consumed by the test threads within the
|
||||
automated test modules is 124 bytes of stack, and the main test thread has
|
||||
been seen to consume 198 bytes of stack. At this time the queue9 test is
|
||||
the largest consumer of test thread stack (124 bytes) and the mutex2 and
|
||||
mutex5 tests consume the largest main thread stack (198 bytes). If your
|
||||
applications have large amounts of local data or call several subroutines
|
||||
then you may find that you need larger than 128 bytes.
|
||||
|
||||
You may monitor the stack usage of your application threads during runtime
|
||||
by defining the macro ATOM_STACK_CHECKING and calling
|
||||
atomThreadStackCheck(). This macro is defined by default in the Makefile
|
||||
so that the automated test modules can check for stack overflows, but you
|
||||
may wish to undefine this in your application Makefiles when you are happy
|
||||
that the stack usage is acceptable. Enabling ATOM_STACK_CHECKING will
|
||||
increase the size of your threads' TCBs slightly, and will incur a minor
|
||||
CPU cycles overhead whenever threads are created due to prefilling the
|
||||
thread stack with a known value.
|
||||
|
||||
With careful consideration and few threads it would be possible to use
|
||||
a platform with 512 bytes RAM, but not all of the automated test suite
|
||||
would run on such a platform (some of the test modules use 6 threads: a
|
||||
main thread together with 4 sub-threads and the idle thread).
|
||||
main thread together with 4 test threads and the idle thread).
|
||||
|
||||
The RAM layout used for the automated test applications is as follows:
|
||||
The default stack area used by GCC is at the top of RAM (RAMEND), so when
|
||||
your application's main() function is called the stack pointer is
|
||||
initialised to RAMEND. This initial stack is only required during startup
|
||||
for the main() function, and as soon as the OS is started the stack
|
||||
pointer switches to the stack areas for the application threads. Once the
|
||||
OS is started the initial startup stack is no longer used at all. You may
|
||||
continue to use the top of RAM for your startup stack, but in the test
|
||||
applications for this port we used another area of RAM. This is an
|
||||
optimisation to allow all of the automated tests to run on platforms with
|
||||
1KB RAM. The area reused is the idle thread's stack, which is not
|
||||
required until the OS is started. Ideally you should provide your own
|
||||
area for your applications, but this was an optimisation that allowed all
|
||||
of the automated tests to run on ATmega devices with 1KB RAM and did not
|
||||
require any AVR-specific changes to the automated test modules. This
|
||||
startup stack does not require a large amount of RAM, probably less than
|
||||
64 bytes.
|
||||
|
||||
RAM Top:
|
||||
* Startup Stack (64 bytes)
|
||||
* Main Thread Stack (Variable size)
|
||||
* Data & BSS area (thread stacks, other application data)
|
||||
RAM End.
|
||||
The application's data starts at the bottom of RAM, and this includes all
|
||||
of the thread stacks which are statically allocated arrays. The idle
|
||||
thread, main thread, and automated test thread stacks are allocated here.
|
||||
|
||||
This is not prescribed, you may use whichever layout you wish for your
|
||||
applications.
|
||||
|
||||
The startup stack area starts at the top of RAM and is only used for first
|
||||
initialisation of the OS and main thread. This uses 64 bytes and could be
|
||||
reused once the OS is started, but for the purposes of the automated test
|
||||
applications it is not reused. Generally you would ensure that this is
|
||||
reused in your own application code.
|
||||
|
||||
The application's data starts at the bottom of RAM, and this includes most
|
||||
of the thread stacks which are statically allocated arrays. The idle thread
|
||||
and automated test thread stacks are allocated here and are 128 bytes each.
|
||||
|
||||
The remaining area between the startup stack (RAMEND-64) and the end of the
|
||||
data/BSS areas is allocated to the main thread stack. As this thread
|
||||
typically requires the largest stack, this uses all of the remaining RAM
|
||||
between the top and bottom. In general for the automated tests this thread
|
||||
does most of the processing and requires more than 128 bytes (it has been
|
||||
seen to exceed 148 bytes). You can check that sufficient RAM is available
|
||||
for the main thread by running the avr-size command on the application ELF.
|
||||
This shows how much RAM is used by the data and BSS areas. If you have 1024
|
||||
bytes RAM, subtract the data and BSS size values from 1024, and subtract
|
||||
the amount used for the startup stack (64 bytes) to figure out the
|
||||
remaining space available for the main thread stack. Again, for your own
|
||||
applications you will probably be reusing the startup stack area, so can
|
||||
exclude that from your calculations.
|
||||
|
||||
As mentioned previously, this RAM layout is only the one utilised by the
|
||||
test applications. You may choose whatever layout you like.
|
||||
This RAM layout is only the one utilised by the test applications. You
|
||||
may choose whatever layout you like.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
@@ -50,6 +50,9 @@
|
||||
/* Default thread stack size (in bytes) */
|
||||
#define TEST_THREAD_STACK_SIZE 128
|
||||
|
||||
/* Uncomment to enable logging of stack usage to UART */
|
||||
/* #define TESTS_LOG_STACK_USAGE */
|
||||
|
||||
|
||||
#endif /* __ATOM_PORT_TESTS_H */
|
||||
|
||||
|
||||
@@ -56,4 +56,8 @@
|
||||
#define CRITICAL_END() SREG = sreg
|
||||
|
||||
|
||||
/* Uncomment to enable stack-checking */
|
||||
/* #define ATOM_STACK_CHECKING */
|
||||
|
||||
|
||||
#endif /* __ATOM_PORT_H */
|
||||
|
||||
@@ -55,43 +55,16 @@
|
||||
#define IDLE_STACK_SIZE_BYTES 128
|
||||
|
||||
|
||||
/*
|
||||
* Startup code stack size
|
||||
*
|
||||
* This defines the size of stack allowed for the main() startup
|
||||
* code before the OS is actually started. This needs to be large
|
||||
* enough to manage the atomOSInit(), atomOSStart() and
|
||||
* atomThreadCreate() calls which occur before the OS is started.
|
||||
*
|
||||
* In this case we use the default startup stack location used by
|
||||
* avr-gcc of the top of RAM (defined as RAMEND). After the OS
|
||||
* is started this allocation is no longer required, therefore
|
||||
* you could alternatively use some location which you know that
|
||||
* your application will not use until the OS is started. Note
|
||||
* that you cannot use the idle thread or main thread stack here
|
||||
* because the stack contexts of these threads are initialised
|
||||
* during OS creation.
|
||||
*
|
||||
* Instead of reusing some application area, here we set aside
|
||||
* 64 bytes of RAM for this purpose, because we call out to
|
||||
* several different test applications, and do not know of any
|
||||
* particular application locations which will be free to use.
|
||||
*/
|
||||
#define STARTUP_STACK_SIZE_BYTES 64
|
||||
|
||||
|
||||
/*
|
||||
* Main thread stack size
|
||||
*
|
||||
* Here we utilise the space starting at 64 bytes below the startup
|
||||
* stack for the Main application thread. Note that this is not a
|
||||
* required OS kernel thread - you will replace this with your own
|
||||
* application thread.
|
||||
* 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 thread remains
|
||||
* running and loops printing out an error message (if the test failed)
|
||||
* or flashes a LED once per second (if the test passed).
|
||||
* 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
|
||||
* flashing a LED.
|
||||
*
|
||||
* The Main thread stack generally needs to be larger than the idle
|
||||
* thread stack, as not only does it need to store interrupt handler
|
||||
@@ -100,13 +73,50 @@
|
||||
* stack for application code local variables etc.
|
||||
*
|
||||
* With all OS tests implemented to date on the AVR, the Main thread
|
||||
* stack has not exceeded 147 bytes. Care must be taken to ensure that
|
||||
* the data section, BSS section, and 64 byte startup section leave
|
||||
* enough free space for the main thread. You can use the avr-size
|
||||
* command to view the size of the BSS and data sections in your
|
||||
* application ELF files. For example if you require a 196 byte main
|
||||
* thread stack, then the data, BSS and startup stack combined must
|
||||
* not exceed RAMSIZE-196 bytes.
|
||||
* stack has not exceeded 198 bytes. To allow all tests to run we set
|
||||
* a minimum main thread stack size of 204 bytes. This may increase in
|
||||
* future as the codebase changes but for the time being is enough to
|
||||
* cope with all of the automated tests.
|
||||
*/
|
||||
#define MAIN_STACK_SIZE_BYTES 204
|
||||
|
||||
|
||||
/*
|
||||
* Startup code stack
|
||||
*
|
||||
* Some stack space is required at initial startup for running the main()
|
||||
* routine. This stack space is only temporarily required at first bootup
|
||||
* and is no longer required as soon as the OS is started. By default
|
||||
* GCC sets this to the top of RAM (RAMEND) and it grows down from there.
|
||||
* Because we only need this temporarily, though, it would be wasteful to
|
||||
* set aside a region at the top of RAM which is not used during runtime.
|
||||
*
|
||||
* What we do here is to reuse part of the idle thread's stack during
|
||||
* initial startup. As soon as we enter the main() routine we move the
|
||||
* stack pointer to half-way down the idle thread's stack. This is used
|
||||
* temporarily while calls are made to atomOSInit(), atomThreadCreate()
|
||||
* and atomOSStart(). Once the OS is started this stack area is no
|
||||
* longer required, and can be used for its original purpose (for the
|
||||
* idle thread's stack).
|
||||
*
|
||||
* This does mean, however, that we cannot monitor the stack usage of the
|
||||
* idle thread. Stack usage is monitored by prefilling the stack with a
|
||||
* known value, and we are obliterating some of that prefilled area by
|
||||
* using it as our startup stack, so we cannot use the stack-checking API
|
||||
* to get a true picture of idle thread stack usage. If you wish to
|
||||
* monitor idle thread stack usage for your applications then you are
|
||||
* free to use a different region for the startup stack (e.g. set aside
|
||||
* an area permanently, or place it somewhere you know you can reuse
|
||||
* later in the application). For the time being, this method gives us a
|
||||
* simple way of reducing the memory consumption without having to add
|
||||
* any special AVR-specific considerations to the automated test
|
||||
* applications.
|
||||
*
|
||||
* This optimisation was required to allow some of the larger automated
|
||||
* test modules to run on devices with 1KB of RAM. You should avoid doing
|
||||
* this if you can afford to set aside 64 bytes or so, or if you are
|
||||
* writing your own applications in which you have further control over
|
||||
* where data is located.
|
||||
*/
|
||||
|
||||
|
||||
@@ -115,6 +125,9 @@
|
||||
/* Application threads' TCBs */
|
||||
static ATOM_TCB main_tcb;
|
||||
|
||||
/* Idle 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];
|
||||
|
||||
@@ -134,10 +147,17 @@ static void main_thread_func (uint32_t data);
|
||||
* Sets up the AVR hardware resources (system tick timer interrupt) necessary
|
||||
* for the OS to be started. Creates an application thread and starts the OS.
|
||||
*/
|
||||
|
||||
int main ( void )
|
||||
{
|
||||
int8_t status;
|
||||
|
||||
/**
|
||||
* Reuse part of the idle thread's stack for the stack required
|
||||
* during this startup function.
|
||||
*/
|
||||
SP = (int)&idle_thread_stack[(IDLE_STACK_SIZE_BYTES/2) - 1];
|
||||
|
||||
/**
|
||||
* Note: to protect OS structures and data during initialisation,
|
||||
* interrupts must remain disabled until the first thread
|
||||
@@ -146,8 +166,20 @@ int main ( void )
|
||||
* reschedule to take place.
|
||||
*/
|
||||
|
||||
/* Initialise the OS before creating our threads */
|
||||
status = atomOSInit(&idle_thread_stack[IDLE_STACK_SIZE_BYTES - 1]);
|
||||
/**
|
||||
* Initialise the OS before creating our threads.
|
||||
*
|
||||
* Note that we tell the OS that the idle stack is half its actual
|
||||
* size. This prevents it prefilling the bottom half with known
|
||||
* values for stack-checkig purposes, which we cannot allow because
|
||||
* we are temporarily using it for our own stack. The remainder will
|
||||
* still be available once the OS is started, this only prevents the
|
||||
* OS from prefilling it.
|
||||
*
|
||||
* If you are not reusing the idle thread's stack during startup then
|
||||
* you should pass in the correct size here.
|
||||
*/
|
||||
status = atomOSInit(&idle_thread_stack[IDLE_STACK_SIZE_BYTES - 1], (IDLE_STACK_SIZE_BYTES/2));
|
||||
if (status == ATOM_OK)
|
||||
{
|
||||
/* Enable the system tick timer */
|
||||
@@ -156,7 +188,8 @@ int main ( void )
|
||||
/* Create an application thread */
|
||||
status = atomThreadCreate(&main_tcb,
|
||||
TEST_THREAD_PRIO, main_thread_func, 0,
|
||||
(POINTER)(RAMEND-STARTUP_STACK_SIZE_BYTES));
|
||||
&main_thread_stack[MAIN_STACK_SIZE_BYTES - 1],
|
||||
MAIN_STACK_SIZE_BYTES);
|
||||
if (status == ATOM_OK)
|
||||
{
|
||||
/**
|
||||
@@ -195,6 +228,7 @@ int main ( void )
|
||||
static void main_thread_func (uint32_t data)
|
||||
{
|
||||
uint32_t test_status;
|
||||
int sleep_ticks;
|
||||
|
||||
/* Enable all LEDs (STK500-specific) */
|
||||
DDRB = 0xFF;
|
||||
@@ -219,21 +253,52 @@ static void main_thread_func (uint32_t data)
|
||||
/* Start test. All tests use the same start API. */
|
||||
test_status = test_start();
|
||||
|
||||
/* Test finished, sleep forever */
|
||||
while (1)
|
||||
/* Check main thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
if (test_status == 0)
|
||||
{
|
||||
/* Log test status */
|
||||
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)
|
||||
{
|
||||
/* Toggle a LED (STK500-specific) */
|
||||
PORTB ^= (1 << 7);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf_P (PSTR("Fail%d\n"), atomTimeGet());
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
printf_P (PSTR("Main stack overflow\n"));
|
||||
test_status++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
printf_P (PSTR("MainUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Sleep for one second and log status again */
|
||||
atomTimerDelay(SYSTEM_TICKS_PER_SEC);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Log final status */
|
||||
if (test_status == 0)
|
||||
{
|
||||
printf_P (PSTR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf_P (PSTR("Fail(%d)\n"), test_status);
|
||||
}
|
||||
|
||||
/* Flash LED once per second if passed, very quickly if failed */
|
||||
sleep_ticks = (test_status == 0) ? SYSTEM_TICKS_PER_SEC : (SYSTEM_TICKS_PER_SEC/8);
|
||||
|
||||
/* Test finished, flash slowly for pass, fast for fail */
|
||||
while (1)
|
||||
{
|
||||
/* Toggle a LED (STK500-specific) */
|
||||
PORTB ^= (1 << 7);
|
||||
|
||||
/* Sleep then toggle LED again */
|
||||
atomTimerDelay(sleep_ticks);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,6 +15,9 @@ ASM=castm8
|
||||
LINK=clnk
|
||||
CHEX=chex
|
||||
|
||||
# Enable stack-checking
|
||||
STACK_CHECK=true
|
||||
|
||||
# Directory for built objects
|
||||
BUILD_DIR=build
|
||||
|
||||
@@ -50,6 +53,12 @@ DBG_CFLAGS=+modsl0 +debug -pxp -no -pp -l
|
||||
ASMFLAGS=
|
||||
DBG_ASMFLAGS=-xx -u
|
||||
|
||||
# Enable stack-checking (disable if not required)
|
||||
ifeq ($(STACK_CHECK),true)
|
||||
CFLAGS += -DATOM_STACK_CHECKING
|
||||
DBG_CFLAGS += -DATOM_STACK_CHECKING
|
||||
endif
|
||||
|
||||
|
||||
#################
|
||||
# Build targets #
|
||||
|
||||
@@ -45,6 +45,9 @@
|
||||
/* Default thread stack size (in bytes) */
|
||||
#define TEST_THREAD_STACK_SIZE 128
|
||||
|
||||
/* Uncomment to enable logging of stack usage to UART */
|
||||
/* #define TESTS_LOG_STACK_USAGE */
|
||||
|
||||
|
||||
#endif /* __ATOM_PORT_TESTS_H */
|
||||
|
||||
|
||||
@@ -56,4 +56,8 @@
|
||||
#define CRITICAL_END() _asm ("ld A,(X)\npush A\npop CC", &ccr)
|
||||
|
||||
|
||||
/* Uncomment to enable stack-checking */
|
||||
/* #define ATOM_STACK_CHECKING */
|
||||
|
||||
|
||||
#endif /* __ATOM_PORT_H */
|
||||
|
||||
@@ -142,7 +142,7 @@ void main ( void )
|
||||
*/
|
||||
|
||||
/* Initialise the OS before creating our threads */
|
||||
status = atomOSInit(&idle_thread_stack[IDLE_STACK_SIZE_BYTES - 1]);
|
||||
status = atomOSInit(&idle_thread_stack[IDLE_STACK_SIZE_BYTES - 1], IDLE_STACK_SIZE_BYTES);
|
||||
if (status == ATOM_OK)
|
||||
{
|
||||
/* Enable the system tick timer */
|
||||
@@ -195,6 +195,24 @@ static void main_thread_func (uint32_t data)
|
||||
/* 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)
|
||||
{
|
||||
test_status++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Flash LED once per second if passed, very quickly if failed */
|
||||
sleep_ticks = (test_status == 0) ? SYSTEM_TICKS_PER_SEC : (SYSTEM_TICKS_PER_SEC/8);
|
||||
|
||||
|
||||
@@ -64,7 +64,8 @@ uint32_t test_start (void)
|
||||
|
||||
/* atomThreadCreate: Pass a bad TCB pointer */
|
||||
if (atomThreadCreate (NULL, TEST_THREAD_PRIO, test_thread_func, 0,
|
||||
&test_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_ERR_PARAM)
|
||||
&test_thread_stack[TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_ERR_PARAM)
|
||||
{
|
||||
ATOMLOG (_STR("Bad TCB check\n"));
|
||||
failures++;
|
||||
@@ -72,7 +73,8 @@ uint32_t test_start (void)
|
||||
|
||||
/* atomThreadCreate: Pass a bad entry point */
|
||||
if (atomThreadCreate (&tcb1, TEST_THREAD_PRIO, NULL, 0,
|
||||
&test_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_ERR_PARAM)
|
||||
&test_thread_stack[TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_ERR_PARAM)
|
||||
{
|
||||
ATOMLOG (_STR("Bad entry check\n"));
|
||||
failures++;
|
||||
@@ -80,20 +82,18 @@ uint32_t test_start (void)
|
||||
|
||||
/* atomThreadCreate: Pass a bad stack pointer */
|
||||
if (atomThreadCreate (&tcb1, TEST_THREAD_PRIO, test_thread_func, 0,
|
||||
NULL) != ATOM_ERR_PARAM)
|
||||
NULL, TEST_THREAD_STACK_SIZE) != ATOM_ERR_PARAM)
|
||||
{
|
||||
ATOMLOG (_STR("Bad stack ptr check\n"));
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
/* atomThreadCreate: Pass a bad stack size */
|
||||
if (atomThreadCreate (&tcb1, TEST_THREAD_PRIO, test_thread_func, 0,
|
||||
&test_thread_stack[TEST_THREAD_STACK_SIZE - 1], 0) != ATOM_ERR_PARAM)
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
ATOMLOG (_STR("Bad stack size check\n"));
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Quit */
|
||||
|
||||
@@ -182,16 +182,6 @@ uint32_t test_start (void)
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
}
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
|
||||
|
||||
@@ -32,10 +32,13 @@
|
||||
#include "atomtests.h"
|
||||
|
||||
|
||||
/* Number of test threads */
|
||||
#define NUM_TEST_THREADS 2
|
||||
|
||||
|
||||
/* Test OS objects */
|
||||
static ATOM_TCB tcb1, tcb2;
|
||||
static uint8_t test1_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test2_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static ATOM_TCB tcb[NUM_TEST_THREADS];
|
||||
static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
|
||||
|
||||
|
||||
/* Test global data (one per thread) */
|
||||
@@ -91,16 +94,18 @@ uint32_t test_start (void)
|
||||
sleep_request[0] = sleep_request[1] = FALSE;
|
||||
|
||||
/* Create low priority thread */
|
||||
if (atomThreadCreate (&tcb1, 253, test_thread_func, 0,
|
||||
&test1_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate (&tcb[0], 253, test_thread_func, 0,
|
||||
&test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("Bad thread create\n"));
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Create high priority thread */
|
||||
else if (atomThreadCreate (&tcb2, 252, test_thread_func, 1,
|
||||
&test2_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
else if (atomThreadCreate (&tcb[1], 252, test_thread_func, 1,
|
||||
&test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("Bad thread create\n"));
|
||||
failures++;
|
||||
@@ -164,15 +169,38 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
/* Check thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
uint32_t used_bytes, free_bytes;
|
||||
int thread;
|
||||
|
||||
/* Check all threads */
|
||||
for (thread = 0; thread < NUM_TEST_THREADS; thread++)
|
||||
{
|
||||
/* Check thread stack usage */
|
||||
if (atomThreadStackCheck (&tcb[thread], &used_bytes, &free_bytes) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("StackCheck\n"));
|
||||
failures++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
ATOMLOG (_STR("StackOverflow %d\n"), thread);
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
|
||||
@@ -32,12 +32,13 @@
|
||||
#include "atomtests.h"
|
||||
|
||||
|
||||
/* Number of test threads */
|
||||
#define NUM_TEST_THREADS 4
|
||||
|
||||
|
||||
/* Test OS objects */
|
||||
static ATOM_TCB tcb1, tcb2, tcb3, tcb4;
|
||||
static uint8_t test1_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test2_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test3_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test4_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static ATOM_TCB tcb[NUM_TEST_THREADS];
|
||||
static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
|
||||
|
||||
|
||||
/* Test global data (one per thread) */
|
||||
@@ -95,26 +96,30 @@ uint32_t test_start (void)
|
||||
* can do so without confusing the scheduling tests by having
|
||||
* a spell in which this thread was run.
|
||||
*/
|
||||
if (atomThreadCreate (&tcb1, TEST_THREAD_PRIO + 1, test_thread_func, 0,
|
||||
&test1_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate (&tcb[0], TEST_THREAD_PRIO + 1, test_thread_func, 0,
|
||||
&test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("Bad thread create\n"));
|
||||
failures++;
|
||||
}
|
||||
else if (atomThreadCreate (&tcb2, TEST_THREAD_PRIO + 1, test_thread_func, 1,
|
||||
&test2_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
else if (atomThreadCreate (&tcb[1], TEST_THREAD_PRIO + 1, test_thread_func, 1,
|
||||
&test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("Bad thread create\n"));
|
||||
failures++;
|
||||
}
|
||||
else if (atomThreadCreate (&tcb3, TEST_THREAD_PRIO + 1, test_thread_func, 2,
|
||||
&test3_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
else if (atomThreadCreate (&tcb[2], TEST_THREAD_PRIO + 1, test_thread_func, 2,
|
||||
&test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("Bad thread create\n"));
|
||||
failures++;
|
||||
}
|
||||
else if (atomThreadCreate (&tcb4, TEST_THREAD_PRIO + 1, test_thread_func, 3,
|
||||
&test4_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
else if (atomThreadCreate (&tcb[3], TEST_THREAD_PRIO + 1, test_thread_func, 3,
|
||||
&test_thread_stack[3][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("Bad thread create\n"));
|
||||
failures++;
|
||||
@@ -135,15 +140,38 @@ uint32_t test_start (void)
|
||||
/* Count any failures from test threads */
|
||||
failures += failure_cnt[0] + failure_cnt[1] + failure_cnt[2] + failure_cnt[3];
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
/* Check thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
uint32_t used_bytes, free_bytes;
|
||||
int thread;
|
||||
|
||||
/* Check all threads */
|
||||
for (thread = 0; thread < NUM_TEST_THREADS; thread++)
|
||||
{
|
||||
/* Check thread stack usage */
|
||||
if (atomThreadStackCheck (&tcb[thread], &used_bytes, &free_bytes) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("StackCheck\n"));
|
||||
failures++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
ATOMLOG (_STR("StackOverflow %d\n"), thread);
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
|
||||
@@ -33,11 +33,14 @@
|
||||
#include "atomtests.h"
|
||||
|
||||
|
||||
/* Number of test threads */
|
||||
#define NUM_TEST_THREADS 2
|
||||
|
||||
|
||||
/* Test OS objects */
|
||||
static ATOM_MUTEX mutex1;
|
||||
static ATOM_TCB tcb1, tcb2;
|
||||
static uint8_t test1_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test2_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static ATOM_TCB tcb[NUM_TEST_THREADS];
|
||||
static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
|
||||
|
||||
|
||||
/* Test result tracking */
|
||||
@@ -134,8 +137,9 @@ uint32_t test_start (void)
|
||||
failures++;
|
||||
}
|
||||
|
||||
else if (atomThreadCreate(&tcb1, TEST_THREAD_PRIO, test1_thread_func, 0,
|
||||
&test1_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test1_thread_func, 0,
|
||||
&test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread 1\n"));
|
||||
@@ -196,8 +200,9 @@ uint32_t test_start (void)
|
||||
failures++;
|
||||
}
|
||||
|
||||
else if (atomThreadCreate(&tcb2, TEST_THREAD_PRIO, test2_thread_func, 0,
|
||||
&test2_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
else if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test2_thread_func, 0,
|
||||
&test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread 2\n"));
|
||||
@@ -243,15 +248,38 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
/* Check thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
uint32_t used_bytes, free_bytes;
|
||||
int thread;
|
||||
|
||||
/* Check all threads */
|
||||
for (thread = 0; thread < NUM_TEST_THREADS; thread++)
|
||||
{
|
||||
/* Check thread stack usage */
|
||||
if (atomThreadStackCheck (&tcb[thread], &used_bytes, &free_bytes) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("StackCheck\n"));
|
||||
failures++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
ATOMLOG (_STR("StackOverflow %d\n"), thread);
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
|
||||
@@ -34,10 +34,14 @@
|
||||
#include "atomtests.h"
|
||||
|
||||
|
||||
/* Number of test threads */
|
||||
#define NUM_TEST_THREADS 1
|
||||
|
||||
|
||||
/* Test OS objects */
|
||||
static ATOM_MUTEX mutex1, mutex2;
|
||||
static ATOM_TCB tcb1;
|
||||
static uint8_t test1_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static ATOM_TCB tcb[NUM_TEST_THREADS];
|
||||
static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
|
||||
|
||||
|
||||
/* Test result tracking */
|
||||
@@ -139,8 +143,9 @@ uint32_t test_start (void)
|
||||
|
||||
/* Create a test thread, the sole purpose of which is to own mutex2 */
|
||||
g_owned = 0;
|
||||
if (atomThreadCreate(&tcb1, TEST_THREAD_PRIO, test_thread_func, 0,
|
||||
&test1_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 0,
|
||||
&test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread 1\n"));
|
||||
@@ -224,15 +229,38 @@ uint32_t test_start (void)
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
/* Check thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
uint32_t used_bytes, free_bytes;
|
||||
int thread;
|
||||
|
||||
/* Check all threads */
|
||||
for (thread = 0; thread < NUM_TEST_THREADS; thread++)
|
||||
{
|
||||
/* Check thread stack usage */
|
||||
if (atomThreadStackCheck (&tcb[thread], &used_bytes, &free_bytes) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("StackCheck\n"));
|
||||
failures++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
ATOMLOG (_STR("StackOverflow %d\n"), thread);
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
|
||||
@@ -33,13 +33,14 @@
|
||||
#include "atommutex.h"
|
||||
|
||||
|
||||
/* Number of test threads */
|
||||
#define NUM_TEST_THREADS 4
|
||||
|
||||
|
||||
/* Test OS objects */
|
||||
static ATOM_MUTEX mutex1;
|
||||
static ATOM_TCB tcb1, tcb2, tcb3, tcb4;
|
||||
static uint8_t test1_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test2_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test3_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test4_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static ATOM_TCB tcb[NUM_TEST_THREADS];
|
||||
static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
|
||||
|
||||
/* Data updated by threads */
|
||||
static volatile uint8_t wake_cnt;
|
||||
@@ -106,8 +107,9 @@ uint32_t test_start (void)
|
||||
else
|
||||
{
|
||||
/* Create Thread 1 (lower priority thread A) */
|
||||
if (atomThreadCreate(&tcb1, TEST_THREAD_PRIO+1, test_thread_func, 1,
|
||||
&test1_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO+1, test_thread_func, 1,
|
||||
&test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -118,8 +120,9 @@ uint32_t test_start (void)
|
||||
atomTimerDelay (SYSTEM_TICKS_PER_SEC/4);
|
||||
|
||||
/* Create Thread 2 (lower priority thread B) */
|
||||
if (atomThreadCreate(&tcb2, TEST_THREAD_PRIO+1, test_thread_func, 2,
|
||||
&test2_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO+1, test_thread_func, 2,
|
||||
&test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -130,8 +133,9 @@ uint32_t test_start (void)
|
||||
atomTimerDelay (SYSTEM_TICKS_PER_SEC/4);
|
||||
|
||||
/* Create Thread 3 (higher priority thread A) */
|
||||
if (atomThreadCreate(&tcb3, TEST_THREAD_PRIO, test_thread_func, 3,
|
||||
&test3_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 3,
|
||||
&test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -142,8 +146,9 @@ uint32_t test_start (void)
|
||||
atomTimerDelay (SYSTEM_TICKS_PER_SEC/4);
|
||||
|
||||
/* Create Thread 4 (higher priority thread B) */
|
||||
if (atomThreadCreate(&tcb4, TEST_THREAD_PRIO, test_thread_func, 4,
|
||||
&test4_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[3], TEST_THREAD_PRIO, test_thread_func, 4,
|
||||
&test_thread_stack[3][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -195,15 +200,38 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
/* Check thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
uint32_t used_bytes, free_bytes;
|
||||
int thread;
|
||||
|
||||
/* Check all threads */
|
||||
for (thread = 0; thread < NUM_TEST_THREADS; thread++)
|
||||
{
|
||||
/* Check thread stack usage */
|
||||
if (atomThreadStackCheck (&tcb[thread], &used_bytes, &free_bytes) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("StackCheck\n"));
|
||||
failures++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
ATOMLOG (_STR("StackOverflow %d\n"), thread);
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
|
||||
@@ -37,15 +37,15 @@
|
||||
/* Number of test loops for stress-test */
|
||||
#define NUM_TEST_LOOPS 10000
|
||||
|
||||
/* Number of test threads */
|
||||
#define NUM_TEST_THREADS 4
|
||||
|
||||
|
||||
/* Test OS objects */
|
||||
static ATOM_MUTEX mutex1;
|
||||
static ATOM_SEM sem1;
|
||||
static ATOM_TCB tcb1, tcb2, tcb3, tcb4;
|
||||
static uint8_t test1_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test2_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test3_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test4_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static ATOM_TCB tcb[NUM_TEST_THREADS];
|
||||
static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
|
||||
|
||||
|
||||
/*
|
||||
@@ -100,8 +100,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create Thread 1 */
|
||||
if (atomThreadCreate(&tcb1, TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test1_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -111,8 +112,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create Thread 2 */
|
||||
if (atomThreadCreate(&tcb2, TEST_THREAD_PRIO, test_thread_func, 2,
|
||||
&test2_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test_thread_func, 2,
|
||||
&test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -122,8 +124,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create Thread 3 */
|
||||
if (atomThreadCreate(&tcb3, TEST_THREAD_PRIO, test_thread_func, 3,
|
||||
&test3_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 3,
|
||||
&test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -133,8 +136,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create Thread 4 */
|
||||
if (atomThreadCreate(&tcb4, TEST_THREAD_PRIO, test_thread_func, 4,
|
||||
&test4_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[3], TEST_THREAD_PRIO, test_thread_func, 4,
|
||||
&test_thread_stack[3][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -193,15 +197,38 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (g_failures == 0)
|
||||
/* Check thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), g_failures);
|
||||
uint32_t used_bytes, free_bytes;
|
||||
int thread;
|
||||
|
||||
/* Check all threads */
|
||||
for (thread = 0; thread < NUM_TEST_THREADS; thread++)
|
||||
{
|
||||
/* Check thread stack usage */
|
||||
if (atomThreadStackCheck (&tcb[thread], &used_bytes, &free_bytes) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("StackCheck\n"));
|
||||
g_failures++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
ATOMLOG (_STR("StackOverflow %d\n"), thread);
|
||||
g_failures++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Quit */
|
||||
return g_failures;
|
||||
|
||||
@@ -33,10 +33,14 @@
|
||||
#include "atommutex.h"
|
||||
|
||||
|
||||
/* Number of test threads */
|
||||
#define NUM_TEST_THREADS 1
|
||||
|
||||
|
||||
/* Test OS objects */
|
||||
static ATOM_MUTEX mutex1;
|
||||
static ATOM_TCB tcb1;
|
||||
static uint8_t test1_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static ATOM_TCB tcb[NUM_TEST_THREADS];
|
||||
static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
|
||||
|
||||
|
||||
/* Global shared data protected by mutex */
|
||||
@@ -90,8 +94,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create second thread */
|
||||
else if (atomThreadCreate(&tcb1, TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test1_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -206,15 +211,38 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
/* Check thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
uint32_t used_bytes, free_bytes;
|
||||
int thread;
|
||||
|
||||
/* Check all threads */
|
||||
for (thread = 0; thread < NUM_TEST_THREADS; thread++)
|
||||
{
|
||||
/* Check thread stack usage */
|
||||
if (atomThreadStackCheck (&tcb[thread], &used_bytes, &free_bytes) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("StackCheck\n"));
|
||||
failures++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
ATOMLOG (_STR("StackOverflow %d\n"), thread);
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
|
||||
@@ -37,10 +37,14 @@
|
||||
#define TEST_LOCK_CNT 250
|
||||
|
||||
|
||||
/* Number of test threads */
|
||||
#define NUM_TEST_THREADS 1
|
||||
|
||||
|
||||
/* Test OS objects */
|
||||
static ATOM_MUTEX mutex1;
|
||||
static ATOM_TCB tcb1;
|
||||
static uint8_t test1_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static ATOM_TCB tcb[NUM_TEST_THREADS];
|
||||
static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
|
||||
|
||||
|
||||
/* Global shared data protected by mutex */
|
||||
@@ -95,8 +99,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create second thread */
|
||||
if (atomThreadCreate(&tcb1, TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test1_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -197,15 +202,38 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
/* Check thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
uint32_t used_bytes, free_bytes;
|
||||
int thread;
|
||||
|
||||
/* Check all threads */
|
||||
for (thread = 0; thread < NUM_TEST_THREADS; thread++)
|
||||
{
|
||||
/* Check thread stack usage */
|
||||
if (atomThreadStackCheck (&tcb[thread], &used_bytes, &free_bytes) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("StackCheck\n"));
|
||||
failures++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
ATOMLOG (_STR("StackOverflow %d\n"), thread);
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
|
||||
@@ -34,10 +34,14 @@
|
||||
#include "atommutex.h"
|
||||
|
||||
|
||||
/* Number of test threads */
|
||||
#define NUM_TEST_THREADS 1
|
||||
|
||||
|
||||
/* Test OS objects */
|
||||
static ATOM_MUTEX mutex1;
|
||||
static ATOM_TCB tcb1;
|
||||
static uint8_t test1_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static ATOM_TCB tcb[NUM_TEST_THREADS];
|
||||
static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
|
||||
|
||||
|
||||
/* Global shared data */
|
||||
@@ -89,8 +93,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create second thread */
|
||||
else if (atomThreadCreate(&tcb1, TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test1_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -161,15 +166,38 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
/* Check thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
uint32_t used_bytes, free_bytes;
|
||||
int thread;
|
||||
|
||||
/* Check all threads */
|
||||
for (thread = 0; thread < NUM_TEST_THREADS; thread++)
|
||||
{
|
||||
/* Check thread stack usage */
|
||||
if (atomThreadStackCheck (&tcb[thread], &used_bytes, &free_bytes) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("StackCheck\n"));
|
||||
failures++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
ATOMLOG (_STR("StackOverflow %d\n"), thread);
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
|
||||
@@ -33,12 +33,14 @@
|
||||
#include "atomtests.h"
|
||||
|
||||
|
||||
/* Number of test threads */
|
||||
#define NUM_TEST_THREADS 3
|
||||
|
||||
|
||||
/* Test OS objects */
|
||||
static ATOM_MUTEX mutex1;
|
||||
static ATOM_TCB tcb1, tcb2, tcb3;
|
||||
static uint8_t test1_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test2_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test3_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static ATOM_TCB tcb[NUM_TEST_THREADS];
|
||||
static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
|
||||
|
||||
|
||||
/* Test results */
|
||||
@@ -91,8 +93,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create test thread 1 */
|
||||
if (atomThreadCreate(&tcb1, TEST_THREAD_PRIO, test_thread_func, 0,
|
||||
&test1_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 0,
|
||||
&test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread 1\n"));
|
||||
@@ -100,8 +103,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create test thread 2 */
|
||||
else if (atomThreadCreate(&tcb2, TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test2_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
else if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread 2\n"));
|
||||
@@ -109,8 +113,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create test thread 3 */
|
||||
else if (atomThreadCreate(&tcb3, TEST_THREAD_PRIO, test_thread_func, 2,
|
||||
&test3_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
else if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 2,
|
||||
&test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread 3\n"));
|
||||
@@ -144,15 +149,38 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
/* Check thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
uint32_t used_bytes, free_bytes;
|
||||
int thread;
|
||||
|
||||
/* Check all threads */
|
||||
for (thread = 0; thread < NUM_TEST_THREADS; thread++)
|
||||
{
|
||||
/* Check thread stack usage */
|
||||
if (atomThreadStackCheck (&tcb[thread], &used_bytes, &free_bytes) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("StackCheck\n"));
|
||||
failures++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
ATOMLOG (_STR("StackOverflow %d\n"), thread);
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
@@ -196,4 +224,4 @@ static void test_thread_func (uint32_t data)
|
||||
{
|
||||
atomTimerDelay (SYSTEM_TICKS_PER_SEC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,10 +33,14 @@
|
||||
#include "atommutex.h"
|
||||
|
||||
|
||||
/* Number of test threads */
|
||||
#define NUM_TEST_THREADS 1
|
||||
|
||||
|
||||
/* Test OS objects */
|
||||
static ATOM_MUTEX mutex1;
|
||||
static ATOM_TCB tcb1;
|
||||
static uint8_t test1_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static ATOM_TCB tcb[NUM_TEST_THREADS];
|
||||
static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
|
||||
|
||||
|
||||
/* Global shared data protected by mutex */
|
||||
@@ -83,8 +87,9 @@ uint32_t test_start (void)
|
||||
shared_data = 0;
|
||||
|
||||
/* Create second thread */
|
||||
if (atomThreadCreate(&tcb1, TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test1_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -136,15 +141,38 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
/* Check thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
uint32_t used_bytes, free_bytes;
|
||||
int thread;
|
||||
|
||||
/* Check all threads */
|
||||
for (thread = 0; thread < NUM_TEST_THREADS; thread++)
|
||||
{
|
||||
/* Check thread stack usage */
|
||||
if (atomThreadStackCheck (&tcb[thread], &used_bytes, &free_bytes) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("StackCheck\n"));
|
||||
failures++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
ATOMLOG (_STR("StackOverflow %d\n"), thread);
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
|
||||
@@ -143,16 +143,6 @@ uint32_t test_start (void)
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
}
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
}
|
||||
|
||||
@@ -202,16 +202,6 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
}
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
}
|
||||
|
||||
@@ -37,12 +37,15 @@
|
||||
#define QUEUE_ENTRIES 16
|
||||
|
||||
|
||||
/* Number of test threads */
|
||||
#define NUM_TEST_THREADS 2
|
||||
|
||||
|
||||
/* Test OS objects */
|
||||
static ATOM_QUEUE queue1;
|
||||
static ATOM_TCB tcb1, tcb2;
|
||||
static uint8_t test1_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test2_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t queue1_storage[QUEUE_ENTRIES];
|
||||
static ATOM_TCB tcb[NUM_TEST_THREADS];
|
||||
static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
|
||||
|
||||
|
||||
/* Test result tracking */
|
||||
@@ -86,8 +89,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create a test thread that will block because the queue is empty */
|
||||
else if (atomThreadCreate(&tcb1, TEST_THREAD_PRIO, test1_thread_func, 0,
|
||||
&test1_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test1_thread_func, 0,
|
||||
&test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread 1\n"));
|
||||
@@ -142,8 +146,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create a test thread that will block because the queue is empty */
|
||||
else if (atomThreadCreate(&tcb2, TEST_THREAD_PRIO, test2_thread_func, 0,
|
||||
&test2_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
else if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test2_thread_func, 0,
|
||||
&test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread 2\n"));
|
||||
@@ -189,15 +194,38 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
/* Check thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
uint32_t used_bytes, free_bytes;
|
||||
int thread;
|
||||
|
||||
/* Check all threads */
|
||||
for (thread = 0; thread < NUM_TEST_THREADS; thread++)
|
||||
{
|
||||
/* Check thread stack usage */
|
||||
if (atomThreadStackCheck (&tcb[thread], &used_bytes, &free_bytes) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("StackCheck\n"));
|
||||
failures++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
ATOMLOG (_STR("StackOverflow %d\n"), thread);
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
|
||||
@@ -37,12 +37,15 @@
|
||||
#define QUEUE_ENTRIES 16
|
||||
|
||||
|
||||
/* Number of test threads */
|
||||
#define NUM_TEST_THREADS 2
|
||||
|
||||
|
||||
/* Test OS objects */
|
||||
static ATOM_QUEUE queue1;
|
||||
static ATOM_TCB tcb1, tcb2;
|
||||
static uint8_t test1_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test2_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t queue1_storage[QUEUE_ENTRIES];
|
||||
static ATOM_TCB tcb[NUM_TEST_THREADS];
|
||||
static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
|
||||
|
||||
|
||||
/* Test result tracking */
|
||||
@@ -103,8 +106,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create a test thread that will block because the queue is full */
|
||||
if (atomThreadCreate(&tcb1, TEST_THREAD_PRIO, test1_thread_func, 0,
|
||||
&test1_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test1_thread_func, 0,
|
||||
&test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread 1\n"));
|
||||
@@ -173,8 +177,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create a test thread that will block because the queue is full */
|
||||
if (atomThreadCreate(&tcb2, TEST_THREAD_PRIO, test2_thread_func, 0,
|
||||
&test2_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test2_thread_func, 0,
|
||||
&test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread 2\n"));
|
||||
@@ -221,15 +226,38 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
/* Check thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
uint32_t used_bytes, free_bytes;
|
||||
int thread;
|
||||
|
||||
/* Check all threads */
|
||||
for (thread = 0; thread < NUM_TEST_THREADS; thread++)
|
||||
{
|
||||
/* Check thread stack usage */
|
||||
if (atomThreadStackCheck (&tcb[thread], &used_bytes, &free_bytes) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("StackCheck\n"));
|
||||
failures++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
ATOMLOG (_STR("StackOverflow %d\n"), thread);
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
|
||||
@@ -225,16 +225,6 @@ uint32_t test_start (void)
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
}
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
}
|
||||
|
||||
@@ -37,14 +37,16 @@
|
||||
#define QUEUE_ENTRIES 8
|
||||
|
||||
|
||||
/* Number of test threads */
|
||||
#define NUM_TEST_THREADS 4
|
||||
|
||||
|
||||
/* Test OS objects */
|
||||
static ATOM_QUEUE queue1;
|
||||
static uint8_t queue1_storage[QUEUE_ENTRIES];
|
||||
static ATOM_TCB tcb1, tcb2, tcb3, tcb4;
|
||||
static uint8_t test1_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test2_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test3_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test4_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static ATOM_TCB tcb[NUM_TEST_THREADS];
|
||||
static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
|
||||
|
||||
|
||||
/* Data updated by threads */
|
||||
static volatile uint8_t wake_cnt;
|
||||
@@ -112,8 +114,9 @@ uint32_t test_start (void)
|
||||
*/
|
||||
|
||||
/* Create Thread 1 (lower priority thread A) */
|
||||
if (atomThreadCreate(&tcb1, TEST_THREAD_PRIO+1, test_thread_func, 1,
|
||||
&test1_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO+1, test_thread_func, 1,
|
||||
&test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -124,8 +127,9 @@ uint32_t test_start (void)
|
||||
atomTimerDelay (SYSTEM_TICKS_PER_SEC/4);
|
||||
|
||||
/* Create Thread 2 (lower priority thread B) */
|
||||
if (atomThreadCreate(&tcb2, TEST_THREAD_PRIO+1, test_thread_func, 2,
|
||||
&test2_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO+1, test_thread_func, 2,
|
||||
&test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -136,8 +140,9 @@ uint32_t test_start (void)
|
||||
atomTimerDelay (SYSTEM_TICKS_PER_SEC/4);
|
||||
|
||||
/* Create Thread 3 (higher priority thread A) */
|
||||
if (atomThreadCreate(&tcb3, TEST_THREAD_PRIO, test_thread_func, 3,
|
||||
&test3_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 3,
|
||||
&test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -148,8 +153,9 @@ uint32_t test_start (void)
|
||||
atomTimerDelay (SYSTEM_TICKS_PER_SEC/4);
|
||||
|
||||
/* Create Thread 4 (higher priority thread B) */
|
||||
if (atomThreadCreate(&tcb4, TEST_THREAD_PRIO, test_thread_func, 4,
|
||||
&test4_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[3], TEST_THREAD_PRIO, test_thread_func, 4,
|
||||
&test_thread_stack[3][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -211,15 +217,38 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
/* Check thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
uint32_t used_bytes, free_bytes;
|
||||
int thread;
|
||||
|
||||
/* Check all threads */
|
||||
for (thread = 0; thread < NUM_TEST_THREADS; thread++)
|
||||
{
|
||||
/* Check thread stack usage */
|
||||
if (atomThreadStackCheck (&tcb[thread], &used_bytes, &free_bytes) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("StackCheck\n"));
|
||||
failures++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
ATOMLOG (_STR("StackOverflow %d\n"), thread);
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
@@ -273,4 +302,4 @@ static void test_thread_func (uint32_t data)
|
||||
{
|
||||
atomTimerDelay (SYSTEM_TICKS_PER_SEC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,11 +37,15 @@
|
||||
#define QUEUE_ENTRIES 8
|
||||
|
||||
|
||||
/* Number of test threads */
|
||||
#define NUM_TEST_THREADS 1
|
||||
|
||||
|
||||
/* Test OS objects */
|
||||
static ATOM_QUEUE queue1;
|
||||
static uint32_t queue1_storage[QUEUE_ENTRIES];
|
||||
static ATOM_TCB tcb1;
|
||||
static uint8_t test1_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static ATOM_TCB tcb[NUM_TEST_THREADS];
|
||||
static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
|
||||
|
||||
|
||||
/* Test message values (more values than can fit in an entire 8 message queue) */
|
||||
@@ -102,8 +106,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create a test thread that will block because the queue is empty */
|
||||
else if (atomThreadCreate(&tcb1, TEST_THREAD_PRIO + 1, test1_thread_func, 0,
|
||||
&test1_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO + 1, test1_thread_func, 0,
|
||||
&test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread 1\n"));
|
||||
@@ -167,15 +172,38 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
/* Check thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
uint32_t used_bytes, free_bytes;
|
||||
int thread;
|
||||
|
||||
/* Check all threads */
|
||||
for (thread = 0; thread < NUM_TEST_THREADS; thread++)
|
||||
{
|
||||
/* Check thread stack usage */
|
||||
if (atomThreadStackCheck (&tcb[thread], &used_bytes, &free_bytes) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("StackCheck\n"));
|
||||
failures++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
ATOMLOG (_STR("StackOverflow %d\n"), thread);
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
|
||||
@@ -37,13 +37,15 @@
|
||||
#define QUEUE_ENTRIES 8
|
||||
|
||||
|
||||
/* Number of test threads */
|
||||
#define NUM_TEST_THREADS 3
|
||||
|
||||
|
||||
/* Test OS objects */
|
||||
static ATOM_QUEUE queue1;
|
||||
static uint8_t queue1_storage[QUEUE_ENTRIES];
|
||||
static ATOM_TCB tcb1, tcb2, tcb3;
|
||||
static uint8_t test1_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test2_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test3_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static ATOM_TCB tcb[NUM_TEST_THREADS];
|
||||
static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
|
||||
|
||||
|
||||
/* Test results */
|
||||
@@ -91,8 +93,9 @@ uint32_t test_start (void)
|
||||
/* The queue is empty so all three test threads will block */
|
||||
|
||||
/* Create test thread 1 */
|
||||
if (atomThreadCreate(&tcb1, TEST_THREAD_PRIO, test_thread_func, 0,
|
||||
&test1_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 0,
|
||||
&test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread 1\n"));
|
||||
@@ -100,8 +103,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create test thread 2 */
|
||||
else if (atomThreadCreate(&tcb2, TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test2_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
else if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread 2\n"));
|
||||
@@ -109,8 +113,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create test thread 3 */
|
||||
else if (atomThreadCreate(&tcb3, TEST_THREAD_PRIO, test_thread_func, 2,
|
||||
&test3_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
else if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 2,
|
||||
&test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread 3\n"));
|
||||
@@ -144,15 +149,38 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
/* Check thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
uint32_t used_bytes, free_bytes;
|
||||
int thread;
|
||||
|
||||
/* Check all threads */
|
||||
for (thread = 0; thread < NUM_TEST_THREADS; thread++)
|
||||
{
|
||||
/* Check thread stack usage */
|
||||
if (atomThreadStackCheck (&tcb[thread], &used_bytes, &free_bytes) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("StackCheck\n"));
|
||||
failures++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
ATOMLOG (_STR("StackOverflow %d\n"), thread);
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
@@ -197,4 +225,4 @@ static void test_thread_func (uint32_t data)
|
||||
{
|
||||
atomTimerDelay (SYSTEM_TICKS_PER_SEC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,16 +102,6 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
}
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
|
||||
|
||||
@@ -42,15 +42,16 @@
|
||||
#define QUEUE_ENTRIES 8
|
||||
|
||||
|
||||
/* Number of test threads */
|
||||
#define NUM_TEST_THREADS 4
|
||||
|
||||
|
||||
/* Test OS objects */
|
||||
static ATOM_QUEUE queue1;
|
||||
static uint8_t queue1_storage[QUEUE_ENTRIES];
|
||||
static ATOM_SEM sem1;
|
||||
static ATOM_TCB tcb1, tcb2, tcb3, tcb4;
|
||||
static uint8_t test1_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test2_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test3_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test4_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static ATOM_TCB tcb[NUM_TEST_THREADS];
|
||||
static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
|
||||
|
||||
|
||||
/*
|
||||
@@ -101,8 +102,9 @@ uint32_t test_start (void)
|
||||
else
|
||||
{
|
||||
/* Create Thread 1 */
|
||||
if (atomThreadCreate(&tcb1, TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test1_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -112,8 +114,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create Thread 2 */
|
||||
if (atomThreadCreate(&tcb2, TEST_THREAD_PRIO, test_thread_func, 2,
|
||||
&test2_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test_thread_func, 2,
|
||||
&test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -123,8 +126,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create Thread 3 */
|
||||
if (atomThreadCreate(&tcb3, TEST_THREAD_PRIO, test_thread_func, 3,
|
||||
&test3_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 3,
|
||||
&test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -134,8 +138,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create Thread 4 */
|
||||
if (atomThreadCreate(&tcb4, TEST_THREAD_PRIO, test_thread_func, 4,
|
||||
&test4_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[3], TEST_THREAD_PRIO, test_thread_func, 4,
|
||||
&test_thread_stack[3][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -187,15 +192,38 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (g_failures == 0)
|
||||
/* Check thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), g_failures);
|
||||
uint32_t used_bytes, free_bytes;
|
||||
int thread;
|
||||
|
||||
/* Check all threads */
|
||||
for (thread = 0; thread < NUM_TEST_THREADS; thread++)
|
||||
{
|
||||
/* Check thread stack usage */
|
||||
if (atomThreadStackCheck (&tcb[thread], &used_bytes, &free_bytes) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("StackCheck\n"));
|
||||
g_failures++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
ATOMLOG (_STR("StackOverflow %d\n"), thread);
|
||||
g_failures++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Quit */
|
||||
return g_failures;
|
||||
@@ -262,4 +290,4 @@ static void test_thread_func (uint32_t data)
|
||||
{
|
||||
atomTimerDelay (SYSTEM_TICKS_PER_SEC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
56
tests/sem1.c
56
tests/sem1.c
@@ -34,11 +34,14 @@
|
||||
#include "atomtests.h"
|
||||
|
||||
|
||||
/* Number of test threads */
|
||||
#define NUM_TEST_THREADS 2
|
||||
|
||||
|
||||
/* Test OS objects */
|
||||
static ATOM_SEM sem1, sem2;
|
||||
static ATOM_TCB tcb1, tcb2;
|
||||
static uint8_t test1_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test2_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static ATOM_TCB tcb[NUM_TEST_THREADS];
|
||||
static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
@@ -130,8 +133,9 @@ uint32_t test_start (void)
|
||||
failures++;
|
||||
}
|
||||
|
||||
else if (atomThreadCreate(&tcb1, TEST_THREAD_PRIO, test1_thread_func, 0,
|
||||
&test1_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test1_thread_func, 0,
|
||||
&test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread 1\n"));
|
||||
@@ -196,8 +200,9 @@ uint32_t test_start (void)
|
||||
ATOMLOG (_STR("Error creating test semaphore 2\n"));
|
||||
failures++;
|
||||
}
|
||||
else if (atomThreadCreate(&tcb2, TEST_THREAD_PRIO, test2_thread_func, 0,
|
||||
&test2_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
else if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test2_thread_func, 0,
|
||||
&test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread 2\n"));
|
||||
@@ -250,15 +255,38 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
/* Check thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
uint32_t used_bytes, free_bytes;
|
||||
int thread;
|
||||
|
||||
/* Check all threads */
|
||||
for (thread = 0; thread < NUM_TEST_THREADS; thread++)
|
||||
{
|
||||
/* Check thread stack usage */
|
||||
if (atomThreadStackCheck (&tcb[thread], &used_bytes, &free_bytes) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("StackCheck\n"));
|
||||
failures++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
ATOMLOG (_STR("StackOverflow %d\n"), thread);
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
|
||||
10
tests/sem2.c
10
tests/sem2.c
@@ -292,16 +292,6 @@ uint32_t test_start (void)
|
||||
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
}
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
}
|
||||
|
||||
70
tests/sem3.c
70
tests/sem3.c
@@ -33,13 +33,14 @@
|
||||
#include "atomsem.h"
|
||||
|
||||
|
||||
/* Number of test threads */
|
||||
#define NUM_TEST_THREADS 4
|
||||
|
||||
|
||||
/* Test OS objects */
|
||||
static ATOM_SEM sem1;
|
||||
static ATOM_TCB tcb1, tcb2, tcb3, tcb4;
|
||||
static uint8_t test1_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test2_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test3_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test4_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static ATOM_TCB tcb[NUM_TEST_THREADS];
|
||||
static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
|
||||
|
||||
|
||||
/* Data updated by threads */
|
||||
@@ -101,8 +102,9 @@ uint32_t test_start (void)
|
||||
else
|
||||
{
|
||||
/* Create Thread 1 (lower priority thread A) */
|
||||
if (atomThreadCreate(&tcb1, TEST_THREAD_PRIO+1, test_thread_func, 1,
|
||||
&test1_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO+1, test_thread_func, 1,
|
||||
&test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -113,8 +115,9 @@ uint32_t test_start (void)
|
||||
atomTimerDelay (SYSTEM_TICKS_PER_SEC/4);
|
||||
|
||||
/* Create Thread 2 (lower priority thread B) */
|
||||
if (atomThreadCreate(&tcb2, TEST_THREAD_PRIO+1, test_thread_func, 2,
|
||||
&test2_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO+1, test_thread_func, 2,
|
||||
&test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -125,8 +128,9 @@ uint32_t test_start (void)
|
||||
atomTimerDelay (SYSTEM_TICKS_PER_SEC/4);
|
||||
|
||||
/* Create Thread 3 (higher priority thread A) */
|
||||
if (atomThreadCreate(&tcb3, TEST_THREAD_PRIO, test_thread_func, 3,
|
||||
&test3_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 3,
|
||||
&test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -137,8 +141,9 @@ uint32_t test_start (void)
|
||||
atomTimerDelay (SYSTEM_TICKS_PER_SEC/4);
|
||||
|
||||
/* Create Thread 4 (higher priority thread B) */
|
||||
if (atomThreadCreate(&tcb4, TEST_THREAD_PRIO, test_thread_func, 4,
|
||||
&test4_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[3], TEST_THREAD_PRIO, test_thread_func, 4,
|
||||
&test_thread_stack[3][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -191,15 +196,38 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
/* Check thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
uint32_t used_bytes, free_bytes;
|
||||
int thread;
|
||||
|
||||
/* Check all threads */
|
||||
for (thread = 0; thread < NUM_TEST_THREADS; thread++)
|
||||
{
|
||||
/* Check thread stack usage */
|
||||
if (atomThreadStackCheck (&tcb[thread], &used_bytes, &free_bytes) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("StackCheck\n"));
|
||||
failures++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
ATOMLOG (_STR("StackOverflow %d\n"), thread);
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
@@ -250,4 +278,4 @@ static void test_thread_func (uint32_t data)
|
||||
{
|
||||
atomTimerDelay (SYSTEM_TICKS_PER_SEC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
70
tests/sem4.c
70
tests/sem4.c
@@ -37,13 +37,14 @@
|
||||
#define NUM_TEST_LOOPS 10000
|
||||
|
||||
|
||||
/* Number of test threads */
|
||||
#define NUM_TEST_THREADS 4
|
||||
|
||||
|
||||
/* Test OS objects */
|
||||
static ATOM_SEM sem1, sem2;
|
||||
static ATOM_TCB tcb1, tcb2, tcb3, tcb4;
|
||||
static uint8_t test1_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test2_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test3_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test4_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static ATOM_TCB tcb[NUM_TEST_THREADS];
|
||||
static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
|
||||
|
||||
|
||||
/*
|
||||
@@ -95,8 +96,9 @@ uint32_t test_start (void)
|
||||
else
|
||||
{
|
||||
/* Create Thread 1 */
|
||||
if (atomThreadCreate(&tcb1, TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test1_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -106,8 +108,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create Thread 2 */
|
||||
if (atomThreadCreate(&tcb2, TEST_THREAD_PRIO, test_thread_func, 2,
|
||||
&test2_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test_thread_func, 2,
|
||||
&test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -117,8 +120,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create Thread 3 */
|
||||
if (atomThreadCreate(&tcb3, TEST_THREAD_PRIO, test_thread_func, 3,
|
||||
&test3_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 3,
|
||||
&test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -128,8 +132,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create Thread 4 */
|
||||
if (atomThreadCreate(&tcb4, TEST_THREAD_PRIO, test_thread_func, 4,
|
||||
&test4_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[3], TEST_THREAD_PRIO, test_thread_func, 4,
|
||||
&test_thread_stack[3][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -181,15 +186,38 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (g_failures == 0)
|
||||
/* Check thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), g_failures);
|
||||
uint32_t used_bytes, free_bytes;
|
||||
int thread;
|
||||
|
||||
/* Check all threads */
|
||||
for (thread = 0; thread < NUM_TEST_THREADS; thread++)
|
||||
{
|
||||
/* Check thread stack usage */
|
||||
if (atomThreadStackCheck (&tcb[thread], &used_bytes, &free_bytes) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("StackCheck\n"));
|
||||
g_failures++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
ATOMLOG (_STR("StackOverflow %d\n"), thread);
|
||||
g_failures++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Quit */
|
||||
return g_failures;
|
||||
@@ -251,4 +279,4 @@ static void test_thread_func (uint32_t data)
|
||||
{
|
||||
atomTimerDelay (SYSTEM_TICKS_PER_SEC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
52
tests/sem5.c
52
tests/sem5.c
@@ -33,10 +33,14 @@
|
||||
#include "atomsem.h"
|
||||
|
||||
|
||||
/* Number of test threads */
|
||||
#define NUM_TEST_THREADS 1
|
||||
|
||||
|
||||
/* Test OS objects */
|
||||
static ATOM_SEM sem1, sem2;
|
||||
static ATOM_TCB tcb1;
|
||||
static uint8_t test1_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static ATOM_TCB tcb[NUM_TEST_THREADS];
|
||||
static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
@@ -79,8 +83,9 @@ uint32_t test_start (void)
|
||||
else
|
||||
{
|
||||
/* Create second thread */
|
||||
if (atomThreadCreate(&tcb1, TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test1_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -144,15 +149,38 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
/* Check thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
uint32_t used_bytes, free_bytes;
|
||||
int thread;
|
||||
|
||||
/* Check all threads */
|
||||
for (thread = 0; thread < NUM_TEST_THREADS; thread++)
|
||||
{
|
||||
/* Check thread stack usage */
|
||||
if (atomThreadStackCheck (&tcb[thread], &used_bytes, &free_bytes) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("StackCheck\n"));
|
||||
failures++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
ATOMLOG (_STR("StackOverflow %d\n"), thread);
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
@@ -192,4 +220,4 @@ static void test_thread_func (uint32_t data)
|
||||
{
|
||||
atomTimerDelay (SYSTEM_TICKS_PER_SEC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
52
tests/sem6.c
52
tests/sem6.c
@@ -37,10 +37,14 @@
|
||||
#define INITIAL_SEM_COUNT 10
|
||||
|
||||
|
||||
/* Number of test threads */
|
||||
#define NUM_TEST_THREADS 1
|
||||
|
||||
|
||||
/* Test OS objects */
|
||||
static ATOM_SEM sem1, sem2;
|
||||
static ATOM_TCB tcb1;
|
||||
static uint8_t test1_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static ATOM_TCB tcb[NUM_TEST_THREADS];
|
||||
static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
|
||||
|
||||
|
||||
/* Forward declarations */
|
||||
@@ -89,8 +93,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create second thread */
|
||||
else if (atomThreadCreate(&tcb1, TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test1_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -127,15 +132,38 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
/* Check thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
uint32_t used_bytes, free_bytes;
|
||||
int thread;
|
||||
|
||||
/* Check all threads */
|
||||
for (thread = 0; thread < NUM_TEST_THREADS; thread++)
|
||||
{
|
||||
/* Check thread stack usage */
|
||||
if (atomThreadStackCheck (&tcb[thread], &used_bytes, &free_bytes) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("StackCheck\n"));
|
||||
failures++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
ATOMLOG (_STR("StackOverflow %d\n"), thread);
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
@@ -198,4 +226,4 @@ static void test_thread_func (uint32_t data)
|
||||
{
|
||||
atomTimerDelay (SYSTEM_TICKS_PER_SEC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
52
tests/sem7.c
52
tests/sem7.c
@@ -33,10 +33,14 @@
|
||||
#include "atomsem.h"
|
||||
|
||||
|
||||
/* Number of test threads */
|
||||
#define NUM_TEST_THREADS 1
|
||||
|
||||
|
||||
/* Test OS objects */
|
||||
static ATOM_SEM sem1;
|
||||
static ATOM_TCB tcb1;
|
||||
static uint8_t test1_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static ATOM_TCB tcb[NUM_TEST_THREADS];
|
||||
static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
|
||||
|
||||
|
||||
/* Global shared data protected by mutex */
|
||||
@@ -95,8 +99,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create second thread */
|
||||
else if (atomThreadCreate(&tcb1, TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test1_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread\n"));
|
||||
@@ -213,15 +218,38 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
/* Check thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
uint32_t used_bytes, free_bytes;
|
||||
int thread;
|
||||
|
||||
/* Check all threads */
|
||||
for (thread = 0; thread < NUM_TEST_THREADS; thread++)
|
||||
{
|
||||
/* Check thread stack usage */
|
||||
if (atomThreadStackCheck (&tcb[thread], &used_bytes, &free_bytes) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("StackCheck\n"));
|
||||
failures++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
ATOMLOG (_STR("StackOverflow %d\n"), thread);
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
@@ -275,4 +303,4 @@ static void test_thread_func (uint32_t data)
|
||||
{
|
||||
atomTimerDelay (SYSTEM_TICKS_PER_SEC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
64
tests/sem8.c
64
tests/sem8.c
@@ -33,12 +33,14 @@
|
||||
#include "atomsem.h"
|
||||
|
||||
|
||||
/* Number of test threads */
|
||||
#define NUM_TEST_THREADS 3
|
||||
|
||||
|
||||
/* Test OS objects */
|
||||
static ATOM_SEM sem1;
|
||||
static ATOM_TCB tcb1, tcb2, tcb3;
|
||||
static uint8_t test1_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test2_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test3_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static ATOM_TCB tcb[NUM_TEST_THREADS];
|
||||
static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
|
||||
|
||||
|
||||
/* Test running flag */
|
||||
@@ -107,8 +109,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create thread 1: Higher priority than main thread so should sleep */
|
||||
else if (atomThreadCreate(&tcb1, TEST_THREAD_PRIO - 1, test_thread_func, 1,
|
||||
&test1_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO - 1, test_thread_func, 1,
|
||||
&test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread 1\n"));
|
||||
@@ -116,8 +119,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create thread 2: Same priority as main thread so should not sleep */
|
||||
else if (atomThreadCreate(&tcb2, TEST_THREAD_PRIO, test_thread_func, 0,
|
||||
&test2_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
else if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test_thread_func, 0,
|
||||
&test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread 2\n"));
|
||||
@@ -125,8 +129,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create thread 3: Same priority as main thread so should not sleep */
|
||||
else if (atomThreadCreate(&tcb3, TEST_THREAD_PRIO + 1, test_thread_func, 0,
|
||||
&test3_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
else if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO + 1, test_thread_func, 0,
|
||||
&test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread 3\n"));
|
||||
@@ -172,15 +177,38 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
/* Check thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
uint32_t used_bytes, free_bytes;
|
||||
int thread;
|
||||
|
||||
/* Check all threads */
|
||||
for (thread = 0; thread < NUM_TEST_THREADS; thread++)
|
||||
{
|
||||
/* Check thread stack usage */
|
||||
if (atomThreadStackCheck (&tcb[thread], &used_bytes, &free_bytes) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("StackCheck\n"));
|
||||
failures++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
ATOMLOG (_STR("StackOverflow %d\n"), thread);
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
@@ -289,4 +317,4 @@ static void testCallback (POINTER cb_data)
|
||||
/* Test finished, no more will be queued */
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
64
tests/sem9.c
64
tests/sem9.c
@@ -33,12 +33,14 @@
|
||||
#include "atomtests.h"
|
||||
|
||||
|
||||
/* Number of test threads */
|
||||
#define NUM_TEST_THREADS 3
|
||||
|
||||
|
||||
/* Test OS objects */
|
||||
static ATOM_SEM sem1;
|
||||
static ATOM_TCB tcb1, tcb2, tcb3;
|
||||
static uint8_t test1_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test2_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test3_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static ATOM_TCB tcb[NUM_TEST_THREADS];
|
||||
static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
|
||||
|
||||
|
||||
/* Test results */
|
||||
@@ -84,8 +86,9 @@ uint32_t test_start (void)
|
||||
else
|
||||
{
|
||||
/* Create test thread 1 */
|
||||
if (atomThreadCreate(&tcb1, TEST_THREAD_PRIO, test_thread_func, 0,
|
||||
&test1_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 0,
|
||||
&test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread 1\n"));
|
||||
@@ -93,8 +96,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create test thread 2 */
|
||||
else if (atomThreadCreate(&tcb2, TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test2_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
else if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread 2\n"));
|
||||
@@ -102,8 +106,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create test thread 3 */
|
||||
else if (atomThreadCreate(&tcb3, TEST_THREAD_PRIO, test_thread_func, 2,
|
||||
&test3_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
else if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 2,
|
||||
&test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Error creating test thread 3\n"));
|
||||
@@ -137,15 +142,38 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
/* Check thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
uint32_t used_bytes, free_bytes;
|
||||
int thread;
|
||||
|
||||
/* Check all threads */
|
||||
for (thread = 0; thread < NUM_TEST_THREADS; thread++)
|
||||
{
|
||||
/* Check thread stack usage */
|
||||
if (atomThreadStackCheck (&tcb[thread], &used_bytes, &free_bytes) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("StackCheck\n"));
|
||||
failures++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
ATOMLOG (_STR("StackOverflow %d\n"), thread);
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
@@ -189,4 +217,4 @@ static void test_thread_func (uint32_t data)
|
||||
{
|
||||
atomTimerDelay (SYSTEM_TICKS_PER_SEC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,15 +46,9 @@ uint32_t test_start (void)
|
||||
/* Default to zero failures */
|
||||
failures = 0;
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
}
|
||||
/* Run test and update "failures" count */
|
||||
|
||||
/* If threads are created, check for thread stack overflow */
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
|
||||
@@ -216,16 +216,6 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
}
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
|
||||
|
||||
@@ -36,12 +36,13 @@
|
||||
/* Test period (in seconds) */
|
||||
#define TEST_PERIOD_SECS 10
|
||||
|
||||
/* Number of test threads */
|
||||
#define NUM_TEST_THREADS 3
|
||||
|
||||
|
||||
/* Test OS objects */
|
||||
static ATOM_TCB tcb1, tcb2, tcb3;
|
||||
static uint8_t test1_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test2_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static uint8_t test3_thread_stack[TEST_THREAD_STACK_SIZE];
|
||||
static ATOM_TCB tcb[NUM_TEST_THREADS];
|
||||
static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE];
|
||||
|
||||
|
||||
/* Per-thread failure counts */
|
||||
@@ -71,8 +72,9 @@ uint32_t test_start (void)
|
||||
g_failure_cnt[0] = g_failure_cnt[1] = g_failure_cnt[2] = 0;
|
||||
|
||||
/* Create Thread 1 */
|
||||
if (atomThreadCreate(&tcb1, TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test1_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1,
|
||||
&test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Thread1\n"));
|
||||
@@ -80,8 +82,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create Thread 2 */
|
||||
if (atomThreadCreate(&tcb2, TEST_THREAD_PRIO, test_thread_func, 2,
|
||||
&test2_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test_thread_func, 2,
|
||||
&test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Thread2\n"));
|
||||
@@ -89,8 +92,9 @@ uint32_t test_start (void)
|
||||
}
|
||||
|
||||
/* Create Thread 3 */
|
||||
if (atomThreadCreate(&tcb3, TEST_THREAD_PRIO, test_thread_func, 3,
|
||||
&test3_thread_stack[TEST_THREAD_STACK_SIZE - 1]) != ATOM_OK)
|
||||
if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 3,
|
||||
&test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1],
|
||||
TEST_THREAD_STACK_SIZE) != ATOM_OK)
|
||||
{
|
||||
/* Fail */
|
||||
ATOMLOG (_STR("Thread3\n"));
|
||||
@@ -107,15 +111,38 @@ uint32_t test_start (void)
|
||||
/* Add the per-thread failure count to the main count */
|
||||
failures += g_failure_cnt[0] + g_failure_cnt[1] + g_failure_cnt[2];
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
/* Check thread stack usage (if enabled) */
|
||||
#ifdef ATOM_STACK_CHECKING
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
uint32_t used_bytes, free_bytes;
|
||||
int thread;
|
||||
|
||||
/* Check all threads */
|
||||
for (thread = 0; thread < NUM_TEST_THREADS; thread++)
|
||||
{
|
||||
/* Check thread stack usage */
|
||||
if (atomThreadStackCheck (&tcb[thread], &used_bytes, &free_bytes) != ATOM_OK)
|
||||
{
|
||||
ATOMLOG (_STR("StackCheck\n"));
|
||||
failures++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check the thread did not use up to the end of stack */
|
||||
if (free_bytes == 0)
|
||||
{
|
||||
ATOMLOG (_STR("StackOverflow %d\n"), thread);
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log the stack usage */
|
||||
#ifdef TESTS_LOG_STACK_USAGE
|
||||
ATOMLOG (_STR("StackUse:%d\n"), used_bytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
@@ -173,4 +200,4 @@ static void test_thread_func (uint32_t data)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,16 +202,6 @@ uint32_t test_start (void)
|
||||
failures++;
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
}
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
|
||||
|
||||
@@ -150,16 +150,6 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
}
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
|
||||
|
||||
@@ -121,16 +121,6 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
}
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
|
||||
|
||||
@@ -133,16 +133,6 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
}
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
|
||||
|
||||
@@ -141,16 +141,6 @@ uint32_t test_start (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log final status */
|
||||
if (failures == 0)
|
||||
{
|
||||
ATOMLOG (_STR("Pass\n"));
|
||||
}
|
||||
else
|
||||
{
|
||||
ATOMLOG (_STR("Fail(%d)\n"), failures);
|
||||
}
|
||||
|
||||
/* Quit */
|
||||
return failures;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user