mirror of
https://github.com/kelvinlawson/atomthreads.git
synced 2026-09-28 00:00:20 +02: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:
+50
-21
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user