Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2017 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 #if !MBED_TICKLESS 00017 #error [NOT_SUPPORTED] Tickless mode not supported for this target. 00018 #endif 00019 00020 #if !DEVICE_LOWPOWERTIMER 00021 #error [NOT_SUPPORTED] Current SysTimer implementation requires lp ticker support. 00022 #endif 00023 00024 #include "mbed.h" 00025 #include "greentea-client/test_env.h" 00026 #include "unity.h" 00027 #include "utest.h" 00028 00029 extern "C" { 00030 #include "rtx_lib.h" 00031 } 00032 #include "rtos/TARGET_CORTEX/SysTimer.h" 00033 00034 #define TEST_TICKS 42UL 00035 #define DELAY_DELTA_US 2500ULL 00036 00037 using namespace utest::v1; 00038 00039 const us_timestamp_t DELAY_US = 1000000ULL * TEST_TICKS / OS_TICK_FREQ; 00040 00041 // Override the handler() -- the SysTick interrupt must not be set as pending by the test code. 00042 class SysTimerTest: public rtos::internal::SysTimer { 00043 private: 00044 Semaphore _sem; 00045 virtual void handler() 00046 { 00047 increment_tick(); 00048 _sem.release(); 00049 } 00050 00051 public: 00052 SysTimerTest() : 00053 SysTimer(), _sem(0, 1) 00054 { 00055 } 00056 00057 virtual ~SysTimerTest() 00058 { 00059 } 00060 00061 int32_t sem_wait(uint32_t millisec) 00062 { 00063 return _sem.wait(millisec); 00064 } 00065 }; 00066 00067 /** Test tick count is zero upon creation 00068 * 00069 * Given a SysTimer 00070 * When the timer is created 00071 * Then tick count is zero 00072 */ 00073 void test_created_with_zero_tick_count(void) 00074 { 00075 SysTimerTest st; 00076 TEST_ASSERT_EQUAL_UINT32(0, st.get_tick()); 00077 } 00078 00079 /** Test tick count is updated correctly 00080 * 00081 * Given a SysTimer 00082 * When @a update_tick method is called immediately after creation 00083 * Then the tick count is not updated 00084 * When @a update_tick is called again after a delay 00085 * Then the tick count is updated 00086 * and the number of ticks incremented is equal TEST_TICKS - 1 00087 * When @a update_tick is called again without a delay 00088 * Then the tick count is not updated 00089 */ 00090 void test_update_tick(void) 00091 { 00092 SysTimerTest st; 00093 TEST_ASSERT_EQUAL_UINT32(0, st.update_tick()); 00094 TEST_ASSERT_EQUAL_UINT32(0, st.get_tick()); 00095 us_timestamp_t test_ticks_elapsed_ts = st.get_time() + DELAY_US; 00096 00097 while (st.get_time() <= test_ticks_elapsed_ts) {} 00098 TEST_ASSERT_EQUAL_UINT32(TEST_TICKS - 1, st.update_tick()); 00099 TEST_ASSERT_EQUAL_UINT32(TEST_TICKS - 1, st.get_tick()); 00100 00101 TEST_ASSERT_EQUAL_UINT32(0, st.update_tick()); 00102 TEST_ASSERT_EQUAL_UINT32(TEST_TICKS - 1, st.get_tick()); 00103 } 00104 00105 /** Test get_time returns correct time 00106 * 00107 * Given a SysTimer 00108 * When @a get_time method is called before and after a delay 00109 * Then time difference is equal the delay 00110 */ 00111 void test_get_time(void) 00112 { 00113 SysTimerTest st; 00114 us_timestamp_t t1 = st.get_time(); 00115 00116 wait_us(DELAY_US); 00117 us_timestamp_t t2 = st.get_time(); 00118 TEST_ASSERT_UINT64_WITHIN(DELAY_DELTA_US, DELAY_US, t2 - t1); 00119 } 00120 00121 /** Test cancel_tick 00122 * 00123 * Given a SysTimer with a scheduled tick 00124 * When @a cancel_tick is called before the given number of ticks elapse 00125 * Then the handler is never called 00126 * and the tick count is not incremented 00127 */ 00128 void test_cancel_tick(void) 00129 { 00130 SysTimerTest st; 00131 st.cancel_tick(); 00132 st.schedule_tick(TEST_TICKS); 00133 00134 st.cancel_tick(); 00135 int32_t sem_slots = st.sem_wait((DELAY_US + DELAY_DELTA_US) / 1000ULL); 00136 TEST_ASSERT_EQUAL_INT32(0, sem_slots); 00137 TEST_ASSERT_EQUAL_UINT32(0, st.get_tick()); 00138 } 00139 00140 /** Test schedule zero 00141 * 00142 * Given a SysTimer 00143 * When a tick is scheduled with delta = 0 ticks 00144 * Then the handler is called instantly 00145 */ 00146 void test_schedule_zero(void) 00147 { 00148 SysTimerTest st; 00149 00150 st.schedule_tick(0UL); 00151 int32_t sem_slots = st.sem_wait(0UL); 00152 TEST_ASSERT_EQUAL_INT32(1, sem_slots); 00153 } 00154 00155 /** Test handler called once 00156 * 00157 * Given a SysTimer with a tick scheduled with delta = TEST_TICKS 00158 * When the handler is called 00159 * Then the tick count is incremented by 1 00160 * and elapsed time is equal 1000000ULL * TEST_TICKS / OS_TICK_FREQ; 00161 * When more time elapses 00162 * Then the handler is not called again 00163 */ 00164 void test_handler_called_once(void) 00165 { 00166 SysTimerTest st; 00167 st.schedule_tick(TEST_TICKS); 00168 us_timestamp_t t1 = st.get_time(); 00169 int32_t sem_slots = st.sem_wait(0); 00170 TEST_ASSERT_EQUAL_INT32(0, sem_slots); 00171 00172 sem_slots = st.sem_wait(osWaitForever); 00173 us_timestamp_t t2 = st.get_time(); 00174 TEST_ASSERT_EQUAL_INT32(1, sem_slots); 00175 TEST_ASSERT_EQUAL_UINT32(1, st.get_tick()); 00176 TEST_ASSERT_UINT64_WITHIN(DELAY_DELTA_US, DELAY_US, t2 - t1); 00177 00178 sem_slots = st.sem_wait((DELAY_US + DELAY_DELTA_US) / 1000ULL); 00179 TEST_ASSERT_EQUAL_INT32(0, sem_slots); 00180 TEST_ASSERT_EQUAL_UINT32(1, st.get_tick()); 00181 } 00182 00183 /** Test wake up from sleep 00184 * 00185 * Given a SysTimer with a tick scheduled in the future 00186 * and a core in sleep mode 00187 * When given time elapses 00188 * Then the uC is woken up from sleep 00189 * and the tick handler is called 00190 * and measured time matches requested delay 00191 */ 00192 void test_sleep(void) 00193 { 00194 Timer timer; 00195 SysTimerTest st; 00196 00197 sleep_manager_lock_deep_sleep(); 00198 timer.start(); 00199 st.schedule_tick(TEST_TICKS); 00200 00201 TEST_ASSERT_FALSE_MESSAGE(sleep_manager_can_deep_sleep(), "Deep sleep should be disallowed"); 00202 while (st.sem_wait(0) != 1) { 00203 sleep(); 00204 } 00205 timer.stop(); 00206 sleep_manager_unlock_deep_sleep(); 00207 00208 TEST_ASSERT_UINT64_WITHIN(DELAY_DELTA_US, DELAY_US, timer.read_high_resolution_us()); 00209 } 00210 00211 #if DEVICE_LOWPOWERTIMER 00212 /** Test wake up from deepsleep 00213 * 00214 * Given a SysTimer with a tick scheduled in the future 00215 * and a core in deepsleep mode 00216 * When given time elapses 00217 * Then the uC is woken up from deepsleep 00218 * and the tick handler is called 00219 * and measured time matches requested delay 00220 */ 00221 void test_deepsleep(void) 00222 { 00223 /* 00224 * Since deepsleep() may shut down the UART peripheral, we wait for 10ms 00225 * to allow for hardware serial buffers to completely flush. 00226 00227 * This should be replaced with a better function that checks if the 00228 * hardware buffers are empty. However, such an API does not exist now, 00229 * so we'll use the wait_ms() function for now. 00230 */ 00231 wait_ms(10); 00232 00233 // Regular Timer might be disabled during deepsleep. 00234 LowPowerTimer lptimer; 00235 SysTimerTest st; 00236 00237 lptimer.start(); 00238 st.schedule_tick(TEST_TICKS); 00239 TEST_ASSERT_TRUE_MESSAGE(sleep_manager_can_deep_sleep(), "Deep sleep should be allowed"); 00240 while (st.sem_wait(0) != 1) { 00241 sleep(); 00242 } 00243 lptimer.stop(); 00244 00245 TEST_ASSERT_UINT64_WITHIN(DELAY_DELTA_US, DELAY_US, lptimer.read_high_resolution_us()); 00246 } 00247 #endif 00248 00249 utest::v1::status_t test_setup(const size_t number_of_cases) 00250 { 00251 GREENTEA_SETUP(5, "default_auto"); 00252 return verbose_test_setup_handler(number_of_cases); 00253 } 00254 00255 Case cases[] = { 00256 Case("Tick count is zero upon creation", test_created_with_zero_tick_count), 00257 Case("Tick count is updated correctly", test_update_tick), 00258 Case("Time is updated correctly", test_get_time), 00259 Case("Tick can be cancelled", test_cancel_tick), 00260 Case("Schedule zero ticks", test_schedule_zero), 00261 Case("Handler called once", test_handler_called_once), 00262 Case("Wake up from sleep", test_sleep), 00263 #if DEVICE_LOWPOWERTIMER 00264 Case("Wake up from deep sleep", test_deepsleep), 00265 #endif 00266 00267 }; 00268 00269 Specification specification(test_setup, cases); 00270 00271 int main() 00272 { 00273 return !Harness::run(specification); 00274 }
Generated on Tue Jul 12 2022 15:17:31 by
1.7.2