WORKS

Dependencies:   MAX44000 PWM_Tone_Library nexpaq_mdk

Fork of LED_Demo by Maxim nexpaq

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 #else
00021     #define STACK_SIZE DEFAULT_STACK_SIZE
00022 #endif
00023 
00024 using namespace utest::v1;
00025 
00026 // The counter type used accross all the tests
00027 // It is internall ysynchronized so read
00028 typedef SynchronizedIntegral<int> counter_t;
00029 
00030 // Tasks with different functions to test on threads
00031 void increment(counter_t* counter) {
00032     (*counter)++;
00033 }
00034 
00035 void increment_with_yield(counter_t* counter) {
00036     Thread::yield();
00037     (*counter)++;
00038 }
00039 
00040 void increment_with_wait(counter_t* counter) {
00041     Thread::wait(100);
00042     (*counter)++;
00043 }
00044 
00045 void increment_with_child(counter_t* counter) {
00046     Thread child(counter, increment, osPriorityNormal, STACK_SIZE);
00047     child.join();
00048 }
00049 
00050 void increment_with_murder(counter_t* counter) {
00051     {
00052         // take ownership of the counter mutex so it prevent the child to
00053         // modify counter.
00054         LockGuard lock(counter->internal_mutex());
00055         Thread child(counter, increment, osPriorityNormal, STACK_SIZE);
00056         child.terminate();
00057     }
00058 
00059     (*counter)++;
00060 }
00061 
00062 void self_terminate(Thread *self) {
00063     self->terminate();
00064     // Code should not get here
00065     TEST_ASSERT(0);
00066 }
00067 
00068 // Tests that spawn tasks in different configurations
00069 template <void (*F)(counter_t *)>
00070 void test_single_thread() {
00071     counter_t counter(0);
00072     Thread thread(&counter, F, osPriorityNormal, STACK_SIZE);
00073     thread.join();
00074     TEST_ASSERT_EQUAL(counter, 1);
00075 }
00076 
00077 template <int N, void (*F)(counter_t *)>
00078 void test_parallel_threads() {
00079     counter_t counter(0);
00080     Thread *threads[N];
00081 
00082     for (int i = 0; i < N; i++) {
00083         threads[i] = new Thread(&counter, F, osPriorityNormal, STACK_SIZE);
00084     }
00085 
00086     for (int i = 0; i < N; i++) {
00087         threads[i]->join();
00088         delete threads[i];
00089     }
00090 
00091     TEST_ASSERT_EQUAL(counter, N);
00092 }
00093 
00094 template <int N, void (*F)(counter_t *)>
00095 void test_serial_threads() {
00096     counter_t counter(0);
00097 
00098     for (int i = 0; i < N; i++) {
00099         Thread thread(&counter, F, osPriorityNormal, STACK_SIZE);
00100         thread.join();
00101     }
00102 
00103     TEST_ASSERT_EQUAL(counter, N);
00104 }
00105 
00106 void test_self_terminate() {
00107     Thread *thread = new Thread(osPriorityNormal, STACK_SIZE);
00108     thread->start(thread, self_terminate);
00109     thread->join();
00110     delete thread;
00111 }
00112 
00113 utest::v1::status_t test_setup(const size_t number_of_cases) {
00114     GREENTEA_SETUP(40, "default_auto");
00115     return verbose_test_setup_handler(number_of_cases);
00116 }
00117 
00118 // Test cases
00119 Case cases[] = {
00120     Case("Testing single thread", test_single_thread<increment>),
00121     Case("Testing parallel threads", test_parallel_threads<3, increment>),
00122     Case("Testing serial threads", test_serial_threads<10, increment>),
00123 
00124     Case("Testing single thread with yield", test_single_thread<increment_with_yield>),
00125     Case("Testing parallel threads with yield", test_parallel_threads<3, increment_with_yield>),
00126     Case("Testing serial threads with yield", test_serial_threads<10, increment_with_yield>),
00127 
00128     Case("Testing single thread with wait", test_single_thread<increment_with_wait>),
00129     Case("Testing parallel threads with wait", test_parallel_threads<3, increment_with_wait>),
00130     Case("Testing serial threads with wait", test_serial_threads<10, increment_with_wait>),
00131 
00132     Case("Testing single thread with child", test_single_thread<increment_with_child>),
00133     Case("Testing parallel threads with child", test_parallel_threads<2, increment_with_child>),
00134     Case("Testing serial threads with child", test_serial_threads<10, increment_with_child>),
00135 
00136     Case("Testing single thread with murder", test_single_thread<increment_with_murder>),
00137     Case("Testing parallel threads with murder", test_parallel_threads<3, increment_with_murder>),
00138     Case("Testing serial threads with murder", test_serial_threads<10, increment_with_murder>),
00139 
00140     Case("Testing thread self terminate", test_self_terminate),
00141 };
00142 
00143 Specification specification(test_setup, cases);
00144 
00145 int main() {
00146     return !Harness::run(specification);
00147 }