Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
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 00017 #include "utest/utest.h" 00018 #include "unity/unity.h" 00019 #include "greentea-client/test_env.h" 00020 00021 #include "mbed.h" 00022 #include "mbed_mktime.h" 00023 00024 // Limit the test range to 1935 for IAR only. From the IAR C/C++ Development Guide: 00025 // "The 32-bit interface supports years from 1900 up to 2035 and uses a 32-bit integer 00026 // for time_t." 00027 #ifdef __ICCARM__ 00028 #define LOCALTIME_MAX 2082758400 // 1st of january 2036 at 00:00:00 00029 #define MKTIME_YR_MAX 136 00030 #else 00031 #define LOCALTIME_MAX INT_MAX 00032 #define MKTIME_YR_MAX 137 00033 #endif 00034 00035 using namespace utest::v1; 00036 00037 /* 00038 * regular is_leap_year, see platform/mbed_mktime.c for the optimized version 00039 */ 00040 bool is_leap_year(int year) { 00041 year = 1900 + year; 00042 if (year % 4) { 00043 return false; 00044 } else if (year % 100) { 00045 return true; 00046 } else if (year % 400) { 00047 return false; 00048 } 00049 return true; 00050 } 00051 00052 /* 00053 * Test the optimized version of _rtc_is_leap_year against the generic version. 00054 */ 00055 void test_is_leap_year() { 00056 for (int i = 70; i < 138; ++i) { 00057 bool expected = is_leap_year(i); 00058 bool actual_value = _rtc_is_leap_year(i); 00059 00060 if (expected != actual_value) { 00061 printf ("leap year failed with i = %d\r\n", i); 00062 } 00063 TEST_ASSERT_EQUAL(expected, actual_value); 00064 } 00065 } 00066 00067 struct tm make_time_info(int year, int month, int day, int hours, int minutes, int seconds) { 00068 struct tm timeinfo = { 00069 seconds, // tm_sec 00070 minutes, // tm_min 00071 hours, // tm_hour 00072 day, // tm_mday 00073 month, // tm_mon 00074 year, // tm_year 00075 0, // tm_wday 00076 0, // tm_yday 00077 0, // tm_isdst 00078 }; 00079 return timeinfo; 00080 } 00081 00082 /* 00083 * test out of range values for _rtc_mktime. 00084 * The function operates from the 1st of january 1970 at 00:00:00 to the 19th 00085 * of january 2038 at 03:14:07. 00086 */ 00087 void test_mk_time_out_of_range() { 00088 tm invalid_lower_bound = make_time_info( 00089 69, 00090 11, 00091 31, 00092 23, 00093 59, 00094 59 00095 ); 00096 00097 tm valid_lower_bound = make_time_info( 00098 70, 00099 0, 00100 1, 00101 0, 00102 0, 00103 0 00104 ); 00105 00106 tm valid_upper_bound = make_time_info( 00107 138, 00108 0, 00109 19, 00110 3, 00111 14, 00112 7 00113 ); 00114 00115 tm invalid_upper_bound = make_time_info( 00116 138, 00117 0, 00118 19, 00119 3, 00120 14, 00121 8 00122 ); 00123 00124 TEST_ASSERT_EQUAL_INT(((time_t) -1), _rtc_mktime(&invalid_lower_bound)); 00125 TEST_ASSERT_EQUAL_INT(((time_t) 0), _rtc_mktime(&valid_lower_bound)); 00126 TEST_ASSERT_EQUAL_INT(((time_t) INT_MAX), _rtc_mktime(&valid_upper_bound)); 00127 TEST_ASSERT_EQUAL_INT(((time_t) -1), _rtc_mktime(&invalid_upper_bound)); 00128 } 00129 00130 /* 00131 * test mktime over a large set of values 00132 */ 00133 void test_mk_time() { 00134 for (size_t year = 70; year < MKTIME_YR_MAX; ++year) { 00135 for (size_t month = 0; month < 12; ++month) { 00136 for (size_t day = 1; day < 32; ++day) { 00137 if (month == 1 && is_leap_year(year) && day == 29) { 00138 break; 00139 } else if(month == 1 && !is_leap_year(year) && day == 28) { 00140 break; 00141 } else if ( 00142 day == 31 && 00143 (month == 3 || month == 5 || month == 8 || month == 10) 00144 ) { 00145 break; 00146 } 00147 00148 for (size_t hour = 0; hour < 24; ++hour) { 00149 tm time_info = make_time_info( 00150 year, 00151 month, 00152 day, 00153 hour, 00154 hour % 2 ? 59 : 0, 00155 hour % 2 ? 59 : 0 00156 ); 00157 00158 time_t expected = mktime(&time_info); 00159 time_t actual_value = _rtc_mktime(&time_info); 00160 00161 char msg[128] = ""; 00162 if (expected != actual_value) { 00163 snprintf( 00164 msg, sizeof(msg), 00165 "year = %d, month = %d, day = %d, diff = %ld", 00166 year, month, day, expected - actual_value 00167 ); 00168 } 00169 00170 TEST_ASSERT_EQUAL_UINT32_MESSAGE(expected, actual_value, msg); 00171 } 00172 } 00173 } 00174 } 00175 } 00176 00177 /* 00178 * test value out of range for localtime 00179 */ 00180 void test_local_time_limit() { 00181 struct tm dummy_value; 00182 TEST_ASSERT_FALSE(_rtc_localtime((time_t) -1, &dummy_value)); 00183 TEST_ASSERT_FALSE(_rtc_localtime((time_t) INT_MIN, &dummy_value)); 00184 } 00185 00186 /* 00187 * test _rtc_localtime over a large set of values. 00188 */ 00189 void test_local_time() { 00190 for (uint32_t i = 0; i < LOCALTIME_MAX; i += 3451) { 00191 time_t copy = (time_t) i; 00192 struct tm* expected = localtime(©); 00193 struct tm actual_value; 00194 bool result = _rtc_localtime((time_t) i, &actual_value); 00195 00196 if ( 00197 expected->tm_sec != actual_value.tm_sec || 00198 expected->tm_min != actual_value.tm_min || 00199 expected->tm_hour != actual_value.tm_hour || 00200 expected->tm_mday != actual_value.tm_mday || 00201 expected->tm_mon != actual_value.tm_mon || 00202 expected->tm_year != actual_value.tm_year || 00203 expected->tm_wday != actual_value.tm_wday || 00204 expected->tm_yday != actual_value.tm_yday || 00205 result == false 00206 ) { 00207 printf("error: i = %lu\r\n", i); 00208 } 00209 00210 TEST_ASSERT_TRUE(result); 00211 TEST_ASSERT_EQUAL_UINT32_MESSAGE( 00212 expected->tm_sec, actual_value.tm_sec, "invalid seconds" 00213 ); 00214 TEST_ASSERT_EQUAL_UINT32_MESSAGE( 00215 expected->tm_min, actual_value.tm_min, "invalid minutes" 00216 ); 00217 TEST_ASSERT_EQUAL_UINT32_MESSAGE( 00218 expected->tm_hour, actual_value.tm_hour, "invalid hours" 00219 ); 00220 TEST_ASSERT_EQUAL_UINT32_MESSAGE( 00221 expected->tm_mday, actual_value.tm_mday, "invalid day" 00222 ); 00223 TEST_ASSERT_EQUAL_UINT32_MESSAGE( 00224 expected->tm_mon, actual_value.tm_mon, "invalid month" 00225 ); 00226 TEST_ASSERT_EQUAL_UINT32_MESSAGE( 00227 expected->tm_year, actual_value.tm_year, "invalid year" 00228 ); 00229 TEST_ASSERT_EQUAL_UINT32_MESSAGE( 00230 expected->tm_wday, actual_value.tm_wday, "invalid weekday" 00231 ); 00232 TEST_ASSERT_EQUAL_UINT32_MESSAGE( 00233 expected->tm_yday, actual_value.tm_yday, "invalid year day" 00234 ); 00235 } 00236 } 00237 00238 utest::v1::status_t greentea_failure_handler(const Case *const source, const failure_t reason) { 00239 greentea_case_failure_abort_handler(source, reason); 00240 return STATUS_CONTINUE; 00241 } 00242 00243 Case cases[] = { 00244 Case("test is leap year", test_is_leap_year, greentea_failure_handler), 00245 Case("test mk time out of range values", test_mk_time_out_of_range, greentea_failure_handler), 00246 Case("mk time", test_mk_time, greentea_failure_handler), 00247 Case("test local time", test_local_time, greentea_failure_handler), 00248 Case("test local time limits", test_local_time_limit, greentea_failure_handler), 00249 }; 00250 00251 utest::v1::status_t greentea_test_setup(const size_t number_of_cases) { 00252 GREENTEA_SETUP(1200, "default_auto"); 00253 return greentea_test_setup_handler(number_of_cases); 00254 } 00255 00256 Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler); 00257 00258 int main() { 00259 return Harness::run(specification); 00260 }
Generated on Sun Jul 17 2022 08:25:27 by 1.7.2