From 68b0b7b9cd8ef478d11c6fb796b0647bc9270598 Mon Sep 17 00:00:00 2001 From: Przemek Wirkus Date: Wed, 1 Jun 2016 16:44:02 +0100 Subject: [PATCH] mbedmicro/mbed RTOS-mbed tests port to greentea-client --- TESTS/mbedmicro-rtos-mbed/basic/main.cpp | 41 ++++++++ TESTS/mbedmicro-rtos-mbed/isr/main.cpp | 68 ++++++++++++++ TESTS/mbedmicro-rtos-mbed/mail/main.cpp | 76 +++++++++++++++ TESTS/mbedmicro-rtos-mbed/mutex/main.cpp | 98 ++++++++++++++++++++ TESTS/mbedmicro-rtos-mbed/queue/main.cpp | 78 ++++++++++++++++ TESTS/mbedmicro-rtos-mbed/semaphore/main.cpp | 88 ++++++++++++++++++ TESTS/mbedmicro-rtos-mbed/signals/main.cpp | 53 +++++++++++ TESTS/mbedmicro-rtos-mbed/timer/main.cpp | 34 +++++++ 8 files changed, 536 insertions(+) create mode 100644 TESTS/mbedmicro-rtos-mbed/basic/main.cpp create mode 100644 TESTS/mbedmicro-rtos-mbed/isr/main.cpp create mode 100644 TESTS/mbedmicro-rtos-mbed/mail/main.cpp create mode 100644 TESTS/mbedmicro-rtos-mbed/mutex/main.cpp create mode 100644 TESTS/mbedmicro-rtos-mbed/queue/main.cpp create mode 100644 TESTS/mbedmicro-rtos-mbed/semaphore/main.cpp create mode 100644 TESTS/mbedmicro-rtos-mbed/signals/main.cpp create mode 100644 TESTS/mbedmicro-rtos-mbed/timer/main.cpp diff --git a/TESTS/mbedmicro-rtos-mbed/basic/main.cpp b/TESTS/mbedmicro-rtos-mbed/basic/main.cpp new file mode 100644 index 0000000000..c98d4c9a64 --- /dev/null +++ b/TESTS/mbedmicro-rtos-mbed/basic/main.cpp @@ -0,0 +1,41 @@ +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "rtos.h" + +/* + * 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 + +DigitalOut led1(LED1); +DigitalOut led2(LED2); + +void led2_thread(void const *argument) { + static int count = 0; + while (true) { + led2 = !led2; + Thread::wait(1000); + greentea_send_kv("tick", count++); + } +} + +int main() { + GREENTEA_SETUP(15, "wait_us_auto"); + + Thread thread(led2_thread, NULL, osPriorityNormal, STACK_SIZE); + + while (true) { + led1 = !led1; + Thread::wait(500); + } +} diff --git a/TESTS/mbedmicro-rtos-mbed/isr/main.cpp b/TESTS/mbedmicro-rtos-mbed/isr/main.cpp new file mode 100644 index 0000000000..ec16a4ea7a --- /dev/null +++ b/TESTS/mbedmicro-rtos-mbed/isr/main.cpp @@ -0,0 +1,68 @@ +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "rtos.h" + +#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 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) { + GREENTEA_SETUP(20, "default_auto"); + + 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; + } + } + } + + GREENTEA_TESTSUITE_RESULT(result); + return 0; +} diff --git a/TESTS/mbedmicro-rtos-mbed/mail/main.cpp b/TESTS/mbedmicro-rtos-mbed/mail/main.cpp new file mode 100644 index 0000000000..60e5117410 --- /dev/null +++ b/TESTS/mbedmicro-rtos-mbed/mail/main.cpp @@ -0,0 +1,76 @@ +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "rtos.h" + +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_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) { + GREENTEA_SETUP(20, "default_auto"); + + 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; + } + } + } + GREENTEA_TESTSUITE_RESULT(result); + return 0; +} diff --git a/TESTS/mbedmicro-rtos-mbed/mutex/main.cpp b/TESTS/mbedmicro-rtos-mbed/mutex/main.cpp new file mode 100644 index 0000000000..bbd29dec2e --- /dev/null +++ b/TESTS/mbedmicro-rtos-mbed/mutex/main.cpp @@ -0,0 +1,98 @@ +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "rtos.h" + +#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 +#elif defined(TARGET_STM32F303K8) && 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() { + GREENTEA_SETUP(20, "default_auto"); + + 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); + GREENTEA_TESTSUITE_RESULT(!mutex_defect); + return 0; +} diff --git a/TESTS/mbedmicro-rtos-mbed/queue/main.cpp b/TESTS/mbedmicro-rtos-mbed/queue/main.cpp new file mode 100644 index 0000000000..98dd5e13f6 --- /dev/null +++ b/TESTS/mbedmicro-rtos-mbed/queue/main.cpp @@ -0,0 +1,78 @@ +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "rtos.h" + +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 mpool; +Queue 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) { + GREENTEA_SETUP(20, "default_auto"); + + 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; + } + } + } + GREENTEA_TESTSUITE_RESULT(result); + return 0; +} diff --git a/TESTS/mbedmicro-rtos-mbed/semaphore/main.cpp b/TESTS/mbedmicro-rtos-mbed/semaphore/main.cpp new file mode 100644 index 0000000000..2024a0286e --- /dev/null +++ b/TESTS/mbedmicro-rtos-mbed/semaphore/main.cpp @@ -0,0 +1,88 @@ +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "rtos.h" + +#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 +#elif defined(TARGET_STM32F303K8) && defined(TOOLCHAIN_IAR) + #define STACK_SIZE DEFAULT_STACK_SIZE/4 +#else + #define STACK_SIZE DEFAULT_STACK_SIZE +#endif + +void print_char(char c = '*') { + printf("%c", c); + fflush(stdout); +} + +Semaphore two_slots(SEMAPHORE_SLOTS); + +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) { + two_slots.wait(); + 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++; + two_slots.release(); + } +} + +int main (void) { + GREENTEA_SETUP(20, "default_auto"); + + 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); + GREENTEA_TESTSUITE_RESULT(!sem_defect); + return 0; +} diff --git a/TESTS/mbedmicro-rtos-mbed/signals/main.cpp b/TESTS/mbedmicro-rtos-mbed/signals/main.cpp new file mode 100644 index 0000000000..866b67d0eb --- /dev/null +++ b/TESTS/mbedmicro-rtos-mbed/signals/main.cpp @@ -0,0 +1,53 @@ +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "rtos.h" + +#define SIGNAL_SET_VALUE 0x01 +const int SIGNALS_TO_EMIT = 100; +const int SIGNAL_HANDLE_DELEY = 25; + +/* + * 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); +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) { + GREENTEA_SETUP(20, "default_auto"); + + Thread thread(led_thread, NULL, osPriorityNormal, STACK_SIZE); + bool result = false; + + printf("Handling %d signals...\r\n", SIGNALS_TO_EMIT); + + 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); + result = true; + break; + } + } + GREENTEA_TESTSUITE_RESULT(result); + return 0; +} diff --git a/TESTS/mbedmicro-rtos-mbed/timer/main.cpp b/TESTS/mbedmicro-rtos-mbed/timer/main.cpp new file mode 100644 index 0000000000..e643333ad6 --- /dev/null +++ b/TESTS/mbedmicro-rtos-mbed/timer/main.cpp @@ -0,0 +1,34 @@ +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "rtos.h" + +DigitalOut LEDs[4] = { + DigitalOut(LED1), DigitalOut(LED2), DigitalOut(LED3), DigitalOut(LED4) +}; + +void blink(void const *n) { + static int blink_counter = 0; + static int count = 0; + const int led_id = int(n); + LEDs[led_id] = !LEDs[led_id]; + if (++blink_counter == 75) { + greentea_send_kv("tick", count++); + blink_counter = 0; + } +} + +int main(void) { + GREENTEA_SETUP(15, "wait_us_auto"); + + 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); +}