Simulated product dispenser

Dependencies:   HTS221

Fork of mbed-cloud-workshop-connect-HTS221 by Jim Carver

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pal_rtos_test.c Source File

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 #include "pal.h"
00018 #include "unity.h"
00019 #include "unity_fixture.h"
00020 #include "pal_rtos_test_utils.h"
00021 #include <string.h>
00022 #include <stdlib.h>
00023 #include "sotp.h"
00024 #include "pal_plat_rtos.h"
00025 
00026 TEST_GROUP(pal_rtos);
00027 
00028 //Sometimes you may want to get local data in a module,
00029 //for example if you need to pass a reference.
00030 //However, you should usually avoid this.
00031 //extern int Counter;
00032 threadsArgument_t g_threadsArg = {0};
00033 timerArgument_t g_timerArgs = {0};
00034 palMutexID_t mutex1 = NULLPTR;
00035 palMutexID_t mutex2 = NULLPTR;
00036 palSemaphoreID_t semaphore1 = NULLPTR;
00037 palRecursiveMutexParam_t* recursiveMutexData = NULL;
00038 #define PAL_RUNNING_TEST_TIME   5  //estimation on length of test in seconds
00039 #define PAL_TEST_HIGH_RES_TIMER 100
00040 #define PAL_TEST_HIGH_RES_TIMER2 10
00041 #define PAL_TEST_PERCENTAGE_LOW 95
00042 #define PAL_TEST_PERCENTAGE_HIGH 105
00043 #define PAL_TEST_PERCENTAGE_HUNDRED  100
00044 
00045 //Forward declarations
00046 void palRunThreads(void);
00047 
00048 
00049 TEST_SETUP(pal_rtos)
00050 {
00051     palStatus_t status = PAL_SUCCESS;
00052     status = pal_init();
00053     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00054 
00055 }
00056 
00057 TEST_TEAR_DOWN(pal_rtos)
00058 {
00059     if (NULL != recursiveMutexData)
00060     {
00061         if (recursiveMutexData->higherPriorityThread != NULLPTR)
00062         {
00063             pal_osThreadTerminate(&(recursiveMutexData->higherPriorityThread));
00064         }
00065         if (recursiveMutexData->lowerPriorityThread != NULLPTR)
00066         {
00067             pal_osThreadTerminate(&(recursiveMutexData->lowerPriorityThread));
00068         }
00069         if (recursiveMutexData->mtx != NULLPTR)
00070         {
00071             pal_osMutexDelete(&(recursiveMutexData->mtx));
00072         }
00073         if (recursiveMutexData->sem != NULLPTR)
00074         {
00075             pal_osSemaphoreDelete(&recursiveMutexData->sem);
00076         }
00077         free(recursiveMutexData);
00078         recursiveMutexData = NULL;
00079     }
00080     pal_destroy();
00081 }
00082 
00083 /*! \brief Sanity check of the kernel system tick API.
00084  * Fails if system tic value is zero (**note:** this can sometimes happen on wrap-around).
00085  *
00086  * | # |    Step                        |   Expected  |
00087  * |---|--------------------------------|-------------|
00088  * | 1 | Get current tick count using `pal_osKernelSysTick` and check that it is not 0.  | PAL_SUCCESS |
00089  */
00090 TEST(pal_rtos, pal_osKernelSysTick_Unity)
00091 {
00092     uint32_t tick1 = 0, tick2 = 0;
00093     /*#1*/
00094     tick1 = pal_osKernelSysTick();
00095     PAL_PRINTF("%" PRIu32 " %" PRIu32 "\n", tick1, tick2);
00096 
00097     TEST_ASSERT_TRUE(tick2 != tick1);
00098 }
00099 
00100 /*! \brief Sanity check of the kernel system tick API.
00101  * Fails if two calls return the same `sysTick` value.
00102  *
00103  * | # |    Step                        |   Expected  |
00104  * |---|--------------------------------|-------------|
00105  * | 1 | Get current tick count using `pal_osKernelSysTick`.       | PAL_SUCCESS |
00106  * | 2 | Get current tick count using `pal_osKernelSysTick`.       | PAL_SUCCESS |
00107  * | 3 | Check that the two tick count values are not the same. | PAL_SUCCESS |
00108  */
00109 TEST(pal_rtos, pal_osKernelSysTick64_Unity)
00110 {
00111     uint64_t tick1 = 0, tick2 = 0;
00112     /*#1*/
00113     tick1 = pal_osKernelSysTick();
00114     /*#2*/
00115     tick2 = pal_osKernelSysTick();
00116     /*#3*/
00117     TEST_ASSERT_TRUE(tick2 >= tick1);
00118 }
00119 
00120 /*! \brief Check the conversion from a non-zero `sysTick` value to microseconds.
00121  * Verify that the result is not 0.
00122  *
00123  * | # |    Step                        |   Expected  |
00124  * |---|--------------------------------|-------------|
00125  * | 1 | Convert a nubmer in `sysTicks` to microseconds using `pal_osKernelSysTickMicroSec` and check it is not 0. | PAL_SUCCESS |
00126  */
00127 TEST(pal_rtos, pal_osKernelSysTickMicroSec_Unity)
00128 {
00129     uint64_t tick = 0;
00130     uint64_t microSec = 2000 * 1000;
00131     /*#1*/
00132     tick = pal_osKernelSysTickMicroSec(microSec);
00133     TEST_ASSERT_TRUE(0 != tick);
00134 }
00135 
00136 /*! \brief Sanity check of non-zero values conversion between microseconds to ticks to milliseconds.
00137  * Verify that the result is correct when converting the input (microseconds) to the test output (milliseconds).
00138  *
00139  * | # |    Step                        |   Expected  |
00140  * |---|--------------------------------|-------------|
00141  * | 1 | Convert a nubmer in `sysTicks` to mircorseconds using `pal_osKernelSysTickMicroSec` and check it is not 0. | PAL_SUCCESS |
00142  * | 2 | Convert a nubmer in `sysTicks` to milliseconds using `pal_osKernelSysMilliSecTick` and check the returned value. | PAL_SUCCESS |
00143  */
00144 TEST(pal_rtos, pal_osKernelSysMilliSecTick_Unity)
00145 {
00146     uint64_t tick = 0;
00147     uint64_t microSec = 200 * 1000;
00148     uint64_t milliseconds = 0;
00149     /*#1*/
00150     tick = pal_osKernelSysTickMicroSec(microSec);
00151     TEST_ASSERT_TRUE(0 != tick);
00152     /*#2*/
00153     milliseconds = pal_osKernelSysMilliSecTick(tick);
00154     TEST_ASSERT_EQUAL(microSec/1000, milliseconds);
00155    
00156 }
00157 
00158 /*! \brief Verify that the tick frequency function returns a non-zero value.
00159  *
00160  * | # |    Step                        |   Expected  |
00161  * |---|--------------------------------|-------------|
00162  * | 1 | Get the kernel `sysTick` frequency and check that it is positive.     | PAL_SUCCESS |
00163  */
00164 TEST(pal_rtos, pal_osKernelSysTickFrequency_Unity)
00165 {
00166     uint64_t frequency = 0;
00167     /*#1*/
00168     frequency = pal_osKernelSysTickFrequency();
00169 
00170     TEST_ASSERT_TRUE(frequency > 0);
00171 }
00172 
00173 /*! \brief Sanity check for the Delay API, verifying that `sysTick` increments after delay.
00174  * The test reads two system tick values. Between the two calls, it calls the delay function and
00175  * verifies that the tick values are different.
00176  *
00177  * | # |    Step                        |   Expected  |
00178  * |---|--------------------------------|-------------|
00179  * | 1 | Get the kernel `sysTick` value.                           | PAL_SUCCESS |
00180  * | 2 | Sleep for a short period .                              | PAL_SUCCESS |
00181  * | 3 | Get the kernel `sysTick` value.                          | PAL_SUCCESS |
00182  * | 4 | Check that second tick value is greater than the first. | PAL_SUCCESS |
00183  */
00184 TEST(pal_rtos, pal_osDelay_Unity)
00185 {
00186     palStatus_t status = PAL_SUCCESS;
00187     uint32_t tick1 , tick2;
00188     /*#1*/
00189     tick1 = pal_osKernelSysTick();
00190     /*#2*/
00191     status = pal_osDelay(200);
00192     /*#3*/
00193     tick2 = pal_osKernelSysTick();
00194     /*#4*/
00195     TEST_ASSERT_TRUE(tick2 > tick1);
00196     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00197 }
00198 
00199 /*! \brief Test for basic timing scenarios based on calls for the ticks and delay
00200 * functionality while verifying that results meet the defined deltas.
00201 *
00202 * | # |    Step                        |   Expected  |
00203 * |---|--------------------------------|-------------|
00204 * | 1 | Get the kernel `sysTick` value.                                      | PAL_SUCCESS |
00205 * | 2 | Sleep for a very short period.                                     | PAL_SUCCESS |
00206 * | 3 | Get the kernel `sysTick` value.                                      | PAL_SUCCESS |
00207 * | 4 | Check that second tick value is greater than the first.            | PAL_SUCCESS |
00208 * | 5 | Get the kernel `sysTick` value.                                      | PAL_SUCCESS |
00209 * | 6 | Sleep for a longer period.                                         | PAL_SUCCESS |
00210 * | 7 | Get the kernel `sysTick` value.                                      | PAL_SUCCESS |
00211 * | 8 | Check that second tick value is greated than the first.           | PAL_SUCCESS |
00212 * | 9 | Calculate the difference between the ticks.                                | PAL_SUCCESS |
00213 * | 10 | Convert last sleep period to ticks.                              | PAL_SUCCESS |
00214 * | 11 | Check that the tick period is correct (same as sleep period +/-delta). | PAL_SUCCESS |
00215 */
00216 TEST(pal_rtos, BasicTimeScenario)
00217 {
00218     palStatus_t status = PAL_SUCCESS;
00219     uint64_t tick, tick1 , tick2 , tickDiff, tickDelta;
00220 
00221     /*#1*/
00222     tick1 = pal_osKernelSysTick();
00223     /*#2*/
00224     status = pal_osDelay(1);
00225     /*#3*/
00226     tick2 = pal_osKernelSysTick();
00227 
00228     /*#4*/
00229     TEST_ASSERT_TRUE(tick1 != tick2);
00230     TEST_ASSERT_TRUE(tick2 > tick1);  // To check that the tick counts are incremental - be aware of wrap-arounds
00231     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00232     /****************************************/
00233     /*#5*/
00234     tick1 = pal_osKernelSysTick();
00235     /*#6*/
00236     status = pal_osDelay(2000);
00237     /*#7*/
00238     tick2 = pal_osKernelSysTick();
00239 
00240     /*#8*/
00241     TEST_ASSERT_TRUE(tick1 != tick2);
00242     TEST_ASSERT_TRUE(tick2 > tick1);
00243     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00244 
00245     /*#9*/
00246     tickDiff = tick2 - tick1;
00247     /*#10*/
00248     tick = pal_osKernelSysTickMicroSec(2000 * 1000);
00249     // 10 milliseconds delta
00250     /*#11*/
00251     tickDelta = pal_osKernelSysTickMicroSec(10 * 1000);
00252     TEST_ASSERT_TRUE((tick - tickDelta < tickDiff) && (tickDiff < tick + tickDelta));
00253     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00254 }
00255 
00256 /*! \brief Create two timers: periodic and one-shot. Starts both timers,
00257 * then causes a delay to allow output from the timer functions to be printed on the console.
00258 *
00259 * | # |    Step                                                                                          |   Expected                     |
00260 * |---|--------------------------------------------------------------------------------------------------|--------------------------------|
00261 * | 1 | Create a one-shot timer, which calls `palTimerFunc1` when triggered, using `pal_osTimerCreate`.  | PAL_SUCCESS                    |
00262 * | 2 | Create a periodic timer, which calls `palTimerFunc2` when triggered, using `pal_osTimerCreate`.  | PAL_SUCCESS                    |
00263 * | 3 | Get the kernel `sysTick` value.                                                                  | PAL_SUCCESS                    |
00264 * | 4 | Start the first timer using `pal_osTimerStart`.                                                  | PAL_SUCCESS                    |
00265 * | 5 | Get the kernel `sysTick` value.                                                                  | PAL_SUCCESS                    |
00266 * | 6 | Start the first timer using `pal_osTimerStart`.                                                  | PAL_SUCCESS                    |
00267 * | 7 | Sleep for a period.                                                                              | PAL_SUCCESS                    |
00268 * | 8 | Stop the second timer using `pal_osTimerStop`.                                                   | PAL_SUCCESS                    |
00269 * | 9 | Delete the first timer using `pal_osTimerDelete`.                                                | PAL_SUCCESS                    |
00270 * | 10 | Delete the second timer using `pal_osTimerDelete`.                                              | PAL_SUCCESS                    |
00271 * | 11 | Create a periodic timer, which calls `palTimerFunc3` when triggered, using `pal_osTimerCreate`. | PAL_SUCCESS                    |
00272 * | 12 | Create a periodic timer, which calls `palTimerFunc4` when triggered, using `pal_osTimerCreate`. | PAL_ERR_NO_HIGH_RES_TIMER_LEFT |
00273 * | 13 | Start the first timer using `pal_osTimerStart` as high res timer.                               | PAL_SUCCESS                    |
00274 * | 14 | Start the second timer using `pal_osTimerStart` as high res timer.                              | PAL_ERR_NO_HIGH_RES_TIMER_LEFT |
00275 * | 15 | Sleep for a period.                                                                             | PAL_SUCCESS                    |
00276 * | 16 | Stop the second timer using `pal_osTimerStop`.                                                  | PAL_SUCCESS                    |
00277 * | 17 | Start the second timer using `pal_osTimerStart` as high res timer                               | PAL_SUCCESS                    |
00278 * | 18 | Sleep for a period.                                                                             | PAL_SUCCESS                    |
00279 * | 19 | Delete the first timer using `pal_osTimerDelete`.                                               | PAL_SUCCESS                    |
00280 * | 20 | Delete the second timer using `pal_osTimerDelete`.                                              | PAL_SUCCESS                    |
00281 * | 21 | Create a periodic timer, which calls `palTimerFunc5` when triggered, using `pal_osTimerCreate`. | PAL_SUCCESS                    |
00282 * | 22 | Sleep for a period.                                                                             | PAL_SUCCESS                    |
00283 * | 23 | Delete the first timer using `pal_osTimerDelete`.                                               | PAL_SUCCESS                    |
00284 * | 24 | Stop the timer using `pal_osTimerStop`.  and check the number of callbacks is correct           | PAL_SUCCESS                    |
00285 * | 25 | Delete the timer using `pal_osTimerDelete`.                                                     | PAL_SUCCESS                    |
00286 * | 26 | Start the timer with zero millisec.                                                             | PAL_ERR_RTOS_VALUE             |
00287 * | 27 | Delete the timer using `pal_osTimerDelete`.                                                     | PAL_SUCCESS                    |
00288 */
00289 TEST(pal_rtos, TimerUnityTest)
00290 {
00291     palStatus_t status = PAL_SUCCESS;
00292     palTimerID_t timerID1 = NULLPTR;
00293     palTimerID_t timerID2 = NULLPTR;
00294     /*#1*/
00295     status = pal_osTimerCreate(palTimerFunc1, NULL, palOsTimerOnce, &timerID1);
00296     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00297     /*#2*/
00298     status = pal_osTimerCreate(palTimerFunc2, NULL, palOsTimerPeriodic , &timerID2);
00299     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00300     /*#3*/
00301     g_timerArgs.ticksBeforeTimer = pal_osKernelSysTick();
00302     /*#4*/
00303     status = pal_osTimerStart(timerID1, 1000);
00304     PAL_PRINTF("ticks before Timer: 0 - %" PRIu32 "\n", g_timerArgs.ticksBeforeTimer);
00305     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00306     /*#5*/
00307     g_timerArgs.ticksBeforeTimer = pal_osKernelSysTick();
00308     /*#6*/
00309     status = pal_osTimerStart(timerID2, 1000);
00310     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00311     /*#7*/
00312     status = pal_osDelay(1500);
00313     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00314     /*#8*/
00315     status = pal_osTimerStop(timerID2);
00316     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00317     /*#9*/
00318     status = pal_osTimerDelete(&timerID1);
00319     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00320     TEST_ASSERT_EQUAL(NULLPTR, timerID1);
00321     /*#10*/
00322     status = pal_osTimerDelete(&timerID2);
00323     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00324     TEST_ASSERT_EQUAL(NULLPTR, timerID2);
00325 
00326     g_timerArgs.ticksBeforeTimer = 0;
00327     g_timerArgs.ticksInFunc1 = 0;
00328     g_timerArgs.ticksInFunc2 = 0;
00329     
00330     /*#11*/
00331     status = pal_osTimerCreate(palTimerFunc3, NULL, palOsTimerPeriodic , &timerID1);
00332     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00333     
00334     /*#12*/
00335     status = pal_osTimerCreate(palTimerFunc4, NULL, palOsTimerPeriodic , &timerID2);
00336     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00337 
00338     /*#13*/
00339     status = pal_osTimerStart(timerID1, PAL_TEST_HIGH_RES_TIMER);
00340     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00341 
00342     /*#14*/
00343     status = pal_osTimerStart(timerID2, PAL_TEST_HIGH_RES_TIMER);
00344     if (PAL_SUCCESS == status) // behavior is slightly different for Linux due to high res timer limitation there (only one at a time supported there)
00345     {
00346         status = pal_osTimerStop(timerID2);
00347         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00348     }
00349     else  
00350     {
00351         TEST_ASSERT_EQUAL_HEX(PAL_ERR_NO_HIGH_RES_TIMER_LEFT, status);
00352     }
00353     /*#15*/
00354     status = pal_osDelay(500);
00355     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00356 
00357     /*#16*/
00358     status = pal_osTimerStop(timerID1);
00359     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00360 
00361     /*#17*/
00362     status = pal_osTimerStart(timerID2, PAL_TEST_HIGH_RES_TIMER2);
00363     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00364 
00365     /*#18*/
00366     status = pal_osDelay(PAL_TIME_TO_WAIT_SHORT_MS);
00367     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00368 
00369     status = pal_osTimerStop(timerID2);
00370     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00371 
00372     TEST_ASSERT_TRUE(g_timerArgs.ticksInFunc1 >= ((PAL_TIME_TO_WAIT_SHORT_MS / PAL_TEST_HIGH_RES_TIMER2)*PAL_TEST_PERCENTAGE_LOW)/ PAL_TEST_PERCENTAGE_HUNDRED); // check there is at least more than 95% of expected timer callbacks.
00373     
00374     /*#19*/
00375     status = pal_osTimerDelete(&timerID1);
00376     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00377     TEST_ASSERT_EQUAL(NULLPTR, timerID1);
00378     
00379     /*#20*/
00380     status = pal_osTimerDelete(&timerID2);
00381     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00382     TEST_ASSERT_EQUAL(NULLPTR, timerID2);
00383 
00384     /*#21*/
00385     g_timerArgs.ticksBeforeTimer = 0;
00386     g_timerArgs.ticksInFunc1 = 0;
00387     g_timerArgs.ticksInFunc2 = 0;
00388 
00389     status = pal_osTimerCreate(palTimerFunc5, NULL, palOsTimerPeriodic , &timerID1);
00390     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00391 
00392     /*#22*/
00393     status = pal_osTimerStart(timerID1, PAL_TEST_HIGH_RES_TIMER);
00394     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00395     
00396     /*#23*/
00397     status = pal_osDelay(PAL_TIME_TO_WAIT_MS);
00398     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00399 
00400     /*#24*/
00401     status = pal_osTimerStop(timerID1);
00402     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00403 
00404     TEST_ASSERT_TRUE(g_timerArgs.ticksInFunc1 >= ((PAL_TIME_TO_WAIT_MS / PAL_TEST_HIGH_RES_TIMER) * PAL_TEST_PERCENTAGE_LOW) / PAL_TEST_PERCENTAGE_HUNDRED); // check there is at least more than 95% of expected timer callbacks.
00405     TEST_ASSERT_TRUE(g_timerArgs.ticksInFunc1 <= ((PAL_TIME_TO_WAIT_MS / PAL_TEST_HIGH_RES_TIMER) * PAL_TEST_PERCENTAGE_HIGH) / PAL_TEST_PERCENTAGE_HUNDRED); // check there is at most less than 105% of expected timer callbacks.
00406 
00407     /*#25*/
00408     status = pal_osTimerDelete(&timerID1);
00409     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00410     TEST_ASSERT_EQUAL(NULLPTR, timerID1);
00411 
00412     /*#26*/
00413     status = pal_osTimerCreate(palTimerFunc5, NULL, palOsTimerPeriodic , &timerID1);
00414     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00415     status = pal_osTimerStart(timerID1, 0);
00416     TEST_ASSERT_EQUAL_HEX(PAL_ERR_RTOS_VALUE , status);
00417 
00418     /*#27*/
00419     status = pal_osTimerDelete(&timerID1);
00420     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00421 }
00422 
00423 /*! \brief Creates mutexes and semaphores and uses them to communicate between
00424 * the different threads it creates (as defined in `pal_rtos_test_utils.c`).
00425 * In this test, we check that thread communication is working as expected between the threads and in the designed order.
00426 * In one case, we expect the thread to fail to lock a mutex – (thread1).
00427 * Threads are created with different priorities (PAL enforces this attribute).
00428 * For each case, the thread function prints the expected result. The test code verifies this result as well.
00429 *
00430 * | # |    Step                        |   Expected  |
00431 * |---|--------------------------------|-------------|
00432 * | 1 | Create a mutex using `pal_osMutexCreate`.                           | PAL_SUCCESS |
00433 * | 2 | Create a mutex using `pal_osMutexCreate`.                           | PAL_SUCCESS |
00434 * | 3 | Create a semaphore with count 1.                                  | PAL_SUCCESS |
00435 * | 4 | Run the PAL test threads using the `palRunThreads` test function.  | PAL_SUCCESS |
00436 * | 5 | Delete the semaphore using `pal_osSemaphoreDelete`.                     | PAL_SUCCESS |
00437 * | 6 | Delete the first mutex using `pal_osMutexDelete`.                       | PAL_SUCCESS |
00438 * | 7 | Delete the second mutex using `pal_osMutexDelete`.                       | PAL_SUCCESS |
00439 */
00440 TEST(pal_rtos, PrimitivesUnityTest1)
00441 {
00442     palStatus_t status = PAL_SUCCESS;
00443     /*#1*/
00444     status = pal_osMutexCreate(&mutex1);
00445     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00446     /*#2*/
00447     status = pal_osMutexCreate(&mutex2);
00448     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00449     /*#3*/
00450     status = pal_osSemaphoreCreate(1 ,&semaphore1);
00451     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00452     /*#4*/
00453     palRunThreads();
00454     /*#5*/
00455     status = pal_osSemaphoreDelete(&semaphore1);
00456     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00457     TEST_ASSERT_EQUAL(NULLPTR, semaphore1);
00458     /*#6*/
00459     status = pal_osMutexDelete(&mutex1);
00460     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00461     TEST_ASSERT_EQUAL(NULLPTR, mutex1);
00462     /*#7*/
00463     status = pal_osMutexDelete(&mutex2);
00464     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00465     TEST_ASSERT_EQUAL(NULLPTR, mutex2);
00466 
00467 }
00468 
00469 /*! \brief Verifies that several RTOS primitives APIs can handle invalid
00470 * arguments. The test calls each API with invalid arguments and verifies the result.
00471 * It also verifies that the semaphore wait API can accept NULL as the third parameter.
00472 *
00473 * | # |    Step                                                                      |   Expected               |
00474 * |---|------------------------------------------------------------------------------|--------------------------|
00475 * | 1 | Test thread creation with invalid arguments (`pal_osThreadCreateWithAlloc`). | PAL_ERR_INVALID_ARGUMENT |
00476 * | 2 | Test thread creation with invalid arguments (`pal_osThreadCreateWithAlloc`). | PAL_ERR_INVALID_ARGUMENT |
00477 * | 3 | Test thread creation with invalid arguments (`pal_osThreadCreateWithAlloc`). | PAL_ERR_INVALID_ARGUMENT |
00478 * | 4 | Test semaphore creation with invalid arguments (`pal_osSemaphoreCreate`).    | PAL_ERR_INVALID_ARGUMENT |
00479 * | 5 | Test semaphore creation with invalid arguments (`pal_osSemaphoreCreate`).    | PAL_ERR_INVALID_ARGUMENT |
00480 * | 6 | Test semaphore creation with invalid arguments (`pal_osSemaphoreCreate`).    | PAL_ERR_INVALID_ARGUMENT |
00481 * | 7 | Test semaphore creation with invalid arguments (`pal_osSemaphoreCreate`).    | PAL_ERR_INVALID_ARGUMENT |
00482 * | 8 | Test legacy thread create api (pal_osThreadCreate).                          | PAL_SUCCESS              |
00483 * | 9 | Call pal_osThreadTerminate with NULL invalid parameter.                      | PAL_ERR_INVALID_ARGUMENT |
00484 */
00485 TEST(pal_rtos, PrimitivesUnityTest2)
00486 {
00487 #ifdef DEBUG
00488     palStatus_t status = PAL_SUCCESS;
00489     palThreadID_t threadID = NULLPTR;
00490     int32_t tmp = 0;
00491     /*#1*/
00492     //Check thread parameter validation
00493     status = pal_osThreadCreateWithAlloc(palThreadFunc1, NULL, PAL_osPriorityError, 1024, NULL, &threadID);
00494     TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status);
00495     /*#2*/
00496     status = pal_osThreadCreateWithAlloc(palThreadFunc1, NULL, PAL_osPriorityIdle, 0, NULL, &threadID);
00497     TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status);
00498     /*#3*/
00499     status = pal_osThreadCreateWithAlloc(palThreadFunc1, NULL, PAL_osPriorityIdle, 1024, NULL, NULL);
00500     TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status);
00501 
00502     /*#4*/
00503     //Check semaphore parameter validation
00504     status = pal_osSemaphoreCreate(1 ,NULL);
00505     TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status);
00506     /*#5*/
00507     status = pal_osSemaphoreDelete(NULL);
00508     TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status);
00509     /*#6*/
00510     status = pal_osSemaphoreWait(NULLPTR, 1000, &tmp);
00511     TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status);
00512     /*#7*/
00513     status = pal_osSemaphoreRelease(NULLPTR);
00514     TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status);
00515     /*#9*/
00516     status = pal_osThreadTerminate(NULL);
00517     TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status);
00518 #endif
00519 }
00520 
00521 /*! \brief Creates a semaphore with count=1 and a thread to
00522 * test that it waits forever (the test waits 5 seconds). Then deletes the semaphore
00523 * and terminates the thread.
00524 *
00525 * | # |    Step                        |   Expected  |
00526 * |---|--------------------------------|-------------|
00527 * | 1 | Create a semaphore with count = 1 using `pal_osSemaphoreCreate`.                          | PAL_SUCCESS |
00528 * | 2 | Wait for the semaphore using `pal_osSemaphoreWait` (should not block).                    | PAL_SUCCESS |
00529 * | 3 | Create a thread running `palThreadFuncWaitForEverTestusing` and `pal_osThreadCreateWithAlloc`. | PAL_SUCCESS |
00530 * | 4 | Set time using `pal_osSetTime`.                                                           | PAL_SUCCESS |
00531 * | 5 | Wait for the semaphore using `pal_osSemaphoreWait` (should block; released by thread).        | PAL_SUCCESS |
00532 * | 6 | Delete the semaphore using `pal_osSemaphoreDelete`.                                           | PAL_SUCCESS |
00533 * | 7 | Terminate the thread using `pal_osThreadTerminate`.                                           | PAL_SUCCESS |
00534 */
00535 TEST(pal_rtos, SemaphoreWaitForever)
00536 {
00537     int32_t count = 0;
00538     uint64_t timeElapsed = PAL_MIN_SEC_FROM_EPOCH;
00539     uint64_t timePassedInSec;
00540     palStatus_t status = PAL_SUCCESS;
00541     palThreadID_t threadID1 = PAL_INVALID_THREAD;
00542 
00543     /*#1*/
00544     status = pal_osSemaphoreCreate(1 ,&semaphore1);
00545     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00546     /*#2*/
00547     status = pal_osSemaphoreWait(semaphore1, PAL_RTOS_WAIT_FOREVER, &count);
00548     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00549     /*#3*/
00550     status = pal_osSetTime(timeElapsed);
00551     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); // More than current epoch time -> success    
00552     status = pal_osThreadCreateWithAlloc(palThreadFuncWaitForEverTest, (void *)&semaphore1, PAL_osPriorityAboveNormal, PAL_TEST_THREAD_STACK_SIZE, NULL, &threadID1);
00553     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00554     /*#4*/
00555     status = pal_osSemaphoreWait(semaphore1, PAL_RTOS_WAIT_FOREVER, &count);
00556     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00557     /*#5*/
00558     timePassedInSec = pal_osGetTime();
00559     TEST_ASSERT_EQUAL_HEX(0, (timePassedInSec - timeElapsed) >= PAL_TIME_TO_WAIT_MS/2);
00560     /*#6*/
00561     status = pal_osSemaphoreDelete(&semaphore1);
00562     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00563     TEST_ASSERT_EQUAL(0, semaphore1);
00564     /*#7*/
00565     status = pal_osThreadTerminate(&threadID1);
00566     TEST_ASSERT_EQUAL(PAL_SUCCESS, status);
00567 }
00568 
00569 /*! \brief Creates a semaphore and waits on it to verify the
00570 * available count for it. Also verifies that the semaphore release API works correctly.
00571 * In addition, it checks the semaphore parameter validation scenarios.
00572 *
00573 * | # |    Step                        |   Expected  |
00574 * |---|--------------------------------|-------------|
00575 * | 1 | Create a semaphore with count = 2 using `pal_osSemaphoreCreate`.                          | PAL_SUCCESS |
00576 * | 2 | Wait for the semaphore using `pal_osSemaphoreWait` (should not block), and check count.   | PAL_SUCCESS |
00577 * | 3 | Increase semaphore count by ten using `pal_osSemaphoreRelease` in a loop.             | PAL_SUCCESS |
00578 * | 4 | Delete semaphore using `pal_osSemaphoreDelete`.                                           | PAL_SUCCESS |
00579 * | 5 | Test semaphore creation with invalid arguments (`pal_osSemaphoreCreate`).                 | PAL_ERR_INVALID_ARGUMENT |
00580 * | 6 | Test semaphore deletion with invalid arguments (`pal_osSemaphoreDelete`).                 | PAL_ERR_INVALID_ARGUMENT |
00581 * | 7 | Test semaphore waiting with invalid arguments (`pal_osSemaphoreWait`).                    | PAL_ERR_INVALID_ARGUMENT |
00582 * | 8 | Test semaphore release with invalid arguments (`pal_osSemaphoreRelease`).                 | PAL_ERR_INVALID_ARGUMENT |
00583 */
00584 TEST(pal_rtos, SemaphoreBasicTest)
00585 {
00586 
00587     palStatus_t status = PAL_SUCCESS;
00588     int counter = 0;
00589     /*#1*/
00590     status = pal_osSemaphoreCreate(2 ,&semaphore1);
00591     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00592     /*#2*/
00593     int32_t count = -1;
00594     status = pal_osSemaphoreWait(semaphore1, 1000, &count);
00595     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00596     TEST_ASSERT_EQUAL(1, count);
00597 
00598     /*#3*/
00599     for(counter = 0; counter < 10; counter++)
00600     {
00601         status=pal_osSemaphoreRelease(semaphore1);
00602         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00603     }
00604     /*#4*/
00605     status=pal_osSemaphoreDelete(&semaphore1);
00606     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00607     TEST_ASSERT_EQUAL(0, semaphore1);
00608 
00609     
00610 #ifdef DEBUG
00611     //Check semaphore parameter validation
00612     int32_t tmp;
00613     /*#5*/
00614     status = pal_osSemaphoreCreate(1 ,NULL);
00615     TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status);
00616     /*#6*/
00617     status = pal_osSemaphoreDelete(NULL);
00618     TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status);
00619     /*#7*/
00620     status = pal_osSemaphoreWait(NULLPTR, 1000, &tmp);
00621     TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status);
00622     /*#8*/
00623     status = pal_osSemaphoreRelease(NULLPTR);
00624     TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status);
00625 #endif
00626 }
00627 
00628 
00629 
00630 /*! \brief Performs a single atomic increment call
00631 * to an integer value and verifies that the result is as expected.
00632 *
00633 * | # |    Step                        |   Expected  |
00634 * |---|--------------------------------|-------------|
00635 * | 1 | Call atomic increment using `pal_osAtomicIncrement` and check that the value was incremented. | PAL_SUCCESS |
00636 */
00637 TEST(pal_rtos, AtomicIncrementUnityTest)
00638 {
00639     int32_t num1 = 0;
00640     int32_t increment = 10;
00641     int32_t tmp = 0;
00642     int32_t original = num1;
00643     /*#1*/
00644     tmp = pal_osAtomicIncrement(&num1, increment);
00645 
00646 
00647     TEST_ASSERT_EQUAL(original + increment, tmp);
00648 
00649 }
00650 
00651 struct randBuf
00652 {
00653     uint8_t rand[6];
00654 };
00655 
00656 /*! \brief Check the random APIs. For each API, the test calls the random API in a loop
00657 * and stores the result. When the loop finishes, we verify that the count of the
00658 * duplication in the stored values is less than the defined random margin value for each API.
00659 *
00660 * | #  |    Step                                                                     |   Expected               |
00661 * |--- |-----------------------------------------------------------------------------|--------------------------|
00662 * | 1  | Fill array with random 32bit values using `pal_osRandom32bit` in a loop.    | PAL_SUCCESS              |
00663 * | 2  | Check array for matching values and make sure there are not too many.       | PAL_SUCCESS              |
00664 * | 3  | Fill array with random values using `pal_osRandomUniform` in a loop.        | PAL_SUCCESS              |
00665 * | 4  | Check array for matching values and make sure there are not too many.       | PAL_SUCCESS              |
00666 * | 5  | Fill array with random byte sequences using `pal_osRandomBuffer` in a loop. | PAL_SUCCESS              |
00667 * | 6  | Check array for matching values and make sure there are not too many.       | PAL_SUCCESS              |
00668 * | 7  | Call pal_osRandom32bit with NULL output parameter.                          | PAL_ERR_INVALID_ARGUMENT |
00669 * | 8  | Call pal_osRandomBuffer with NULL output parameter.                         | PAL_ERR_INVALID_ARGUMENT |
00670 * | 9  | Call pal_osRandomUniform with NULL output parameter.                        | PAL_ERR_INVALID_ARGUMENT |
00671 * | 10 | Call pal_osRandomBuffer while pal is not initialized.                       | PAL_ERR_NOT_INITIALIZED  |
00672 */
00673 TEST(pal_rtos, RandomUnityTest)
00674 {
00675     palStatus_t status = PAL_SUCCESS;
00676     uint32_t randomArray[PAL_RANDOM_ARRAY_TEST_SIZE];
00677     struct randBuf randomBufArray[PAL_RANDOM_BUFFER_ARRAY_TEST_SIZE];
00678     uint32_t randomMargin = 0;
00679 
00680     memset(randomArray, 0x0, sizeof(randomArray));
00681     memset(randomBufArray, 0x0, sizeof(randomBufArray));
00682     /*#1*/
00683     for(int i = 0; i < PAL_RANDOM_ARRAY_TEST_SIZE ; ++i)
00684     {
00685         status = pal_osRandom32bit(&randomArray[i]);
00686         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00687     }
00688     /*#2*/
00689     for(int k = 0; k < PAL_RANDOM_ARRAY_TEST_SIZE ; ++k)
00690     {
00691         for (int j = k+1 ; j < PAL_RANDOM_ARRAY_TEST_SIZE ; ++j)
00692         {
00693             if (randomArray[k] == randomArray[j])
00694             {
00695                 ++randomMargin;
00696             }
00697         }
00698         randomArray[k] = 0;
00699     }
00700     TEST_ASSERT_TRUE(20 >= randomMargin);
00701     randomMargin = 0;
00702     /*#5*/
00703     for (int i = 0; i < PAL_RANDOM_BUFFER_ARRAY_TEST_SIZE ; ++i)
00704     {
00705         status = pal_osRandomBuffer(randomBufArray[i].rand, sizeof(randomBufArray[i].rand));
00706         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00707     }
00708     /*#6*/
00709     for(int k = 0; k < PAL_RANDOM_BUFFER_ARRAY_TEST_SIZE ; ++k)
00710     {
00711         for (int j = k+1 ; j < PAL_RANDOM_BUFFER_ARRAY_TEST_SIZE ; ++j)
00712         {
00713             if(0 == memcmp(randomBufArray[k].rand, randomBufArray[j].rand, sizeof(uint8_t)*6))
00714             {
00715                 ++randomMargin;
00716             }
00717         }
00718     }
00719 
00720     TEST_ASSERT_TRUE(10 >= randomMargin);
00721 
00722 #ifdef DEBUG
00723     /*#7*/
00724     status = pal_osRandom32bit(NULL);
00725     TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status);
00726 
00727     /*#8*/
00728     status = pal_osRandomBuffer(NULL, 0);
00729     TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status);
00730 
00731 
00732 #endif
00733 
00734     /*#10*/
00735     pal_destroy();
00736     status = pal_osRandomBuffer(randomBufArray[0].rand, sizeof(randomBufArray[0].rand));
00737     TEST_ASSERT_EQUAL_HEX(PAL_ERR_NOT_INITIALIZED , status);
00738 }
00739 
00740 
00741 /*! \brief call the random API in a PAL_RANDOM_TEST_LOOP loop.
00742 * | # |    Step                        |   Expected  |
00743 * |---|--------------------------------|-------------|
00744 * | 1 | Call `pal_osRandomBuffer` in a PAL_RANDOM_TEST_LOOP loop .         PAL_SUCCESS |
00745 */
00746 TEST(pal_rtos, loopRandomBigNumber)
00747 {
00748     palStatus_t status = PAL_SUCCESS;
00749     uint8_t loopRandomArray[PAL_RANDOM_ARRAY_TEST_SIZE];
00750 
00751     for (int i = 0; i < PAL_RANDOM_TEST_LOOP; ++i)
00752     {
00753         status = pal_osRandomBuffer(loopRandomArray, sizeof(loopRandomArray));
00754         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00755     }
00756 }
00757 
00758 /*! \brief Verify that PAL can handle multiple calls for `pal_init()` and `pal_destroy()`.
00759 *
00760 * | # |    Step                                              |   Expected  |
00761 * |---|------------------------------------------------------|-------------|
00762 * | 1 | Call `pal_init`.                                     | PAL_SUCCESS |
00763 * | 2 | Call `pal_init`.                                     | PAL_SUCCESS |
00764 * | 3 | Call `pal_init`.                                     | PAL_SUCCESS |
00765 * | 4 | Call `pal_destroy` in a loop untill init count == 0. | PAL_SUCCESS |
00766 * | 5 | Call `pal_init`.                                     | PAL_SUCCESS |
00767 * | 6 | Call `pal_RTOSInitialize`.                           | PAL_SUCCESS |
00768 * | 7 | Call `pal_destroy`.                                  | PAL_SUCCESS |
00769 */
00770 TEST(pal_rtos, pal_init_test)
00771 {
00772     palStatus_t status = PAL_SUCCESS;
00773     int32_t initCounter = 0;
00774     /*#1*/
00775     status = pal_init();
00776     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00777     /*#2*/
00778     status = pal_init();
00779     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00780     /*#3*/
00781     status = pal_init();
00782     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00783 
00784     /*#4*/
00785     do
00786     {
00787         initCounter = pal_destroy();
00788         //TEST_ASSERT_EQUAL_HEX(0, initCounter);
00789 
00790     }while(initCounter != 0);
00791 
00792     /*#5*/
00793     status = pal_init();
00794     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00795 
00796     status = pal_RTOSInitialize(NULLPTR);
00797     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00798 
00799     /*#7*/
00800     initCounter = pal_destroy();
00801     TEST_ASSERT_EQUAL_HEX(0, initCounter);
00802 }
00803 
00804 /*! \brief Check derivation of keys from the platform's Root of Trust using the KDF algorithm.
00805  *
00806  * 
00807  *
00808 * | # |    Step                        |   Expected  |
00809 * |---|--------------------------------|-------------|
00810 * | 1 | Start a loop to perform the following steps.                                               |  |
00811 * | 2 | Derive a device key for encryption using `pal_osGetDeviceKey`.                   | PAL_SUCCESS |
00812 * | 3 | Derive a device key for signing using `pal_osGetDeviceKey`.                      | PAL_SUCCESS |
00813 * | 4 | Call `pal_osGetDeviceKey` with invalid arguments.                              | PAL_FAILURE |
00814 * | 5 | Call `pal_osGetDeviceKey` with invalid arguments.                              | PAL_FAILURE |
00815 * | 6 | Check that the derived signing and encryption keys are different.                     | PAL_SUCCESS |
00816 * | 7 | Check that all integrations of each type of derivation return the same value.       | PAL_SUCCESS |
00817  */
00818 TEST(pal_rtos, GetDeviceKeyTest_CMAC)
00819 {
00820     palStatus_t status = PAL_SUCCESS;
00821     size_t keyLenBytes = 16;
00822     uint8_t timesToDerive = 4;
00823     unsigned char encKeyDerive[timesToDerive][keyLenBytes]; //16 bytes=128bit
00824     unsigned char signKeyDerive[timesToDerive][keyLenBytes]; //16 bytes=128bit
00825     /*#1*/
00826     for (int i=0; i < timesToDerive; i++)
00827     {
00828         /*#2*/
00829         status = pal_osGetDeviceKey(palOsStorageEncryptionKey128Bit, encKeyDerive[i], keyLenBytes);
00830         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00831         /*#3*/
00832         status = pal_osGetDeviceKey(palOsStorageSignatureKey128Bit ,  signKeyDerive[i], keyLenBytes);
00833         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00834         /*#4*/
00835         status = pal_osGetDeviceKey(palOsStorageSignatureKey128Bit ,  signKeyDerive[i], keyLenBytes-1);
00836         TEST_ASSERT_NOT_EQUAL(PAL_SUCCESS, status);
00837         /*#5*/
00838         status = pal_osGetDeviceKey(palOsStorageSignatureKey128Bit ,  NULL, keyLenBytes);
00839         TEST_ASSERT_NOT_EQUAL(PAL_SUCCESS, status);
00840         /*#6*/
00841         status = memcmp(encKeyDerive[i], signKeyDerive[i], keyLenBytes);
00842         TEST_ASSERT_NOT_EQUAL(status,0); //The keys MUST be different!
00843         /*#7*/
00844         if (i > 0) //Make sure key derivation is persistent every time
00845         {
00846             TEST_ASSERT_EQUAL_MEMORY(encKeyDerive[i-1], encKeyDerive[i], keyLenBytes);
00847             TEST_ASSERT_EQUAL_MEMORY(signKeyDerive[i-1], signKeyDerive[i], keyLenBytes);
00848 
00849         } //if
00850 
00851     } //for
00852 
00853 }
00854 
00855 /*! \brief Check derivation of keys from the platform's Root of Trust using the KDF algorithm.
00856  *
00857  * 
00858  *
00859 * | # |    Step                                                                        | Expected            |
00860 * |---|--------------------------------------------------------------------------------|---------------------|
00861 * | 1 | Start a loop to perform the following steps.                                   |                     |
00862 * | 2 | Derive a device key for encryption using `pal_osGetDeviceKey`.                 | PAL_SUCCESS         |
00863 * | 3 | Call `pal_osGetDeviceKey` with invalid arguments.                              | PAL_FAILURE         |
00864 * | 4 | Call `pal_osGetDeviceKey` with invalid arguments.                              | PAL_FAILURE         |
00865 * | 5 | Check that all integrations of each type of derivation return the same value.  | PAL_SUCCESS         |
00866 * | 6 | Call `pal_osGetDeviceKey` with invalid palDevKeyType_t.                        | PAL_ERR_GET_DEV_KEY |
00867  */
00868 TEST(pal_rtos, GetDeviceKeyTest_HMAC_SHA256)
00869 {
00870     palStatus_t status = PAL_SUCCESS;
00871     size_t keyLenBytes = 32;
00872     uint8_t timesToDerive = 4;
00873     unsigned char encKeyDerive[timesToDerive][keyLenBytes]; //32 bytes=256bit
00874     /*#1*/
00875     for (int i=0; i < timesToDerive; i++)
00876     {
00877         /*#2*/
00878         status = pal_osGetDeviceKey(palOsStorageHmacSha256 , encKeyDerive[i], keyLenBytes);
00879         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00880 #ifdef DEBUG
00881         /*#3*/
00882         status = pal_osGetDeviceKey(palOsStorageHmacSha256 ,  encKeyDerive[i], keyLenBytes-1);
00883         TEST_ASSERT_NOT_EQUAL(PAL_SUCCESS, status);
00884         /*#4*/
00885         status = pal_osGetDeviceKey(palOsStorageHmacSha256 ,  NULL, keyLenBytes);
00886         TEST_ASSERT_NOT_EQUAL(PAL_SUCCESS, status);
00887 #endif
00888         /*#5*/
00889         if (i > 0) //Make sure key derivation is persistent every time
00890         {
00891             TEST_ASSERT_EQUAL_MEMORY(encKeyDerive[i-1], encKeyDerive[i], keyLenBytes);
00892         } //if
00893 
00894     } //for
00895 
00896 #ifdef DEBUG
00897       /*#6*/
00898     status = pal_osGetDeviceKey((palDevKeyType_t)999, encKeyDerive[0], keyLenBytes);
00899     TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status);
00900 #endif
00901 }
00902 
00903 /*! \brief Check the APIs `pal_osSetTime()` and `pal_osGetTime()` with different scenarios
00904 * for valid and non-valid scenarios and epoch values.
00905 * The test also checks that the time increases.
00906 *
00907 * | # |    Step                        |   Expected  |
00908 * |---|--------------------------------|-------------|
00909 * | 1 | Start a loop for the following steps.                                                | PAL_SUCCESS |
00910 * | 2 | Set time to invalid value using `pal_osSetTime`.                                 | PAL_ERR_INVALID_TIME |
00911 * | 3 | Get time using `pal_osGetTime`.                                                  | PAL_SUCCESS |
00912 * | 4 | Set time to valid value using `pal_osSetTime`.                                   | PAL_SUCCESS |
00913 * | 5 | Sleep.                                                                         | PAL_SUCCESS |
00914 * | 6 | Get time using `pal_osGetTime` and check that it equals set time + sleep time.   | PAL_SUCCESS |
00915 */
00916 TEST(pal_rtos, RealTimeClockTest1)
00917 {
00918     palStatus_t status;
00919     uint64_t curTime = 0;
00920     uint64_t lastTimeSeen = 0;
00921     const uint64_t minSecSinceEpoch = PAL_MIN_SEC_FROM_EPOCH + 1; //At least 47 years passed from 1.1.1970 in seconds
00922 
00923     /*#1*/
00924     for (int i=0; i < 2; i++)
00925     {
00926     /*#2*/
00927         status = pal_osSetTime(3);
00928         TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_TIME , status); // Less than current epoch time -> error
00929 
00930     /*#3*/
00931         curTime = pal_osGetTime();
00932         TEST_ASSERT_TRUE(lastTimeSeen <= curTime); //Time was not previously set; 0 is acceptable
00933     /*#4*/
00934         status = pal_osSetTime(minSecSinceEpoch);
00935         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); // More than current epoch time -> success
00936     /*#5*/
00937         int milliDelay = 1500;
00938         pal_osDelay(milliDelay); //500 milliseconds
00939     /*#6*/
00940         curTime = pal_osGetTime();
00941         TEST_ASSERT_TRUE(curTime > minSecSinceEpoch);
00942         TEST_ASSERT_TRUE(curTime <= minSecSinceEpoch+(int)ceil((float)milliDelay/1000));
00943         lastTimeSeen = curTime;
00944     }
00945 }
00946 
00947 
00948 /*! \brief Check recursive mutex behavior.
00949 *
00950 * | # |    Step                        |   Expected  |
00951 * |---|--------------------------------|-------------|
00952 * | 1 | Create a mutex using `pal_osMutexCreate`.                                             | PAL_SUCCESS |
00953 * | 2 | Create a semaphore using `pal_osSemaphoreCreate`.                                     | PAL_SUCCESS |
00954 * | 3 | Create a thread running `RecursiveLockThread` using `pal_osThreadCreateWithAlloc`.       | PAL_SUCCESS |
00955 * | 4 | Create a thread running `RecursiveLockThread` using `pal_osThreadCreateWithAlloc`.       | PAL_SUCCESS |
00956 * | 5 | Release the semaphore using `pal_osSemaphoreRelease`.                                    | PAL_SUCCESS |
00957 * | 6 | Release the semaphore using `pal_osSemaphoreRelease`.                                    | PAL_SUCCESS |
00958 * | 7 | Sleep for a short interval.                                                          | PAL_SUCCESS |
00959 * | 8 | Wait for the semaphore using `pal_osSemaphoreWait`.                                      | PAL_SUCCESS |
00960 * | 9 | Wait for the semaphore using `pal_osSemaphoreWait`.                                      | PAL_SUCCESS |
00961 * | 10 | Terminate the first thread using `pal_osThreadTerminate`.                               | PAL_SUCCESS |
00962 * | 11 | Terminate the second thread using `pal_osThreadTerminate`.                              | PAL_SUCCESS |
00963 * | 12 | Delete the mutex using `pal_osMutexDelete`.                                           | PAL_SUCCESS |
00964 * | 13 | Delete the semaphore using `pal_osSemaphoreDelete`.                                   | PAL_SUCCESS |
00965 */
00966 TEST(pal_rtos, Recursive_Mutex_Test)
00967 {
00968     palStatus_t status;
00969     int32_t val = 0;
00970 
00971     recursiveMutexData = malloc(sizeof(palRecursiveMutexParam_t));
00972     TEST_ASSERT_NOT_NULL(recursiveMutexData);
00973     memset(recursiveMutexData, 0, sizeof(palRecursiveMutexParam_t));
00974     /*#1*/
00975     status = pal_osMutexCreate(&(recursiveMutexData->mtx));
00976     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00977     /*#2*/
00978     status = pal_osSemaphoreCreate(0, &(recursiveMutexData->sem));
00979     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00980     /*#3*/
00981     status = pal_osThreadCreateWithAlloc(RecursiveLockThread, (void*)recursiveMutexData, PAL_osPriorityHigh , PAL_TEST_THREAD_STACK_SIZE, NULL, &(recursiveMutexData->higherPriorityThread));
00982     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00983     /*#4*/
00984      status = pal_osThreadCreateWithAlloc(RecursiveLockThread, (void*)recursiveMutexData, PAL_osPriorityAboveNormal, PAL_TEST_THREAD_STACK_SIZE, NULL, &(recursiveMutexData->lowerPriorityThread));
00985      TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00986     /*#5*/
00987     status = pal_osSemaphoreRelease(recursiveMutexData->sem);
00988     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00989     /*#6*/
00990     status = pal_osSemaphoreRelease(recursiveMutexData->sem);
00991     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00992     /*#7*/
00993     pal_osDelay(1000);
00994     /*#8*/
00995     status = pal_osSemaphoreWait(recursiveMutexData->sem, PAL_RTOS_WAIT_FOREVER, &val);
00996     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00997     /*#9*/
00998     status = pal_osSemaphoreWait(recursiveMutexData->sem, PAL_RTOS_WAIT_FOREVER, &val);
00999     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01000     TEST_ASSERT_EQUAL(0, val);
01001     TEST_ASSERT_EQUAL_HEX(NULLPTR, recursiveMutexData->activeThread);
01002     /*#10*/
01003     status = pal_osThreadTerminate(&(recursiveMutexData->higherPriorityThread));
01004     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01005     /*#11*/
01006     status = pal_osThreadTerminate(&(recursiveMutexData->lowerPriorityThread));
01007     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01008     /*#12*/
01009     status = pal_osMutexDelete(&(recursiveMutexData->mtx));
01010     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01011     /*#13*/
01012     status = pal_osSemaphoreDelete(&recursiveMutexData->sem);
01013     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01014 
01015     TEST_ASSERT_EQUAL(400, recursiveMutexData->count);
01016 
01017     free(recursiveMutexData);
01018     recursiveMutexData = NULL;
01019 }
01020 
01021 
01022 
01023 /*! \brief Check Weak Set Time - Forword flow.
01024 *
01025 * | # |    Step                        |   Expected  |
01026 * |---|--------------------------------|-------------|
01027 * | 1 | checking RTC and SOTP flow - not set SOTP SAVED TIME  + LAST TIME BACK + RTC to new time                      | PAL_SUCCESS |
01028 * | 2 | checking RTC and SOTP flow - not set SOTP SAVED TIME  + LAST TIME BACK to new time but set RTC to new time    | PAL_SUCCESS |
01029 * | 3 | checking RTC and SOTP flow - set SOTP SAVED TIME  + LAST TIME BACK + RTC to new time                          | PAL_SUCCESS |
01030 */
01031 TEST(pal_rtos, OsWeakSetTime_Forword)
01032 {
01033     palStatus_t status;
01034     sotp_result_e sotpStatus = SOTP_SUCCESS;
01035     uint64_t setTimeInSeconds = 0;
01036     uint64_t curentTimeInSeconds=0;
01037     uint64_t pal_Time = 0;
01038     uint64_t sotpGetTime = 0;
01039     uint16_t actualLenBytes = 0;
01040 
01041 #if (PAL_USE_HW_RTC)
01042     //This code is to preserve system time
01043     uint64_t testStartTime = 0;
01044     status = pal_plat_osGetRtcTime(&testStartTime);
01045 #endif
01046 
01047 
01048     /*#1*/
01049 #if (PAL_USE_HW_RTC)
01050     pal_plat_osSetRtcTime(PAL_MIN_RTC_SET_TIME);
01051 #endif
01052     pal_osSetTime(PAL_MIN_SEC_FROM_EPOCH + PAL_SECONDS_PER_DAY * 100);
01053     curentTimeInSeconds = pal_osGetTime();
01054 
01055     sotpStatus = sotp_set(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t *)&curentTimeInSeconds);
01056     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01057 
01058     sotpStatus = sotp_set(SOTP_TYPE_LAST_TIME_BACK, sizeof(uint64_t), (uint32_t *)&curentTimeInSeconds);
01059     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01060 
01061 #if (PAL_USE_HW_RTC)
01062     uint64_t rtcTime = 0;
01063     status = pal_plat_osSetRtcTime(curentTimeInSeconds);
01064     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01065 #endif//PAL_USE_HW_RTC
01066 
01067     setTimeInSeconds = curentTimeInSeconds + (50 * PAL_ONE_SEC);
01068     status = pal_osSetWeakTime(setTimeInSeconds);
01069 
01070     pal_Time = pal_osGetTime();
01071     if (pal_Time - setTimeInSeconds > 5)
01072     {
01073         status = PAL_ERR_GENERAL_BASE;
01074     }
01075     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01076 #if PAL_USE_INTERNAL_FLASH
01077     sotpStatus = sotp_get(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01078     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01079     TEST_ASSERT_NOT_EQUAL(sotpGetTime, setTimeInSeconds);
01080 
01081     sotpStatus = sotp_get(SOTP_TYPE_LAST_TIME_BACK, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01082     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01083     TEST_ASSERT_NOT_EQUAL(sotpGetTime, setTimeInSeconds);
01084 #endif 
01085 
01086 #if (PAL_USE_HW_RTC)
01087     status = pal_plat_osGetRtcTime(&rtcTime);
01088     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01089     TEST_ASSERT_NOT_EQUAL(rtcTime, setTimeInSeconds);
01090 #endif//PAL_USE_HW_RTC
01091 
01092     /*#2*/
01093     curentTimeInSeconds = pal_osGetTime();
01094 #if (PAL_USE_HW_RTC)
01095     pal_plat_osSetRtcTime(curentTimeInSeconds);
01096 #endif//PAL_USE_HW_RTC
01097     
01098     setTimeInSeconds = curentTimeInSeconds+(200 * PAL_ONE_SEC);
01099 
01100     status = pal_osSetWeakTime(setTimeInSeconds);
01101     pal_Time = pal_osGetTime();
01102     if (pal_Time - setTimeInSeconds > 5)
01103     {
01104         status = PAL_ERR_GENERAL_BASE;
01105     }
01106     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01107 
01108 #if PAL_USE_INTERNAL_FLASH
01109     sotpStatus = sotp_get(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01110     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01111     TEST_ASSERT_NOT_EQUAL(sotpGetTime, setTimeInSeconds);
01112 
01113     sotpStatus = sotp_get(SOTP_TYPE_LAST_TIME_BACK, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01114     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01115     TEST_ASSERT_NOT_EQUAL(sotpGetTime, setTimeInSeconds);
01116 #endif
01117 
01118 #if (PAL_USE_HW_RTC)
01119     status = pal_plat_osGetRtcTime(&rtcTime);
01120     TEST_ASSERT_EQUAL_UINT64(rtcTime, setTimeInSeconds);
01121 #endif//PAL_USE_HW_RTC
01122 
01123     /*#3*/
01124     curentTimeInSeconds = pal_osGetTime();
01125     sotpStatus = sotp_set(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t *)&curentTimeInSeconds);
01126     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01127 
01128     sotpStatus = sotp_set(SOTP_TYPE_LAST_TIME_BACK, sizeof(uint64_t), (uint32_t *)&curentTimeInSeconds);
01129     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01130 
01131 #if (PAL_USE_HW_RTC)
01132     status = pal_plat_osSetRtcTime(curentTimeInSeconds);
01133     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01134 #endif//PAL_USE_HW_RTC
01135 
01136     setTimeInSeconds = curentTimeInSeconds + PAL_MINIMUM_SOTP_FORWARD_LATENCY_SEC + (100 * PAL_ONE_SEC);
01137     status = pal_osSetWeakTime(setTimeInSeconds);
01138     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01139 
01140 #if PAL_USE_INTERNAL_FLASH
01141     sotpStatus = sotp_get(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01142     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01143     TEST_ASSERT_EQUAL_UINT64(sotpGetTime, setTimeInSeconds);
01144 #endif
01145 
01146 #if (PAL_USE_HW_RTC)
01147     status = pal_plat_osGetRtcTime(&rtcTime);
01148     TEST_ASSERT_EQUAL_UINT64(rtcTime, setTimeInSeconds);
01149 #endif//PAL_USE_HW_RTC
01150 
01151 #if (PAL_USE_HW_RTC)
01152     //restore System time
01153     pal_plat_osSetRtcTime(testStartTime + PAL_RUNNING_TEST_TIME);
01154 #endif
01155 }
01156 
01157 /*! \brief Check Weak Set Time - Backword flow.
01158 *
01159 * | # |    Step                        |   Expected  |
01160 * |---|--------------------------------|-------------|
01161 * | 1 | checking SOTP flow - set SOTP SAVED TIME and LAST TIME BACK to new time         | PAL_SUCCESS |
01162 * | 2 | checking SOTP flow - not set SOTP SAVED TIME and LAST TIME BACK to new time     | PAL_SUCCESS |
01163 */
01164 TEST(pal_rtos, OsWeakSetTime_Backword)
01165 {
01166     uint64_t setTimeInSeconds = 0;
01167     uint64_t curentTimeInSeconds = 0;
01168     palStatus_t status;
01169     sotp_result_e sotpStatus = SOTP_SUCCESS;
01170     uint64_t getTimeValueBackword = 0;
01171     uint64_t pal_Time = 0;
01172 #if (PAL_USE_HW_RTC)
01173     //This code is to preserve system time
01174     uint64_t testStartTime = 0;
01175     status = pal_plat_osGetRtcTime(&testStartTime);
01176 #endif
01177 
01178     /*#1*/
01179 #if (PAL_USE_HW_RTC)
01180     pal_plat_osSetRtcTime(PAL_MIN_RTC_SET_TIME);
01181     pal_osSetTime(PAL_MIN_SEC_FROM_EPOCH + PAL_SECONDS_PER_DAY * 100);
01182 #endif
01183     curentTimeInSeconds = pal_osGetTime();
01184 
01185     getTimeValueBackword = curentTimeInSeconds - (3 * PAL_MINIMUM_SOTP_FORWARD_LATENCY_SEC);
01186     sotpStatus = sotp_set(SOTP_TYPE_LAST_TIME_BACK, sizeof(uint64_t), (uint32_t *)&getTimeValueBackword);
01187     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01188 
01189 
01190     setTimeInSeconds = curentTimeInSeconds - (6 * PAL_SECONDS_PER_MIN);
01191     status = pal_osSetWeakTime(setTimeInSeconds);
01192 
01193     pal_Time = pal_osGetTime();
01194     if (pal_Time - setTimeInSeconds > 5)
01195     {
01196         status = PAL_ERR_GENERAL_BASE;
01197     }
01198     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01199 
01200     uint64_t sotpGetTime = 0;
01201     uint16_t actualLenBytes = 0;
01202 
01203 #if PAL_USE_INTERNAL_FLASH
01204     sotpStatus = sotp_get(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01205     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01206     TEST_ASSERT_EQUAL_UINT64(sotpGetTime, setTimeInSeconds);
01207 
01208     sotpStatus = sotp_get(SOTP_TYPE_LAST_TIME_BACK, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01209     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01210     TEST_ASSERT_EQUAL_UINT64(sotpGetTime, setTimeInSeconds);
01211 #endif
01212 
01213     /*#2*/
01214     curentTimeInSeconds = pal_osGetTime();
01215     getTimeValueBackword = curentTimeInSeconds - (3 * PAL_MINIMUM_SOTP_FORWARD_LATENCY_SEC);
01216     sotpStatus = sotp_set(SOTP_TYPE_LAST_TIME_BACK, sizeof(uint64_t), (uint32_t *)&getTimeValueBackword);
01217     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01218 
01219     sotpStatus = sotp_set(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t *)&getTimeValueBackword);
01220     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01221 
01222     setTimeInSeconds = curentTimeInSeconds - (12 * PAL_SECONDS_PER_MIN);
01223 
01224     status = pal_osSetWeakTime(setTimeInSeconds);
01225     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01226 
01227 #if PAL_USE_INTERNAL_FLASH
01228     sotpStatus = sotp_get(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01229     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01230     TEST_ASSERT_NOT_EQUAL(sotpGetTime, setTimeInSeconds);
01231     sotpStatus = sotp_get(SOTP_TYPE_LAST_TIME_BACK, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01232     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01233     TEST_ASSERT_NOT_EQUAL(sotpGetTime, setTimeInSeconds);
01234 #endif
01235 
01236 #if (PAL_USE_HW_RTC)
01237     //restore System time
01238     pal_plat_osSetRtcTime(testStartTime + PAL_RUNNING_TEST_TIME);
01239 #endif
01240 }
01241 
01242 /*! \brief Weak Strong Set Time- minimalStoredLag flow.
01243 *
01244 * | # |    Step                        |   Expected  |
01245 * |---|--------------------------------|-------------|
01246 * | 1 | checking SOTP flow- set SOTP SAVED TIME to new time                         | PAL_SUCCESS |
01247 * | 2 | checking SOTP flow- not set SOTP SAVED TIME to new time                     | PAL_SUCCESS |
01248 */
01249 TEST(pal_rtos, OsWeakSetTime_minimalStoredLag)
01250 {
01251     palStatus_t status;
01252     sotp_result_e sotpStatus = SOTP_SUCCESS;
01253     uint64_t setTimeInSeconds = 0;
01254     uint64_t curentTimeInSeconds = 0;
01255     uint64_t sotpGetTime = 0;
01256     uint16_t actualLenBytes = 0;
01257     uint64_t setSotpTimeValue = 0;
01258     
01259 #if (PAL_USE_HW_RTC)
01260     //This code is to preserve system time
01261     uint64_t testStartTime = 0;
01262     status = pal_plat_osGetRtcTime(&testStartTime);
01263 #endif
01264 
01265     /*#1*/
01266 #if (PAL_USE_HW_RTC)
01267     pal_plat_osSetRtcTime(PAL_MIN_RTC_SET_TIME);
01268 #endif
01269     pal_osSetTime(PAL_MIN_SEC_FROM_EPOCH + PAL_SECONDS_PER_DAY * 100);
01270     curentTimeInSeconds = pal_osGetTime();
01271     setTimeInSeconds = curentTimeInSeconds;
01272 
01273     setSotpTimeValue = curentTimeInSeconds - (PAL_MINIMUM_STORAGE_LATENCY_SEC + 50);
01274     sotpStatus = sotp_set(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t *)&setSotpTimeValue);
01275     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01276 
01277     status = pal_osSetWeakTime(setTimeInSeconds);
01278     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01279 
01280 #if PAL_USE_INTERNAL_FLASH
01281     sotpStatus = sotp_get(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01282     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01283     TEST_ASSERT_EQUAL_UINT64(sotpGetTime, setTimeInSeconds);
01284 #endif
01285 
01286     /*#2*/
01287     curentTimeInSeconds = pal_osGetTime();
01288     setTimeInSeconds = curentTimeInSeconds - 50;
01289 
01290     setSotpTimeValue = curentTimeInSeconds;
01291     sotpStatus = sotp_set(SOTP_TYPE_LAST_TIME_BACK, sizeof(uint64_t), (uint32_t *)&setSotpTimeValue);
01292     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01293 
01294     status = pal_osSetWeakTime(setTimeInSeconds);
01295     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01296     
01297 #if PAL_USE_INTERNAL_FLASH
01298     sotpStatus = sotp_get(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01299     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01300     TEST_ASSERT_NOT_EQUAL(sotpGetTime, setTimeInSeconds);
01301 #endif
01302 
01303 #if (PAL_USE_HW_RTC)
01304     //restore System time
01305     pal_plat_osSetRtcTime(testStartTime + PAL_RUNNING_TEST_TIME);
01306 #endif
01307 }
01308 
01309 /*! \brief Check Strong Set Time.
01310 *
01311 * | # |    Step                        |   Expected  |
01312 * |---|--------------------------------|-------------|
01313 * | 1 | checking RTC flow - set new RTC time                                            | PAL_SUCCESS |
01314 * | 2 | checking RTC flow - not set RTC new time                                        | PAL_SUCCESS |
01315 * | 3 | checking SOTP flow - set SOTP SAVED TIME and LAST TIME BACK to new time         | PAL_SUCCESS |
01316 * | 4 | checking SOTP flow - not set SOTP SAVED TIME and LAST TIME BACK to new time       | PAL_SUCCESS |
01317 */
01318 TEST(pal_rtos, OsStrongSetTime)
01319 {
01320     palStatus_t status;
01321     sotp_result_e sotpStatus = SOTP_SUCCESS;
01322     uint64_t setTimeInSeconds = 0;
01323     uint64_t curentTimeInSeconds = 0;
01324     uint64_t pal_Time = 0;
01325     uint64_t sotpGetTime = 0;
01326     uint16_t actualLenBytes = 0;
01327     uint64_t setSotpTimeValue = 0;
01328 
01329 #if (PAL_USE_HW_RTC)
01330     //This code is to preserve system time
01331     uint64_t testStartTime = 0;
01332     status = pal_plat_osGetRtcTime(&testStartTime);
01333 #endif
01334 
01335     /*#1*/
01336 #if (PAL_USE_HW_RTC)
01337     pal_plat_osSetRtcTime(PAL_MIN_RTC_SET_TIME);
01338 #endif
01339     pal_osSetTime(PAL_MIN_SEC_FROM_EPOCH + PAL_SECONDS_PER_DAY * 100);
01340     curentTimeInSeconds = pal_osGetTime();
01341     setTimeInSeconds = curentTimeInSeconds;
01342 
01343 #if (PAL_USE_HW_RTC)
01344     uint64_t rtcTime = 0;
01345     rtcTime = curentTimeInSeconds - (50 + PAL_MINIMUM_RTC_LATENCY_SEC);
01346     status = pal_plat_osSetRtcTime(rtcTime);
01347     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01348 #endif//PAL_USE_HW_RTC
01349 
01350     status = pal_osSetStrongTime(setTimeInSeconds);
01351     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01352 
01353 #if (PAL_USE_HW_RTC)
01354     status = pal_plat_osGetRtcTime(&rtcTime);
01355     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01356     TEST_ASSERT_EQUAL_UINT64(rtcTime, setTimeInSeconds);
01357 #endif//PAL_USE_HW_RTC
01358 
01359     pal_Time = pal_osGetTime();
01360     if (pal_Time - setTimeInSeconds > 5)
01361     {
01362         status = PAL_ERR_GENERAL_BASE;
01363     }
01364     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01365 
01366     /*#2*/
01367     curentTimeInSeconds = pal_osGetTime();
01368     setTimeInSeconds = curentTimeInSeconds;
01369 
01370 #if (PAL_USE_HW_RTC)
01371     rtcTime = curentTimeInSeconds;
01372     status = pal_plat_osSetRtcTime(rtcTime - 50);
01373     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01374 #endif//PAL_USE_HW_RTC
01375 
01376     status = pal_osSetStrongTime(setTimeInSeconds);
01377 
01378 #if (PAL_USE_HW_RTC)
01379     status = pal_plat_osGetRtcTime(&rtcTime);
01380     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01381     TEST_ASSERT_NOT_EQUAL(rtcTime, setTimeInSeconds);
01382 #endif//PAL_USE_HW_RTC
01383 
01384     pal_Time = pal_osGetTime();
01385     if (pal_Time - setTimeInSeconds > 5){
01386         status = PAL_ERR_GENERAL_BASE;
01387     }
01388     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01389 
01390     /*#3*/
01391     curentTimeInSeconds = pal_osGetTime();
01392     setTimeInSeconds = curentTimeInSeconds;
01393     setSotpTimeValue = curentTimeInSeconds - (PAL_MINIMUM_SOTP_FORWARD_LATENCY_SEC + 1*PAL_ONE_SEC);
01394     sotpStatus = sotp_set(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t *)&setSotpTimeValue);
01395     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01396 
01397     status = pal_osSetStrongTime(setTimeInSeconds);
01398     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01399 
01400 #if PAL_USE_INTERNAL_FLASH
01401     sotpStatus = sotp_get(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01402     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01403     TEST_ASSERT_EQUAL_UINT64(sotpGetTime, setTimeInSeconds);
01404 
01405     sotpStatus = sotp_get(SOTP_TYPE_LAST_TIME_BACK, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01406     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01407     TEST_ASSERT_EQUAL_UINT64(sotpGetTime, setTimeInSeconds);
01408 #endif
01409 
01410     pal_Time = pal_osGetTime();
01411     if (pal_Time - setTimeInSeconds > 5)
01412     {
01413         status = PAL_ERR_GENERAL_BASE;
01414     }
01415     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01416 
01417     /*#4*/
01418     curentTimeInSeconds = pal_osGetTime();
01419     setTimeInSeconds = curentTimeInSeconds;
01420 
01421     setSotpTimeValue = curentTimeInSeconds - 5;
01422     sotpStatus = sotp_set(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t *)&setSotpTimeValue);
01423     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01424 
01425     sotpStatus = sotp_set(SOTP_TYPE_LAST_TIME_BACK, sizeof(uint64_t), (uint32_t *)&setSotpTimeValue);
01426     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01427 
01428     status = pal_osSetStrongTime(setTimeInSeconds);
01429     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01430 
01431 #if PAL_USE_INTERNAL_FLASH
01432     sotpStatus = sotp_get(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01433     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01434     TEST_ASSERT_NOT_EQUAL(sotpGetTime, setTimeInSeconds);
01435 
01436     sotpStatus = sotp_get(SOTP_TYPE_LAST_TIME_BACK, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01437     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01438     TEST_ASSERT_NOT_EQUAL(sotpGetTime, setTimeInSeconds);
01439 #endif
01440 
01441     pal_Time = pal_osGetTime();
01442     if (pal_Time - setTimeInSeconds > 5)
01443     {
01444         status = PAL_ERR_GENERAL_BASE;
01445     }
01446     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01447 
01448 #if (PAL_USE_HW_RTC)
01449     //restore System time
01450     pal_plat_osSetRtcTime(testStartTime + PAL_RUNNING_TEST_TIME);
01451 #endif
01452 }
01453 
01454 
01455 /*! \brief This test verify the functionality of the RTC
01456  *
01457  * | # |    Step                        |   Expected  |
01458  * |---|--------------------------------|-------------|
01459  * | 1 | Get system RTC                           | PAL_SUCCESS |
01460  * | 2 | set new RTC                              | PAL_SUCCESS |
01461  * | 3 | delay for 2 seconds                      | PAL_SUCCESS |
01462  * | 4 | get RTC & compare to RTC from (2)        | PAL_SUCCESS |
01463  * | 5 | restore system time from (1)             | PAL_SUCCESS |
01464  */
01465 TEST(pal_rtos, pal_rtc)
01466 {
01467 #if (PAL_USE_HW_RTC)
01468     palStatus_t status = PAL_SUCCESS;
01469     uint64_t time1 = 0, sysTime = 0;
01470 
01471     /*#1*/
01472     status = pal_plat_osGetRtcTime(&sysTime);
01473     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01474 
01475     /*#2*/
01476     status = pal_plat_osSetRtcTime(PAL_MIN_RTC_SET_TIME);
01477     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01478 
01479     /*#3*/
01480     status = pal_osDelay(2000);
01481     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01482 
01483     /*#4*/
01484     status = pal_plat_osGetRtcTime(&time1);
01485     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01486     TEST_ASSERT_TRUE(time1 - PAL_MIN_RTC_SET_TIME >=  1 * PAL_ONE_SEC);
01487 
01488     /*#5*/
01489     pal_plat_osSetRtcTime(sysTime + time1 - PAL_MIN_RTC_SET_TIME  + 1); //add lost time from delay
01490 
01491 
01492 #endif
01493 }
01494 
01495 // the following functions are not part of PAL's external API hence extern
01496 extern palStatus_t pal_noiseWriteValue(const int32_t* data, uint8_t startBit, uint8_t lenBits, uint8_t* bitsWritten);
01497 extern palStatus_t pal_noiseWriteBuffer(int32_t* buffer, uint16_t lenBits, uint16_t* bitsWritten);
01498 extern palStatus_t pal_noiseRead(int32_t buffer[PAL_NOISE_BUFFER_LEN], bool partial, uint16_t* bitsRead);
01499 
01500 /*! \brief This test verifies the functionality of noise collection
01501 *
01502 * | # |    Step                                                                                    |   Expected  |
01503 * |---|--------------------------------------------------------------------------------------------|-------------|
01504 * | 1 | Reset the noise buffer by reading watever is available                                     | PAL_SUCCESS |
01505 * | 2 | Write an entire int32_t (all bits) and verify writes and that full read not possible       | PAL_SUCCESS |
01506 * | 3 | Write only some bits of the int32_t and verify writes and that full read not possible      | PAL_SUCCESS |
01507 * | 4 | Write only some bits of the int32_t, implicitly causing splitting the value into 2 indexes | PAL_SUCCESS |
01508 * | 5 | Read whatever was collected thus far (partial read) and verify output                      | PAL_SUCCESS |
01509 * | 6 | Try to read again and verify buffer is empty                                               | PAL_SUCCESS |
01510 * | 7 | Write a buffer excluding the last 7 bits of the last index and verify results              | PAL_SUCCESS |
01511 * | 8 | Fill the buffer and try to write some more data into it                                    | PAL_SUCCESS |
01512 */
01513 TEST(pal_rtos, pal_noise)
01514 {
01515     palStatus_t status;
01516     int32_t outBuffer[PAL_NOISE_BUFFER_LEN] = { 0 };
01517     int32_t inBuffer[] = { 0xB76EC265, 0xD16ACE6E, 0xF56AAD6A };
01518     uint16_t bitsWritten = 0;
01519     uint16_t bitsRead = 0;
01520     int32_t writeValue;
01521     uint8_t i;
01522 
01523     /*#1*/
01524     pal_noiseRead(outBuffer, true, &bitsRead);
01525     memset(outBuffer, 0, PAL_NOISE_SIZE_BYTES);
01526 
01527     /*#2*/
01528     writeValue = 0xCB76102A;
01529     status = pal_noiseWriteValue(&writeValue, 0, 32, (uint8_t*)&bitsWritten); // write all bits
01530     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01531     TEST_ASSERT_EQUAL(32, bitsWritten);
01532     status = pal_noiseRead(outBuffer, false, &bitsRead);
01533     TEST_ASSERT_EQUAL_HEX(PAL_ERR_RTOS_NOISE_BUFFER_NOT_FULL , status);
01534     TEST_ASSERT_EQUAL(0, bitsRead);
01535 
01536     /*#3*/
01537     status = pal_noiseWriteValue(&writeValue, 3, 20, (uint8_t*)&bitsWritten); // write some of the bits, starting at bit index 3
01538     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01539     TEST_ASSERT_EQUAL(20, bitsWritten);
01540     status = pal_noiseRead(outBuffer, false, &bitsRead);
01541     TEST_ASSERT_EQUAL_HEX(PAL_ERR_RTOS_NOISE_BUFFER_NOT_FULL , status);
01542     TEST_ASSERT_EQUAL(0, bitsRead);
01543 
01544     /*#4*/
01545     status = pal_noiseWriteValue(&writeValue, 16, 16, (uint8_t*)&bitsWritten); // write some of the bits, starting at bit index 16, this functionality tests splitting the bits into 2 different indexes
01546     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01547     TEST_ASSERT_EQUAL(16, bitsWritten);
01548     status = pal_noiseRead(outBuffer, false, &bitsRead);
01549     TEST_ASSERT_EQUAL_HEX(PAL_ERR_RTOS_NOISE_BUFFER_NOT_FULL , status);
01550     TEST_ASSERT_EQUAL(0, bitsRead);
01551 
01552     /*#5*/
01553     status = pal_noiseRead(outBuffer, true, &bitsRead); // read whatever collected (resets buffer)
01554     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01555     TEST_ASSERT_EQUAL(64, bitsRead); // even though we wrote 68 bits by now, output should be 64 since the last byte is not full so we should not receive it back
01556     TEST_ASSERT_EQUAL_HEX(0xCB76102A, outBuffer[0]);
01557     TEST_ASSERT_EQUAL_HEX(0xB76EC205, outBuffer[1]);
01558     TEST_ASSERT_EQUAL_HEX(0, outBuffer[2]);
01559     memset(outBuffer, 0, PAL_NOISE_SIZE_BYTES);
01560 
01561     /*#6*/
01562     status = pal_noiseRead(outBuffer, false, &bitsRead);
01563     TEST_ASSERT_EQUAL_HEX(PAL_ERR_RTOS_NOISE_BUFFER_EMPTY , status);
01564     TEST_ASSERT_EQUAL(0, bitsRead);
01565 
01566     /*#7*/
01567     status = pal_noiseWriteBuffer(inBuffer, ((sizeof(inBuffer) * CHAR_BIT) - 7), &bitsWritten); // write all except for the last 7 bits of index 2
01568     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01569     TEST_ASSERT_EQUAL(((sizeof(inBuffer) * CHAR_BIT) - 7), bitsWritten);
01570     status = pal_noiseRead(outBuffer, false, &bitsRead);
01571     TEST_ASSERT_EQUAL_HEX(PAL_ERR_RTOS_NOISE_BUFFER_NOT_FULL , status);
01572     TEST_ASSERT_EQUAL(0, bitsRead);
01573     status = pal_noiseRead(outBuffer, true, &bitsRead); // read whatever collected (resets buffer)
01574     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01575     TEST_ASSERT_NOT_EQUAL(0, bitsRead);
01576     TEST_ASSERT_EQUAL_HEX(inBuffer[0], outBuffer[0]);
01577     TEST_ASSERT_EQUAL_HEX(inBuffer[1], outBuffer[1]);
01578     TEST_ASSERT_EQUAL_HEX(0x6AAD6A, outBuffer[2]);
01579 
01580     /*#8*/
01581     for (i = 0; i <= (sizeof(inBuffer) / sizeof(int32_t)); ++i)
01582     {
01583         status = pal_noiseWriteBuffer(inBuffer, (sizeof(inBuffer) * CHAR_BIT), &bitsWritten);
01584         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01585         TEST_ASSERT_EQUAL_HEX((sizeof(inBuffer) * CHAR_BIT), bitsWritten);
01586     }
01587     status = pal_noiseWriteBuffer(inBuffer, (sizeof(inBuffer) * CHAR_BIT), &bitsWritten);
01588     TEST_ASSERT_EQUAL_HEX(PAL_ERR_RTOS_NOISE_BUFFER_FULL , status);
01589     TEST_ASSERT_EQUAL_HEX(0, bitsWritten);
01590 }