From a4dcd16b170811a4dd453983c1187fa52626eb7e Mon Sep 17 00:00:00 2001 From: Przemek Wirkus Date: Wed, 1 Jun 2016 15:33:17 +0100 Subject: [PATCH 01/16] mbed-drivers test cases port to mbed-os --- TESTS/mbed_drivers/c_strings/main.cpp | 124 +++++++++++++++++++ TESTS/mbed_drivers/dev_null/main.cpp | 48 ++++++++ TESTS/mbed_drivers/echo/main.cpp | 64 ++++++++++ TESTS/mbed_drivers/generic_tests/main.cpp | 119 ++++++++++++++++++ TESTS/mbed_drivers/rtc/main.cpp | 56 +++++++++ TESTS/mbed_drivers/stl_features/main.cpp | 139 ++++++++++++++++++++++ TESTS/mbed_drivers/ticker/main.cpp | 80 +++++++++++++ TESTS/mbed_drivers/ticker_2/main.cpp | 69 +++++++++++ TESTS/mbed_drivers/ticker_3/main.cpp | 73 ++++++++++++ TESTS/mbed_drivers/timeout/main.cpp | 77 ++++++++++++ TESTS/mbed_drivers/wait_us/main.cpp | 51 ++++++++ 11 files changed, 900 insertions(+) create mode 100644 TESTS/mbed_drivers/c_strings/main.cpp create mode 100644 TESTS/mbed_drivers/dev_null/main.cpp create mode 100644 TESTS/mbed_drivers/echo/main.cpp create mode 100644 TESTS/mbed_drivers/generic_tests/main.cpp create mode 100644 TESTS/mbed_drivers/rtc/main.cpp create mode 100644 TESTS/mbed_drivers/stl_features/main.cpp create mode 100644 TESTS/mbed_drivers/ticker/main.cpp create mode 100644 TESTS/mbed_drivers/ticker_2/main.cpp create mode 100644 TESTS/mbed_drivers/ticker_3/main.cpp create mode 100644 TESTS/mbed_drivers/timeout/main.cpp create mode 100644 TESTS/mbed_drivers/wait_us/main.cpp diff --git a/TESTS/mbed_drivers/c_strings/main.cpp b/TESTS/mbed_drivers/c_strings/main.cpp new file mode 100644 index 0000000000..efb73999ef --- /dev/null +++ b/TESTS/mbed_drivers/c_strings/main.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity/unity.h" +#include "utest/utest.h" + +namespace { +static char buffer[256] = {0}; +} + +#define CLEAN_BUFFER memset(::buffer, 0x00, sizeof(::buffer)) +#define NEGATIVE_INTEGERS -32768,-3214,-999,-100,-1,0,-1,-4231,-999,-4123,-32760,-99999 +#define POSITIVE_INTEGERS 32768,3214,999,100,1,0,1,4231,999,4123,32760,99999 +#define FLOATS 0.002,0.92430,15.91320,791.77368,6208.2,25719.4952,426815.982588,6429271.046,42468024.93,212006462.910 + +using namespace utest::v1; + + +void test_case_c_string_i_d() { + CLEAN_BUFFER; + sprintf(buffer, "%i %d %i %d %i %d %i %d %i %d %i %i", NEGATIVE_INTEGERS); + TEST_ASSERT_EQUAL_STRING("-32768 -3214 -999 -100 -1 0 -1 -4231 -999 -4123 -32760 -99999", buffer); +} + +void test_case_c_string_u_d() { + CLEAN_BUFFER; + sprintf(buffer, "%u %d %u %d %u %d %u %d %u %d %u %d", POSITIVE_INTEGERS); + TEST_ASSERT_EQUAL_STRING("32768 3214 999 100 1 0 1 4231 999 4123 32760 99999", buffer); +} + +void test_case_c_string_x_E() { + CLEAN_BUFFER; + sprintf(buffer, "%x %X %x %X %x %X %x %X %x %X %x %X", POSITIVE_INTEGERS); + TEST_ASSERT_EQUAL_STRING("8000 C8E 3e7 64 1 0 1 1087 3e7 101B 7ff8 1869F", buffer); +} + +void test_case_c_string_f_f() { + CLEAN_BUFFER; + sprintf(buffer, "%f %f %f %f %f %f %f %f %f %f", FLOATS); + TEST_ASSERT_EQUAL_STRING("0.002000 0.924300 15.913200 791.773680 6208.200000 25719.495200 426815.982588 6429271.046000 42468024.930000 212006462.910000", buffer); +} + +void test_case_c_string_g_g() { + CLEAN_BUFFER; + sprintf(buffer, "%g %g %g %g %g %g %g %g %g %g", FLOATS); + TEST_ASSERT_EQUAL_STRING("0.002 0.9243 15.9132 791.774 6208.2 25719.5 426816 6.42927e+006 4.2468e+007 2.12006e+008", buffer); + TEST_ASSERT_EQUAL_STRING("0.002 0.9243 15.9132 791.774 6208.2 25719.5 426816 6.42927e+06 4.2468e+07 2.12006e+08", buffer); +} + +void test_case_c_string_e_E() { + CLEAN_BUFFER; + sprintf(buffer, "%e %E %e %E %e %E %e %E %e %E", FLOATS); + TEST_ASSERT_EQUAL_STRING("2.000000e-003 9.243000E-001 1.591320e+001 7.917737E+002 6.208200e+003 2.571950E+004 4.268160e+005 6.429271E+006 4.246802e+007 2.120065E+008", buffer); + TEST_ASSERT_EQUAL_STRING("2.000000e-03 9.243000E-01 1.591320e+01 7.917737E+02 6.208200e+03 2.571950E+04 4.268160e+05 6.429271E+06 4.246802e+07 2.120065E+08", buffer); +} + +void test_case_c_string_strtok() { + CLEAN_BUFFER; + char str[] ="- This, a sample string."; + char * pch = strtok (str," ,.-"); + while (pch != NULL) { + strcat(buffer, pch); + pch = strtok (NULL, " ,.-"); + } + TEST_ASSERT_EQUAL_STRING("Thisasamplestring", buffer); +} + +void test_case_c_string_strpbrk() { + CLEAN_BUFFER; + char str[] = "This is a sample string"; + char key[] = "aeiou"; + char *pch = strpbrk(str, key); + while (pch != NULL) + { + char buf[2] = {*pch, '\0'}; + strcat(buffer, buf); + pch = strpbrk(pch + 1,key); + } + TEST_ASSERT_EQUAL_STRING("iiaaei", buffer); +} + +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { + greentea_case_failure_abort_handler(source, reason); + return STATUS_CONTINUE; +} + +Case cases[] = { + Case("C strings: strtok", test_case_c_string_strtok, greentea_failure_handler), + Case("C strings: strpbrk", test_case_c_string_strpbrk, greentea_failure_handler), + Case("C strings: %i %d integer formatting", test_case_c_string_i_d, greentea_failure_handler), + Case("C strings: %u %d integer formatting", test_case_c_string_u_d, greentea_failure_handler), + Case("C strings: %x %E integer formatting", test_case_c_string_x_E, greentea_failure_handler), + Case("C strings: %f %f float formatting", test_case_c_string_f_f, greentea_failure_handler), + Case("C strings: %e %E float formatting", test_case_c_string_e_E, greentea_failure_handler), + Case("C strings: %g %g float formatting", test_case_c_string_g_g, greentea_failure_handler), +}; + +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(5, "default_auto"); + return greentea_test_setup_handler(number_of_cases); +} + +Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); + +int main() { + Harness::run(specification); +} diff --git a/TESTS/mbed_drivers/dev_null/main.cpp b/TESTS/mbed_drivers/dev_null/main.cpp new file mode 100644 index 0000000000..22940d026f --- /dev/null +++ b/TESTS/mbed_drivers/dev_null/main.cpp @@ -0,0 +1,48 @@ +/* mbed Microcontroller Library + * Copyright (c) 2013-2014 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mbed.h" +#include "greentea-client/test_env.h" + +class DevNull : public Stream { +public: + DevNull(const char *name = NULL) : Stream(name) {} + +protected: + virtual int _getc() { + return 0; + } + virtual int _putc(int c) { + return c; + } +}; + +DevNull null("null"); + +int main() { + GREENTEA_SETUP(2, "dev_null_auto"); + + printf("MBED: before re-routing stdout to /null\n"); // This shouldn't appear + greentea_send_kv("to_stdout", "re-routing stdout to /null"); + + if (freopen("/null", "w", stdout)) { + // This shouldn't appear on serial + // We should use pure printf here to send KV + printf("{{to_null;printf redirected to /null}}\n"); + printf("MBED: this printf is already redirected to /null\n"); + } + GREENTEA_TESTSUITE_RESULT(false); +} diff --git a/TESTS/mbed_drivers/echo/main.cpp b/TESTS/mbed_drivers/echo/main.cpp new file mode 100644 index 0000000000..f531a79f7d --- /dev/null +++ b/TESTS/mbed_drivers/echo/main.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity/unity.h" +#include "utest/utest.h" + +using namespace utest::v1; + +// Echo server (echo payload to host) +template +void test_case_echo_server_x() { + char _key[10] = {}; + char _value[128] = {}; + const int echo_count = N; + + // Handshake with host + greentea_send_kv("echo_count", echo_count); + greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value)); + TEST_ASSERT_EQUAL_INT(echo_count, atoi(_value)); + + for (int i=0; i < echo_count; ++i) { + greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value)); + greentea_send_kv(_key, _value); + } +} + +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { + greentea_case_failure_abort_handler(source, reason); + return STATUS_CONTINUE; +} + +Case cases[] = { + Case("Echo server: x16", test_case_echo_server_x<16>, greentea_failure_handler), + Case("Echo server: x32", test_case_echo_server_x<32>, greentea_failure_handler), + Case("Echo server: x64", test_case_echo_server_x<64>, greentea_failure_handler), +}; + +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(30, "echo"); + return greentea_test_setup_handler(number_of_cases); +} + +Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); + +int main() { + Harness::run(specification); +} diff --git a/TESTS/mbed_drivers/generic_tests/main.cpp b/TESTS/mbed_drivers/generic_tests/main.cpp new file mode 100644 index 0000000000..dc177e3f4d --- /dev/null +++ b/TESTS/mbed_drivers/generic_tests/main.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include // std::pair +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity/unity.h" +#include "utest/utest.h" + +using namespace utest::v1; + +#define PATTERN_CHECK_VALUE 0xF0F0ADAD + +class CppTestCaseHelperClass { +private: + const char* name; + const unsigned pattern; + +public: + CppTestCaseHelperClass(const char* _name) : name(_name), pattern(PATTERN_CHECK_VALUE) { + print("init"); + } + + void print(const char *message) { + printf("%s::%s\n", name, message); + } + + bool check_init(void) { + bool result = (pattern == PATTERN_CHECK_VALUE); + print(result ? "check_init: OK" : "check_init: ERROR"); + return result; + } + + void stack_test(void) { + print("stack_test"); + CppTestCaseHelperClass t("Stack"); + t.hello(); + } + + void hello(void) { + print("hello"); + } + + ~CppTestCaseHelperClass() { + print("destroy"); + } +}; + + +void test_case_basic() { + TEST_ASSERT_TRUE(true); + TEST_ASSERT_FALSE(false); + TEST_ASSERT_EQUAL_STRING("The quick brown fox jumps over the lazy dog", + "The quick brown fox jumps over the lazy dog"); +} + +void test_case_blinky() { + static DigitalOut myled(LED1); + const int cnt_max = 1024; + for (int cnt = 0; cnt < cnt_max; ++cnt) { + myled = !myled; + } +} + +void test_case_cpp_stack() { + // Check C++ start-up initialisation + CppTestCaseHelperClass s("Static"); + + // Global stack object simple test + s.stack_test(); + TEST_ASSERT_TRUE_MESSAGE(s.check_init(), "s.check_init() failed"); +} + +void test_case_cpp_heap() { + // Heap test object simple test + CppTestCaseHelperClass *m = new CppTestCaseHelperClass("Heap"); + m->hello(); + TEST_ASSERT_TRUE_MESSAGE(m->check_init(), "m->check_init() failed"); + delete m; +} + +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { + greentea_case_failure_abort_handler(source, reason); + return STATUS_CONTINUE; +} + +// Generic test cases +Case cases[] = { + Case("Basic", test_case_basic, greentea_failure_handler), + Case("Blinky", test_case_blinky, greentea_failure_handler), + Case("C++ stack", test_case_cpp_stack, greentea_failure_handler), + Case("C++ heap", test_case_cpp_heap, greentea_failure_handler) +}; + +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(20, "default_auto"); + return greentea_test_setup_handler(number_of_cases); +} + +Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); + +int main() { + Harness::run(specification); +} diff --git a/TESTS/mbed_drivers/rtc/main.cpp b/TESTS/mbed_drivers/rtc/main.cpp new file mode 100644 index 0000000000..fae4d06e20 --- /dev/null +++ b/TESTS/mbed_drivers/rtc/main.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity/unity.h" +#include "utest/utest.h" + +using namespace utest::v1; + +#define CUSTOM_TIME 1256729737 + +void test_case_rtc_strftime() { + greentea_send_kv("timestamp", CUSTOM_TIME); + + char buffer[32] = {0}; + char kv_buff[64] = {0}; + set_time(CUSTOM_TIME); // Set RTC time to Wed, 28 Oct 2009 11:35:37 + + for (int i=0; i<10; ++i) { + time_t seconds = time(NULL); + sprintf(kv_buff, "[%ld] ", seconds); + strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S %p", localtime(&seconds)); + strcat(kv_buff, buffer); + greentea_send_kv("rtc", kv_buff); + wait(1); + } +} + +Case cases[] = { + Case("RTC strftime", test_case_rtc_strftime), +}; + +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(20, "rtc_auto"); + return greentea_test_setup_handler(number_of_cases); +} + +Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); + +int main() { + Harness::run(specification); +} diff --git a/TESTS/mbed_drivers/stl_features/main.cpp b/TESTS/mbed_drivers/stl_features/main.cpp new file mode 100644 index 0000000000..ec99282d45 --- /dev/null +++ b/TESTS/mbed_drivers/stl_features/main.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity/unity.h" +#include "utest/utest.h" + +using namespace utest::v1; + +#define TABLE_SIZE(TAB) (sizeof(TAB) / sizeof(TAB[0])) + +#define NEGATIVE_INTEGERS -32768,-3214,-999,-100,-1,0,1,4231,999,4123,32760,99999 +#define POSITIVE_INTEGERS 32768,3214,999,100,1,0,1,4231,999,4123,32760,99999 +#define FLOATS 0.002,0.92430,15.91320,791.77368,6208.2,25719.4952,426815.982588,6429271.046,42468024.93,212006462.910 +#define FLOATS_STR "0.002","0.92430","15.91320","791.77368","6208.2","25719.4952","426815.982588","6429271.046","42468024.93","212006462.910" + + +namespace { +int p_integers[] = {POSITIVE_INTEGERS}; +int n_integers[] = {NEGATIVE_INTEGERS}; +float floats[] = {FLOATS}; + +template +void BubbleSort(T& _array, size_t array_size, F functor) { + bool flag = true; + size_t numLength = array_size; + for(size_t i = 1; (i <= numLength) && flag; i++) { + flag = false; + for (size_t j = 0; j < (numLength - 1); j++) { + if (functor(_array[j+1], _array[j])) { + int temp = _array[j]; + _array[j] = _array[j + 1]; + _array[j+1] = temp; + flag = true; + } + } + } +} + +struct printInt { + void operator()(int i) { printf("%d ", i); } +}; + +struct printFloat { + void operator()(float f) { printf("%f ", f); } +}; + +struct printString { + void operator()(const char* s) { printf("%s ", s); } +}; + +struct greaterAbs { + bool operator()(int a, int b) { return abs(a) > abs(b); } +}; + +} // namespace + +void test_case_stl_equal() { + std::vector v_pints(p_integers, p_integers + TABLE_SIZE(p_integers)); + TEST_ASSERT_TRUE(std::equal(v_pints.begin(), v_pints.end(), p_integers)); +} + +void test_case_stl_transform() { + const char* floats_str[] = {FLOATS_STR}; + float floats_transform[TABLE_SIZE(floats_str)] = {0.0}; + std::transform(floats_str, floats_str + TABLE_SIZE(floats_str), floats_transform, atof); + //printf("stl_transform::floats_str: "); + //std::for_each(floats_str, floats_str + TABLE_SIZE(floats_str), printString()); + //printf("stl_transform::floats_transform: "); + //std::for_each(floats_transform, floats_transform + TABLE_SIZE(floats_transform), printFloat()); + //printf("\n"); + + TEST_ASSERT_TRUE(std::equal(floats_transform, floats_transform + TABLE_SIZE(floats_transform), floats)); +} + +void test_case_stl_sort_greater() { + std::vector v_nints_1(n_integers, n_integers + TABLE_SIZE(n_integers)); + std::vector v_nints_2(n_integers, n_integers + TABLE_SIZE(n_integers)); + + BubbleSort(v_nints_1, v_nints_1.size(), std::greater()); + std::sort(v_nints_2.begin(), v_nints_2.end(), std::greater()); + + TEST_ASSERT_TRUE(std::equal(v_nints_1.begin(), v_nints_1.end(), v_nints_2.begin())); +} + +void test_case_stl_sort_abs() { + std::vector v_nints_1(n_integers, n_integers + TABLE_SIZE(n_integers)); + std::vector v_nints_2(n_integers, n_integers + TABLE_SIZE(n_integers)); + + BubbleSort(v_nints_1, v_nints_1.size(), greaterAbs()); + std::sort(v_nints_2.begin(), v_nints_2.end(), greaterAbs()); + + TEST_ASSERT_TRUE(std::equal(v_nints_1.begin(), v_nints_1.end(), v_nints_2.begin())); +} + +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { + greentea_case_failure_abort_handler(source, reason); + return STATUS_CONTINUE; +} + +Case cases[] = { + Case("STL std::equal", test_case_stl_equal, greentea_failure_handler), + Case("STL std::transform", test_case_stl_transform, greentea_failure_handler), + Case("STL std::sort greater", test_case_stl_sort_greater, greentea_failure_handler), + Case("STL std::sort abs", test_case_stl_sort_abs, greentea_failure_handler) +}; + +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(5, "default_auto"); + return greentea_test_setup_handler(number_of_cases); +} + +Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); + +int main() { + Harness::run(specification); +} diff --git a/TESTS/mbed_drivers/ticker/main.cpp b/TESTS/mbed_drivers/ticker/main.cpp new file mode 100644 index 0000000000..0b6cdeac1c --- /dev/null +++ b/TESTS/mbed_drivers/ticker/main.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "utest/utest.h" + +using namespace utest::v1; + +void send_kv_tick() { + static int count = 0; + if (count < 10) { + greentea_send_kv("tick", count); + } else if (count == 10) { + Harness::validate_callback(); + } + count++; +} + +Ticker flipper_1; +DigitalOut led1(LED1); + +void flip_1() { + static int led1_state = 0; + if (led1_state) { + led1 = 0; led1_state = 0; + } else { + led1 = 1; led1_state = 1; + } + send_kv_tick(); +} + +Ticker flipper_2; +DigitalOut led2(LED2); + +void flip_2() { + static int led2_state = 0; + if (led2_state) { + led2 = 0; led2_state = 0; + } else { + led2 = 1; led2_state = 1; + } +} + +control_t test_case_ticker() { + led1 = 0; + led2 = 0; + flipper_1.attach(&flip_1, 1.0); + flipper_2.attach(&flip_2, 2.0); + return CaseTimeout(15 * 1000); +} + +// Test cases +Case cases[] = { + Case("Timers: 2 x tickers", test_case_ticker), +}; + +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(20, "wait_us_auto"); + return greentea_test_setup_handler(number_of_cases); +} + +Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); + +int main() { + Harness::run(specification); +} diff --git a/TESTS/mbed_drivers/ticker_2/main.cpp b/TESTS/mbed_drivers/ticker_2/main.cpp new file mode 100644 index 0000000000..7fcc526d8a --- /dev/null +++ b/TESTS/mbed_drivers/ticker_2/main.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "utest/utest.h" + +using namespace utest::v1; + +Ticker tick; +DigitalOut led(LED1); + +namespace { + const int MS_INTERVALS = 1000; +} + +void send_kv_tick() { + static int count = 0; + if (count < 10) { + greentea_send_kv("tick", count); + } else if (count == 10) { + Harness::validate_callback(); + } + count++; +} + +void togglePin(void) { + static int ticker_count = 0; + if (ticker_count >= MS_INTERVALS) { + send_kv_tick(); + ticker_count = 0; + led = !led; + } + ticker_count++; +} + +utest::v1::control_t test_case_ticker() { + tick.attach_us(togglePin, 1000); + return CaseTimeout(15 * 1000); +} + +// Test cases +Case cases[] = { + Case("Timers: 1x ticker", test_case_ticker), +}; + +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(20, "wait_us_auto"); + return greentea_test_setup_handler(number_of_cases); +} + +Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); + +int main() { + Harness::run(specification); +} diff --git a/TESTS/mbed_drivers/ticker_3/main.cpp b/TESTS/mbed_drivers/ticker_3/main.cpp new file mode 100644 index 0000000000..dcb95d8127 --- /dev/null +++ b/TESTS/mbed_drivers/ticker_3/main.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "utest/utest.h" + +using namespace utest::v1; + +void ticker_callback_1(void); +void ticker_callback_2(void); + +DigitalOut led0(LED1); +DigitalOut led1(LED2); +Ticker ticker; + +void send_kv_tick() { + static int count = 0; + if (count < 10) { + greentea_send_kv("tick", count); + } else if (count == 10) { + Harness::validate_callback(); + } + count++; +} + +void ticker_callback_2(void) { + ticker.detach(); + ticker.attach(ticker_callback_1, 1.0); + led1 = !led1; + send_kv_tick(); +} + +void ticker_callback_1(void) { + ticker.detach(); + ticker.attach(ticker_callback_2, 1.0); + led0 = !led0; + send_kv_tick(); +} + +utest::v1::control_t test_case_ticker() { + ticker.attach(ticker_callback_1, 1.0); + return CaseTimeout(15 * 1000); +} + +// Test cases +Case cases[] = { + Case("Timers: 2x callbacks", test_case_ticker), +}; + +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(20, "wait_us_auto"); + return greentea_test_setup_handler(number_of_cases); +} + +Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); + +int main() { + Harness::run(specification); +} diff --git a/TESTS/mbed_drivers/timeout/main.cpp b/TESTS/mbed_drivers/timeout/main.cpp new file mode 100644 index 0000000000..1317475db4 --- /dev/null +++ b/TESTS/mbed_drivers/timeout/main.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "utest/utest.h" + +using namespace utest::v1; + +Timeout timer; +DigitalOut led(LED1); + +namespace { + const int MS_INTERVALS = 1000; +} + +void send_kv_tick() { + static int count = 0; + if (count < 10) { + greentea_send_kv("tick", count); + } else if (count == 10) { + Harness::validate_callback(); + } + count++; +} + +void toggleOff(void); + +void toggleOn(void) { + static int toggle_counter = 0; + if (toggle_counter == MS_INTERVALS) { + led = !led; + send_kv_tick(); + toggle_counter = 0; + } + toggle_counter++; + timer.attach_us(toggleOff, 500); +} + +void toggleOff(void) { + timer.attach_us(toggleOn, 500); +} + +control_t test_case_ticker() { + toggleOn(); + return CaseTimeout(15 * 1000); +} + +// Test cases +Case cases[] = { + Case("Timers: toggle on/off", test_case_ticker), +}; + +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(20, "wait_us_auto"); + return greentea_test_setup_handler(number_of_cases); +} + +Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); + +int main() { + Harness::run(specification); +} + diff --git a/TESTS/mbed_drivers/wait_us/main.cpp b/TESTS/mbed_drivers/wait_us/main.cpp new file mode 100644 index 0000000000..429f2409cb --- /dev/null +++ b/TESTS/mbed_drivers/wait_us/main.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "utest/utest.h" + +using namespace utest::v1; + +DigitalOut led(LED1); + +void test_case_ticker() { + for (int i=0; i < 10; ++i) { + // 10 secs... + for (int j = 0; j < 1000; ++j) { + // 1000 * 1000us = 1 sec + wait_us(1000); + } + led = !led; // Blink + greentea_send_kv("tick", i); + } +} + +// Test cases +Case cases[] = { + Case("Timers: wait_us", test_case_ticker), +}; + +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(20, "wait_us_auto"); + return greentea_test_setup_handler(number_of_cases); +} + +Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); + +int main() { + Harness::run(specification); +} From 40dbbc72da4f6374489091ebe2c69c40f8e2226d Mon Sep 17 00:00:00 2001 From: Przemek Wirkus Date: Wed, 1 Jun 2016 16:44:02 +0100 Subject: [PATCH 02/16] 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); +} From b54960866b59aea32b249cb6551ac8b2fe7d3f7c Mon Sep 17 00:00:00 2001 From: Przemek Wirkus Date: Thu, 2 Jun 2016 17:11:27 +0100 Subject: [PATCH 03/16] Add few non-peripheral tests from mbedmicro/mbed/libraries/tests/mbed Tested on K64F: ``` $ mbedgt -VS -n TESTS-mbedmicro-mbed* ``` ``` mbedgt: test suite report: +--------------+---------------+---------------------------------------+--------+--------------------+-------------+ | target | platform_name | test suite | result | elapsed_time (sec) | copy_method | +--------------+---------------+---------------------------------------+--------+--------------------+-------------+ | K64F-GCC_ARM | K64F | tests-mbedmicro-mbed-call_before_main | OK | 10.53 | shell | | K64F-GCC_ARM | K64F | tests-mbedmicro-mbed-cpp | OK | 10.64 | shell | | K64F-GCC_ARM | K64F | tests-mbedmicro-mbed-div | OK | 10.64 | shell | | K64F-GCC_ARM | K64F | tests-mbedmicro-mbed-heap_and_stack | OK | 30.32 | shell | +--------------+---------------+---------------------------------------+--------+--------------------+-------------+ mbedgt: test suite results: 4 OK mbedgt: test case report: +--------------+---------------+---------------------------------------+---------------------------------------+--------+--------+--------+--------------------+ | target | platform_name | test suite | test case | passed | failed | result | elapsed_time (sec) | +--------------+---------------+---------------------------------------+---------------------------------------+--------+--------+--------+--------------------+ | K64F-GCC_ARM | K64F | tests-mbedmicro-mbed-call_before_main | tests-mbedmicro-mbed-call_before_main | 1 | 0 | OK | 10.53 | | K64F-GCC_ARM | K64F | tests-mbedmicro-mbed-cpp | tests-mbedmicro-mbed-cpp | 1 | 0 | OK | 10.64 | | K64F-GCC_ARM | K64F | tests-mbedmicro-mbed-div | tests-mbedmicro-mbed-div | 1 | 0 | OK | 10.64 | | K64F-GCC_ARM | K64F | tests-mbedmicro-mbed-heap_and_stack | tests-mbedmicro-mbed-heap_and_stack | 1 | 0 | OK | 30.32 | +--------------+---------------+---------------------------------------+---------------------------------------+--------+--------+--------+--------------------+ mbedgt: test case results: 4 OK mbedgt: completed in 62.25 sec ``` --- .../mbedmicro-mbed/call_before_main/main.cpp | 16 ++++ TESTS/mbedmicro-mbed/cpp/main.cpp | 83 +++++++++++++++++++ TESTS/mbedmicro-mbed/div/main.cpp | 41 +++++++++ TESTS/mbedmicro-mbed/heap_and_stack/main.cpp | 80 ++++++++++++++++++ 4 files changed, 220 insertions(+) create mode 100644 TESTS/mbedmicro-mbed/call_before_main/main.cpp create mode 100644 TESTS/mbedmicro-mbed/cpp/main.cpp create mode 100644 TESTS/mbedmicro-mbed/div/main.cpp create mode 100644 TESTS/mbedmicro-mbed/heap_and_stack/main.cpp diff --git a/TESTS/mbedmicro-mbed/call_before_main/main.cpp b/TESTS/mbedmicro-mbed/call_before_main/main.cpp new file mode 100644 index 0000000000..9a713d3f30 --- /dev/null +++ b/TESTS/mbedmicro-mbed/call_before_main/main.cpp @@ -0,0 +1,16 @@ +#include "greentea-client/test_env.h" + +namespace { + bool mbed_main_called = false; +} + +extern "C" void mbed_main() { + printf("MBED: mbed_main() call before main()\r\n"); + mbed_main_called = true; +} + +int main() { + GREENTEA_SETUP(5, "default_auto"); + printf("MBED: main() starts now!\r\n"); + GREENTEA_TESTSUITE_RESULT(mbed_main_called); +} diff --git a/TESTS/mbedmicro-mbed/cpp/main.cpp b/TESTS/mbedmicro-mbed/cpp/main.cpp new file mode 100644 index 0000000000..bfa02200ae --- /dev/null +++ b/TESTS/mbedmicro-mbed/cpp/main.cpp @@ -0,0 +1,83 @@ +#include "greentea-client/test_env.h" + +#define PATTERN_CHECK_VALUE 0xF0F0ADAD + +class Test { + +private: + const char* name; + const int pattern; + +public: + Test(const char* _name) : name(_name), pattern(PATTERN_CHECK_VALUE) { + print("init"); + } + + void print(const char *message) { + printf("%s::%s\n", name, message); + } + + bool check_init(void) { + bool result = (pattern == PATTERN_CHECK_VALUE); + print(result ? "check_init: OK" : "check_init: ERROR"); + return result; + } + + void stack_test(void) { + print("stack_test"); + Test t("Stack"); + t.hello(); + } + + void hello(void) { + print("hello"); + } + + ~Test() { + print("destroy"); + } +}; + +/* Check C++ startup initialisation */ +Test s("Static"); + +/* EXPECTED OUTPUT: +******************* +Static::init +Static::stack_test +Stack::init +Stack::hello +Stack::destroy +Static::check_init: OK +Heap::init +Heap::hello +Heap::destroy +*******************/ +int main (void) { + GREENTEA_SETUP(10, "default_auto"); + + bool result = true; + for (;;) + { + // Global stack object simple test + s.stack_test(); + if (s.check_init() == false) + { + result = false; + break; + } + + // Heap test object simple test + Test *m = new Test("Heap"); + m->hello(); + + if (m->check_init() == false) + { + result = false; + } + delete m; + break; + } + + GREENTEA_TESTSUITE_RESULT(result); +} diff --git a/TESTS/mbedmicro-mbed/div/main.cpp b/TESTS/mbedmicro-mbed/div/main.cpp new file mode 100644 index 0000000000..6658d6db15 --- /dev/null +++ b/TESTS/mbedmicro-mbed/div/main.cpp @@ -0,0 +1,41 @@ +#include // std::pair +#include "mbed.h" +#include "greentea-client/test_env.h" + +uint32_t test_64(uint64_t ticks) { + ticks >>= 3; // divide by 8 + if (ticks > 0xFFFFFFFF) { + ticks /= 3; + } else { + ticks = (ticks * 0x55555556) >> 32; // divide by 3 + } + return (uint32_t)(0xFFFFFFFF & ticks); +} + +const char *result_str(bool result) { + return result ? "[OK]" : "[FAIL]"; +} + +int main() { + GREENTEA_SETUP(5, "default_auto"); + + bool result = true; + + { // 0xFFFFFFFF * 8 = 0x7fffffff8 + std::pair values = std::make_pair(0x55555555, 0x7FFFFFFF8); + uint32_t test_ret = test_64(values.second); + bool test_res = values.first == test_ret; + result = result && test_res; + printf("64bit: 0x7FFFFFFF8: expected 0x%lX got 0x%lX ... %s\r\n", values.first, test_ret, result_str(test_res)); + } + + { // 0xFFFFFFFF * 24 = 0x17ffffffe8 + std::pair values = std::make_pair(0xFFFFFFFF, 0x17FFFFFFE8); + uint32_t test_ret = test_64(values.second); + bool test_res = values.first == test_ret; + result = result && test_res; + printf("64bit: 0x17FFFFFFE8: expected 0x%lX got 0x%lX ... %s\r\n", values.first, test_ret, result_str(test_res)); + } + + GREENTEA_TESTSUITE_RESULT(result); +} diff --git a/TESTS/mbedmicro-mbed/heap_and_stack/main.cpp b/TESTS/mbedmicro-mbed/heap_and_stack/main.cpp new file mode 100644 index 0000000000..b27f7f1f90 --- /dev/null +++ b/TESTS/mbedmicro-mbed/heap_and_stack/main.cpp @@ -0,0 +1,80 @@ +#include +#include +#include "greentea-client/test_env.h" + +static char *initial_stack_p; +static char *initial_heap_p; + +static char line[256]; +static unsigned int iterations = 0; + +void report_iterations(void) { + unsigned int tot = (0x100 * iterations)*2; + printf("\nAllocated (%d)Kb in (%u) iterations\n", tot/1024, iterations); +#if !defined(TOOLCHAIN_GCC_CR) + // EA: This causes a crash when compiling with GCC_CR??? + printf("%.2f\n", ((float)(tot)/(float)(initial_stack_p - initial_heap_p))*100.); +#endif +#ifdef TOOLCHAIN_ARM +#ifndef __MICROLIB + __heapvalid((__heapprt) fprintf, stdout, 1); +#endif +#endif +} + +void stack_test(char *latest_heap_pointer) { + char stack_line[256]; + iterations++; + + sprintf(stack_line, "\nstack pointer: %p", &stack_line[255]); + puts(stack_line); + + char *heap_pointer = (char*)malloc(0x100); + + if (heap_pointer == NULL) { + int diff = (&stack_line[255] - latest_heap_pointer); + if (diff > 0x200) { + sprintf(stack_line, "\n[WARNING] Malloc failed to allocate memory too soon. There are (0x%x) free bytes", diff); + report_iterations(); + puts(stack_line); + } else { + puts("\n[SUCCESS] Stack/Heap collision detected"); + report_iterations(); + } + return; + } else { + heap_pointer += 0x100; + sprintf(line, "heap pointer: %p", heap_pointer); + puts(line); + } + + if ((&stack_line[255]) > heap_pointer) { + stack_test(heap_pointer); + } else { + puts("\n[WARNING] The Stack/Heap collision was not detected"); + report_iterations(); + } +} + + +int main (void) { + GREENTEA_SETUP(30, "default_auto"); + + char c; + initial_stack_p = &c; + + initial_heap_p = (char*)malloc(1); + if (initial_heap_p == NULL) { + printf("Unable to malloc a single byte\n"); + GREENTEA_TESTSUITE_RESULT(false); + } + + printf("Initial stack/heap geometry:\n"); + printf(" stack pointer:V %p\n", initial_stack_p); + printf(" heap pointer :^ %p\n", initial_heap_p); + + initial_heap_p++; + stack_test(initial_heap_p); + + GREENTEA_TESTSUITE_RESULT(true); +} From 1b686c685493a2de898d32fd593340804f1087dc Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sun, 5 Jun 2016 14:52:30 -0500 Subject: [PATCH 04/16] Added rtos::Thread tests --- TESTS/mbedmicro-rtos-mbed/threads/main.cpp | 110 +++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 TESTS/mbedmicro-rtos-mbed/threads/main.cpp diff --git a/TESTS/mbedmicro-rtos-mbed/threads/main.cpp b/TESTS/mbedmicro-rtos-mbed/threads/main.cpp new file mode 100644 index 0000000000..555a2a1bfe --- /dev/null +++ b/TESTS/mbedmicro-rtos-mbed/threads/main.cpp @@ -0,0 +1,110 @@ +#include "mbed.h" +#include "test_env.h" +#include "unity.h" +#include "utest.h" +#include "rtos.h" + + +using namespace utest::v1; + + +// Tasks with different functions to test on threads +void increment(const void *var) { + (*(int *)var)++; +} + +void increment_with_yield(const void *var) { + Thread::yield(); + (*(int *)var)++; +} + +void increment_with_wait(const void *var) { + Thread::wait(100); + (*(int *)var)++; +} + +void increment_with_child(const void *var) { + Thread child(increment, (void*)var); + child.join(); +} + +void increment_with_murder(const void *var) { + Thread child(increment_with_wait, (void*)var); + // Kill child before it can increment var + child.terminate(); + (*(int *)var)++; +} + + +// Tests that spawn tasks in different configurations +template +void test_single_thread() { + int var = 0; + Thread thread(F, &var); + thread.join(); + TEST_ASSERT_EQUAL(var, 1); +} + +template +void test_parallel_threads() { + int var = 0; + Thread *threads[N]; + + for (int i = 0; i < N; i++) { + threads[i] = new Thread(F, &var); + } + + for (int i = 0; i < N; i++) { + threads[i]->join(); + delete threads[i]; + } + + TEST_ASSERT_EQUAL(var, N); +} + +template +void test_serial_threads() { + int var = 0; + + for (int i = 0; i < N; i++) { + Thread thread(F, &var); + thread.join(); + } + + TEST_ASSERT_EQUAL(var, N); +} + + +utest::v1::status_t test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(40, "default_auto"); + return verbose_test_setup_handler(number_of_cases); +} + +// Test cases +Case cases[] = { + Case("Testing single thread", test_single_thread), + Case("Testing parallel threads", test_parallel_threads<3, increment>), + Case("Testing serial threads", test_serial_threads<10, increment>), + + Case("Testing single thread with yield", test_single_thread), + Case("Testing parallel threads with yield", test_parallel_threads<3, increment_with_yield>), + Case("Testing serial threads with yield", test_serial_threads<10, increment_with_yield>), + + Case("Testing single thread with wait", test_single_thread), + Case("Testing parallel threads with wait", test_parallel_threads<3, increment_with_wait>), + Case("Testing serial threads with wait", test_serial_threads<10, increment_with_wait>), + + Case("Testing single thread with child", test_single_thread), + Case("Testing parallel threads with child", test_parallel_threads<3, increment_with_child>), + Case("Testing serial threads with child", test_serial_threads<10, increment_with_child>), + + Case("Testing single thread with murder", test_single_thread), + Case("Testing parallel threads with murder", test_parallel_threads<3, increment_with_murder>), + Case("Testing serial threads with murder", test_serial_threads<10, increment_with_murder>), +}; + +Specification specification(test_setup, cases); + +int main() { + return !Harness::run(specification); +} From 8a90b557c94230e0fe5a59fa88e930ea49f80a23 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sun, 5 Jun 2016 15:11:58 -0500 Subject: [PATCH 05/16] Added Callback and FunctionPointer tests --- TESTS/mbed_drivers/callback/main.cpp | 267 +++++++++++++++++++++++++++ 1 file changed, 267 insertions(+) create mode 100644 TESTS/mbed_drivers/callback/main.cpp diff --git a/TESTS/mbed_drivers/callback/main.cpp b/TESTS/mbed_drivers/callback/main.cpp new file mode 100644 index 0000000000..90fdd1af1c --- /dev/null +++ b/TESTS/mbed_drivers/callback/main.cpp @@ -0,0 +1,267 @@ +#include "mbed.h" +#include "test_env.h" +#include "unity.h" +#include "utest.h" + +using namespace utest::v1; + + +// static functions +template +T static_func5(T a0, T a1, T a2, T a3, T a4) { return a0 | a1 | a2 | a3 | a4; } +template +T static_func4(T a0, T a1, T a2, T a3) { return a0 | a1 | a2 | a3; } +template +T static_func3(T a0, T a1, T a2) { return a0 | a1 | a2; } +template +T static_func2(T a0, T a1) { return a0 | a1; } +template +T static_func1(T a0) { return a0; } +template +T static_func0() { return 0; } + +// class functions +template +struct Thing { + T t; + Thing() : t(0x80) {} + + T member_func5(T a0, T a1, T a2, T a3, T a4) { return t | a0 | a1 | a2 | a3 | a4; } + T member_func4(T a0, T a1, T a2, T a3) { return t | a0 | a1 | a2 | a3; } + T member_func3(T a0, T a1, T a2) { return t | a0 | a1 | a2; } + T member_func2(T a0, T a1) { return t | a0 | a1; } + T member_func1(T a0) { return t | a0; } + T member_func0() { return t; } +}; + +// bound functions +template +T bound_func5(Thing *t, T a0, T a1, T a2, T a3, T a4) { return t->t | a0 | a1 | a2 | a3 | a4; } +template +T bound_func4(Thing *t, T a0, T a1, T a2, T a3) { return t->t | a0 | a1 | a2 | a3; } +template +T bound_func3(Thing *t, T a0, T a1, T a2) { return t->t | a0 | a1 | a2; } +template +T bound_func2(Thing *t, T a0, T a1) { return t->t | a0 | a1; } +template +T bound_func1(Thing *t, T a0) { return t->t | a0; } +template +T bound_func0(Thing *t) { return t->t; } + + +// function call and result verification +template +struct Verifier { + static void verify5(Callback func) { + T result = func(0x01, 0x02, 0x04, 0x08, 0x10); + TEST_ASSERT_EQUAL(result, 0x1f); + } + + template + static void verify5(O *obj, M method) { + Callback func(obj, method); + T result = func(0x01, 0x02, 0x04, 0x08, 0x10); + TEST_ASSERT_EQUAL(result, 0x9f); + } + + static void verify4(Callback func) { + T result = func(0x01, 0x02, 0x04, 0x08); + TEST_ASSERT_EQUAL(result, 0x0f); + } + + template + static void verify4(O *obj, M method) { + Callback func(obj, method); + T result = func(0x01, 0x02, 0x04, 0x08); + TEST_ASSERT_EQUAL(result, 0x8f); + } + + static void verify3(Callback func) { + T result = func(0x01, 0x02, 0x04); + TEST_ASSERT_EQUAL(result, 0x07); + } + + template + static void verify3(O *obj, M method) { + Callback func(obj, method); + T result = func(0x01, 0x02, 0x04); + TEST_ASSERT_EQUAL(result, 0x87); + } + + static void verify2(Callback func) { + T result = func(0x01, 0x02); + TEST_ASSERT_EQUAL(result, 0x03); + } + + template + static void verify2(O *obj, M method) { + Callback func(obj, method); + T result = func(0x01, 0x02); + TEST_ASSERT_EQUAL(result, 0x83); + } + + static void verify1(Callback func) { + T result = func(0x01); + TEST_ASSERT_EQUAL(result, 0x01); + } + + template + static void verify1(O *obj, M method) { + Callback func(obj, method); + T result = func(0x01); + TEST_ASSERT_EQUAL(result, 0x81); + } + + static void verify0(Callback func) { + T result = func(); + TEST_ASSERT_EQUAL(result, 0x00); + } + + template + static void verify0(O *obj, M method) { + Callback func(obj, method); + T result = func(); + TEST_ASSERT_EQUAL(result, 0x80); + } +}; + + +// test dispatch +template +void test_dispatch5() { + Thing thing; + Verifier::verify5(static_func5); + Verifier::verify5(&thing, &Thing::member_func5); + Verifier::verify5(&thing, &bound_func5); + + Callback callback(static_func5); + Verifier::verify5(callback); + callback.attach(&thing, &bound_func5); + Verifier::verify5(&callback, &Callback::call); + Verifier::verify5((void*)&callback, &Callback::thunk); +} + +template +void test_dispatch4() { + Thing thing; + Verifier::verify4(static_func4); + Verifier::verify4(&thing, &Thing::member_func4); + Verifier::verify4(&thing, &bound_func4); + + Callback callback(static_func4); + Verifier::verify4(callback); + callback.attach(&thing, &bound_func4); + Verifier::verify4(&callback, &Callback::call); + Verifier::verify4((void*)&callback, &Callback::thunk); +} + +template +void test_dispatch3() { + Thing thing; + Verifier::verify3(static_func3); + Verifier::verify3(&thing, &Thing::member_func3); + Verifier::verify3(&thing, &bound_func3); + + Callback callback(static_func3); + Verifier::verify3(callback); + callback.attach(&thing, &bound_func3); + Verifier::verify3(&callback, &Callback::call); + Verifier::verify3((void*)&callback, &Callback::thunk); +} + +template +void test_dispatch2() { + Thing thing; + Verifier::verify2(static_func2); + Verifier::verify2(&thing, &Thing::member_func2); + Verifier::verify2(&thing, &bound_func2); + + Callback callback(static_func2); + Verifier::verify2(callback); + callback.attach(&thing, &bound_func2); + Verifier::verify2(&callback, &Callback::call); + Verifier::verify2((void*)&callback, &Callback::thunk); +} + +template +void test_dispatch1() { + Thing thing; + Verifier::verify1(static_func1); + Verifier::verify1(&thing, &Thing::member_func1); + Verifier::verify1(&thing, &bound_func1); + + Callback callback(static_func1); + Verifier::verify1(callback); + callback.attach(&thing, &bound_func1); + Verifier::verify1(&callback, &Callback::call); + Verifier::verify1((void*)&callback, &Callback::thunk); +} + +template +void test_dispatch0() { + Thing thing; + Verifier::verify0(static_func0); + Verifier::verify0(&thing, &Thing::member_func0); + Verifier::verify0(&thing, &bound_func0); + + Callback callback(static_func0); + Verifier::verify0(callback); + callback.attach(&thing, &bound_func0); + Verifier::verify0(&callback, &Callback::call); + Verifier::verify0((void*)&callback, &Callback::thunk); +} + +template +void test_fparg1() { + Thing thing; + FunctionPointerArg1 fp(static_func1); + Verifier::verify1(fp); + Verifier::verify1(fp.get_function()); +} + +template +void test_fparg0() { + Thing thing; + FunctionPointerArg1 fp(static_func0); + Verifier::verify0(fp); + Verifier::verify0(fp.get_function()); +} + + +// Test setup +utest::v1::status_t test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(40, "default_auto"); + return verbose_test_setup_handler(number_of_cases); +} + +Case cases[] = { + Case("Testing callbacks with 5 ints", test_dispatch5), + Case("Testing callbacks with 4 ints", test_dispatch4), + Case("Testing callbacks with 3 ints", test_dispatch3), + Case("Testing callbacks with 2 ints", test_dispatch2), + Case("Testing callbacks with 1 ints", test_dispatch1), + Case("Testing callbacks with 0 ints", test_dispatch0), + + Case("Testing callbacks with 5 uchars", test_dispatch5), + Case("Testing callbacks with 4 uchars", test_dispatch4), + Case("Testing callbacks with 3 uchars", test_dispatch3), + Case("Testing callbacks with 2 uchars", test_dispatch2), + Case("Testing callbacks with 1 uchars", test_dispatch1), + Case("Testing callbacks with 0 uchars", test_dispatch0), + + Case("Testing callbacks with 5 uint64s", test_dispatch5), + Case("Testing callbacks with 4 uint64s", test_dispatch4), + Case("Testing callbacks with 3 uint64s", test_dispatch3), + Case("Testing callbacks with 2 uint64s", test_dispatch2), + Case("Testing callbacks with 1 uint64s", test_dispatch1), + Case("Testing callbacks with 0 uint64s", test_dispatch0), + + Case("Testing FunctionPointerArg1 compatibility", test_fparg1), + Case("Testing FunctionPointer compatibility", test_fparg0), +}; + +Specification specification(test_setup, cases); + +int main() { + return !Harness::run(specification); +} From 47e41ac321b5d3266b6e6d29f7575262dbd41ea4 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sun, 5 Jun 2016 15:22:11 -0500 Subject: [PATCH 06/16] Added attribute tests based off tests from armmbed/compiler-polyfil --- TESTS/mbedmicro-mbed/attributes/attributes.c | 143 +++++++++++++++++++ TESTS/mbedmicro-mbed/attributes/main.cpp | 53 +++++++ TESTS/mbedmicro-mbed/attributes/weak.c | 10 ++ 3 files changed, 206 insertions(+) create mode 100644 TESTS/mbedmicro-mbed/attributes/attributes.c create mode 100644 TESTS/mbedmicro-mbed/attributes/main.cpp create mode 100644 TESTS/mbedmicro-mbed/attributes/weak.c diff --git a/TESTS/mbedmicro-mbed/attributes/attributes.c b/TESTS/mbedmicro-mbed/attributes/attributes.c new file mode 100644 index 0000000000..f8ad7f7a40 --- /dev/null +++ b/TESTS/mbedmicro-mbed/attributes/attributes.c @@ -0,0 +1,143 @@ +#include "toolchain.h" + +#include +#include + + +MBED_PACKED(struct) TestAttrPackedStruct1 { + char a; + int x; +}; + +typedef MBED_PACKED(struct) { + char a; + int x; +} TestAttrPackedStruct2; + +int testPacked() { + int failed = 0; + + if (sizeof(struct TestAttrPackedStruct1) != sizeof(int) + sizeof(char)) { + failed++; + } + + if (sizeof(TestAttrPackedStruct2) != sizeof(int) + sizeof(char)) { + failed++; + } + + return failed; +} + + +int testAlign() { + int failed = 0; + + MBED_ALIGN(8) char a; + MBED_ALIGN(8) char b; + MBED_ALIGN(16) char c; + MBED_ALIGN(8) char d; + MBED_ALIGN(16) char e; + + if(((uintptr_t)&a) & 0x7){ + failed++; + } + if(((uintptr_t)&b) & 0x7){ + failed++; + } + if(((uintptr_t)&c) & 0xf){ + failed++; + } + if(((uintptr_t)&d) & 0x7){ + failed++; + } + if(((uintptr_t)&e) & 0xf){ + failed++; + } + + return failed; +} + + +int testUnused1(MBED_UNUSED int arg) { + return 0; +} + +int testUnused() { + return testUnused1(0); +} + + +int testWeak1(); +int testWeak2(); + +MBED_WEAK int testWeak1() { + return 1; +} + +int testWeak2() { + return 0; +} + +int testWeak() { + return testWeak1() | testWeak2(); +} + + +MBED_PURE int testPure1() { + return 0; +} + +int testPure() { + return testPure1(); +} + + +MBED_FORCEINLINE int testForceInline1() { + return 0; +} + +int testForceInline() { + return testForceInline1(); +} + + +MBED_NORETURN int testNoReturn1() { + while (1) {} +} + +int testNoReturn() { + if (0) { + testNoReturn1(); + } + return 0; +} + + +int testUnreachable1(int i) { + switch (i) { + case 0: + return 0; + } + + MBED_UNREACHABLE; +} + +int testUnreachable() { + return testUnreachable1(0); +} + + +MBED_DEPRECATED("this message should not be displayed") +void testDeprecatedUnused(); +void testDeprecatedUnused() { } + +MBED_DEPRECATED("this message should be displayed") +int testDeprecatedUsed(); +int testDeprecatedUsed() { + return 0; +} + +int testDeprecated() { + return testDeprecatedUsed(); +} + diff --git a/TESTS/mbedmicro-mbed/attributes/main.cpp b/TESTS/mbedmicro-mbed/attributes/main.cpp new file mode 100644 index 0000000000..1a0feb99ae --- /dev/null +++ b/TESTS/mbedmicro-mbed/attributes/main.cpp @@ -0,0 +1,53 @@ +#include +#include + +#include "toolchain.h" +#include "test_env.h" +#include "unity.h" +#include "utest.h" + +using namespace utest::v1; + + +// Test functions declared as C functions to avoid issues with name mangling +extern "C" { + int testPacked(); + int testAlign(); + int testUnused(); + int testWeak(); + int testPure(); + int testForceInline(); + int testNoReturn(); + int testUnreachable(); + int testDeprecated(); +} + + +// Test wrapper and test cases for utest +template +void test_wrapper() { + TEST_ASSERT_UNLESS(F()); +} + +utest::v1::status_t test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(40, "default_auto"); + return verbose_test_setup_handler(number_of_cases); +} + +Case cases[] = { + Case("Testing PACKED attribute", test_wrapper), + Case("Testing ALIGN attribute", test_wrapper), + Case("Testing UNUSED attribute", test_wrapper), + Case("Testing WEAK attribute", test_wrapper), + Case("Testing PURE attribute", test_wrapper), + Case("Testing FORCEINLINE attribute", test_wrapper), + Case("Testing NORETURN attribute", test_wrapper), + Case("Testing UNREACHABLE attribute", test_wrapper), + Case("Testing DEPRECATED attribute", test_wrapper), +}; + +Specification specification(test_setup, cases); + +int main() { + return !Harness::run(specification); +} diff --git a/TESTS/mbedmicro-mbed/attributes/weak.c b/TESTS/mbedmicro-mbed/attributes/weak.c new file mode 100644 index 0000000000..05db78dbea --- /dev/null +++ b/TESTS/mbedmicro-mbed/attributes/weak.c @@ -0,0 +1,10 @@ +#include "toolchain.h" + +int testWeak1() { + return 0; +} + +MBED_WEAK int testWeak2() { + return 1; +} + From 88ee8caaddccc2b9f33b7e23de09d67c82bca246 Mon Sep 17 00:00:00 2001 From: Przemek Wirkus Date: Tue, 7 Jun 2016 14:03:14 +0100 Subject: [PATCH 07/16] Add TCP Client Download --- .../tcp_client_hello_world/main.cpp | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 TESTS/mbedmicro-net/tcp_client_hello_world/main.cpp diff --git a/TESTS/mbedmicro-net/tcp_client_hello_world/main.cpp b/TESTS/mbedmicro-net/tcp_client_hello_world/main.cpp new file mode 100644 index 0000000000..3f094a90e6 --- /dev/null +++ b/TESTS/mbedmicro-net/tcp_client_hello_world/main.cpp @@ -0,0 +1,78 @@ +#include +#include "mbed.h" +#include "LWIPInterface.h" +#include "TCPSocket.h" +#include "greentea-client/test_env.h" +#include "unity/unity.h" + +namespace { + // Test connection information + const char *HTTP_SERVER_NAME = "developer.mbed.org"; + const char *HTTP_SERVER_FILE_PATH = "/media/uploads/mbed_official/hello.txt"; + const int HTTP_SERVER_PORT = 80; +#if defined(TARGET_VK_RZ_A1H) + const int RECV_BUFFER_SIZE = 300; +#else + const int RECV_BUFFER_SIZE = 512; +#endif + // Test related data + const char *HTTP_OK_STR = "200 OK"; + const char *HTTP_HELLO_STR = "Hello world!"; + + // Test buffers + char buffer[RECV_BUFFER_SIZE] = {0}; +} + +bool find_substring(const char *first, const char *last, const char *s_first, const char *s_last) { + const char *f = std::search(first, last, s_first, s_last); + return (f != last); +} + +int main() { + GREENTEA_SETUP(20, "default_auto"); + + bool result = true; + LWIPInterface eth; + //eth.init(); //Use DHCP + eth.connect(); + printf("TCP client IP Address is %s\r\n", eth.get_ip_address()); + + TCPSocket sock(ð); + if (sock.connect(HTTP_SERVER_NAME, HTTP_SERVER_PORT) == 0) { + printf("HTTP: Connected to %s:%d\r\n", HTTP_SERVER_NAME, HTTP_SERVER_PORT); + + // We are constructing GET command like this: + // GET http://developer.mbed.org/media/uploads/mbed_official/hello.txt HTTP/1.0\n\n + strcpy(buffer, "GET http://"); + strcat(buffer, HTTP_SERVER_NAME); + strcat(buffer, HTTP_SERVER_FILE_PATH); + strcat(buffer, " HTTP/1.0\n\n"); + // Send GET command + sock.send(buffer, strlen(buffer)); + + // Server will respond with HTTP GET's success code + const int ret = sock.recv(buffer, sizeof(buffer) - 1); + buffer[ret] = '\0'; + + // Find 200 OK HTTP status in reply + bool found_200_ok = find_substring(buffer, buffer + ret, HTTP_OK_STR, HTTP_OK_STR + strlen(HTTP_OK_STR)); + // Find "Hello World!" string in reply + bool found_hello = find_substring(buffer, buffer + ret, HTTP_HELLO_STR, HTTP_HELLO_STR + strlen(HTTP_HELLO_STR)); + + TEST_ASSERT_TRUE(found_200_ok); + TEST_ASSERT_TRUE(found_hello); + + if (!found_200_ok) result = false; + if (!found_hello) result = false; + + printf("HTTP: Received %d chars from server\r\n", ret); + printf("HTTP: Received 200 OK status ... %s\r\n", found_200_ok ? "[OK]" : "[FAIL]"); + printf("HTTP: Received '%s' status ... %s\r\n", HTTP_HELLO_STR, found_hello ? "[OK]" : "[FAIL]"); + printf("HTTP: Received massage:\r\n\r\n"); + printf("%s", buffer); + } + + sock.close(); + eth.disconnect(); + GREENTEA_TESTSUITE_RESULT(result); +} From 40a090bc2be89a26b26370ba44abdb4743f78500 Mon Sep 17 00:00:00 2001 From: Przemek Wirkus Date: Tue, 7 Jun 2016 16:26:16 +0100 Subject: [PATCH 08/16] Add simple TCP client with simple TCP echo server host test --- TESTS/mbedmicro-net/.mbedignore | 1 + .../host_tests/tcp_echo_client.py | 198 ++++++++++++++++++ TESTS/mbedmicro-net/tcp_client_echo/main.cpp | 73 +++++++ 3 files changed, 272 insertions(+) create mode 100644 TESTS/mbedmicro-net/.mbedignore create mode 100644 TESTS/mbedmicro-net/host_tests/tcp_echo_client.py create mode 100644 TESTS/mbedmicro-net/tcp_client_echo/main.cpp diff --git a/TESTS/mbedmicro-net/.mbedignore b/TESTS/mbedmicro-net/.mbedignore new file mode 100644 index 0000000000..709fc03605 --- /dev/null +++ b/TESTS/mbedmicro-net/.mbedignore @@ -0,0 +1 @@ +host_tests/* \ No newline at end of file diff --git a/TESTS/mbedmicro-net/host_tests/tcp_echo_client.py b/TESTS/mbedmicro-net/host_tests/tcp_echo_client.py new file mode 100644 index 0000000000..51a3c21c14 --- /dev/null +++ b/TESTS/mbedmicro-net/host_tests/tcp_echo_client.py @@ -0,0 +1,198 @@ +# Copyright 2015 ARM Limited, All rights reserved +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +import select +import socket +import logging +from threading import Thread +from sys import stdout +from SocketServer import BaseRequestHandler, TCPServer +from mbed_host_tests import BaseHostTest, event_callback + + +class TCPEchoClientHandler(BaseRequestHandler): + def handle(self): + """ + Handles a connection. Test starts by client(i.e. mbed) connecting to server. + This connection handler receives data and echoes back to the client util + {{end}} is received. Then it sits on recv() for client to terminate the + connection. + + Note: reason for not echoing data back after receiving {{end}} is that send + fails raising a SocketError as client closes connection. + """ + print ("HOST: TCPEchoClient_Handler: Connection received...") + while self.server.isrunning(): + try: + data = self.recv() + if not data: break + except Exception as e: + print ('HOST: TCPEchoClient_Handler recv error: %s' % str(e)) + break + + print ('HOST: TCPEchoClient_Handler: Rx: \n%s\n' % data) + + try: + # echo data back to the client + self.send(data) + except Exception as e: + print ('HOST: TCPEchoClient_Handler send error: %s' % str(e)) + break + print 'Connection finished' + + def recv(self): + """ + Try to receive until server is shutdown + """ + while self.server.isrunning(): + rl, wl, xl = select.select([self.request], [], [], 1) + if len(rl): + return self.request.recv(1024) + + def send(self, data): + """ + Try to send until server is shutdown + """ + while self.server.isrunning(): + rl, wl, xl = select.select([], [self.request], [], 1) + if len(wl): + self.request.sendall(data) + break + + +class TCPServerWrapper(TCPServer): + """ + Wrapper over TCP server to implement server initiated shutdown. + Adds a flag:= running that a request handler can check and come out of + recv loop when shutdown is called. + """ + + def __init__(self, addr, request_handler): + # hmm, TCPServer is not sub-classed from object! + if issubclass(TCPServer, object): + super(TCPServerWrapper, self).__init__(addr, request_handler) + else: + TCPServer.__init__(self, addr, request_handler) + self.running = False + + def serve_forever(self): + self.running = True + if issubclass(TCPServer, object): + super(TCPServerWrapper, self).serve_forever() + else: + TCPServer.serve_forever(self) + + def shutdown(self): + self.running = False + if issubclass(TCPServer, object): + super(TCPServerWrapper, self).shutdown() + else: + TCPServer.shutdown(self) + + def isrunning(self): + return self.running + + +class TCPEchoClientTest(BaseHostTest): + + def __init__(self): + """ + Initialise test parameters. + + :return: + """ + BaseHostTest.__init__(self) + self.SERVER_IP = None # Will be determined after knowing the target IP + self.SERVER_PORT = 0 # Let TCPServer choose an arbitrary port + self.server = None + self.server_thread = None + self.target_ip = None + + @staticmethod + def find_interface_to_target_addr(target_ip): + """ + Finds IP address of the interface through which it is connected to the target. + + :return: + """ + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.connect((target_ip, 0)) # Target IP, Any port + ip = s.getsockname()[0] + s.close() + return ip + + def setup_tcp_server(self): + """ + sets up a TCP server for target to connect and send test data. + + :return: + """ + # !NOTE: There should mechanism to assert in the host test + if self.SERVER_IP is None: + self.log("setup_tcp_server() called before determining server IP!") + self.notify_complete(False) + + # Returning none will suppress host test from printing success code + self.server = TCPServerWrapper((self.SERVER_IP, self.SERVER_PORT), TCPEchoClientHandler) + ip, port = self.server.server_address + self.SERVER_PORT = port + self.server.allow_reuse_address = True + self.log("HOST: Listening for TCP connections: " + self.SERVER_IP + ":" + str(self.SERVER_PORT)) + self.server_thread = Thread(target=TCPEchoClientTest.server_thread_func, args=(self,)) + self.server_thread.start() + + @staticmethod + def server_thread_func(this): + """ + Thread function to run TCP server forever. + + :param this: + :return: + """ + this.server.serve_forever() + + @event_callback("target_ip") + def _callback_target_ip(self, key, value, timestamp): + """ + Callback to handle reception of target's IP address. + + :param key: + :param value: + :param timestamp: + :return: + """ + self.target_ip = value + self.SERVER_IP = self.find_interface_to_target_addr(self.target_ip) + self.setup_tcp_server() + + @event_callback("host_ip") + def _callback_host_ip(self, key, value, timestamp): + """ + Callback for request for host IP Addr + + """ + self.send_kv("host_ip", self.SERVER_IP) + + @event_callback("host_port") + def _callback_host_port(self, key, value, timestamp): + """ + Callback for request for host port + """ + self.send_kv("host_port", self.SERVER_PORT) + + def teardown(self): + if self.server: + self.server.shutdown() + self.server_thread.join() diff --git a/TESTS/mbedmicro-net/tcp_client_echo/main.cpp b/TESTS/mbedmicro-net/tcp_client_echo/main.cpp new file mode 100644 index 0000000000..4b0e9a8afc --- /dev/null +++ b/TESTS/mbedmicro-net/tcp_client_echo/main.cpp @@ -0,0 +1,73 @@ +#include "mbed.h" +#include "LWIPInterface.h" +#include "TCPSocket.h" +#include "greentea-client/test_env.h" +#include "unity/unity.h" + + +#ifndef MBED_CFG_TCP_CLIENT_ECHO_BUFFER_SIZE +#define MBED_CFG_TCP_CLIENT_ECHO_BUFFER_SIZE 256 +#endif + +namespace { + char tx_buffer[MBED_CFG_TCP_CLIENT_ECHO_BUFFER_SIZE] = {0}; + char rx_buffer[MBED_CFG_TCP_CLIENT_ECHO_BUFFER_SIZE] = {0}; + const char ASCII_MAX = '~' - ' '; +} + +void prep_buffer(char *tx_buffer, size_t tx_size) { + for (size_t i=0; i Date: Wed, 8 Jun 2016 17:25:34 +0100 Subject: [PATCH 09/16] Add NIST/NTP client UDP test Test case run: ``` [1465403072.69][CONN][RXD] {{__sync;a0c12e11-442c-4a60-aecf-448b5877cee3}} [1465403072.69][CONN][RXD] {{__version;1.1.0}} [1465403072.69][CONN][RXD] {{__timeout;20}} [1465403072.69][CONN][RXD] {{__host_test_name;default_auto}} [1465403072.69][CONN][INF] found SYNC in stream: {{__sync;a0c12e11-442c-4a60-aecf-448b5877cee3}}, queued... [1465403072.69][CONN][INF] found KV pair in stream: {{__version;1.1.0}}, queued... [1465403072.69][CONN][INF] found KV pair in stream: {{__timeout;20}}, queued... [1465403072.69][CONN][INF] found KV pair in stream: {{__host_test_name;default_auto}}, queued... [1465403072.69][HTST][INF] sync KV found, uuid=a0c12e11-442c-4a60-aecf-448b5877cee3, timestamp=1465403072.693000 [1465403072.69][HTST][INF] DUT greentea-client version: 1.1.0 [1465403072.69][HTST][INF] setting timeout to: 20 sec [1465403072.69][HTST][INF] host test class: '' [1465403072.69][HTST][INF] host test setup() call... [1465403072.69][HTST][INF] CALLBACKs updated [1465403072.69][HTST][INF] host test detected: default_auto [1465403075.73][CONN][RXD] UDP client IP Address is 10.254.2.206 [1465403075.73][CONN][RXD] UDP: NIST server pool.ntp.org address: 143.210.16.201 on port 123 [1465403075.73][CONN][RXD] UDP: Sent 48 Bytes to NTP server [1465403075.73][CONN][RXD] UDP: Recved from NTP server 48 Bytes [1465403076.74][CONN][RXD] UDP: Values returned by NTP server: [1465403076.74][CONN][RXD] [00] 0x1C0203EA [1465403076.74][CONN][RXD] [01] 0x140 [1465403076.74][CONN][RXD] [02] 0xB34 [1465403076.74][CONN][RXD] [03] 0x9E2BC042 [1465403076.74][CONN][RXD] [04] 0xDB02BE9F [1465403076.74][CONN][RXD] [05] 0xBB720306 [1465403076.74][CONN][RXD] [06] 0x0 [1465403076.74][CONN][RXD] [07] 0x0 [1465403076.74][CONN][RXD] [08] 0xDB02C543 [1465403076.74][CONN][RXD] [09] 0x98E6A7C1 [1465403076.74][CONN][RXD] [10] 0xDB02C543 NTP timestamp is Wed Jun 8 16:24:35 2016 [1465403076.74][CONN][RXD] [11] 0x98E8E8EF [1465403076.74][CONN][RXD] {{end;success}} ``` --- .../nist_internet_time_service/main.cpp | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 TESTS/mbedmicro-net/nist_internet_time_service/main.cpp diff --git a/TESTS/mbedmicro-net/nist_internet_time_service/main.cpp b/TESTS/mbedmicro-net/nist_internet_time_service/main.cpp new file mode 100644 index 0000000000..aefa9931bf --- /dev/null +++ b/TESTS/mbedmicro-net/nist_internet_time_service/main.cpp @@ -0,0 +1,61 @@ +#include "mbed.h" +#include "LWIPInterface.h" +#include "UDPSocket.h" +#include "greentea-client/test_env.h" + +namespace { + //const char *HTTP_SERVER_NAME = "utcnist.colorado.edu"; + const char *HTTP_SERVER_NAME = "pool.ntp.org"; + const int HTTP_SERVER_PORT = 123; +} + + +int main() { + GREENTEA_SETUP(20, "default_auto"); + + bool result = false; + const time_t TIME1970 = 2208988800L; + int ntp_values[12] = {0}; + + LWIPInterface eth; + //eth.init(); //Use DHCP + eth.connect(); + printf("UDP client IP Address is %s\n", eth.get_ip_address()); + + UDPSocket sock; + sock.open(ð); + + SocketAddress nist(ð, HTTP_SERVER_NAME, HTTP_SERVER_PORT); + + printf("UDP: NIST server %s address: %s on port %d\r\n", HTTP_SERVER_NAME, nist.get_ip_address(), nist.get_port()); + + memset(ntp_values, 0x00, sizeof(ntp_values)); + ntp_values[0] = '\x1b'; + + int ret_send = sock.sendto(nist, (void*)ntp_values, sizeof(ntp_values)); + printf("UDP: Sent %d Bytes to NTP server \n", ret_send); + + const int n = sock.recvfrom(&nist, (void*)ntp_values, sizeof(ntp_values)); + + printf("UDP: Recved from NTP server %d Bytes \n", n); + + if (n > 0 ) { + result = true; + + printf("UDP: Values returned by NTP server: \n"); + for (size_t i=0; i < sizeof(ntp_values) / sizeof(ntp_values[0]); ++i) { + printf("\t[%02d] 0x%X", i, ntohl(ntp_values[i])); + + if (i == 10) { + time_t timestamp = ntohl(ntp_values[i]) - TIME1970; + printf("\tNTP timestamp is %s", ctime(×tamp)); + } else { + printf("\n"); + } + } + } + + sock.close(); + eth.disconnect(); + GREENTEA_TESTSUITE_RESULT(result); +} From f01ae8ab9a67e6bc2052ce3050b260a8ac4fabd9 Mon Sep 17 00:00:00 2001 From: Przemek Wirkus Date: Thu, 9 Jun 2016 16:10:06 +0100 Subject: [PATCH 10/16] Add UDP Echo client test ``` mbedgt: test on hardware with target id: 0240000029304e450038500878a3003cf131000097969900 mbedgt: test suite 'TESTS-mbedmicro-net-udp_echo_client' ............................................. OK in 18.33 sec test case: 'tests-mbedmicro-net-udp_echo_client' ............................................. OK in 18.33 sec mbedgt: test case summary: 1 pass, 0 failures mbedgt: all tests finished! mbedgt: shuffle seed: 0.6134776338 mbedgt: test suite report: +--------------+---------------+-------------------------------------+--------+--------------------+-------------+ | target | platform_name | test suite | result | elapsed_time (sec) | copy_method | +--------------+---------------+-------------------------------------+--------+--------------------+-------------+ | K64F-GCC_ARM | K64F | tests-mbedmicro-net-udp_echo_client | OK | 18.33 | shell | +--------------+---------------+-------------------------------------+--------+--------------------+-------------+ mbedgt: test suite results: 1 OK mbedgt: test case report: +--------------+---------------+-------------------------------------+-------------------------------------+--------+--------+--------+--------------------+ | target | platform_name | test suite | test case | passed | failed | result | elapsed_time (sec) | +--------------+---------------+-------------------------------------+-------------------------------------+--------+--------+--------+--------------------+ | K64F-GCC_ARM | K64F | tests-mbedmicro-net-udp_echo_client | tests-mbedmicro-net-udp_echo_client | 1 | 0 | OK | 18.33 | +--------------+---------------+-------------------------------------+-------------------------------------+--------+--------+--------+--------------------+ mbedgt: test case results: 1 OK mbedgt: completed in 18.48 sec ``` --- .../host_tests/udp_echo_client.py | 125 ++++++++++++++++++ TESTS/mbedmicro-net/udp_echo_client/main.cpp | 70 ++++++++++ 2 files changed, 195 insertions(+) create mode 100644 TESTS/mbedmicro-net/host_tests/udp_echo_client.py create mode 100644 TESTS/mbedmicro-net/udp_echo_client/main.cpp diff --git a/TESTS/mbedmicro-net/host_tests/udp_echo_client.py b/TESTS/mbedmicro-net/host_tests/udp_echo_client.py new file mode 100644 index 0000000000..a2882c6aa2 --- /dev/null +++ b/TESTS/mbedmicro-net/host_tests/udp_echo_client.py @@ -0,0 +1,125 @@ +""" +mbed SDK +Copyright (c) 2011-2013 ARM Limited + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +""" + +import sys +import socket +from sys import stdout +from threading import Thread +from SocketServer import BaseRequestHandler, UDPServer +from mbed_host_tests import BaseHostTest, event_callback + + +class UDPEchoClientHandler(BaseRequestHandler): + def handle(self): + """ UDP packet handler. Echoes data back to sender's address. + """ + data, sock = self.request + print ('HOST: UDPEchoClientHandler: Rx: \n%s\n' % data) + sock.sendto(data, self.client_address) + + +class UDPEchoClientTest(BaseHostTest): + + def __init__(self): + """ + Initialise test parameters. + + :return: + """ + BaseHostTest.__init__(self) + self.SERVER_IP = None # Will be determined after knowing the target IP + self.SERVER_PORT = 0 # Let TCPServer choose an arbitrary port + self.server = None + self.server_thread = None + self.target_ip = None + + @staticmethod + def find_interface_to_target_addr(target_ip): + """ + Finds IP address of the interface through which it is connected to the target. + + :return: + """ + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + s.connect((target_ip, 0)) # Target IP, Any port + ip = s.getsockname()[0] + s.close() + return ip + + def setup_udp_server(self): + """ + sets up a UDP server for target to connect and send test data. + + :return: + """ + # !NOTE: There should mechanism to assert in the host test + if self.SERVER_IP is None: + self.log("setup_udp_server() called before determining server IP!") + self.notify_complete(False) + + # Returning none will suppress host test from printing success code + self.server = UDPServer((self.SERVER_IP, self.SERVER_PORT), UDPEchoClientHandler) + ip, port = self.server.server_address + self.SERVER_PORT = port + self.server.allow_reuse_address = True + self.log("HOST: Listening for UDP packets: " + self.SERVER_IP + ":" + str(self.SERVER_PORT)) + self.server_thread = Thread(target=UDPEchoClientTest.server_thread_func, args=(self,)) + self.server_thread.start() + + @staticmethod + def server_thread_func(this): + """ + Thread function to run TCP server forever. + + :param this: + :return: + """ + this.server.serve_forever() + + @event_callback("target_ip") + def _callback_target_ip(self, key, value, timestamp): + """ + Callback to handle reception of target's IP address. + + :param key: + :param value: + :param timestamp: + :return: + """ + self.target_ip = value + self.SERVER_IP = self.find_interface_to_target_addr(self.target_ip) + self.setup_udp_server() + + @event_callback("host_ip") + def _callback_host_ip(self, key, value, timestamp): + """ + Callback for request for host IP Addr + + """ + self.send_kv("host_ip", self.SERVER_IP) + + @event_callback("host_port") + def _callback_host_port(self, key, value, timestamp): + """ + Callback for request for host port + """ + self.send_kv("host_port", self.SERVER_PORT) + + def teardown(self): + if self.server: + self.server.shutdown() + self.server_thread.join() diff --git a/TESTS/mbedmicro-net/udp_echo_client/main.cpp b/TESTS/mbedmicro-net/udp_echo_client/main.cpp new file mode 100644 index 0000000000..84c0b26fa8 --- /dev/null +++ b/TESTS/mbedmicro-net/udp_echo_client/main.cpp @@ -0,0 +1,70 @@ +#include "mbed.h" +#include "LWIPInterface.h" +#include "UDPSocket.h" +#include "greentea-client/test_env.h" + +#ifndef MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE +#define MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE 256 +#endif + +namespace { + char tx_buffer[MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE] = {0}; + char rx_buffer[MBED_CFG_UDP_CLIENT_ECHO_BUFFER_SIZE] = {0}; + const char ASCII_MAX = '~' - ' '; + const int ECHO_LOOPS = 16; +} + +void prep_buffer(char *tx_buffer, size_t tx_size) { + for (size_t i=0; i Date: Mon, 6 Jun 2016 11:17:00 -0500 Subject: [PATCH 11/16] Updated pre-defork-tests with feedback --- TESTS/mbed_drivers/callback/main.cpp | 4 ++-- TESTS/mbedmicro-mbed/attributes/main.cpp | 4 ++-- TESTS/mbedmicro-rtos-mbed/threads/main.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/TESTS/mbed_drivers/callback/main.cpp b/TESTS/mbed_drivers/callback/main.cpp index 90fdd1af1c..7d229fa7a3 100644 --- a/TESTS/mbed_drivers/callback/main.cpp +++ b/TESTS/mbed_drivers/callback/main.cpp @@ -1,5 +1,5 @@ #include "mbed.h" -#include "test_env.h" +#include "greentea-client/test_env.h" #include "unity.h" #include "utest.h" @@ -230,7 +230,7 @@ void test_fparg0() { // Test setup utest::v1::status_t test_setup(const size_t number_of_cases) { - GREENTEA_SETUP(40, "default_auto"); + GREENTEA_SETUP(5, "default_auto"); return verbose_test_setup_handler(number_of_cases); } diff --git a/TESTS/mbedmicro-mbed/attributes/main.cpp b/TESTS/mbedmicro-mbed/attributes/main.cpp index 1a0feb99ae..c006e904db 100644 --- a/TESTS/mbedmicro-mbed/attributes/main.cpp +++ b/TESTS/mbedmicro-mbed/attributes/main.cpp @@ -2,7 +2,7 @@ #include #include "toolchain.h" -#include "test_env.h" +#include "greentea-client/test_env.h" #include "unity.h" #include "utest.h" @@ -30,7 +30,7 @@ void test_wrapper() { } utest::v1::status_t test_setup(const size_t number_of_cases) { - GREENTEA_SETUP(40, "default_auto"); + GREENTEA_SETUP(5, "default_auto"); return verbose_test_setup_handler(number_of_cases); } diff --git a/TESTS/mbedmicro-rtos-mbed/threads/main.cpp b/TESTS/mbedmicro-rtos-mbed/threads/main.cpp index 555a2a1bfe..d3f8acc18f 100644 --- a/TESTS/mbedmicro-rtos-mbed/threads/main.cpp +++ b/TESTS/mbedmicro-rtos-mbed/threads/main.cpp @@ -1,5 +1,5 @@ #include "mbed.h" -#include "test_env.h" +#include "greentea-client/test_env.h" #include "unity.h" #include "utest.h" #include "rtos.h" From 3dc7d3d323100cecd2da24db2bd33ad48d11bd85 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Thu, 9 Jun 2016 19:06:02 -0500 Subject: [PATCH 12/16] Fixed issue with stricter alignment than stack in IAR --- TESTS/mbedmicro-mbed/attributes/attributes.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/TESTS/mbedmicro-mbed/attributes/attributes.c b/TESTS/mbedmicro-mbed/attributes/attributes.c index f8ad7f7a40..1130b43461 100644 --- a/TESTS/mbedmicro-mbed/attributes/attributes.c +++ b/TESTS/mbedmicro-mbed/attributes/attributes.c @@ -29,15 +29,15 @@ int testPacked() { } +MBED_ALIGN(8) char a; +MBED_ALIGN(8) char b; +MBED_ALIGN(16) char c; +MBED_ALIGN(8) char d; +MBED_ALIGN(16) char e; + int testAlign() { int failed = 0; - MBED_ALIGN(8) char a; - MBED_ALIGN(8) char b; - MBED_ALIGN(16) char c; - MBED_ALIGN(8) char d; - MBED_ALIGN(16) char e; - if(((uintptr_t)&a) & 0x7){ failed++; } From 8300c2ea471c99e388d26a2088535b059aaa5641 Mon Sep 17 00:00:00 2001 From: Brian Daniels Date: Fri, 10 Jun 2016 12:06:17 +0100 Subject: [PATCH 13/16] Workaround for collision of _UP in IAR --- TESTS/mbed_drivers/stl_features/main.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/TESTS/mbed_drivers/stl_features/main.cpp b/TESTS/mbed_drivers/stl_features/main.cpp index ec99282d45..2cfbd2b50c 100644 --- a/TESTS/mbed_drivers/stl_features/main.cpp +++ b/TESTS/mbed_drivers/stl_features/main.cpp @@ -14,6 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity/unity.h" +#include "utest/utest.h" #include #include #include @@ -22,10 +26,6 @@ #include #include #include -#include "mbed.h" -#include "greentea-client/test_env.h" -#include "unity/unity.h" -#include "utest/utest.h" using namespace utest::v1; From 00efb00aacda1362e9d0b6a672ae75825ed2e8bb Mon Sep 17 00:00:00 2001 From: Przemek Wirkus Date: Wed, 1 Jun 2016 15:33:17 +0100 Subject: [PATCH 14/16] mbed-drivers test cases port to mbed-os --- TESTS/mbed_drivers/c_strings/main.cpp | 124 +++++++++++++++++++ TESTS/mbed_drivers/dev_null/main.cpp | 48 ++++++++ TESTS/mbed_drivers/echo/main.cpp | 64 ++++++++++ TESTS/mbed_drivers/generic_tests/main.cpp | 119 ++++++++++++++++++ TESTS/mbed_drivers/rtc/main.cpp | 56 +++++++++ TESTS/mbed_drivers/stl_features/main.cpp | 139 ++++++++++++++++++++++ TESTS/mbed_drivers/ticker/main.cpp | 80 +++++++++++++ TESTS/mbed_drivers/ticker_2/main.cpp | 69 +++++++++++ TESTS/mbed_drivers/ticker_3/main.cpp | 73 ++++++++++++ TESTS/mbed_drivers/timeout/main.cpp | 77 ++++++++++++ TESTS/mbed_drivers/wait_us/main.cpp | 51 ++++++++ 11 files changed, 900 insertions(+) create mode 100644 TESTS/mbed_drivers/c_strings/main.cpp create mode 100644 TESTS/mbed_drivers/dev_null/main.cpp create mode 100644 TESTS/mbed_drivers/echo/main.cpp create mode 100644 TESTS/mbed_drivers/generic_tests/main.cpp create mode 100644 TESTS/mbed_drivers/rtc/main.cpp create mode 100644 TESTS/mbed_drivers/stl_features/main.cpp create mode 100644 TESTS/mbed_drivers/ticker/main.cpp create mode 100644 TESTS/mbed_drivers/ticker_2/main.cpp create mode 100644 TESTS/mbed_drivers/ticker_3/main.cpp create mode 100644 TESTS/mbed_drivers/timeout/main.cpp create mode 100644 TESTS/mbed_drivers/wait_us/main.cpp diff --git a/TESTS/mbed_drivers/c_strings/main.cpp b/TESTS/mbed_drivers/c_strings/main.cpp new file mode 100644 index 0000000000..efb73999ef --- /dev/null +++ b/TESTS/mbed_drivers/c_strings/main.cpp @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity/unity.h" +#include "utest/utest.h" + +namespace { +static char buffer[256] = {0}; +} + +#define CLEAN_BUFFER memset(::buffer, 0x00, sizeof(::buffer)) +#define NEGATIVE_INTEGERS -32768,-3214,-999,-100,-1,0,-1,-4231,-999,-4123,-32760,-99999 +#define POSITIVE_INTEGERS 32768,3214,999,100,1,0,1,4231,999,4123,32760,99999 +#define FLOATS 0.002,0.92430,15.91320,791.77368,6208.2,25719.4952,426815.982588,6429271.046,42468024.93,212006462.910 + +using namespace utest::v1; + + +void test_case_c_string_i_d() { + CLEAN_BUFFER; + sprintf(buffer, "%i %d %i %d %i %d %i %d %i %d %i %i", NEGATIVE_INTEGERS); + TEST_ASSERT_EQUAL_STRING("-32768 -3214 -999 -100 -1 0 -1 -4231 -999 -4123 -32760 -99999", buffer); +} + +void test_case_c_string_u_d() { + CLEAN_BUFFER; + sprintf(buffer, "%u %d %u %d %u %d %u %d %u %d %u %d", POSITIVE_INTEGERS); + TEST_ASSERT_EQUAL_STRING("32768 3214 999 100 1 0 1 4231 999 4123 32760 99999", buffer); +} + +void test_case_c_string_x_E() { + CLEAN_BUFFER; + sprintf(buffer, "%x %X %x %X %x %X %x %X %x %X %x %X", POSITIVE_INTEGERS); + TEST_ASSERT_EQUAL_STRING("8000 C8E 3e7 64 1 0 1 1087 3e7 101B 7ff8 1869F", buffer); +} + +void test_case_c_string_f_f() { + CLEAN_BUFFER; + sprintf(buffer, "%f %f %f %f %f %f %f %f %f %f", FLOATS); + TEST_ASSERT_EQUAL_STRING("0.002000 0.924300 15.913200 791.773680 6208.200000 25719.495200 426815.982588 6429271.046000 42468024.930000 212006462.910000", buffer); +} + +void test_case_c_string_g_g() { + CLEAN_BUFFER; + sprintf(buffer, "%g %g %g %g %g %g %g %g %g %g", FLOATS); + TEST_ASSERT_EQUAL_STRING("0.002 0.9243 15.9132 791.774 6208.2 25719.5 426816 6.42927e+006 4.2468e+007 2.12006e+008", buffer); + TEST_ASSERT_EQUAL_STRING("0.002 0.9243 15.9132 791.774 6208.2 25719.5 426816 6.42927e+06 4.2468e+07 2.12006e+08", buffer); +} + +void test_case_c_string_e_E() { + CLEAN_BUFFER; + sprintf(buffer, "%e %E %e %E %e %E %e %E %e %E", FLOATS); + TEST_ASSERT_EQUAL_STRING("2.000000e-003 9.243000E-001 1.591320e+001 7.917737E+002 6.208200e+003 2.571950E+004 4.268160e+005 6.429271E+006 4.246802e+007 2.120065E+008", buffer); + TEST_ASSERT_EQUAL_STRING("2.000000e-03 9.243000E-01 1.591320e+01 7.917737E+02 6.208200e+03 2.571950E+04 4.268160e+05 6.429271E+06 4.246802e+07 2.120065E+08", buffer); +} + +void test_case_c_string_strtok() { + CLEAN_BUFFER; + char str[] ="- This, a sample string."; + char * pch = strtok (str," ,.-"); + while (pch != NULL) { + strcat(buffer, pch); + pch = strtok (NULL, " ,.-"); + } + TEST_ASSERT_EQUAL_STRING("Thisasamplestring", buffer); +} + +void test_case_c_string_strpbrk() { + CLEAN_BUFFER; + char str[] = "This is a sample string"; + char key[] = "aeiou"; + char *pch = strpbrk(str, key); + while (pch != NULL) + { + char buf[2] = {*pch, '\0'}; + strcat(buffer, buf); + pch = strpbrk(pch + 1,key); + } + TEST_ASSERT_EQUAL_STRING("iiaaei", buffer); +} + +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { + greentea_case_failure_abort_handler(source, reason); + return STATUS_CONTINUE; +} + +Case cases[] = { + Case("C strings: strtok", test_case_c_string_strtok, greentea_failure_handler), + Case("C strings: strpbrk", test_case_c_string_strpbrk, greentea_failure_handler), + Case("C strings: %i %d integer formatting", test_case_c_string_i_d, greentea_failure_handler), + Case("C strings: %u %d integer formatting", test_case_c_string_u_d, greentea_failure_handler), + Case("C strings: %x %E integer formatting", test_case_c_string_x_E, greentea_failure_handler), + Case("C strings: %f %f float formatting", test_case_c_string_f_f, greentea_failure_handler), + Case("C strings: %e %E float formatting", test_case_c_string_e_E, greentea_failure_handler), + Case("C strings: %g %g float formatting", test_case_c_string_g_g, greentea_failure_handler), +}; + +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(5, "default_auto"); + return greentea_test_setup_handler(number_of_cases); +} + +Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); + +int main() { + Harness::run(specification); +} diff --git a/TESTS/mbed_drivers/dev_null/main.cpp b/TESTS/mbed_drivers/dev_null/main.cpp new file mode 100644 index 0000000000..22940d026f --- /dev/null +++ b/TESTS/mbed_drivers/dev_null/main.cpp @@ -0,0 +1,48 @@ +/* mbed Microcontroller Library + * Copyright (c) 2013-2014 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mbed.h" +#include "greentea-client/test_env.h" + +class DevNull : public Stream { +public: + DevNull(const char *name = NULL) : Stream(name) {} + +protected: + virtual int _getc() { + return 0; + } + virtual int _putc(int c) { + return c; + } +}; + +DevNull null("null"); + +int main() { + GREENTEA_SETUP(2, "dev_null_auto"); + + printf("MBED: before re-routing stdout to /null\n"); // This shouldn't appear + greentea_send_kv("to_stdout", "re-routing stdout to /null"); + + if (freopen("/null", "w", stdout)) { + // This shouldn't appear on serial + // We should use pure printf here to send KV + printf("{{to_null;printf redirected to /null}}\n"); + printf("MBED: this printf is already redirected to /null\n"); + } + GREENTEA_TESTSUITE_RESULT(false); +} diff --git a/TESTS/mbed_drivers/echo/main.cpp b/TESTS/mbed_drivers/echo/main.cpp new file mode 100644 index 0000000000..f531a79f7d --- /dev/null +++ b/TESTS/mbed_drivers/echo/main.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity/unity.h" +#include "utest/utest.h" + +using namespace utest::v1; + +// Echo server (echo payload to host) +template +void test_case_echo_server_x() { + char _key[10] = {}; + char _value[128] = {}; + const int echo_count = N; + + // Handshake with host + greentea_send_kv("echo_count", echo_count); + greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value)); + TEST_ASSERT_EQUAL_INT(echo_count, atoi(_value)); + + for (int i=0; i < echo_count; ++i) { + greentea_parse_kv(_key, _value, sizeof(_key), sizeof(_value)); + greentea_send_kv(_key, _value); + } +} + +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { + greentea_case_failure_abort_handler(source, reason); + return STATUS_CONTINUE; +} + +Case cases[] = { + Case("Echo server: x16", test_case_echo_server_x<16>, greentea_failure_handler), + Case("Echo server: x32", test_case_echo_server_x<32>, greentea_failure_handler), + Case("Echo server: x64", test_case_echo_server_x<64>, greentea_failure_handler), +}; + +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(30, "echo"); + return greentea_test_setup_handler(number_of_cases); +} + +Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); + +int main() { + Harness::run(specification); +} diff --git a/TESTS/mbed_drivers/generic_tests/main.cpp b/TESTS/mbed_drivers/generic_tests/main.cpp new file mode 100644 index 0000000000..dc177e3f4d --- /dev/null +++ b/TESTS/mbed_drivers/generic_tests/main.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include // std::pair +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity/unity.h" +#include "utest/utest.h" + +using namespace utest::v1; + +#define PATTERN_CHECK_VALUE 0xF0F0ADAD + +class CppTestCaseHelperClass { +private: + const char* name; + const unsigned pattern; + +public: + CppTestCaseHelperClass(const char* _name) : name(_name), pattern(PATTERN_CHECK_VALUE) { + print("init"); + } + + void print(const char *message) { + printf("%s::%s\n", name, message); + } + + bool check_init(void) { + bool result = (pattern == PATTERN_CHECK_VALUE); + print(result ? "check_init: OK" : "check_init: ERROR"); + return result; + } + + void stack_test(void) { + print("stack_test"); + CppTestCaseHelperClass t("Stack"); + t.hello(); + } + + void hello(void) { + print("hello"); + } + + ~CppTestCaseHelperClass() { + print("destroy"); + } +}; + + +void test_case_basic() { + TEST_ASSERT_TRUE(true); + TEST_ASSERT_FALSE(false); + TEST_ASSERT_EQUAL_STRING("The quick brown fox jumps over the lazy dog", + "The quick brown fox jumps over the lazy dog"); +} + +void test_case_blinky() { + static DigitalOut myled(LED1); + const int cnt_max = 1024; + for (int cnt = 0; cnt < cnt_max; ++cnt) { + myled = !myled; + } +} + +void test_case_cpp_stack() { + // Check C++ start-up initialisation + CppTestCaseHelperClass s("Static"); + + // Global stack object simple test + s.stack_test(); + TEST_ASSERT_TRUE_MESSAGE(s.check_init(), "s.check_init() failed"); +} + +void test_case_cpp_heap() { + // Heap test object simple test + CppTestCaseHelperClass *m = new CppTestCaseHelperClass("Heap"); + m->hello(); + TEST_ASSERT_TRUE_MESSAGE(m->check_init(), "m->check_init() failed"); + delete m; +} + +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { + greentea_case_failure_abort_handler(source, reason); + return STATUS_CONTINUE; +} + +// Generic test cases +Case cases[] = { + Case("Basic", test_case_basic, greentea_failure_handler), + Case("Blinky", test_case_blinky, greentea_failure_handler), + Case("C++ stack", test_case_cpp_stack, greentea_failure_handler), + Case("C++ heap", test_case_cpp_heap, greentea_failure_handler) +}; + +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(20, "default_auto"); + return greentea_test_setup_handler(number_of_cases); +} + +Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); + +int main() { + Harness::run(specification); +} diff --git a/TESTS/mbed_drivers/rtc/main.cpp b/TESTS/mbed_drivers/rtc/main.cpp new file mode 100644 index 0000000000..fae4d06e20 --- /dev/null +++ b/TESTS/mbed_drivers/rtc/main.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity/unity.h" +#include "utest/utest.h" + +using namespace utest::v1; + +#define CUSTOM_TIME 1256729737 + +void test_case_rtc_strftime() { + greentea_send_kv("timestamp", CUSTOM_TIME); + + char buffer[32] = {0}; + char kv_buff[64] = {0}; + set_time(CUSTOM_TIME); // Set RTC time to Wed, 28 Oct 2009 11:35:37 + + for (int i=0; i<10; ++i) { + time_t seconds = time(NULL); + sprintf(kv_buff, "[%ld] ", seconds); + strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S %p", localtime(&seconds)); + strcat(kv_buff, buffer); + greentea_send_kv("rtc", kv_buff); + wait(1); + } +} + +Case cases[] = { + Case("RTC strftime", test_case_rtc_strftime), +}; + +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(20, "rtc_auto"); + return greentea_test_setup_handler(number_of_cases); +} + +Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); + +int main() { + Harness::run(specification); +} diff --git a/TESTS/mbed_drivers/stl_features/main.cpp b/TESTS/mbed_drivers/stl_features/main.cpp new file mode 100644 index 0000000000..ec99282d45 --- /dev/null +++ b/TESTS/mbed_drivers/stl_features/main.cpp @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "unity/unity.h" +#include "utest/utest.h" + +using namespace utest::v1; + +#define TABLE_SIZE(TAB) (sizeof(TAB) / sizeof(TAB[0])) + +#define NEGATIVE_INTEGERS -32768,-3214,-999,-100,-1,0,1,4231,999,4123,32760,99999 +#define POSITIVE_INTEGERS 32768,3214,999,100,1,0,1,4231,999,4123,32760,99999 +#define FLOATS 0.002,0.92430,15.91320,791.77368,6208.2,25719.4952,426815.982588,6429271.046,42468024.93,212006462.910 +#define FLOATS_STR "0.002","0.92430","15.91320","791.77368","6208.2","25719.4952","426815.982588","6429271.046","42468024.93","212006462.910" + + +namespace { +int p_integers[] = {POSITIVE_INTEGERS}; +int n_integers[] = {NEGATIVE_INTEGERS}; +float floats[] = {FLOATS}; + +template +void BubbleSort(T& _array, size_t array_size, F functor) { + bool flag = true; + size_t numLength = array_size; + for(size_t i = 1; (i <= numLength) && flag; i++) { + flag = false; + for (size_t j = 0; j < (numLength - 1); j++) { + if (functor(_array[j+1], _array[j])) { + int temp = _array[j]; + _array[j] = _array[j + 1]; + _array[j+1] = temp; + flag = true; + } + } + } +} + +struct printInt { + void operator()(int i) { printf("%d ", i); } +}; + +struct printFloat { + void operator()(float f) { printf("%f ", f); } +}; + +struct printString { + void operator()(const char* s) { printf("%s ", s); } +}; + +struct greaterAbs { + bool operator()(int a, int b) { return abs(a) > abs(b); } +}; + +} // namespace + +void test_case_stl_equal() { + std::vector v_pints(p_integers, p_integers + TABLE_SIZE(p_integers)); + TEST_ASSERT_TRUE(std::equal(v_pints.begin(), v_pints.end(), p_integers)); +} + +void test_case_stl_transform() { + const char* floats_str[] = {FLOATS_STR}; + float floats_transform[TABLE_SIZE(floats_str)] = {0.0}; + std::transform(floats_str, floats_str + TABLE_SIZE(floats_str), floats_transform, atof); + //printf("stl_transform::floats_str: "); + //std::for_each(floats_str, floats_str + TABLE_SIZE(floats_str), printString()); + //printf("stl_transform::floats_transform: "); + //std::for_each(floats_transform, floats_transform + TABLE_SIZE(floats_transform), printFloat()); + //printf("\n"); + + TEST_ASSERT_TRUE(std::equal(floats_transform, floats_transform + TABLE_SIZE(floats_transform), floats)); +} + +void test_case_stl_sort_greater() { + std::vector v_nints_1(n_integers, n_integers + TABLE_SIZE(n_integers)); + std::vector v_nints_2(n_integers, n_integers + TABLE_SIZE(n_integers)); + + BubbleSort(v_nints_1, v_nints_1.size(), std::greater()); + std::sort(v_nints_2.begin(), v_nints_2.end(), std::greater()); + + TEST_ASSERT_TRUE(std::equal(v_nints_1.begin(), v_nints_1.end(), v_nints_2.begin())); +} + +void test_case_stl_sort_abs() { + std::vector v_nints_1(n_integers, n_integers + TABLE_SIZE(n_integers)); + std::vector v_nints_2(n_integers, n_integers + TABLE_SIZE(n_integers)); + + BubbleSort(v_nints_1, v_nints_1.size(), greaterAbs()); + std::sort(v_nints_2.begin(), v_nints_2.end(), greaterAbs()); + + TEST_ASSERT_TRUE(std::equal(v_nints_1.begin(), v_nints_1.end(), v_nints_2.begin())); +} + +utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { + greentea_case_failure_abort_handler(source, reason); + return STATUS_CONTINUE; +} + +Case cases[] = { + Case("STL std::equal", test_case_stl_equal, greentea_failure_handler), + Case("STL std::transform", test_case_stl_transform, greentea_failure_handler), + Case("STL std::sort greater", test_case_stl_sort_greater, greentea_failure_handler), + Case("STL std::sort abs", test_case_stl_sort_abs, greentea_failure_handler) +}; + +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(5, "default_auto"); + return greentea_test_setup_handler(number_of_cases); +} + +Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); + +int main() { + Harness::run(specification); +} diff --git a/TESTS/mbed_drivers/ticker/main.cpp b/TESTS/mbed_drivers/ticker/main.cpp new file mode 100644 index 0000000000..0b6cdeac1c --- /dev/null +++ b/TESTS/mbed_drivers/ticker/main.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "utest/utest.h" + +using namespace utest::v1; + +void send_kv_tick() { + static int count = 0; + if (count < 10) { + greentea_send_kv("tick", count); + } else if (count == 10) { + Harness::validate_callback(); + } + count++; +} + +Ticker flipper_1; +DigitalOut led1(LED1); + +void flip_1() { + static int led1_state = 0; + if (led1_state) { + led1 = 0; led1_state = 0; + } else { + led1 = 1; led1_state = 1; + } + send_kv_tick(); +} + +Ticker flipper_2; +DigitalOut led2(LED2); + +void flip_2() { + static int led2_state = 0; + if (led2_state) { + led2 = 0; led2_state = 0; + } else { + led2 = 1; led2_state = 1; + } +} + +control_t test_case_ticker() { + led1 = 0; + led2 = 0; + flipper_1.attach(&flip_1, 1.0); + flipper_2.attach(&flip_2, 2.0); + return CaseTimeout(15 * 1000); +} + +// Test cases +Case cases[] = { + Case("Timers: 2 x tickers", test_case_ticker), +}; + +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(20, "wait_us_auto"); + return greentea_test_setup_handler(number_of_cases); +} + +Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); + +int main() { + Harness::run(specification); +} diff --git a/TESTS/mbed_drivers/ticker_2/main.cpp b/TESTS/mbed_drivers/ticker_2/main.cpp new file mode 100644 index 0000000000..7fcc526d8a --- /dev/null +++ b/TESTS/mbed_drivers/ticker_2/main.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "utest/utest.h" + +using namespace utest::v1; + +Ticker tick; +DigitalOut led(LED1); + +namespace { + const int MS_INTERVALS = 1000; +} + +void send_kv_tick() { + static int count = 0; + if (count < 10) { + greentea_send_kv("tick", count); + } else if (count == 10) { + Harness::validate_callback(); + } + count++; +} + +void togglePin(void) { + static int ticker_count = 0; + if (ticker_count >= MS_INTERVALS) { + send_kv_tick(); + ticker_count = 0; + led = !led; + } + ticker_count++; +} + +utest::v1::control_t test_case_ticker() { + tick.attach_us(togglePin, 1000); + return CaseTimeout(15 * 1000); +} + +// Test cases +Case cases[] = { + Case("Timers: 1x ticker", test_case_ticker), +}; + +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(20, "wait_us_auto"); + return greentea_test_setup_handler(number_of_cases); +} + +Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); + +int main() { + Harness::run(specification); +} diff --git a/TESTS/mbed_drivers/ticker_3/main.cpp b/TESTS/mbed_drivers/ticker_3/main.cpp new file mode 100644 index 0000000000..dcb95d8127 --- /dev/null +++ b/TESTS/mbed_drivers/ticker_3/main.cpp @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "utest/utest.h" + +using namespace utest::v1; + +void ticker_callback_1(void); +void ticker_callback_2(void); + +DigitalOut led0(LED1); +DigitalOut led1(LED2); +Ticker ticker; + +void send_kv_tick() { + static int count = 0; + if (count < 10) { + greentea_send_kv("tick", count); + } else if (count == 10) { + Harness::validate_callback(); + } + count++; +} + +void ticker_callback_2(void) { + ticker.detach(); + ticker.attach(ticker_callback_1, 1.0); + led1 = !led1; + send_kv_tick(); +} + +void ticker_callback_1(void) { + ticker.detach(); + ticker.attach(ticker_callback_2, 1.0); + led0 = !led0; + send_kv_tick(); +} + +utest::v1::control_t test_case_ticker() { + ticker.attach(ticker_callback_1, 1.0); + return CaseTimeout(15 * 1000); +} + +// Test cases +Case cases[] = { + Case("Timers: 2x callbacks", test_case_ticker), +}; + +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(20, "wait_us_auto"); + return greentea_test_setup_handler(number_of_cases); +} + +Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); + +int main() { + Harness::run(specification); +} diff --git a/TESTS/mbed_drivers/timeout/main.cpp b/TESTS/mbed_drivers/timeout/main.cpp new file mode 100644 index 0000000000..1317475db4 --- /dev/null +++ b/TESTS/mbed_drivers/timeout/main.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "utest/utest.h" + +using namespace utest::v1; + +Timeout timer; +DigitalOut led(LED1); + +namespace { + const int MS_INTERVALS = 1000; +} + +void send_kv_tick() { + static int count = 0; + if (count < 10) { + greentea_send_kv("tick", count); + } else if (count == 10) { + Harness::validate_callback(); + } + count++; +} + +void toggleOff(void); + +void toggleOn(void) { + static int toggle_counter = 0; + if (toggle_counter == MS_INTERVALS) { + led = !led; + send_kv_tick(); + toggle_counter = 0; + } + toggle_counter++; + timer.attach_us(toggleOff, 500); +} + +void toggleOff(void) { + timer.attach_us(toggleOn, 500); +} + +control_t test_case_ticker() { + toggleOn(); + return CaseTimeout(15 * 1000); +} + +// Test cases +Case cases[] = { + Case("Timers: toggle on/off", test_case_ticker), +}; + +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(20, "wait_us_auto"); + return greentea_test_setup_handler(number_of_cases); +} + +Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); + +int main() { + Harness::run(specification); +} + diff --git a/TESTS/mbed_drivers/wait_us/main.cpp b/TESTS/mbed_drivers/wait_us/main.cpp new file mode 100644 index 0000000000..429f2409cb --- /dev/null +++ b/TESTS/mbed_drivers/wait_us/main.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "mbed.h" +#include "greentea-client/test_env.h" +#include "utest/utest.h" + +using namespace utest::v1; + +DigitalOut led(LED1); + +void test_case_ticker() { + for (int i=0; i < 10; ++i) { + // 10 secs... + for (int j = 0; j < 1000; ++j) { + // 1000 * 1000us = 1 sec + wait_us(1000); + } + led = !led; // Blink + greentea_send_kv("tick", i); + } +} + +// Test cases +Case cases[] = { + Case("Timers: wait_us", test_case_ticker), +}; + +utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { + GREENTEA_SETUP(20, "wait_us_auto"); + return greentea_test_setup_handler(number_of_cases); +} + +Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); + +int main() { + Harness::run(specification); +} From 68b0b7b9cd8ef478d11c6fb796b0647bc9270598 Mon Sep 17 00:00:00 2001 From: Przemek Wirkus Date: Wed, 1 Jun 2016 16:44:02 +0100 Subject: [PATCH 15/16] 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); +} From 3b3745e00833929c1d5a943a3d4e8caf532b90d0 Mon Sep 17 00:00:00 2001 From: Przemek Wirkus Date: Thu, 2 Jun 2016 17:11:27 +0100 Subject: [PATCH 16/16] Add few non-peripheral tests from mbedmicro/mbed/libraries/tests/mbed Tested on K64F: ``` $ mbedgt -VS -n TESTS-mbedmicro-mbed* ``` ``` mbedgt: test suite report: +--------------+---------------+---------------------------------------+--------+--------------------+-------------+ | target | platform_name | test suite | result | elapsed_time (sec) | copy_method | +--------------+---------------+---------------------------------------+--------+--------------------+-------------+ | K64F-GCC_ARM | K64F | tests-mbedmicro-mbed-call_before_main | OK | 10.53 | shell | | K64F-GCC_ARM | K64F | tests-mbedmicro-mbed-cpp | OK | 10.64 | shell | | K64F-GCC_ARM | K64F | tests-mbedmicro-mbed-div | OK | 10.64 | shell | | K64F-GCC_ARM | K64F | tests-mbedmicro-mbed-heap_and_stack | OK | 30.32 | shell | +--------------+---------------+---------------------------------------+--------+--------------------+-------------+ mbedgt: test suite results: 4 OK mbedgt: test case report: +--------------+---------------+---------------------------------------+---------------------------------------+--------+--------+--------+--------------------+ | target | platform_name | test suite | test case | passed | failed | result | elapsed_time (sec) | +--------------+---------------+---------------------------------------+---------------------------------------+--------+--------+--------+--------------------+ | K64F-GCC_ARM | K64F | tests-mbedmicro-mbed-call_before_main | tests-mbedmicro-mbed-call_before_main | 1 | 0 | OK | 10.53 | | K64F-GCC_ARM | K64F | tests-mbedmicro-mbed-cpp | tests-mbedmicro-mbed-cpp | 1 | 0 | OK | 10.64 | | K64F-GCC_ARM | K64F | tests-mbedmicro-mbed-div | tests-mbedmicro-mbed-div | 1 | 0 | OK | 10.64 | | K64F-GCC_ARM | K64F | tests-mbedmicro-mbed-heap_and_stack | tests-mbedmicro-mbed-heap_and_stack | 1 | 0 | OK | 30.32 | +--------------+---------------+---------------------------------------+---------------------------------------+--------+--------+--------+--------------------+ mbedgt: test case results: 4 OK mbedgt: completed in 62.25 sec ``` --- .../mbedmicro-mbed/call_before_main/main.cpp | 16 ++++ TESTS/mbedmicro-mbed/cpp/main.cpp | 83 +++++++++++++++++++ TESTS/mbedmicro-mbed/div/main.cpp | 41 +++++++++ TESTS/mbedmicro-mbed/heap_and_stack/main.cpp | 80 ++++++++++++++++++ 4 files changed, 220 insertions(+) create mode 100644 TESTS/mbedmicro-mbed/call_before_main/main.cpp create mode 100644 TESTS/mbedmicro-mbed/cpp/main.cpp create mode 100644 TESTS/mbedmicro-mbed/div/main.cpp create mode 100644 TESTS/mbedmicro-mbed/heap_and_stack/main.cpp diff --git a/TESTS/mbedmicro-mbed/call_before_main/main.cpp b/TESTS/mbedmicro-mbed/call_before_main/main.cpp new file mode 100644 index 0000000000..9a713d3f30 --- /dev/null +++ b/TESTS/mbedmicro-mbed/call_before_main/main.cpp @@ -0,0 +1,16 @@ +#include "greentea-client/test_env.h" + +namespace { + bool mbed_main_called = false; +} + +extern "C" void mbed_main() { + printf("MBED: mbed_main() call before main()\r\n"); + mbed_main_called = true; +} + +int main() { + GREENTEA_SETUP(5, "default_auto"); + printf("MBED: main() starts now!\r\n"); + GREENTEA_TESTSUITE_RESULT(mbed_main_called); +} diff --git a/TESTS/mbedmicro-mbed/cpp/main.cpp b/TESTS/mbedmicro-mbed/cpp/main.cpp new file mode 100644 index 0000000000..bfa02200ae --- /dev/null +++ b/TESTS/mbedmicro-mbed/cpp/main.cpp @@ -0,0 +1,83 @@ +#include "greentea-client/test_env.h" + +#define PATTERN_CHECK_VALUE 0xF0F0ADAD + +class Test { + +private: + const char* name; + const int pattern; + +public: + Test(const char* _name) : name(_name), pattern(PATTERN_CHECK_VALUE) { + print("init"); + } + + void print(const char *message) { + printf("%s::%s\n", name, message); + } + + bool check_init(void) { + bool result = (pattern == PATTERN_CHECK_VALUE); + print(result ? "check_init: OK" : "check_init: ERROR"); + return result; + } + + void stack_test(void) { + print("stack_test"); + Test t("Stack"); + t.hello(); + } + + void hello(void) { + print("hello"); + } + + ~Test() { + print("destroy"); + } +}; + +/* Check C++ startup initialisation */ +Test s("Static"); + +/* EXPECTED OUTPUT: +******************* +Static::init +Static::stack_test +Stack::init +Stack::hello +Stack::destroy +Static::check_init: OK +Heap::init +Heap::hello +Heap::destroy +*******************/ +int main (void) { + GREENTEA_SETUP(10, "default_auto"); + + bool result = true; + for (;;) + { + // Global stack object simple test + s.stack_test(); + if (s.check_init() == false) + { + result = false; + break; + } + + // Heap test object simple test + Test *m = new Test("Heap"); + m->hello(); + + if (m->check_init() == false) + { + result = false; + } + delete m; + break; + } + + GREENTEA_TESTSUITE_RESULT(result); +} diff --git a/TESTS/mbedmicro-mbed/div/main.cpp b/TESTS/mbedmicro-mbed/div/main.cpp new file mode 100644 index 0000000000..6658d6db15 --- /dev/null +++ b/TESTS/mbedmicro-mbed/div/main.cpp @@ -0,0 +1,41 @@ +#include // std::pair +#include "mbed.h" +#include "greentea-client/test_env.h" + +uint32_t test_64(uint64_t ticks) { + ticks >>= 3; // divide by 8 + if (ticks > 0xFFFFFFFF) { + ticks /= 3; + } else { + ticks = (ticks * 0x55555556) >> 32; // divide by 3 + } + return (uint32_t)(0xFFFFFFFF & ticks); +} + +const char *result_str(bool result) { + return result ? "[OK]" : "[FAIL]"; +} + +int main() { + GREENTEA_SETUP(5, "default_auto"); + + bool result = true; + + { // 0xFFFFFFFF * 8 = 0x7fffffff8 + std::pair values = std::make_pair(0x55555555, 0x7FFFFFFF8); + uint32_t test_ret = test_64(values.second); + bool test_res = values.first == test_ret; + result = result && test_res; + printf("64bit: 0x7FFFFFFF8: expected 0x%lX got 0x%lX ... %s\r\n", values.first, test_ret, result_str(test_res)); + } + + { // 0xFFFFFFFF * 24 = 0x17ffffffe8 + std::pair values = std::make_pair(0xFFFFFFFF, 0x17FFFFFFE8); + uint32_t test_ret = test_64(values.second); + bool test_res = values.first == test_ret; + result = result && test_res; + printf("64bit: 0x17FFFFFFE8: expected 0x%lX got 0x%lX ... %s\r\n", values.first, test_ret, result_str(test_res)); + } + + GREENTEA_TESTSUITE_RESULT(result); +} diff --git a/TESTS/mbedmicro-mbed/heap_and_stack/main.cpp b/TESTS/mbedmicro-mbed/heap_and_stack/main.cpp new file mode 100644 index 0000000000..b27f7f1f90 --- /dev/null +++ b/TESTS/mbedmicro-mbed/heap_and_stack/main.cpp @@ -0,0 +1,80 @@ +#include +#include +#include "greentea-client/test_env.h" + +static char *initial_stack_p; +static char *initial_heap_p; + +static char line[256]; +static unsigned int iterations = 0; + +void report_iterations(void) { + unsigned int tot = (0x100 * iterations)*2; + printf("\nAllocated (%d)Kb in (%u) iterations\n", tot/1024, iterations); +#if !defined(TOOLCHAIN_GCC_CR) + // EA: This causes a crash when compiling with GCC_CR??? + printf("%.2f\n", ((float)(tot)/(float)(initial_stack_p - initial_heap_p))*100.); +#endif +#ifdef TOOLCHAIN_ARM +#ifndef __MICROLIB + __heapvalid((__heapprt) fprintf, stdout, 1); +#endif +#endif +} + +void stack_test(char *latest_heap_pointer) { + char stack_line[256]; + iterations++; + + sprintf(stack_line, "\nstack pointer: %p", &stack_line[255]); + puts(stack_line); + + char *heap_pointer = (char*)malloc(0x100); + + if (heap_pointer == NULL) { + int diff = (&stack_line[255] - latest_heap_pointer); + if (diff > 0x200) { + sprintf(stack_line, "\n[WARNING] Malloc failed to allocate memory too soon. There are (0x%x) free bytes", diff); + report_iterations(); + puts(stack_line); + } else { + puts("\n[SUCCESS] Stack/Heap collision detected"); + report_iterations(); + } + return; + } else { + heap_pointer += 0x100; + sprintf(line, "heap pointer: %p", heap_pointer); + puts(line); + } + + if ((&stack_line[255]) > heap_pointer) { + stack_test(heap_pointer); + } else { + puts("\n[WARNING] The Stack/Heap collision was not detected"); + report_iterations(); + } +} + + +int main (void) { + GREENTEA_SETUP(30, "default_auto"); + + char c; + initial_stack_p = &c; + + initial_heap_p = (char*)malloc(1); + if (initial_heap_p == NULL) { + printf("Unable to malloc a single byte\n"); + GREENTEA_TESTSUITE_RESULT(false); + } + + printf("Initial stack/heap geometry:\n"); + printf(" stack pointer:V %p\n", initial_stack_p); + printf(" heap pointer :^ %p\n", initial_heap_p); + + initial_heap_p++; + stack_test(initial_heap_p); + + GREENTEA_TESTSUITE_RESULT(true); +}