Greg Steiert / pegasus_dev

Dependents:   blinky_max32630fthr

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "greentea-client/test_env.h"
00003 #include "unity.h"
00004 #include "utest.h"
00005 #include "rtos.h"
00006 #include "SynchronizedIntegral.h"
00007 #include "LockGuard.h"
00008 
00009 #if defined(MBED_RTOS_SINGLE_THREAD)
00010   #error [NOT_SUPPORTED] test not supported
00011 #endif
00012 
00013 /*
00014  * The stack size is defined in cmsis_os.h mainly dependent on the underlying toolchain and
00015  * the C standard library. For GCC, ARM_STD and IAR it is defined with a size of 2048 bytes
00016  * and for ARM_MICRO 512. Because of reduce RAM size some targets need a reduced stacksize.
00017  */
00018 #if defined(TARGET_MCU_NRF51822) || defined(TARGET_MCU_NRF52832)
00019     #define STACK_SIZE 512
00020 #elif defined(TARGET_STM32F070RB) || defined(TARGET_STM32F072RB) || defined(TARGET_STM32F103RB) || defined(TARGET_STM32F091RC)
00021     #define STACK_SIZE 512
00022 #elif defined(TARGET_STM32F410RB)
00023     #define STACK_SIZE 512
00024 #elif defined(TARGET_STM32L073RZ)
00025     #define STACK_SIZE 512
00026 #elif defined(TARGET_XDOT_L151CC)
00027     #define STACK_SIZE 1024
00028 #elif defined(TARGET_HI2110)
00029     #define STACK_SIZE 512
00030 #else
00031     #define STACK_SIZE DEFAULT_STACK_SIZE
00032 #endif
00033 
00034 using namespace utest::v1;
00035 
00036 // The counter type used accross all the tests
00037 // It is internall ysynchronized so read
00038 typedef SynchronizedIntegral<int> counter_t;
00039 
00040 // Tasks with different functions to test on threads
00041 void increment(counter_t* counter) {
00042     (*counter)++;
00043 }
00044 
00045 void increment_with_yield(counter_t* counter) {
00046     Thread::yield();
00047     (*counter)++;
00048 }
00049 
00050 void increment_with_wait(counter_t* counter) {
00051     Thread::wait(100);
00052     (*counter)++;
00053 }
00054 
00055 void increment_with_child(counter_t* counter) {
00056     Thread child(counter, increment, osPriorityNormal, STACK_SIZE);
00057     child.join();
00058 }
00059 
00060 void increment_with_murder(counter_t* counter) {
00061     {
00062         // take ownership of the counter mutex so it prevent the child to
00063         // modify counter.
00064         LockGuard lock(counter->internal_mutex());
00065         Thread child(counter, increment, osPriorityNormal, STACK_SIZE);
00066         child.terminate();
00067     }
00068 
00069     (*counter)++;
00070 }
00071 
00072 void self_terminate(Thread *self) {
00073     self->terminate();
00074     // Code should not get here
00075     TEST_ASSERT(0);
00076 }
00077 
00078 // Tests that spawn tasks in different configurations
00079 template <void (*F)(counter_t *)>
00080 void test_single_thread() {
00081     counter_t counter(0);
00082     Thread thread(&counter, F, osPriorityNormal, STACK_SIZE);
00083     thread.join();
00084     TEST_ASSERT_EQUAL(counter, 1);
00085 }
00086 
00087 template <int N, void (*F)(counter_t *)>
00088 void test_parallel_threads() {
00089     counter_t counter(0);
00090     Thread *threads[N];
00091 
00092     for (int i = 0; i < N; i++) {
00093         threads[i] = new Thread(&counter, F, osPriorityNormal, STACK_SIZE);
00094     }
00095 
00096     for (int i = 0; i < N; i++) {
00097         threads[i]->join();
00098         delete threads[i];
00099     }
00100 
00101     TEST_ASSERT_EQUAL(counter, N);
00102 }
00103 
00104 template <int N, void (*F)(counter_t *)>
00105 void test_serial_threads() {
00106     counter_t counter(0);
00107 
00108     for (int i = 0; i < N; i++) {
00109         Thread thread(&counter, F, osPriorityNormal, STACK_SIZE);
00110         thread.join();
00111     }
00112 
00113     TEST_ASSERT_EQUAL(counter, N);
00114 }
00115 
00116 void test_self_terminate() {
00117     Thread *thread = new Thread(osPriorityNormal, STACK_SIZE);
00118     thread->start(thread, self_terminate);
00119     thread->join();
00120     delete thread;
00121 }
00122 
00123 utest::v1::status_t  test_setup(const size_t number_of_cases) {
00124     GREENTEA_SETUP(40, "default_auto");
00125     return verbose_test_setup_handler(number_of_cases);
00126 }
00127 
00128 // Test cases
00129 Case cases[] = {
00130     Case("Testing single thread", test_single_thread<increment>),
00131     Case("Testing parallel threads", test_parallel_threads<3, increment>),
00132     Case("Testing serial threads", test_serial_threads<10, increment>),
00133 
00134     Case("Testing single thread with yield", test_single_thread<increment_with_yield>),
00135     Case("Testing parallel threads with yield", test_parallel_threads<3, increment_with_yield>),
00136     Case("Testing serial threads with yield", test_serial_threads<10, increment_with_yield>),
00137 
00138     Case("Testing single thread with wait", test_single_thread<increment_with_wait>),
00139     Case("Testing parallel threads with wait", test_parallel_threads<3, increment_with_wait>),
00140     Case("Testing serial threads with wait", test_serial_threads<10, increment_with_wait>),
00141 
00142     Case("Testing single thread with child", test_single_thread<increment_with_child>),
00143     Case("Testing parallel threads with child", test_parallel_threads<2, increment_with_child>),
00144     Case("Testing serial threads with child", test_serial_threads<10, increment_with_child>),
00145 
00146     Case("Testing single thread with murder", test_single_thread<increment_with_murder>),
00147     Case("Testing parallel threads with murder", test_parallel_threads<3, increment_with_murder>),
00148     Case("Testing serial threads with murder", test_serial_threads<10, increment_with_murder>),
00149 
00150     Case("Testing thread self terminate", test_self_terminate),
00151 };
00152 
00153 Specification specification(test_setup, cases);
00154 
00155 int main() {
00156     return !Harness::run(specification);
00157 }