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.
Dependencies: FXAS21002 FXOS8700Q
pal_rtos_test.c
00001 /******************************************************************************* 00002 * Copyright 2016, 2017 ARM Ltd. 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 // Needed for PRIu64 on FreeRTOS 00018 #include <stdio.h> 00019 00020 #include "pal.h" 00021 #include "unity.h" 00022 #include "unity_fixture.h" 00023 #include "pal_rtos_test_utils.h" 00024 #include "sotp.h" 00025 #include "pal_plat_rtos.h" 00026 #include "test_runners.h" 00027 00028 #include <string.h> 00029 #include <stdlib.h> 00030 00031 #define TRACE_GROUP "PAL" 00032 00033 TEST_GROUP(pal_rtos); 00034 00035 //Sometimes you may want to get local data in a module, 00036 //for example if you need to pass a reference. 00037 //However, you should usually avoid this. 00038 //extern int Counter; 00039 threadsArgument_t g_threadsArg = {0}; 00040 00041 // Note: this struct is accessed from the test code thread and timer callbacks 00042 // without any synchronization, so beware. 00043 volatile timerArgument_t g_timerArgs = {0}; 00044 00045 palMutexID_t mutex1 = NULLPTR; 00046 palMutexID_t mutex2 = NULLPTR; 00047 palSemaphoreID_t semaphore1 = NULLPTR; 00048 palRecursiveMutexParam_t* recursiveMutexData = NULL; 00049 #define PAL_RUNNING_TEST_TIME 5 //estimation on length of test in seconds 00050 #define PAL_TEST_HIGH_RES_TIMER 100 00051 #define PAL_TEST_HIGH_RES_TIMER2 10 00052 #define PAL_TEST_PERCENTAGE_TIMER_ERROR 10 00053 #define PAL_TEST_PERCENTAGE_HUNDRED 100 00054 #define PAL_TEST_TIME_SECOND 1000 00055 00056 #define PAL_DELAY_RUN_LOOPS 10 00057 00058 //Forward declarations 00059 void palRunThreads(void); 00060 00061 00062 TEST_SETUP(pal_rtos) 00063 { 00064 palStatus_t status = PAL_SUCCESS; 00065 status = pal_init(); 00066 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00067 00068 } 00069 00070 TEST_TEAR_DOWN(pal_rtos) 00071 { 00072 if (NULL != recursiveMutexData) 00073 { 00074 if (recursiveMutexData->higherPriorityThread != NULLPTR) 00075 { 00076 pal_osThreadTerminate(&(recursiveMutexData->higherPriorityThread)); 00077 } 00078 if (recursiveMutexData->lowerPriorityThread != NULLPTR) 00079 { 00080 pal_osThreadTerminate(&(recursiveMutexData->lowerPriorityThread)); 00081 } 00082 if (recursiveMutexData->mtx != NULLPTR) 00083 { 00084 pal_osMutexDelete(&(recursiveMutexData->mtx)); 00085 } 00086 if (recursiveMutexData->sem != NULLPTR) 00087 { 00088 pal_osSemaphoreDelete(&recursiveMutexData->sem); 00089 } 00090 free(recursiveMutexData); 00091 recursiveMutexData = NULL; 00092 } 00093 pal_destroy(); 00094 } 00095 00096 #define TEST_OUTPUT_32_1 "u32 1: 123456789" 00097 #define TEST_OUTPUT_32_2 "s32 2: -123456789" 00098 00099 #define TEST_OUTPUT_INT_1 "int 1: 12345" 00100 00101 #define TEST_OUTPUT_64_1 "u64 1: 123456789" 00102 #define TEST_OUTPUT_64_2 "u64 2: 18446744073709551615" 00103 #define TEST_OUTPUT_64_3 "s64 1: -123456789" 00104 #define TEST_OUTPUT_64_4 "s64 2: -9223372036854775801" 00105 00106 /*! \brief Sanity check of the snprintf() from the libc/system 00107 * Fails if the snprintf() does not support 64b formatter (%lld or %llu) 00108 * 00109 * | # | Step | Expected | 00110 * |---|---------------------------------------|-------------| 00111 * | 1| snprintf("%PRIu32) | success | 00112 * | 2| snprintf("%PRId32) | success | 00113 * | 3| snprintf("%d) | success | 00114 * | 4| snprintf("%llu) (32b value) | success | 00115 * | 5| snprintf("%llu) (64b value) | success | 00116 * | 6| snprintf("%PRIu64) (32b value) | success | 00117 * | 7| snprintf("%PRIu64) (64b value) | success | 00118 * | 8| snprintf("%lld) (32b value) | success | 00119 * | 9| snprintf("%lld) (64b value) | success | 00120 * | 10| snprintf("%PRId64) (32b value) | success | 00121 * | 11| snprintf("%PRId64) (64b value) | success | 00122 */ 00123 00124 TEST(pal_rtos, BasicSnprintfTestInt) 00125 { 00126 char output[64]; 00127 00128 int result; 00129 00130 uint32_t test32u; 00131 int32_t test32s; 00132 00133 uint64_t test64u; 00134 int64_t test64s; 00135 00136 // first test with 32b variables 00137 /*#1*/ 00138 test32u = 123456789; 00139 result = snprintf(output, sizeof(output), "u32 1: %" PRIu32, test32u); 00140 TEST_ASSERT_EQUAL(strlen(TEST_OUTPUT_32_1), result); 00141 TEST_ASSERT_EQUAL_STRING(TEST_OUTPUT_32_1, output); 00142 00143 /*#2*/ 00144 test32s = 0 - 123456789; 00145 result = snprintf(output, sizeof(output), "s32 2: %" PRId32, test32s); 00146 TEST_ASSERT_EQUAL(strlen(TEST_OUTPUT_32_2), result); 00147 TEST_ASSERT_EQUAL_STRING(TEST_OUTPUT_32_2, output); 00148 00149 /*#3*/ 00150 // Note: this assumes just that int is at least 16 bits, which should be somewhat safe 00151 int testInt = 12345; 00152 result = snprintf(output, sizeof(output), "int 1: %d", testInt); 00153 TEST_ASSERT_EQUAL(strlen(TEST_OUTPUT_INT_1), result); 00154 TEST_ASSERT_EQUAL_STRING(TEST_OUTPUT_INT_1, output); 00155 00156 /*#4*/ 00157 // Then with 64b variables, hard coded, non standard %llu and %lld. 00158 // This part is a bit questionable, should it be ran or actually the code 00159 // which uses the %llu and expects it to have 64b fixed?! 00160 test64u = UINT64_C(123456789); 00161 result = snprintf(output, sizeof(output), "u64 1: %llu", (long long unsigned)test64u); 00162 TEST_ASSERT_EQUAL(strlen(TEST_OUTPUT_64_1), result); 00163 TEST_ASSERT_EQUAL_STRING(TEST_OUTPUT_64_1, output); 00164 00165 /*#5*/ 00166 test64u = UINT64_C(18446744073709551615); 00167 result = snprintf(output, sizeof(output), "u64 2: %llu", (long long unsigned)test64u); 00168 TEST_ASSERT_EQUAL(strlen(TEST_OUTPUT_64_2), result); 00169 TEST_ASSERT_EQUAL_STRING(TEST_OUTPUT_64_2, output); 00170 00171 /*#6*/ 00172 // the standard PRIu64 should work everywhere 00173 test64u = UINT64_C(123456789); 00174 result = snprintf(output, sizeof(output), "u64 1: %" PRIu64, test64u); 00175 TEST_ASSERT_EQUAL(strlen(TEST_OUTPUT_64_1), result); 00176 TEST_ASSERT_EQUAL_STRING(TEST_OUTPUT_64_1, output); 00177 00178 /*#7*/ 00179 test64u = UINT64_C(18446744073709551615); 00180 result = snprintf(output, sizeof(output), "u64 2: %" PRIu64, test64u); 00181 TEST_ASSERT_EQUAL(strlen(TEST_OUTPUT_64_2), result); 00182 TEST_ASSERT_EQUAL_STRING(TEST_OUTPUT_64_2, output); 00183 00184 /*#8*/ 00185 // Then with 64b signed variables, hard coded, non standard %lld 00186 // Again, this part is a bit questionable, should it be ran or actually the code 00187 // which uses the %lld and expects it to have 64b fixed?! 00188 test64s = INT64_C(-123456789); 00189 result = snprintf(output, sizeof(output), "s64 1: %lld", (long long)test64s); 00190 TEST_ASSERT_EQUAL(strlen(TEST_OUTPUT_64_3), result); 00191 TEST_ASSERT_EQUAL_STRING(TEST_OUTPUT_64_3, output); 00192 00193 /*#9*/ 00194 // a value of INT64_MIN might also be used, but setting that portably would need use of INT64_C() 00195 test64s = INT64_C(-9223372036854775801); 00196 result = snprintf(output, sizeof(output), "s64 2: %lld", (long long)test64s); 00197 TEST_ASSERT_EQUAL(strlen(TEST_OUTPUT_64_4), result); 00198 TEST_ASSERT_EQUAL_STRING(TEST_OUTPUT_64_4, output); 00199 00200 /*#10*/ 00201 // the standard PRId64 should work everywhere 00202 test64s = INT64_C(-123456789); 00203 result = snprintf(output, sizeof(output), "s64 1: %" PRId64, test64s); 00204 TEST_ASSERT_EQUAL(strlen(TEST_OUTPUT_64_3), result); 00205 TEST_ASSERT_EQUAL_STRING(TEST_OUTPUT_64_3, output); 00206 00207 /*#11*/ 00208 test64s = INT64_C(-9223372036854775801); 00209 result = snprintf(output, sizeof(output), "s64 2: %" PRId64, test64s); 00210 TEST_ASSERT_EQUAL(strlen(TEST_OUTPUT_64_4), result); 00211 TEST_ASSERT_EQUAL_STRING(TEST_OUTPUT_64_4, output); 00212 } 00213 00214 #define TEST_OUTPUT_SIZE_1 "size_t 1: 123456789" 00215 #define TEST_OUTPUT_SIZE_2 "size_t 2: -123456789" 00216 00217 /*! \brief Sanity check of the snprintf() from the libc/system 00218 * Fails if the snprintf() does not support size_t/ssize_t formatter (%zu or %zd) 00219 * 00220 * | # | Step | Expected | 00221 * |---|---------------------------------------|-------------| 00222 * | 1 | snprintf("%zu) (size_t/32b value) | success | 00223 * | 2 | snprintf("%zd) (size_t/32b value) | success | 00224 */ 00225 TEST(pal_rtos, BasicSnprintfTestSize) 00226 { 00227 // The %zu and %zd are not supported by newlib nano used in Mbed OS and FreeRTOS, 00228 // so these tests need to be left out. 00229 // Note: __GNUC__ is also defined by ARMCC in "--gnu" mode, so it can not be used directly. 00230 #if (!(defined(TARGET_LIKE_MBED) && defined(TOOLCHAIN_GCC)) && !(defined(__FREERTOS__) && !defined(__CC_ARM))) 00231 char output[64]; 00232 00233 int result; 00234 00235 size_t testU; 00236 00237 // Note: if the environment has 64b size_t, the code should have bigger 00238 // constant in use 00239 00240 testU = 123456789; 00241 00242 // Note: the newlib nano fails on these: 00243 00244 /*#1*/ 00245 result = snprintf(output, sizeof(output), "size_t 1: %zu", testU); 00246 TEST_ASSERT_EQUAL(strlen(TEST_OUTPUT_SIZE_1), result); 00247 TEST_ASSERT_EQUAL_STRING(TEST_OUTPUT_SIZE_1, output); 00248 00249 // Note: the ssize_t is not that universally available or used as size_t so 00250 // this test is in comments. 00251 /*#2*/ 00252 #if 0 00253 ssize_t testS; 00254 testS = 0 - 123456789; 00255 00256 result = snprintf(output, sizeof(output), "size_t 2: %zd", testS); 00257 TEST_ASSERT_EQUAL(strlen(TEST_OUTPUT_SIZE_2), result); 00258 TEST_ASSERT_EQUAL_STRING(TEST_OUTPUT_SIZE_2, output); 00259 #endif 00260 #else 00261 TEST_IGNORE_MESSAGE("Ignored, zu and zd not supported"); 00262 #endif 00263 } 00264 00265 /*! \brief Sanity check of the kernel system tick API. 00266 * Fails if system tic value is zero (**note:** this can sometimes happen on wrap-around). 00267 * 00268 * | # | Step | Expected | 00269 * |---|--------------------------------|-------------| 00270 * | 1 | Get current tick count using `pal_osKernelSysTick` and check that it is not 0. | PAL_SUCCESS | 00271 */ 00272 TEST(pal_rtos, pal_osKernelSysTick_Unity) 00273 { 00274 uint32_t tick1 = 0, tick2 = 0; 00275 /*#1*/ 00276 tick1 = pal_osKernelSysTick(); 00277 PAL_PRINTF("%" PRIu32 " %" PRIu32 "\n", tick1, tick2); 00278 00279 TEST_ASSERT_TRUE(tick2 != tick1); 00280 } 00281 00282 /*! \brief Sanity check of the kernel system tick API. 00283 * Fails if two calls return the same `sysTick` value. 00284 * 00285 * | # | Step | Expected | 00286 * |---|--------------------------------|-------------| 00287 * | 1 | Get current tick count using `pal_osKernelSysTick`. | PAL_SUCCESS | 00288 * | 2 | Get current tick count using `pal_osKernelSysTick`. | PAL_SUCCESS | 00289 * | 3 | Check that the two tick count values are not the same. | PAL_SUCCESS | 00290 */ 00291 TEST(pal_rtos, pal_osKernelSysTick64_Unity) 00292 { 00293 uint64_t tick1 = 0, tick2 = 0; 00294 /*#1*/ 00295 tick1 = pal_osKernelSysTick(); 00296 /*#2*/ 00297 tick2 = pal_osKernelSysTick(); 00298 /*#3*/ 00299 TEST_ASSERT_TRUE(tick2 >= tick1); 00300 } 00301 00302 /*! \brief Check the conversion from a non-zero `sysTick` value to microseconds. 00303 * Verify that the result is not 0. 00304 * 00305 * | # | Step | Expected | 00306 * |---|--------------------------------|-------------| 00307 * | 1 | Convert a nubmer in `sysTicks` to microseconds using `pal_osKernelSysTickMicroSec` and check it is not 0. | PAL_SUCCESS | 00308 */ 00309 TEST(pal_rtos, pal_osKernelSysTickMicroSec_Unity) 00310 { 00311 uint64_t tick = 0; 00312 uint64_t microSec = 2000 * 1000; 00313 /*#1*/ 00314 tick = pal_osKernelSysTickMicroSec(microSec); 00315 TEST_ASSERT_TRUE(0 != tick); 00316 } 00317 00318 /*! \brief Sanity check of non-zero values conversion between microseconds to ticks to milliseconds. 00319 * Verify that the result is correct when converting the input (microseconds) to the test output (milliseconds). 00320 * 00321 * | # | Step | Expected | 00322 * |---|--------------------------------|-------------| 00323 * | 1 | Convert a nubmer in `sysTicks` to mircorseconds using `pal_osKernelSysTickMicroSec` and check it is not 0. | PAL_SUCCESS | 00324 * | 2 | Convert a nubmer in `sysTicks` to milliseconds using `pal_osKernelSysMilliSecTick` and check the returned value. | PAL_SUCCESS | 00325 */ 00326 TEST(pal_rtos, pal_osKernelSysMilliSecTick_Unity) 00327 { 00328 uint64_t tick = 0; 00329 uint64_t microSec = 200 * 1000; 00330 uint64_t milliseconds = 0; 00331 /*#1*/ 00332 tick = pal_osKernelSysTickMicroSec(microSec); 00333 TEST_ASSERT_TRUE(0 != tick); 00334 /*#2*/ 00335 milliseconds = pal_osKernelSysMilliSecTick(tick); 00336 00337 // Calculation in PAL might be done using integer values and therefore 00338 // the result can be off by 1 millisecond due to rounding 00339 TEST_ASSERT_INT_WITHIN(1, microSec/1000, milliseconds); 00340 } 00341 00342 /*! \brief Verify that the tick frequency function returns a non-zero value. 00343 * 00344 * | # | Step | Expected | 00345 * |---|--------------------------------|-------------| 00346 * | 1 | Get the kernel `sysTick` frequency and check that it is positive. | PAL_SUCCESS | 00347 */ 00348 TEST(pal_rtos, pal_osKernelSysTickFrequency_Unity) 00349 { 00350 uint64_t frequency = 0; 00351 /*#1*/ 00352 frequency = pal_osKernelSysTickFrequency(); 00353 00354 TEST_ASSERT_TRUE(frequency > 0); 00355 } 00356 00357 /*! \brief Sanity check for the Delay API, verifying that `sysTick` increments after delay. 00358 * The test reads two system tick values. Between the two calls, it calls the delay function and 00359 * verifies that the tick values are different. 00360 * 00361 * | # | Step | Expected | 00362 * |---|--------------------------------|-------------| 00363 * | 1 | Get the kernel `sysTick` value. | PAL_SUCCESS | 00364 * | 2 | Sleep for a short period . | PAL_SUCCESS | 00365 * | 3 | Get the kernel `sysTick` value. | PAL_SUCCESS | 00366 * | 4 | Check that second tick value is greater than the first. | PAL_SUCCESS | 00367 */ 00368 TEST(pal_rtos, pal_osDelay_Unity) 00369 { 00370 palStatus_t status = PAL_SUCCESS; 00371 uint32_t tick1 , tick2; 00372 /*#1*/ 00373 tick1 = pal_osKernelSysTick(); 00374 /*#2*/ 00375 status = pal_osDelay(200); 00376 /*#3*/ 00377 tick2 = pal_osKernelSysTick(); 00378 /*#4*/ 00379 TEST_ASSERT_TRUE(tick2 > tick1); 00380 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00381 } 00382 00383 /*! \brief Test for basic timing scenarios based on calls for the ticks and delay 00384 * functionality while verifying that results meet the defined deltas. 00385 * 00386 * | # | Step | Expected | 00387 * |---|--------------------------------|-------------| 00388 * | 1 | Get the kernel `sysTick` value. | PAL_SUCCESS | 00389 * | 2 | Sleep for a very short period. | PAL_SUCCESS | 00390 * | 3 | Get the kernel `sysTick` value. | PAL_SUCCESS | 00391 * | 4 | Check that second tick value is greater than the first. | PAL_SUCCESS | 00392 * | 5 | Get the kernel `sysTick` value. | PAL_SUCCESS | 00393 * | 6 | Sleep for a longer period. | PAL_SUCCESS | 00394 * | 7 | Get the kernel `sysTick` value. | PAL_SUCCESS | 00395 * | 8 | Check that second tick value is greated than the first. | PAL_SUCCESS | 00396 * | 9 | Calculate the difference between the ticks. | PAL_SUCCESS | 00397 * | 10 | Convert last sleep period to ticks. | PAL_SUCCESS | 00398 * | 11 | Check that the tick period is correct (same as sleep period +/-delta). | PAL_SUCCESS | 00399 */ 00400 TEST(pal_rtos, BasicTimeScenario) 00401 { 00402 palStatus_t status = PAL_SUCCESS; 00403 uint64_t tick, tick1 , tick2 , tickDiff, tickDelta; 00404 00405 /*#1*/ 00406 tick1 = pal_osKernelSysTick(); 00407 /*#2*/ 00408 status = pal_osDelay(1); 00409 /*#3*/ 00410 tick2 = pal_osKernelSysTick(); 00411 00412 /*#4*/ 00413 TEST_ASSERT_TRUE(tick1 != tick2); 00414 TEST_ASSERT_TRUE(tick2 > tick1); // To check that the tick counts are incremental - be aware of wrap-arounds 00415 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00416 /****************************************/ 00417 /*#5*/ 00418 tick1 = pal_osKernelSysTick(); 00419 /*#6*/ 00420 status = pal_osDelay(2000); 00421 /*#7*/ 00422 tick2 = pal_osKernelSysTick(); 00423 00424 /*#8*/ 00425 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00426 TEST_ASSERT_TRUE(tick1 != tick2); 00427 TEST_ASSERT_TRUE(tick2 > tick1); 00428 00429 /*#9*/ 00430 tickDiff = tick2 - tick1; 00431 /*#10*/ 00432 tick = pal_osKernelSysTickMicroSec(2000 * 1000); 00433 // 10 milliseconds delta 00434 /*#11*/ 00435 tickDelta = pal_osKernelSysTickMicroSec(10 * 1000); 00436 TEST_ASSERT_TRUE((tick - tickDelta < tickDiff) && (tickDiff < tick + tickDelta)); 00437 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00438 } 00439 00440 00441 /*! \brief Test for basic long timing scenarios based on calls for the ticks and delay 00442 * functionality while verifying that results meet the defined deltas. In practice this 00443 * may be one of the first tests to run to get some baseline for timer accuracy measurements. 00444 * 00445 * | # | Step | Expected | 00446 * |---|-------------------------------------------------------------------------|-------------| 00447 * | 1 | Get the kernel `sysTick` value. | PAL_SUCCESS | 00448 * | 2 | Get the kernel `millisecond` value. | PAL_SUCCESS | 00449 * | 3 | start loop 00450 * | 4 | Get the kernel `sysTick` value. | PAL_SUCCESS | 00451 * | 5 | Get the kernel `millisecond` value. | PAL_SUCCESS | 00452 * | 6 | Delay for one second. | PAL_SUCCESS | 00453 * | 7 | Get the kernel `sysTick` value. | PAL_SUCCESS | 00454 * | 8 | Get the kernel `millisecond` value. | PAL_SUCCESS | 00455 * | 9 | Verify that `sysTick` diff for one second value is within error margin. | PAL_SUCCESS | 00456 * |10 | Verify that `ms` diff for one second value is within error margin. | PAL_SUCCESS | 00457 * |11 | Continue loop 00458 * |12 | Get the kernel `sysTick` value. | PAL_SUCCESS | 00459 * |13 | Get the kernel `millisecond` value. | PAL_SUCCESS | 00460 * |14 | Verify that `sysTick` diff for loop duration is within error margin. | PAL_SUCCESS | 00461 * |15 | Verify that `ms` diff for loop duration is within error margin. | PAL_SUCCESS | 00462 */ 00463 TEST(pal_rtos, BasicDelayTime) 00464 { 00465 palStatus_t status = PAL_SUCCESS; 00466 00467 uint64_t tickTestStart; 00468 uint64_t tickTestEnd; 00469 uint64_t msTestStart; 00470 uint64_t msTestEnd; 00471 00472 uint64_t tickInLoopStart; 00473 uint64_t tickInLoopEnd; 00474 00475 uint64_t msInLoopStart; 00476 uint64_t msInLoopEnd; 00477 00478 uint64_t tickDiff; 00479 uint64_t msDiff; 00480 00481 const uint64_t ticksPerSecond = pal_osKernelSysTickFrequency(); 00482 00483 // Delay time can legally drift one 16th of a fraction (~6,25%) into one direction or another 00484 const uint64_t tickLoopDiffAllowed = ticksPerSecond / 32; 00485 const uint64_t msLoopDiffAllowed = 1000 / 32; 00486 00487 const uint64_t tickTestDiffAllowed = (ticksPerSecond * PAL_DELAY_RUN_LOOPS) / 16; 00488 const uint64_t msTestDiffAllowed = (1000 * PAL_DELAY_RUN_LOOPS) / 16; 00489 00490 /*#1*/ 00491 tickTestStart = pal_osKernelSysTick(); 00492 00493 /*#2*/ 00494 msTestStart = pal_osKernelSysMilliSecTick(tickTestStart); 00495 00496 /*#3*/ 00497 00498 // Loop N times, one second per loop. Verify, that the timer values 00499 // are somewhere in the correct ballpark and the more complex timer 00500 // checks have hope to pass. Note: the times are evaluated in ticks 00501 // and also converted to milliseconds to help in debugging (and to 00502 // verify that the conversion actually works). 00503 for (int i=1; i <= PAL_DELAY_RUN_LOOPS; i++) { 00504 00505 /*#4*/ 00506 tickInLoopStart = pal_osKernelSysTick(); 00507 00508 /*#5*/ 00509 msInLoopStart = pal_osKernelSysMilliSecTick(tickInLoopStart); 00510 00511 /*#6*/ 00512 status = pal_osDelay(1000); 00513 00514 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00515 00516 /*#7*/ 00517 tickInLoopEnd = pal_osKernelSysTick(); 00518 00519 /*#8*/ 00520 msInLoopEnd = pal_osKernelSysMilliSecTick(tickInLoopEnd); 00521 00522 tickDiff = tickInLoopEnd - tickInLoopStart; 00523 msDiff = msInLoopEnd - msInLoopStart; 00524 00525 // XXX: This code is in comments to help in debugging the case when this 00526 // test fails on new platform 00527 /* 00528 tr_info("tickDiff : %llu", tickDiff); 00529 tr_info("msDiff : %llu", msDiff); 00530 00531 tr_info("tickInLoopStart: %llu", tickInLoopStart); 00532 tr_info("tickInLoopEnd : %llu", tickInLoopEnd); 00533 00534 tr_info("msInLoopStart : %llu", msInLoopStart); 00535 tr_info("msInLoopEnd : %llu", msInLoopEnd); 00536 */ 00537 00538 /*#9*/ 00539 TEST_ASSERT_UINT64_WITHIN(tickLoopDiffAllowed, ticksPerSecond, tickDiff); 00540 00541 /*#10*/ 00542 TEST_ASSERT_UINT64_WITHIN(msLoopDiffAllowed, 1000, msDiff); 00543 00544 /*#11*/ 00545 } 00546 00547 /*#12*/ 00548 tickTestEnd = pal_osKernelSysTick(); 00549 00550 /*#13*/ 00551 msTestEnd = pal_osKernelSysMilliSecTick(tickTestEnd); 00552 00553 tickDiff = tickTestEnd - tickTestStart; 00554 msDiff = msTestEnd - msTestStart; 00555 00556 /* 00557 tr_info("tickTestStart : %llu", tickTestStart); 00558 tr_info("msTestStart : %llu", msTestStart); 00559 tr_info("tickTestEnd : %llu", tickTestEnd); 00560 tr_info("msTestEnd : %llu", msTestEnd); 00561 */ 00562 00563 /*#14*/ 00564 TEST_ASSERT_UINT64_WITHIN(tickTestDiffAllowed, (ticksPerSecond*PAL_DELAY_RUN_LOOPS), tickDiff); 00565 00566 /*#15*/ 00567 TEST_ASSERT_UINT64_WITHIN(msTestDiffAllowed, (1000*PAL_DELAY_RUN_LOOPS), msDiff); 00568 } 00569 00570 /*! \brief Test single-shot timer accuracy against system clock. 00571 * 00572 * | # | Step | Expected | 00573 * |---|--------------------------------------------------------------------------------------------------|--------------------------------| 00574 * | 1 | Create a one-shot timer, which calls `palTimerFunc1` when triggered, using `pal_osTimerCreate`. | PAL_SUCCESS | 00575 * | 2 | Get the kernel `sysTick` value. | PAL_SUCCESS | 00576 * | 3 | Start the timer using `pal_osTimerStart`. | PAL_SUCCESS | 00577 * | 4 | Sleep for a period. | PAL_SUCCESS | 00578 * | 5 | Check that timer is in 10% limits. | PAL_SUCCESS | 00579 * | 6 | Delete the timer. | PAL_SUCCESS | 00580 */ 00581 TEST(pal_rtos, OneShotTimerAccuracyUnityTest) 00582 { 00583 palStatus_t status = PAL_SUCCESS; 00584 palTimerID_t timerID1 = NULLPTR; 00585 00586 g_timerArgs.ticksInFunc1 = 0; 00587 g_timerArgs.ticksBeforeTimer = 0; 00588 00589 /*#1*/ 00590 status = pal_osTimerCreate(palTimerFunc1, NULL, palOsTimerOnce , &timerID1); 00591 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00592 /*#2*/ 00593 g_timerArgs.ticksBeforeTimer = pal_osKernelSysTick(); 00594 /*#3*/ 00595 status = pal_osTimerStart(timerID1, PAL_TEST_TIME_SECOND); 00596 PAL_PRINTF("ticks before Timer: 0 - %" PRIu32 "\n", g_timerArgs.ticksBeforeTimer); 00597 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00598 /*#4*/ 00599 status = pal_osDelay(1500); 00600 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00601 /*#5*/ 00602 // check that timer is in 90..110% accuracy. 00603 TEST_ASSERT_UINT32_WITHIN((PAL_TEST_TIME_SECOND/PAL_TEST_PERCENTAGE_HUNDRED) * PAL_TEST_PERCENTAGE_TIMER_ERROR, PAL_TEST_TIME_SECOND, (pal_osKernelSysMilliSecTick(g_timerArgs.ticksInFunc1) - pal_osKernelSysMilliSecTick(g_timerArgs.ticksBeforeTimer))); 00604 /*#6*/ 00605 status = pal_osTimerDelete(&timerID1); 00606 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00607 TEST_ASSERT_EQUAL(NULLPTR, timerID1); 00608 } 00609 00610 /*! \brief Test periodic timer accuracy against system clock. 00611 * 00612 * | # | Step | Expected | 00613 * |---|--------------------------------------------------------------------------------------------------|--------------------------------| 00614 * | 1 | Create a periodic timer, which calls `palTimerFunc7` when triggered, using `pal_osTimerCreate`. | PAL_SUCCESS | 00615 * | 2 | Get the kernel `sysTick` value. | PAL_SUCCESS | 00616 * | 3 | Start the timer using `pal_osTimerStart`. | PAL_SUCCESS | 00617 * | 4 | Sleep for a period. | PAL_SUCCESS | 00618 * | 5 | Check callback counter and that timer is in 10% limits. | PAL_SUCCESS | 00619 * | 6 | Delete the timer . | PAL_SUCCESS | 00620 */ 00621 00622 TEST(pal_rtos, PeriodicTimerAccuracyUnityTest) 00623 { 00624 palStatus_t status = PAL_SUCCESS; 00625 palTimerID_t timerID1 = NULLPTR; 00626 00627 g_timerArgs.ticksInFunc1 = 0; 00628 g_timerArgs.ticksInFunc2 = 0; 00629 g_timerArgs.ticksBeforeTimer = 0; 00630 00631 /*#1*/ 00632 status = pal_osTimerCreate(palTimerFunc7, &timerID1, palOsTimerPeriodic , &timerID1); 00633 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00634 /*#2*/ 00635 g_timerArgs.ticksBeforeTimer = pal_osKernelSysTick(); 00636 /*#3*/ 00637 status = pal_osTimerStart(timerID1, 100); 00638 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00639 /*#4*/ 00640 status = pal_osDelay(1500); 00641 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00642 /*#5*/ 00643 TEST_ASSERT_EQUAL_INT(10, g_timerArgs.ticksInFunc1); 00644 TEST_ASSERT_UINT32_WITHIN(((PAL_TEST_TIME_SECOND/PAL_TEST_PERCENTAGE_HUNDRED) * PAL_TEST_PERCENTAGE_TIMER_ERROR), PAL_TEST_TIME_SECOND, (pal_osKernelSysMilliSecTick(g_timerArgs.ticksInFunc2) - pal_osKernelSysMilliSecTick(g_timerArgs.ticksBeforeTimer))); 00645 /*#6*/ 00646 status = pal_osTimerDelete(&timerID1); 00647 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00648 TEST_ASSERT_EQUAL(NULLPTR, timerID1); 00649 } 00650 00651 /*! \brief Test that single-shot and periodic timer works when stopped from callback. 00652 * 00653 * | # | Step | Expected | 00654 * |---|--------------------------------------------------------------------------------------------------|--------------------------------| 00655 * | 1 | Create a one-shot timer, which calls `palTimerFunc6` when triggered, using `pal_osTimerCreate`. | PAL_SUCCESS | 00656 * | 2 | Start the timer using `pal_osTimerStart`. | PAL_SUCCESS | 00657 * | 3 | Sleep for a period. | PAL_SUCCESS | 00658 * | 4 | Check that timer is in fired only one time. | PAL_SUCCESS | 00659 * | 5 | Delete the timer. | PAL_SUCCESS | 00660 */ 00661 TEST(pal_rtos, OneShotTimerStopUnityTest) 00662 { 00663 palStatus_t status = PAL_SUCCESS; 00664 palTimerID_t timerID1 = NULLPTR; 00665 00666 g_timerArgs.ticksBeforeTimer = 0; 00667 g_timerArgs.ticksInFunc1 = 0; 00668 00669 /*#1*/ 00670 status = pal_osTimerCreate(palTimerFunc6, &timerID1, palOsTimerOnce , &timerID1); 00671 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00672 /*#2*/ 00673 status = pal_osTimerStart(timerID1, 500); 00674 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00675 /*#3*/ 00676 status = pal_osDelay(1500); 00677 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00678 /*#4*/ 00679 TEST_ASSERT_EQUAL_INT(1, g_timerArgs.ticksInFunc1); 00680 /*#5*/ 00681 status = pal_osTimerDelete(&timerID1); 00682 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00683 TEST_ASSERT_EQUAL(NULLPTR, timerID1); 00684 00685 } 00686 00687 /*! \brief Test that single-shot and periodic timer works when stopped from callback. 00688 * 00689 * | # | Step | Expected | 00690 * |---|--------------------------------------------------------------------------------------------------|--------------------------------| 00691 * | 1 | Create a periodic timer, which calls `palTimerFunc6` when triggered, using `pal_osTimerCreate`. | PAL_SUCCESS | 00692 * | 2 | Start the timer using `pal_osTimerStart`. | PAL_SUCCESS | 00693 * | 3 | Sleep for a period. | PAL_SUCCESS | 00694 * | 4 | Check that timer is in fired only one time. | PAL_SUCCESS | 00695 * | 5 | Delete the timer. | PAL_SUCCESS | 00696 */ 00697 TEST(pal_rtos, PeriodicTimerStopUnityTest) 00698 { 00699 palStatus_t status = PAL_SUCCESS; 00700 palTimerID_t timerID1 = NULLPTR; 00701 00702 g_timerArgs.ticksInFunc1 = 0; 00703 00704 /*#1*/ 00705 status = pal_osTimerCreate(palTimerFunc6, &timerID1, palOsTimerPeriodic , &timerID1); 00706 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00707 /*#2*/ 00708 status = pal_osTimerStart(timerID1, 500); 00709 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00710 /*#3*/ 00711 status = pal_osDelay(1500); 00712 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00713 /*#4*/ 00714 TEST_ASSERT_EQUAL_INT(1, g_timerArgs.ticksInFunc1); 00715 /*#5*/ 00716 status = pal_osTimerDelete(&timerID1); 00717 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00718 TEST_ASSERT_EQUAL(NULLPTR, timerID1); 00719 } 00720 /*! \brief Create two timers: periodic and one-shot. Starts both timers, 00721 * then causes a delay to allow output from the timer functions to be printed on the console. 00722 * 00723 * | # | Step | Expected | 00724 * |---|--------------------------------------------------------------------------------------------------|--------------------------------| 00725 * | 1 | Create a one-shot timer, which calls `palTimerFunc1` when triggered, using `pal_osTimerCreate`. | PAL_SUCCESS | 00726 * | 2 | Create a periodic timer, which calls `palTimerFunc2` when triggered, using `pal_osTimerCreate`. | PAL_SUCCESS | 00727 * | 3 | Get the kernel `sysTick` value. | PAL_SUCCESS | 00728 * | 4 | Start the first timer using `pal_osTimerStart`. | PAL_SUCCESS | 00729 * | 5 | Get the kernel `sysTick` value. | PAL_SUCCESS | 00730 * | 6 | Start the first timer using `pal_osTimerStart`. | PAL_SUCCESS | 00731 * | 7 | Sleep for a period. | PAL_SUCCESS | 00732 * | 8 | Stop the second timer using `pal_osTimerStop`. | PAL_SUCCESS | 00733 * | 9 | Delete the first timer using `pal_osTimerDelete`. | PAL_SUCCESS | 00734 * | 10 | Delete the second timer using `pal_osTimerDelete`. | PAL_SUCCESS | 00735 */ 00736 00737 TEST(pal_rtos, TimerStartUnityTest) 00738 { 00739 uint32_t expectedTicks; 00740 uint32_t ticksInFuncError; 00741 00742 palStatus_t status = PAL_SUCCESS; 00743 palTimerID_t timerID1 = NULLPTR; 00744 palTimerID_t timerID2 = NULLPTR; 00745 00746 g_timerArgs.ticksBeforeTimer = 0; 00747 g_timerArgs.ticksInFunc1 = 0; 00748 g_timerArgs.ticksInFunc2 = 0; 00749 00750 /*#1*/ 00751 status = pal_osTimerCreate(palTimerFunc1, NULL, palOsTimerOnce , &timerID1); 00752 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00753 /*#2*/ 00754 status = pal_osTimerCreate(palTimerFunc2, NULL, palOsTimerPeriodic , &timerID2); 00755 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00756 /*#3*/ 00757 g_timerArgs.ticksBeforeTimer = pal_osKernelSysTick(); 00758 /*#4*/ 00759 status = pal_osTimerStart(timerID1, 1000); 00760 PAL_PRINTF("ticks before Timer: 0 - %" PRIu32 "\n", g_timerArgs.ticksBeforeTimer); 00761 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00762 /*#5*/ 00763 g_timerArgs.ticksBeforeTimer = pal_osKernelSysTick(); 00764 /*#6*/ 00765 status = pal_osTimerStart(timerID2, 1000); 00766 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00767 /*#7*/ 00768 status = pal_osDelay(1500); 00769 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00770 /*#8*/ 00771 status = pal_osTimerStop(timerID2); 00772 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00773 /*#9*/ 00774 status = pal_osTimerDelete(&timerID1); 00775 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00776 TEST_ASSERT_EQUAL(NULLPTR, timerID1); 00777 /*#10*/ 00778 status = pal_osTimerDelete(&timerID2); 00779 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00780 TEST_ASSERT_EQUAL(NULLPTR, timerID2); 00781 } 00782 00783 /*! \brief Test high-resolution timers 00784 * 00785 * | 1 | Create a periodic timer, which calls `palTimerFunc3` when triggered, using `pal_osTimerCreate`. | PAL_SUCCESS | 00786 * | 2 | Create a periodic timer, which calls `palTimerFunc4` when triggered, using `pal_osTimerCreate`. | PAL_ERR_NO_HIGH_RES_TIMER_LEFT | 00787 * | 3 | Start the first timer using `pal_osTimerStart` as high res timer. | PAL_SUCCESS | 00788 * | 4 | Start the second timer using `pal_osTimerStart` as high res timer. | PAL_ERR_NO_HIGH_RES_TIMER_LEFT | 00789 * | 5 | Sleep for a period. | PAL_SUCCESS | 00790 * | 6 | Stop the second timer using `pal_osTimerStop`. | PAL_SUCCESS | 00791 * | 7 | Start the second timer using `pal_osTimerStart` as high res timer | PAL_SUCCESS | 00792 * | 8 | Sleep for a period. | PAL_SUCCESS | 00793 * | 9 | Delete the first timer using `pal_osTimerDelete`. | PAL_SUCCESS | 00794 * | 10 | Delete the second timer using `pal_osTimerDelete`. | PAL_SUCCESS | 00795 */ 00796 TEST(pal_rtos, HighResTimerUnityTest) 00797 { 00798 palStatus_t status = PAL_SUCCESS; 00799 palTimerID_t timerID1 = NULLPTR; 00800 palTimerID_t timerID2 = NULLPTR; 00801 uint32_t expectedTicks; 00802 uint32_t ticksInFuncError; 00803 00804 g_timerArgs.ticksBeforeTimer = 0; 00805 g_timerArgs.ticksInFunc1 = 0; 00806 g_timerArgs.ticksInFunc2 = 0; 00807 00808 /*#1*/ 00809 status = pal_osTimerCreate(palTimerFunc3, NULL, palOsTimerPeriodic , &timerID1); 00810 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00811 00812 /*#2*/ 00813 status = pal_osTimerCreate(palTimerFunc4, NULL, palOsTimerPeriodic , &timerID2); 00814 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00815 00816 /*#3*/ 00817 status = pal_osTimerStart(timerID1, PAL_TEST_HIGH_RES_TIMER); 00818 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00819 00820 /*#4*/ 00821 status = pal_osTimerStart(timerID2, PAL_TEST_HIGH_RES_TIMER); 00822 if (PAL_SUCCESS == status) // behavior is slightly different for Linux due to high res timer limitation there (only one at a time supported there) 00823 { 00824 status = pal_osTimerStop(timerID2); 00825 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00826 } 00827 else 00828 { 00829 TEST_ASSERT_EQUAL_HEX(PAL_ERR_NO_HIGH_RES_TIMER_LEFT , status); 00830 } 00831 /*#5*/ 00832 status = pal_osDelay(500); 00833 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00834 00835 /*#6*/ 00836 status = pal_osTimerStop(timerID1); 00837 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00838 00839 /*#7*/ 00840 status = pal_osTimerStart(timerID2, PAL_TEST_HIGH_RES_TIMER2); 00841 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00842 00843 /*#8*/ 00844 status = pal_osDelay(PAL_TIME_TO_WAIT_SHORT_MS); 00845 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00846 00847 status = pal_osTimerStop(timerID2); 00848 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00849 00850 // check there is at 90..110% of expected timer callbacks. 00851 expectedTicks = (uint32_t)((float)PAL_TIME_TO_WAIT_SHORT_MS / (float)PAL_TEST_HIGH_RES_TIMER2); 00852 ticksInFuncError = (uint32_t)(((float)PAL_TIME_TO_WAIT_SHORT_MS / (float)PAL_TEST_HIGH_RES_TIMER2) * (float)PAL_TEST_PERCENTAGE_TIMER_ERROR); 00853 TEST_ASSERT_UINT32_WITHIN(ticksInFuncError, expectedTicks, g_timerArgs.ticksInFunc1); 00854 00855 /*#9*/ 00856 status = pal_osTimerDelete(&timerID1); 00857 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00858 TEST_ASSERT_EQUAL(NULLPTR, timerID1); 00859 00860 /*#10*/ 00861 status = pal_osTimerDelete(&timerID2); 00862 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00863 TEST_ASSERT_EQUAL(NULLPTR, timerID2); 00864 } 00865 00866 /*! /brief Test periodic timer with sleep inside the callback 00867 * 00868 * | 1 | Create a periodic timer, which calls `palTimerFunc5` when triggered, using `pal_osTimerCreate`. | PAL_SUCCESS | 00869 * | 2 | Sleep for a period. | PAL_SUCCESS | 00870 * | 3 | Delete the first timer using `pal_osTimerDelete`. | PAL_SUCCESS | 00871 * | 4 | Stop the timer using `pal_osTimerStop`. and check the number of callbacks is correct | PAL_SUCCESS | 00872 * | 5 | Delete the timer using `pal_osTimerDelete`. | PAL_SUCCESS | 00873 * | 6 | Start the timer with zero millisec. | PAL_ERR_RTOS_VALUE | 00874 * | 7 | Delete the timer using `pal_osTimerDelete`. | PAL_SUCCESS | 00875 */ 00876 TEST(pal_rtos, TimerSleepUnityTest) 00877 { 00878 palStatus_t status = PAL_SUCCESS; 00879 palTimerID_t timerID1 = NULLPTR; 00880 uint32_t expectedTicks; 00881 uint32_t ticksInFuncError; 00882 00883 /*#1*/ 00884 g_timerArgs.ticksBeforeTimer = 0; 00885 g_timerArgs.ticksInFunc1 = 0; 00886 g_timerArgs.ticksInFunc2 = 0; 00887 00888 status = pal_osTimerCreate(palTimerFunc5, NULL, palOsTimerPeriodic , &timerID1); 00889 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00890 00891 /*#2*/ 00892 status = pal_osTimerStart(timerID1, PAL_TEST_HIGH_RES_TIMER); 00893 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00894 00895 /*#3*/ 00896 status = pal_osDelay(PAL_TIME_TO_WAIT_MS); 00897 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00898 00899 /*#4*/ 00900 status = pal_osTimerStop(timerID1); 00901 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00902 00903 // The code expects currently timer to have +-10% accuracy, or actually a 90% of success 00904 // rate in getting CPU time. The previous +-5% did fail at random on Linux for perfectly 00905 // valid reasons, as the timer is ran in a thread and on a multi user, non-rtos OS the 00906 // CPU time is given at best effort basis. There is no need to ask for realtime thread 00907 // priority just to serve PAL tests, as nothing else in related codebase actually expects to have 00908 // semi hard realtime guarantees from a timer. 00909 expectedTicks = (uint32_t)((float)PAL_TIME_TO_WAIT_MS / (float)PAL_TEST_HIGH_RES_TIMER); 00910 ticksInFuncError = (uint32_t)(((float)PAL_TIME_TO_WAIT_MS / (float)PAL_TEST_HIGH_RES_TIMER) * (float)PAL_TEST_PERCENTAGE_TIMER_ERROR); 00911 TEST_ASSERT_UINT32_WITHIN(ticksInFuncError, expectedTicks, g_timerArgs.ticksInFunc1); 00912 00913 /*#5*/ 00914 status = pal_osTimerDelete(&timerID1); 00915 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00916 TEST_ASSERT_EQUAL(NULLPTR, timerID1); 00917 00918 } 00919 00920 /*! /brief Test timer API with non-valid parameters 00921 * 00922 * | 1 | Start the timer with zero millisec. | PAL_ERR_RTOS_VALUE | 00923 * | 2 | Delete the timer using `pal_osTimerDelete`. | PAL_SUCCESS | 00924 */ 00925 TEST(pal_rtos, TimerNegativeUnityTest) 00926 { 00927 palStatus_t status = PAL_SUCCESS; 00928 palTimerID_t timerID1 = NULLPTR; 00929 00930 g_timerArgs.ticksBeforeTimer = 0; 00931 g_timerArgs.ticksInFunc1 = 0; 00932 g_timerArgs.ticksInFunc2 = 0; 00933 00934 /*#1*/ 00935 status = pal_osTimerCreate(palTimerFunc5, NULL, palOsTimerPeriodic , &timerID1); 00936 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00937 status = pal_osTimerStart(timerID1, 0); 00938 TEST_ASSERT_EQUAL_HEX(PAL_ERR_RTOS_VALUE , status); 00939 00940 /*#2*/ 00941 status = pal_osTimerDelete(&timerID1); 00942 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00943 } 00944 00945 /*! \brief Creates mutexes and semaphores and uses them to communicate between 00946 * the different threads it creates (as defined in `pal_rtos_test_utils.c`). 00947 * In this test, we check that thread communication is working as expected between the threads and in the designed order. 00948 * In one case, we expect the thread to fail to lock a mutex – (thread1). 00949 * Threads are created with different priorities (PAL enforces this attribute). 00950 * For each case, the thread function prints the expected result. The test code verifies this result as well. 00951 * 00952 * | # | Step | Expected | 00953 * |---|--------------------------------|-------------| 00954 * | 1 | Create a mutex using `pal_osMutexCreate`. | PAL_SUCCESS | 00955 * | 2 | Create a mutex using `pal_osMutexCreate`. | PAL_SUCCESS | 00956 * | 3 | Create a semaphore with count 1. | PAL_SUCCESS | 00957 * | 4 | Run the PAL test threads using the `palRunThreads` test function. | PAL_SUCCESS | 00958 * | 5 | Delete the semaphore using `pal_osSemaphoreDelete`. | PAL_SUCCESS | 00959 * | 6 | Delete the first mutex using `pal_osMutexDelete`. | PAL_SUCCESS | 00960 * | 7 | Delete the second mutex using `pal_osMutexDelete`. | PAL_SUCCESS | 00961 */ 00962 TEST(pal_rtos, PrimitivesUnityTest1) 00963 { 00964 palStatus_t status = PAL_SUCCESS; 00965 /*#1*/ 00966 status = pal_osMutexCreate(&mutex1); 00967 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00968 /*#2*/ 00969 status = pal_osMutexCreate(&mutex2); 00970 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00971 /*#3*/ 00972 status = pal_osSemaphoreCreate(1 ,&semaphore1); 00973 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00974 /*#4*/ 00975 palRunThreads(); 00976 /*#5*/ 00977 status = pal_osSemaphoreDelete(&semaphore1); 00978 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00979 TEST_ASSERT_EQUAL(NULLPTR, semaphore1); 00980 /*#6*/ 00981 status = pal_osMutexDelete(&mutex1); 00982 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00983 TEST_ASSERT_EQUAL(NULLPTR, mutex1); 00984 /*#7*/ 00985 status = pal_osMutexDelete(&mutex2); 00986 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00987 TEST_ASSERT_EQUAL(NULLPTR, mutex2); 00988 00989 } 00990 00991 /*! \brief Verifies that several RTOS primitives APIs can handle invalid 00992 * arguments. The test calls each API with invalid arguments and verifies the result. 00993 * It also verifies that the semaphore wait API can accept NULL as the third parameter. 00994 * 00995 * | # | Step | Expected | 00996 * |---|------------------------------------------------------------------------------|--------------------------| 00997 * | 1 | Test thread creation with invalid arguments (`pal_osThreadCreateWithAlloc`). | PAL_ERR_INVALID_ARGUMENT | 00998 * | 2 | Test thread creation with invalid arguments (`pal_osThreadCreateWithAlloc`). | PAL_ERR_INVALID_ARGUMENT | 00999 * | 3 | Test thread creation with invalid arguments (`pal_osThreadCreateWithAlloc`). | PAL_ERR_INVALID_ARGUMENT | 01000 * | 4 | Test semaphore creation with invalid arguments (`pal_osSemaphoreCreate`). | PAL_ERR_INVALID_ARGUMENT | 01001 * | 5 | Test semaphore creation with invalid arguments (`pal_osSemaphoreCreate`). | PAL_ERR_INVALID_ARGUMENT | 01002 * | 6 | Test semaphore creation with invalid arguments (`pal_osSemaphoreCreate`). | PAL_ERR_INVALID_ARGUMENT | 01003 * | 7 | Test semaphore creation with invalid arguments (`pal_osSemaphoreCreate`). | PAL_ERR_INVALID_ARGUMENT | 01004 * | 8 | Test legacy thread create api (pal_osThreadCreate). | PAL_SUCCESS | 01005 * | 9 | Call pal_osThreadTerminate with NULL invalid parameter. | PAL_ERR_INVALID_ARGUMENT | 01006 */ 01007 TEST(pal_rtos, PrimitivesUnityTest2) 01008 { 01009 #ifdef DEBUG 01010 palStatus_t status = PAL_SUCCESS; 01011 palThreadID_t threadID = NULLPTR; 01012 int32_t tmp = 0; 01013 /*#1*/ 01014 //Check thread parameter validation 01015 status = pal_osThreadCreateWithAlloc(palThreadFunc1, NULL, PAL_osPriorityError, 1024, NULL, &threadID); 01016 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01017 /*#2*/ 01018 status = pal_osThreadCreateWithAlloc(palThreadFunc1, NULL, PAL_osPriorityIdle, 0, NULL, &threadID); 01019 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01020 /*#3*/ 01021 status = pal_osThreadCreateWithAlloc(palThreadFunc1, NULL, PAL_osPriorityIdle, 1024, NULL, NULL); 01022 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01023 01024 /*#4*/ 01025 //Check semaphore parameter validation 01026 status = pal_osSemaphoreCreate(1 ,NULL); 01027 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01028 /*#5*/ 01029 status = pal_osSemaphoreDelete(NULL); 01030 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01031 /*#6*/ 01032 status = pal_osSemaphoreWait(NULLPTR, 1000, &tmp); 01033 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01034 /*#7*/ 01035 status = pal_osSemaphoreRelease(NULLPTR); 01036 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01037 /*#9*/ 01038 status = pal_osThreadTerminate(NULL); 01039 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01040 #else 01041 TEST_IGNORE_MESSAGE("Ignored, tested only with DEBUG build"); 01042 #endif 01043 } 01044 01045 /*! \brief Creates a semaphore with count=1 and a thread to 01046 * test that it waits forever (the test waits 5 seconds). Then deletes the semaphore 01047 * and terminates the thread. 01048 * 01049 * | # | Step | Expected | 01050 * |---|--------------------------------|-------------| 01051 * | 1 | Create a semaphore with count = 1 using `pal_osSemaphoreCreate`. | PAL_SUCCESS | 01052 * | 2 | Wait for the semaphore using `pal_osSemaphoreWait` (should not block). | PAL_SUCCESS | 01053 * | 3 | Create a thread running `palThreadFuncWaitForEverTestusing` and `pal_osThreadCreateWithAlloc`. | PAL_SUCCESS | 01054 * | 4 | Get time using `pal_osKernelSysMilliSecTick` & pal_osKernelSysTick(). | PAL_SUCCESS | 01055 * | 5 | Wait for the semaphore using `pal_osSemaphoreWait` (should block; released by thread). Allow 25% inaccuracy on timing. | PAL_SUCCESS | 01056 * | 6 | Delete the semaphore using `pal_osSemaphoreDelete`. | PAL_SUCCESS | 01057 * | 7 | Terminate the thread using `pal_osThreadTerminate`. | PAL_SUCCESS | 01058 */ 01059 TEST(pal_rtos, SemaphoreWaitForever) 01060 { 01061 int32_t count = 0; 01062 uint64_t timeStartMs = PAL_MIN_SEC_FROM_EPOCH; 01063 uint64_t timeEndMs; 01064 palStatus_t status = PAL_SUCCESS; 01065 palThreadID_t threadID1 = PAL_INVALID_THREAD; 01066 01067 /*#1*/ 01068 status = pal_osSemaphoreCreate(1 ,&semaphore1); 01069 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01070 /*#2*/ 01071 status = pal_osSemaphoreWait(semaphore1, PAL_RTOS_WAIT_FOREVER, &count); 01072 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01073 /*#3*/ 01074 timeStartMs = pal_osKernelSysMilliSecTick(pal_osKernelSysTick()); 01075 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); // More than current epoch time -> success 01076 status = pal_osThreadCreateWithAlloc(palThreadFuncWaitForEverTest, (void *)&semaphore1, PAL_osPriorityAboveNormal, PAL_TEST_THREAD_STACK_SIZE, NULL, &threadID1); 01077 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01078 /*#4*/ 01079 status = pal_osSemaphoreWait(semaphore1, PAL_RTOS_WAIT_FOREVER, &count); 01080 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01081 /*#5*/ 01082 timeEndMs = pal_osKernelSysMilliSecTick(pal_osKernelSysTick()); 01083 TEST_ASSERT_UINT64_WITHIN(PAL_TIME_TO_WAIT_MS/4, PAL_TIME_TO_WAIT_MS/2, (timeEndMs - timeStartMs)); 01084 /*#6*/ 01085 status = pal_osSemaphoreDelete(&semaphore1); 01086 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01087 TEST_ASSERT_EQUAL(0, semaphore1); 01088 /*#7*/ 01089 status = pal_osThreadTerminate(&threadID1); 01090 TEST_ASSERT_EQUAL(PAL_SUCCESS, status); 01091 } 01092 01093 /*! \brief Creates a semaphore and waits on it to verify the 01094 * available count for it. Also verifies that the semaphore release API works correctly. 01095 * In addition, it checks the semaphore parameter validation scenarios. 01096 * 01097 * | # | Step | Expected | 01098 * |---|--------------------------------|-------------| 01099 * | 1 | Create a semaphore with count = 2 using `pal_osSemaphoreCreate`. | PAL_SUCCESS | 01100 * | 2 | Wait for the semaphore using `pal_osSemaphoreWait` (should not block), and check count. | PAL_SUCCESS | 01101 * | 3 | Increase semaphore count by ten using `pal_osSemaphoreRelease` in a loop. | PAL_SUCCESS | 01102 * | 4 | Delete semaphore using `pal_osSemaphoreDelete`. | PAL_SUCCESS | 01103 * | 5 | Test semaphore creation with invalid arguments (`pal_osSemaphoreCreate`). | PAL_ERR_INVALID_ARGUMENT | 01104 * | 6 | Test semaphore deletion with invalid arguments (`pal_osSemaphoreDelete`). | PAL_ERR_INVALID_ARGUMENT | 01105 * | 7 | Test semaphore waiting with invalid arguments (`pal_osSemaphoreWait`). | PAL_ERR_INVALID_ARGUMENT | 01106 * | 8 | Test semaphore release with invalid arguments (`pal_osSemaphoreRelease`). | PAL_ERR_INVALID_ARGUMENT | 01107 */ 01108 TEST(pal_rtos, SemaphoreBasicTest) 01109 { 01110 01111 palStatus_t status = PAL_SUCCESS; 01112 int counter = 0; 01113 /*#1*/ 01114 status = pal_osSemaphoreCreate(2 ,&semaphore1); 01115 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01116 /*#2*/ 01117 int32_t count = -1; 01118 status = pal_osSemaphoreWait(semaphore1, 1000, &count); 01119 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01120 TEST_ASSERT_EQUAL(1, count); 01121 01122 /*#3*/ 01123 for(counter = 0; counter < 10; counter++) 01124 { 01125 status=pal_osSemaphoreRelease(semaphore1); 01126 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01127 } 01128 /*#4*/ 01129 status=pal_osSemaphoreDelete(&semaphore1); 01130 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01131 TEST_ASSERT_EQUAL(0, semaphore1); 01132 01133 01134 #ifdef DEBUG 01135 //Check semaphore parameter validation 01136 int32_t tmp; 01137 /*#5*/ 01138 status = pal_osSemaphoreCreate(1 ,NULL); 01139 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01140 /*#6*/ 01141 status = pal_osSemaphoreDelete(NULL); 01142 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01143 /*#7*/ 01144 status = pal_osSemaphoreWait(NULLPTR, 1000, &tmp); 01145 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01146 /*#8*/ 01147 status = pal_osSemaphoreRelease(NULLPTR); 01148 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01149 #endif 01150 } 01151 01152 01153 01154 /*! \brief Performs a single atomic increment call 01155 * to an integer value and verifies that the result is as expected. 01156 * 01157 * | # | Step | Expected | 01158 * |---|--------------------------------|-------------| 01159 * | 1 | Call atomic increment using `pal_osAtomicIncrement` and check that the value was incremented. | PAL_SUCCESS | 01160 * | 2 | Call atomic increment using `pal_osAtomicIncrement` and check that the value was incremented. | PAL_SUCCESS | 01161 * | 3 | Call atomic increment using `pal_osAtomicIncrement` with negative value and check that the value was decremented. | PAL_SUCCESS | 01162 * | 4 | Call atomic increment using `pal_osAtomicIncrement` with zero value and check that the value was same. | PAL_SUCCESS | 01163 * | 5 | Call atomic increment using `pal_osAtomicIncrement` with negative value and check that the value was decremented. | PAL_SUCCESS | 01164 * | 6 | Call atomic increment using `pal_osAtomicIncrement` with negative value and check that the value was decremented. | PAL_SUCCESS | 01165 */ 01166 TEST(pal_rtos, AtomicIncrementUnityTest) 01167 { 01168 int32_t num1 = 0; 01169 int32_t increment = 10; 01170 int32_t tmp = 0; 01171 int32_t original = num1; 01172 01173 /*#1*/ 01174 tmp = pal_osAtomicIncrement(&num1, increment); 01175 TEST_ASSERT_EQUAL(original + increment, tmp); 01176 TEST_ASSERT_EQUAL(num1, tmp); 01177 01178 /*#2*/ 01179 increment = 40; 01180 tmp = pal_osAtomicIncrement(&num1, increment); 01181 TEST_ASSERT_EQUAL(50, tmp); 01182 TEST_ASSERT_EQUAL(num1, tmp); 01183 01184 /*#3*/ 01185 increment = -45; 01186 tmp = pal_osAtomicIncrement(&num1, increment); 01187 TEST_ASSERT_EQUAL(5, tmp); 01188 TEST_ASSERT_EQUAL(num1, tmp); 01189 01190 /*#4*/ 01191 // verify with zero too, as it is legal value 01192 increment = 0; 01193 tmp = pal_osAtomicIncrement(&num1, increment); 01194 TEST_ASSERT_EQUAL(5, tmp); 01195 TEST_ASSERT_EQUAL(num1, tmp); 01196 01197 /*#5*/ 01198 increment = -5; 01199 tmp = pal_osAtomicIncrement(&num1, increment); 01200 TEST_ASSERT_EQUAL(0, tmp); 01201 TEST_ASSERT_EQUAL(num1, tmp); 01202 01203 /*#6*/ 01204 increment = -15; 01205 tmp = pal_osAtomicIncrement(&num1, increment); 01206 TEST_ASSERT_EQUAL(-15, tmp); 01207 TEST_ASSERT_EQUAL(num1, tmp); 01208 } 01209 01210 01211 /*! \brief Verify that PAL can handle multiple calls for `pal_init()` and `pal_destroy()`. 01212 * 01213 * | # | Step | Expected | 01214 * |---|------------------------------------------------------|-------------| 01215 * | 1 | Call `pal_init`. | PAL_SUCCESS | 01216 * | 2 | Call `pal_init`. | PAL_SUCCESS | 01217 * | 3 | Call `pal_init`. | PAL_SUCCESS | 01218 * | 4 | Call `pal_destroy` in a loop untill init count == 0. | PAL_SUCCESS | 01219 * | 5 | Call `pal_init`. | PAL_SUCCESS | 01220 * | 6 | Call `pal_RTOSInitialize`. | PAL_SUCCESS | 01221 * | 7 | Call `pal_destroy`. | PAL_SUCCESS | 01222 */ 01223 TEST(pal_rtos, pal_init_test) 01224 { 01225 #if (PAL_INITIALIZED_BEFORE_TESTS == 0) 01226 01227 palStatus_t status = PAL_SUCCESS; 01228 int32_t initCounter = 0; 01229 /*#1*/ 01230 status = pal_init(); 01231 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01232 /*#2*/ 01233 status = pal_init(); 01234 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01235 /*#3*/ 01236 status = pal_init(); 01237 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01238 01239 /*#4*/ 01240 do 01241 { 01242 initCounter = pal_destroy(); 01243 //TEST_ASSERT_EQUAL_HEX(0, initCounter); 01244 01245 }while(initCounter != 0); 01246 01247 /*#5*/ 01248 status = pal_init(); 01249 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01250 01251 status = pal_RTOSInitialize(NULLPTR); 01252 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01253 01254 /*#7*/ 01255 initCounter = pal_destroy(); 01256 TEST_ASSERT_EQUAL_HEX(0, initCounter); 01257 #else 01258 TEST_IGNORE_MESSAGE("Ignored, PAL_INITIALIZED_BEFORE_TESTS set"); 01259 #endif 01260 } 01261 01262 /*! \brief Check derivation of keys from the platform's Root of Trust using the KDF algorithm. 01263 * 01264 * 01265 * 01266 * | # | Step | Expected | 01267 * |---|--------------------------------|-------------| 01268 * | 1 | Start a loop to perform the following steps. | | 01269 * | 2 | Derive a device key for encryption using `pal_osGetDeviceKey`. | PAL_SUCCESS | 01270 * | 3 | Derive a device key for signing using `pal_osGetDeviceKey`. | PAL_SUCCESS | 01271 * | 4 | Call `pal_osGetDeviceKey` with invalid arguments. | PAL_FAILURE | 01272 * | 5 | Call `pal_osGetDeviceKey` with invalid arguments. | PAL_FAILURE | 01273 * | 6 | Check that the derived signing and encryption keys are different. | PAL_SUCCESS | 01274 * | 7 | Check that all integrations of each type of derivation return the same value. | PAL_SUCCESS | 01275 */ 01276 TEST(pal_rtos, GetDeviceKeyTest_CMAC) 01277 { 01278 palStatus_t status = PAL_SUCCESS; 01279 size_t keyLenBytes = 16; 01280 uint8_t timesToDerive = 4; 01281 unsigned char encKeyDerive[timesToDerive][keyLenBytes]; //16 bytes=128bit 01282 unsigned char signKeyDerive[timesToDerive][keyLenBytes]; //16 bytes=128bit 01283 /*#1*/ 01284 for (int i=0; i < timesToDerive; i++) 01285 { 01286 /*#2*/ 01287 status = pal_osGetDeviceKey(palOsStorageEncryptionKey128Bit, encKeyDerive[i], keyLenBytes); 01288 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01289 /*#3*/ 01290 status = pal_osGetDeviceKey(palOsStorageSignatureKey128Bit , signKeyDerive[i], keyLenBytes); 01291 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01292 /*#4*/ 01293 status = pal_osGetDeviceKey(palOsStorageSignatureKey128Bit , signKeyDerive[i], keyLenBytes-1); 01294 TEST_ASSERT_NOT_EQUAL(PAL_SUCCESS, status); 01295 /*#5*/ 01296 status = pal_osGetDeviceKey(palOsStorageSignatureKey128Bit , NULL, keyLenBytes); 01297 TEST_ASSERT_NOT_EQUAL(PAL_SUCCESS, status); 01298 /*#6*/ 01299 status = memcmp(encKeyDerive[i], signKeyDerive[i], keyLenBytes); 01300 TEST_ASSERT_NOT_EQUAL(status,0); //The keys MUST be different! 01301 /*#7*/ 01302 if (i > 0) //Make sure key derivation is persistent every time 01303 { 01304 TEST_ASSERT_EQUAL_MEMORY(encKeyDerive[i-1], encKeyDerive[i], keyLenBytes); 01305 TEST_ASSERT_EQUAL_MEMORY(signKeyDerive[i-1], signKeyDerive[i], keyLenBytes); 01306 01307 } //if 01308 01309 } //for 01310 01311 } 01312 01313 /*! \brief Check derivation of keys from the platform's Root of Trust using the KDF algorithm. 01314 * 01315 * 01316 * 01317 * | # | Step | Expected | 01318 * |---|--------------------------------------------------------------------------------|---------------------| 01319 * | 1 | Start a loop to perform the following steps. | | 01320 * | 2 | Derive a device key for encryption using `pal_osGetDeviceKey`. | PAL_SUCCESS | 01321 * | 3 | Call `pal_osGetDeviceKey` with invalid arguments. | PAL_FAILURE | 01322 * | 4 | Call `pal_osGetDeviceKey` with invalid arguments. | PAL_FAILURE | 01323 * | 5 | Check that all integrations of each type of derivation return the same value. | PAL_SUCCESS | 01324 * | 6 | Call `pal_osGetDeviceKey` with invalid palDevKeyType_t. | PAL_ERR_INVALID_ARGUMENT | 01325 */ 01326 TEST(pal_rtos, GetDeviceKeyTest_HMAC_SHA256) 01327 { 01328 palStatus_t status = PAL_SUCCESS; 01329 size_t keyLenBytes = 32; 01330 uint8_t timesToDerive = 4; 01331 unsigned char encKeyDerive[timesToDerive][keyLenBytes]; //32 bytes=256bit 01332 /*#1*/ 01333 for (int i=0; i < timesToDerive; i++) 01334 { 01335 /*#2*/ 01336 status = pal_osGetDeviceKey(palOsStorageHmacSha256 , encKeyDerive[i], keyLenBytes); 01337 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01338 #ifdef DEBUG 01339 /*#3*/ 01340 status = pal_osGetDeviceKey(palOsStorageHmacSha256 , encKeyDerive[i], keyLenBytes-1); 01341 TEST_ASSERT_NOT_EQUAL(PAL_SUCCESS, status); 01342 /*#4*/ 01343 status = pal_osGetDeviceKey(palOsStorageHmacSha256 , NULL, keyLenBytes); 01344 TEST_ASSERT_NOT_EQUAL(PAL_SUCCESS, status); 01345 #endif 01346 /*#5*/ 01347 if (i > 0) //Make sure key derivation is persistent every time 01348 { 01349 TEST_ASSERT_EQUAL_MEMORY(encKeyDerive[i-1], encKeyDerive[i], keyLenBytes); 01350 } //if 01351 01352 } //for 01353 01354 #ifdef DEBUG 01355 /*#6*/ 01356 status = pal_osGetDeviceKey((palDevKeyType_t)999, encKeyDerive[0], keyLenBytes); 01357 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01358 #endif 01359 } 01360 01361 01362 /*! \brief Check recursive mutex behavior. 01363 * 01364 * | # | Step | Expected | 01365 * |---|--------------------------------|-------------| 01366 * | 1 | Create a mutex using `pal_osMutexCreate`. | PAL_SUCCESS | 01367 * | 2 | Create a semaphore using `pal_osSemaphoreCreate`. | PAL_SUCCESS | 01368 * | 3 | Create a thread running `RecursiveLockThread` using `pal_osThreadCreateWithAlloc`. | PAL_SUCCESS | 01369 * | 4 | Create a thread running `RecursiveLockThread` using `pal_osThreadCreateWithAlloc`. | PAL_SUCCESS | 01370 * | 5 | Release the semaphore using `pal_osSemaphoreRelease`. | PAL_SUCCESS | 01371 * | 6 | Release the semaphore using `pal_osSemaphoreRelease`. | PAL_SUCCESS | 01372 * | 7 | Sleep for a short interval. | PAL_SUCCESS | 01373 * | 8 | Wait for the semaphore using `pal_osSemaphoreWait`. | PAL_SUCCESS | 01374 * | 9 | Wait for the semaphore using `pal_osSemaphoreWait`. | PAL_SUCCESS | 01375 * | 10 | Terminate the first thread using `pal_osThreadTerminate`. | PAL_SUCCESS | 01376 * | 11 | Terminate the second thread using `pal_osThreadTerminate`. | PAL_SUCCESS | 01377 * | 12 | Delete the mutex using `pal_osMutexDelete`. | PAL_SUCCESS | 01378 * | 13 | Delete the semaphore using `pal_osSemaphoreDelete`. | PAL_SUCCESS | 01379 */ 01380 TEST(pal_rtos, Recursive_Mutex_Test) 01381 { 01382 palStatus_t status; 01383 int32_t val = 0; 01384 01385 recursiveMutexData = malloc(sizeof(palRecursiveMutexParam_t)); 01386 TEST_ASSERT_NOT_NULL(recursiveMutexData); 01387 memset(recursiveMutexData, 0, sizeof(palRecursiveMutexParam_t)); 01388 /*#1*/ 01389 status = pal_osMutexCreate(&(recursiveMutexData->mtx)); 01390 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01391 /*#2*/ 01392 status = pal_osSemaphoreCreate(0, &(recursiveMutexData->sem)); 01393 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01394 /*#3*/ 01395 status = pal_osThreadCreateWithAlloc(RecursiveLockThread, (void*)recursiveMutexData, PAL_osPriorityHigh, PAL_TEST_THREAD_STACK_SIZE, NULL, &(recursiveMutexData->higherPriorityThread)); 01396 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01397 /*#4*/ 01398 status = pal_osThreadCreateWithAlloc(RecursiveLockThread, (void*)recursiveMutexData, PAL_osPriorityAboveNormal, PAL_TEST_THREAD_STACK_SIZE, NULL, &(recursiveMutexData->lowerPriorityThread)); 01399 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01400 /*#5*/ 01401 status = pal_osSemaphoreRelease(recursiveMutexData->sem); 01402 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01403 /*#6*/ 01404 status = pal_osSemaphoreRelease(recursiveMutexData->sem); 01405 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01406 /*#7*/ 01407 pal_osDelay(1000); 01408 /*#8*/ 01409 status = pal_osSemaphoreWait(recursiveMutexData->sem, PAL_RTOS_WAIT_FOREVER, &val); 01410 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01411 /*#9*/ 01412 status = pal_osSemaphoreWait(recursiveMutexData->sem, PAL_RTOS_WAIT_FOREVER, &val); 01413 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01414 TEST_ASSERT_EQUAL(0, val); 01415 TEST_ASSERT_EQUAL_HEX(NULLPTR, recursiveMutexData->activeThread); 01416 /*#10*/ 01417 status = pal_osThreadTerminate(&(recursiveMutexData->higherPriorityThread)); 01418 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01419 /*#11*/ 01420 status = pal_osThreadTerminate(&(recursiveMutexData->lowerPriorityThread)); 01421 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01422 /*#12*/ 01423 status = pal_osMutexDelete(&(recursiveMutexData->mtx)); 01424 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01425 /*#13*/ 01426 status = pal_osSemaphoreDelete(&recursiveMutexData->sem); 01427 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01428 01429 TEST_ASSERT_EQUAL(400, recursiveMutexData->count); 01430 01431 free(recursiveMutexData); 01432 recursiveMutexData = NULL; 01433 } 01434 01435 01436 01437 01438 /*! \brief This test verify the functionality of the RTC 01439 * 01440 * | # | Step | Expected | 01441 * |---|--------------------------------|-------------| 01442 * | 1 | Get system RTC | PAL_SUCCESS | 01443 * | 2 | set new RTC | PAL_SUCCESS | 01444 * | 3 | delay for 2 seconds | PAL_SUCCESS | 01445 * | 4 | get RTC & compare to RTC from (2) | PAL_SUCCESS | 01446 * | 5 | restore system time from (1) | PAL_SUCCESS | 01447 */ 01448 TEST(pal_rtos, pal_rtc) 01449 { 01450 #if (PAL_USE_HW_RTC) 01451 palStatus_t status = PAL_SUCCESS; 01452 uint64_t time1 = 0, sysTime = 0; 01453 01454 /*#1*/ 01455 status = pal_plat_osGetRtcTime(&sysTime); 01456 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01457 01458 /*#2*/ 01459 status = pal_plat_osSetRtcTime(PAL_MIN_RTC_SET_TIME); 01460 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01461 01462 /*#3*/ 01463 status = pal_osDelay(2000); 01464 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01465 01466 /*#4*/ 01467 status = pal_plat_osGetRtcTime(&time1); 01468 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01469 TEST_ASSERT_TRUE(time1 - PAL_MIN_RTC_SET_TIME >= 1 * PAL_ONE_SEC); 01470 01471 /*#5*/ 01472 pal_plat_osSetRtcTime(sysTime + time1 - PAL_MIN_RTC_SET_TIME + 1); //add lost time from delay 01473 01474 #else 01475 TEST_IGNORE_MESSAGE("Ignored, PAL_USE_HW_RTC not set"); 01476 #endif 01477 } 01478
Generated on Tue Jul 12 2022 20:21:02 by
