mbed-rtos test programs for DISCO_F746NG. #Test for thread, mutex, semaphore, signals, queues, mail, ISR

Dependencies:   mbed-rtos mbed-src

Revision:
0:225c1da086a1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Nov 11 07:53:46 2015 +0000
@@ -0,0 +1,591 @@
+#include "mbed.h"
+#include "test_env.h"
+#include "rtos.h"
+
+/********************
+ * Switch test case
+ ********************/
+#define TEST_84_BASIC
+//#define TEST_85_MUTEX
+//#define TEST_86_SEMAPHORE
+//#define TEST_87_SIGNALS
+//#define TEST_88_QUEUE
+//#define TEST_89_MAIL
+//#define TEST_90_TIMER
+//#define TEST_91_ISR
+
+#if defined(TEST_84_BASIC)
+
+/*
+ * The stack size is defined in cmsis_os.h mainly dependent on the underlying toolchain and
+ * the C standard library. For GCC, ARM_STD and IAR it is defined with a size of 2048 bytes
+ * and for ARM_MICRO 512. Because of reduce RAM size some targets need a reduced stacksize.
+ */
+#if (defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8)) && defined(TOOLCHAIN_GCC)
+#define STACK_SIZE DEFAULT_STACK_SIZE/2
+#elif (defined(TARGET_STM32F030R8) || defined(TARGET_STM32F070RB)) && defined(TOOLCHAIN_GCC)
+#define STACK_SIZE DEFAULT_STACK_SIZE/2
+#elif (defined(TARGET_STM32F030R8)) && defined(TOOLCHAIN_IAR)
+#define STACK_SIZE DEFAULT_STACK_SIZE/2
+#else
+#define STACK_SIZE DEFAULT_STACK_SIZE
+#endif
+
+void print_char(char c = '*') {
+    printf("%c", c);
+    fflush(stdout);
+}
+
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+
+void led2_thread(void const *argument) {
+    while (true) {
+        led2 = !led2;
+        Thread::wait(1000);
+        print_char();
+    }
+}
+
+int main() {
+    MBED_HOSTTEST_TIMEOUT(15);
+    MBED_HOSTTEST_SELECT(wait_us_auto);
+    MBED_HOSTTEST_DESCRIPTION(Basic thread);
+    MBED_HOSTTEST_START("RTOS_1");
+
+    Thread thread(led2_thread, NULL, osPriorityNormal, STACK_SIZE);
+
+    while (true) {
+        led1 = !led1;
+        Thread::wait(500);
+    }
+}
+
+#elif defined(TEST_85_MUTEX)
+
+#define THREAD_DELAY     50
+#define SIGNALS_TO_EMIT  100
+
+/*
+ * The stack size is defined in cmsis_os.h mainly dependent on the underlying toolchain and
+ * the C standard library. For GCC, ARM_STD and IAR it is defined with a size of 2048 bytes
+ * and for ARM_MICRO 512. Because of reduce RAM size some targets need a reduced stacksize.
+ */
+#if (defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8)) && defined(TOOLCHAIN_GCC)
+    #define STACK_SIZE DEFAULT_STACK_SIZE/4
+#elif (defined(TARGET_STM32F030R8) || defined(TARGET_STM32F070RB)) && defined(TOOLCHAIN_GCC)
+    #define STACK_SIZE DEFAULT_STACK_SIZE/4
+#elif defined(TARGET_STM32F334R8) && defined(TOOLCHAIN_IAR)
+    #define STACK_SIZE DEFAULT_STACK_SIZE/4
+#elif defined(TARGET_STM32F030R8) && defined(TOOLCHAIN_IAR)
+    #define STACK_SIZE DEFAULT_STACK_SIZE/4 
+#elif defined(TARGET_STM32F070RB) && defined(TOOLCHAIN_IAR)
+    #define STACK_SIZE DEFAULT_STACK_SIZE/2 
+#elif defined(TARGET_STM32F072RB) && defined(TOOLCHAIN_IAR)
+    #define STACK_SIZE DEFAULT_STACK_SIZE/2 
+#elif defined(TARGET_STM32F302R8) && defined(TOOLCHAIN_IAR)
+    #define STACK_SIZE DEFAULT_STACK_SIZE/2     
+#else
+    #define STACK_SIZE DEFAULT_STACK_SIZE
+#endif
+
+void print_char(char c = '*') {
+    printf("%c", c);
+    fflush(stdout);
+}
+
+Mutex stdio_mutex;
+DigitalOut led(LED1);
+
+volatile int change_counter = 0;
+volatile bool changing_counter = false;
+volatile bool mutex_defect = false;
+
+bool manipulate_protected_zone(const int thread_delay) {
+    bool result = true;
+
+    stdio_mutex.lock(); // LOCK
+    if (changing_counter == true) {
+        // 'e' stands for error. If changing_counter is true access is not exclusively
+        print_char('e');
+        result = false;
+        mutex_defect = true;
+    }
+    changing_counter = true;
+
+    // Some action on protected
+    led = !led;
+    change_counter++;
+    print_char('.');
+    Thread::wait(thread_delay);
+
+    changing_counter = false;
+    stdio_mutex.unlock();   // UNLOCK
+    return result;
+}
+
+void test_thread(void const *args) {
+    const int thread_delay = int(args);
+    while (true) {
+        manipulate_protected_zone(thread_delay);
+    }
+}
+
+int main() {
+    MBED_HOSTTEST_TIMEOUT(20);
+    MBED_HOSTTEST_SELECT(default);
+    MBED_HOSTTEST_DESCRIPTION(Mutex resource lock);
+    MBED_HOSTTEST_START("RTOS_2");
+
+    const int t1_delay = THREAD_DELAY * 1;
+    const int t2_delay = THREAD_DELAY * 2;
+    const int t3_delay = THREAD_DELAY * 3;
+    Thread t2(test_thread, (void *)t2_delay, osPriorityNormal, STACK_SIZE);
+    Thread t3(test_thread, (void *)t3_delay, osPriorityNormal, STACK_SIZE);
+
+    while (true) {
+        // Thread 1 action
+        Thread::wait(t1_delay);
+        manipulate_protected_zone(t1_delay);
+        if (change_counter >= SIGNALS_TO_EMIT or mutex_defect == true) {
+            t2.terminate();
+            t3.terminate();
+            break;
+        }
+    }
+
+    fflush(stdout);
+    MBED_HOSTTEST_RESULT(!mutex_defect);
+    return 0;
+}
+
+#elif defined(TEST_86_SEMAPHORE)
+
+#define THREAD_DELAY     75
+#define SEMAPHORE_SLOTS  2
+#define SEM_CHANGES      100
+
+/*
+ * The stack size is defined in cmsis_os.h mainly dependent on the underlying toolchain and
+ * the C standard library. For GCC, ARM_STD and IAR it is defined with a size of 2048 bytes
+ * and for ARM_MICRO 512. Because of reduce RAM size some targets need a reduced stacksize.
+ */
+#if (defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8)) && defined(TOOLCHAIN_GCC)
+    #define STACK_SIZE DEFAULT_STACK_SIZE/16
+#elif (defined(TARGET_STM32F030R8) || defined(TARGET_STM32F070RB)) && defined(TOOLCHAIN_GCC)
+    #define STACK_SIZE DEFAULT_STACK_SIZE/8
+#elif defined(TARGET_STM32F334R8) && (defined(TOOLCHAIN_GCC) || defined(TOOLCHAIN_IAR))
+    #define STACK_SIZE DEFAULT_STACK_SIZE/4
+#elif defined(TARGET_STM32F103RB) && defined(TOOLCHAIN_IAR)
+    #define STACK_SIZE DEFAULT_STACK_SIZE/4
+#elif defined(TARGET_STM32F030R8) && defined(TOOLCHAIN_IAR)
+    #define STACK_SIZE DEFAULT_STACK_SIZE/4 
+#elif defined(TARGET_STM32F070RB) && defined(TOOLCHAIN_IAR)
+    #define STACK_SIZE DEFAULT_STACK_SIZE/2 
+#elif defined(TARGET_STM32F072RB) && defined(TOOLCHAIN_IAR)
+    #define STACK_SIZE DEFAULT_STACK_SIZE/2 
+#elif defined(TARGET_STM32F302R8) && defined(TOOLCHAIN_IAR)
+    #define STACK_SIZE DEFAULT_STACK_SIZE/2     
+#else
+    #define STACK_SIZE DEFAULT_STACK_SIZE
+#endif
+
+void print_char(char c = '*') {
+    printf("%c", c);
+    fflush(stdout);
+}
+
+#define ORIGINAL 1
+#undef ORIGINAL
+
+#if ORIGINAL
+Semaphore two_slots(SEMAPHORE_SLOTS);
+#else
+Semaphore *two_slots;
+#endif
+
+volatile int change_counter = 0;
+volatile int sem_counter = 0;
+volatile bool sem_defect = false;
+
+void test_thread(void const *delay) {
+    const int thread_delay = int(delay);
+    while (true) {
+#if ORIGINAL
+        two_slots.wait();
+#else
+        two_slots->wait();
+#endif
+        sem_counter++;
+        const bool sem_lock_failed = sem_counter > SEMAPHORE_SLOTS;
+        const char msg = sem_lock_failed ? 'e' : sem_counter + '0';
+        print_char(msg);
+        if (sem_lock_failed) {
+            sem_defect = true;
+        }
+        Thread::wait(thread_delay);
+        print_char('.');
+        sem_counter--;
+        change_counter++;
+#if ORIGINAL
+        two_slots.release();
+#else
+        two_slots->release();
+#endif
+    }
+}
+
+int main (void) {
+
+#ifndef ORIGINAL
+    two_slots = new Semaphore(SEMAPHORE_SLOTS);
+#endif
+
+    MBED_HOSTTEST_TIMEOUT(20);
+    MBED_HOSTTEST_SELECT(default_auto);
+    MBED_HOSTTEST_DESCRIPTION(Semaphore resource lock);
+    MBED_HOSTTEST_START("RTOS_3");
+
+    const int t1_delay = THREAD_DELAY * 1;
+    const int t2_delay = THREAD_DELAY * 2;
+    const int t3_delay = THREAD_DELAY * 3;
+    Thread t1(test_thread, (void *)t1_delay, osPriorityNormal, STACK_SIZE);
+    Thread t2(test_thread, (void *)t2_delay, osPriorityNormal, STACK_SIZE);
+    Thread t3(test_thread, (void *)t3_delay, osPriorityNormal, STACK_SIZE);
+
+    while (true) {
+        if (change_counter >= SEM_CHANGES or sem_defect == true) {
+            t1.terminate();
+            t2.terminate();
+            t3.terminate();
+            break;
+        }
+    }
+
+    fflush(stdout);
+    MBED_HOSTTEST_RESULT(!sem_defect);
+    return 0;
+}
+
+#elif defined(TEST_87_SIGNALS)
+
+#define SIGNALS_TO_EMIT     100
+#define SIGNAL_HANDLE_DELEY 25
+#define SIGNAL_SET_VALUE    0x01
+
+/*
+ * The stack size is defined in cmsis_os.h mainly dependent on the underlying toolchain and
+ * the C standard library. For GCC, ARM_STD and IAR it is defined with a size of 2048 bytes
+ * and for ARM_MICRO 512. Because of reduce RAM size some targets need a reduced stacksize.
+ */
+#if defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8)
+    #define STACK_SIZE DEFAULT_STACK_SIZE/4
+#elif (defined(TARGET_STM32F030R8)) && defined(TOOLCHAIN_IAR)
+    #define STACK_SIZE DEFAULT_STACK_SIZE/2
+#else
+    #define STACK_SIZE DEFAULT_STACK_SIZE
+#endif
+
+DigitalOut led(LED1);
+volatile int signal_counter = 0;
+
+void led_thread(void const *argument) {
+    while (true) {
+        // Signal flags that are reported as event are automatically cleared.
+        Thread::signal_wait(SIGNAL_SET_VALUE);
+        led = !led;
+        signal_counter++;
+    }
+}
+
+int main (void) {
+    MBED_HOSTTEST_TIMEOUT(20);
+    MBED_HOSTTEST_SELECT(default_auto);
+    MBED_HOSTTEST_DESCRIPTION(Signals messaging);
+    MBED_HOSTTEST_START("RTOS_4");
+
+    Thread thread(led_thread, NULL, osPriorityNormal, STACK_SIZE);
+    bool result = true;
+
+    while (true) {
+        Thread::wait(2 * SIGNAL_HANDLE_DELEY);
+        thread.signal_set(SIGNAL_SET_VALUE);
+        if (signal_counter == SIGNALS_TO_EMIT) {
+            printf("Handled %d signals\r\n", signal_counter);
+            break;
+        }
+    }
+    MBED_HOSTTEST_RESULT(result);
+    return 0;
+}
+
+#elif defined(TEST_88_QUEUE)
+
+typedef struct {
+    float    voltage;   /* AD result of measured voltage */
+    float    current;   /* AD result of measured current */
+    uint32_t counter;   /* A counter value               */
+} message_t;
+
+#define CREATE_VOLTAGE(COUNTER) (COUNTER * 0.1) * 33
+#define CREATE_CURRENT(COUNTER) (COUNTER * 0.1) * 11
+#define QUEUE_SIZE       16
+#define QUEUE_PUT_DELAY  100
+
+/*
+ * The stack size is defined in cmsis_os.h mainly dependent on the underlying toolchain and
+ * the C standard library. For GCC, ARM_STD and IAR it is defined with a size of 2048 bytes
+ * and for ARM_MICRO 512. Because of reduce RAM size some targets need a reduced stacksize.
+ */
+#if (defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8)) && defined(TOOLCHAIN_GCC)
+    #define STACK_SIZE DEFAULT_STACK_SIZE/4
+#elif (defined(TARGET_STM32F030R8)) && defined(TOOLCHAIN_GCC)
+    #define STACK_SIZE DEFAULT_STACK_SIZE/4
+#elif (defined(TARGET_STM32F030R8)) && defined(TOOLCHAIN_IAR)
+    #define STACK_SIZE DEFAULT_STACK_SIZE/2
+#else
+    #define STACK_SIZE DEFAULT_STACK_SIZE
+#endif
+
+MemoryPool<message_t, QUEUE_SIZE> mpool;
+Queue<message_t, QUEUE_SIZE> queue;
+
+/* Send Thread */
+void send_thread (void const *argument) {
+    static uint32_t i = 10;
+    while (true) {
+        i++; // Fake data update
+        message_t *message = mpool.alloc();
+        message->voltage = CREATE_VOLTAGE(i);
+        message->current = CREATE_CURRENT(i);
+        message->counter = i;
+        queue.put(message);
+        Thread::wait(QUEUE_PUT_DELAY);
+    }
+}
+
+int main (void) {
+    MBED_HOSTTEST_TIMEOUT(20);
+    MBED_HOSTTEST_SELECT(default_auto);
+    MBED_HOSTTEST_DESCRIPTION(Queue messaging);
+    MBED_HOSTTEST_START("RTOS_5");
+
+    Thread thread(send_thread, NULL, osPriorityNormal, STACK_SIZE);
+    bool result = true;
+    int result_counter = 0;
+
+    while (true) {
+        osEvent evt = queue.get();
+        if (evt.status == osEventMessage) {
+            message_t *message = (message_t*)evt.value.p;
+            const float expected_voltage = CREATE_VOLTAGE(message->counter);
+            const float expected_current = CREATE_CURRENT(message->counter);
+            // Check using macros if received values correspond to values sent via queue
+            bool expected_values = (expected_voltage == message->voltage) &&
+                                   (expected_current == message->current);
+            result = result && expected_values;
+            const char *result_msg = expected_values ? "OK" : "FAIL";
+            printf("%3d %.2fV %.2fA ... [%s]\r\n", message->counter,
+                                                   message->voltage,
+                                                   message->current,
+                                                   result_msg);
+            mpool.free(message);
+            if (result == false || ++result_counter == QUEUE_SIZE) {
+                break;
+            }
+        }
+    }
+    MBED_HOSTTEST_RESULT(result);
+    return 0;
+}
+
+#elif defined(TEST_89_MAIL)
+
+typedef struct {
+    float    voltage;   /* AD result of measured voltage */
+    float    current;   /* AD result of measured current */
+    uint32_t counter;   /* A counter value               */
+} mail_t;
+
+#define CREATE_VOLTAGE(COUNTER) (COUNTER * 0.1) * 33
+#define CREATE_CURRENT(COUNTER) (COUNTER * 0.1) * 11
+#define QUEUE_SIZE       16
+#define QUEUE_PUT_DELAY  100
+
+/*
+ * The stack size is defined in cmsis_os.h mainly dependent on the underlying toolchain and
+ * the C standard library. For GCC, ARM_STD and IAR it is defined with a size of 2048 bytes
+ * and for ARM_MICRO 512. Because of reduce RAM size some targets need a reduced stacksize.
+ */
+#if (defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8)) && defined(TOOLCHAIN_GCC)
+    #define STACK_SIZE DEFAULT_STACK_SIZE/4
+#elif (defined(TARGET_STM32F030R8)) && defined(TOOLCHAIN_GCC)
+    #define STACK_SIZE DEFAULT_STACK_SIZE/2
+#elif (defined(TARGET_STM32F030R8)) && defined(TOOLCHAIN_IAR)
+    #define STACK_SIZE DEFAULT_STACK_SIZE/2
+#else
+    #define STACK_SIZE DEFAULT_STACK_SIZE
+#endif
+
+Mail<mail_t, QUEUE_SIZE> mail_box;
+
+void send_thread (void const *argument) {
+    static uint32_t i = 10;
+    while (true) {
+        i++; // fake data update
+        mail_t *mail = mail_box.alloc();
+        mail->voltage = CREATE_VOLTAGE(i);
+        mail->current = CREATE_CURRENT(i);
+        mail->counter = i;
+        mail_box.put(mail);
+        Thread::wait(QUEUE_PUT_DELAY);
+    }
+}
+
+int main (void) {
+    MBED_HOSTTEST_TIMEOUT(20);
+    MBED_HOSTTEST_SELECT(default_auto);
+    MBED_HOSTTEST_DESCRIPTION(Mail messaging);
+    MBED_HOSTTEST_START("RTOS_6");
+
+    Thread thread(send_thread, NULL, osPriorityNormal, STACK_SIZE);
+    bool result = true;
+    int result_counter = 0;
+
+    while (true) {
+        osEvent evt = mail_box.get();
+        if (evt.status == osEventMail) {
+            mail_t *mail = (mail_t*)evt.value.p;
+            const float expected_voltage = CREATE_VOLTAGE(mail->counter);
+            const float expected_current = CREATE_CURRENT(mail->counter);
+            // Check using macros if received values correspond to values sent via queue
+            bool expected_values = (expected_voltage == mail->voltage) &&
+                                   (expected_current == mail->current);
+            result = result && expected_values;
+            const char *result_msg = expected_values ? "OK" : "FAIL";
+            printf("%3d %.2fV %.2fA ... [%s]\r\n", mail->counter,
+                                                   mail->voltage,
+                                                   mail->current,
+                                                   result_msg);
+            mail_box.free(mail);
+            if (result == false || ++result_counter == QUEUE_SIZE) {
+                break;
+            }
+        }
+    }
+    MBED_HOSTTEST_RESULT(result);
+    return 0;
+}
+
+#elif defined(TEST_90_TIMER)
+
+DigitalOut LEDs[4] = {
+    DigitalOut(LED1), DigitalOut(LED2), DigitalOut(LED3), DigitalOut(LED4)
+};
+
+void print_char(char c = '*')
+{
+    printf("%c", c);
+    fflush(stdout);
+}
+
+void blink(void const *n) {
+    static int counter = 0;
+    const int led_id = int(n);
+    LEDs[led_id] = !LEDs[led_id];
+    if (++counter == 75) {
+        print_char();
+        counter = 0;
+    }
+}
+
+int main(void) {
+    MBED_HOSTTEST_TIMEOUT(15);
+    MBED_HOSTTEST_SELECT(wait_us_auto);
+    MBED_HOSTTEST_DESCRIPTION(Timer);
+    MBED_HOSTTEST_START("RTOS_7");
+
+    RtosTimer led_1_timer(blink, osTimerPeriodic, (void *)0);
+    RtosTimer led_2_timer(blink, osTimerPeriodic, (void *)1);
+    RtosTimer led_3_timer(blink, osTimerPeriodic, (void *)2);
+    RtosTimer led_4_timer(blink, osTimerPeriodic, (void *)3);
+
+    led_1_timer.start(200);
+    led_2_timer.start(100);
+    led_3_timer.start(50);
+    led_4_timer.start(25);
+
+    Thread::wait(osWaitForever);
+}
+
+#elif defined(TEST_91_ISR)
+
+#define QUEUE_SIZE              5
+#define THREAD_DELAY            250
+#define QUEUE_PUT_ISR_VALUE     128
+#define QUEUE_PUT_THREAD_VALUE  127
+
+/*
+ * The stack size is defined in cmsis_os.h mainly dependent on the underlying toolchain and
+ * the C standard library. For GCC, ARM_STD and IAR it is defined with a size of 2048 bytes
+ * and for ARM_MICRO 512. Because of reduce RAM size some targets need a reduced stacksize.
+ */
+#if defined(TARGET_STM32L053R8) || defined(TARGET_STM32L053C8)
+    #define STACK_SIZE DEFAULT_STACK_SIZE/4
+#elif (defined(TARGET_STM32F030R8)) && defined(TOOLCHAIN_IAR)
+    #define STACK_SIZE DEFAULT_STACK_SIZE/2
+#else
+    #define STACK_SIZE DEFAULT_STACK_SIZE
+#endif
+
+Queue<uint32_t, QUEUE_SIZE> queue;
+
+DigitalOut myled(LED1);
+
+void queue_isr() {
+
+    queue.put((uint32_t*)QUEUE_PUT_ISR_VALUE);
+    myled = !myled;
+}
+
+void queue_thread(void const *argument) {
+    while (true) {
+        queue.put((uint32_t*)QUEUE_PUT_THREAD_VALUE);
+        Thread::wait(THREAD_DELAY);
+    }
+}
+
+int main (void) {
+    MBED_HOSTTEST_TIMEOUT(20);
+    MBED_HOSTTEST_SELECT(default_auto);
+    MBED_HOSTTEST_DESCRIPTION(ISR (Queue));
+    MBED_HOSTTEST_START("RTOS_8");
+
+    Thread thread(queue_thread, NULL, osPriorityNormal, STACK_SIZE);
+    Ticker ticker;
+    ticker.attach(queue_isr, 1.0);
+    int isr_puts_counter = 0;
+    bool result = true;
+
+    while (true) {
+        osEvent evt = queue.get();
+        if (evt.status != osEventMessage) {
+            printf("QUEUE_GET: Status(0x%02X) ... [FAIL]\r\n", evt.status);
+            result = false;
+            break;
+        } else {
+            printf("QUEUE_GET: Value(%u) ... [OK]\r\n", evt.value.v);
+            if (evt.value.v == QUEUE_PUT_ISR_VALUE) {
+                isr_puts_counter++;
+            }
+            if (isr_puts_counter >= QUEUE_SIZE) {
+                break;
+            }
+        }
+    }
+
+    MBED_HOSTTEST_RESULT(result);
+    return 0;
+}
+
+#endif