Rtos API example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2016 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #if !DEVICE_LOWPOWERTIMER
00018     #error [NOT_SUPPORTED] Low power timer not supported for this target
00019 #endif
00020 
00021 #include "utest/utest.h"
00022 #include "unity/unity.h"
00023 #include "greentea-client/test_env.h"
00024 
00025 #include "mbed.h"
00026 
00027 using namespace utest::v1;
00028 
00029 volatile static bool complete;
00030 static LowPowerTimeout lpt;
00031 
00032 /* Timeouts are quite arbitrary due to large number of boards with varying level of accuracy */
00033 #define LONG_TIMEOUT (100000)
00034 #define SHORT_TIMEOUT (600)
00035 
00036 void cb_done() {
00037     complete = true;
00038 }
00039 
00040 #if DEVICE_SLEEP
00041 void lp_timeout_1s_deepsleep(void)
00042 {
00043     complete = false;
00044     LowPowerTimer timer;
00045 
00046     /*
00047      * Since deepsleep() may shut down the UART peripheral, we wait for 10ms
00048      * to allow for hardware serial buffers to completely flush.
00049 
00050      * This should be replaced with a better function that checks if the
00051      * hardware buffers are empty. However, such an API does not exist now,
00052      * so we'll use the wait_ms() function for now.
00053      */
00054     wait_ms(10);
00055 
00056     /*
00057      * We use here the low power timer instead of microsecond timer for start and
00058      * end because the microseconds timer might be disable during deepsleep.
00059      */
00060     timer.start();
00061     lpt.attach(&cb_done, 1);
00062     /* Make sure deepsleep is allowed, to go to deepsleep */
00063     bool deep_sleep_allowed = sleep_manager_can_deep_sleep();
00064     TEST_ASSERT_TRUE_MESSAGE(deep_sleep_allowed, "Deep sleep should be allowed");
00065     sleep();
00066     while (!complete);
00067 
00068     /* It takes longer to wake up from deep sleep */
00069     TEST_ASSERT_UINT32_WITHIN(LONG_TIMEOUT, 1000000, timer.read_us());
00070     TEST_ASSERT_TRUE(complete);
00071 }
00072 
00073 void lp_timeout_1s_sleep(void)
00074 {
00075     complete = false;
00076     Timer timer;
00077     timer.start();
00078 
00079     sleep_manager_lock_deep_sleep();
00080     lpt.attach(&cb_done, 1);
00081     bool deep_sleep_allowed = sleep_manager_can_deep_sleep();
00082     TEST_ASSERT_FALSE_MESSAGE(deep_sleep_allowed, "Deep sleep should be disallowed");
00083     sleep();
00084     while (!complete);
00085     sleep_manager_unlock_deep_sleep();
00086 
00087     TEST_ASSERT_UINT32_WITHIN(LONG_TIMEOUT, 1000000, timer.read_us());
00088     TEST_ASSERT_TRUE(complete);
00089 }
00090 #endif /* DEVICE_SLEEP */
00091 
00092 void lp_timeout_us(uint32_t delay_us, uint32_t tolerance)
00093 {
00094     complete = false;
00095     Timer timer;
00096     timer.start();
00097 
00098     lpt.attach_us(&cb_done, delay_us);
00099     while (!complete);
00100 
00101     /* Using RTC which is less accurate */
00102     TEST_ASSERT_UINT32_WITHIN(tolerance, delay_us, timer.read_us());
00103     TEST_ASSERT_TRUE(complete);
00104 }
00105 
00106 void lp_timeout_5s(void)
00107 {
00108     lp_timeout_us(5000000, LONG_TIMEOUT);
00109 }
00110 
00111 void lp_timeout_1s(void)
00112 {
00113     lp_timeout_us(1000000, LONG_TIMEOUT);
00114 }
00115 
00116 void lp_timeout_1ms(void)
00117 {
00118     lp_timeout_us(1000, SHORT_TIMEOUT);
00119 }
00120 
00121 void lp_timeout_500us(void)
00122 {
00123     lp_timeout_us(500, SHORT_TIMEOUT);
00124 
00125 }
00126 
00127 utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) {
00128     greentea_case_failure_abort_handler(source, reason);
00129     return STATUS_CONTINUE;
00130 }
00131 
00132 Case cases[] = {
00133     Case("500us LowPowerTimeout", lp_timeout_500us, greentea_failure_handler),
00134     Case("1ms LowPowerTimeout", lp_timeout_1ms, greentea_failure_handler),
00135     Case("1sec LowPowerTimeout", lp_timeout_1s, greentea_failure_handler),
00136     Case("5sec LowPowerTimeout", lp_timeout_5s, greentea_failure_handler),
00137 #if DEVICE_SLEEP
00138     Case("1sec LowPowerTimeout from sleep", lp_timeout_1s_sleep, greentea_failure_handler),
00139     Case("1sec LowPowerTimeout from deepsleep", lp_timeout_1s_deepsleep, greentea_failure_handler),
00140 #endif /* DEVICE_SLEEP */
00141 };
00142 
00143 utest::v1::status_t greentea_test_setup(const size_t number_of_cases) {
00144     GREENTEA_SETUP(20, "default_auto");
00145     return greentea_test_setup_handler(number_of_cases);
00146 }
00147 
00148 Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
00149 
00150 int main() {
00151     Harness::run(specification);
00152 }