Simple interface for Mbed Cloud Client

Dependents:  

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 palThreadLocalStore_t g_threadStorage = {NULL};
00033 threadsArgument_t g_threadsArg = {0};
00034 timerArgument_t g_timerArgs = {0};
00035 palMutexID_t mutex1 = NULLPTR;
00036 palMutexID_t mutex2 = NULLPTR;
00037 palSemaphoreID_t semaphore1 = NULLPTR;
00038 palRecursiveMutexParam_t* recursiveMutexData = NULL;
00039 #define PAL_RUNNING_TEST_TIME   5  //estimation on length of test in seconds
00040 #define PAL_TEST_HIGH_RES_TIMER 100
00041 #define PAL_TEST_HIGH_RES_TIMER2 10
00042 #define PAL_TEST_PERCENTAGE_LOW 95
00043 #define PAL_TEST_PERCENTAGE_HIGH 105
00044 #define PAL_TEST_PERCENTAGE_HUNDRED  100
00045 
00046 //Forward declarations
00047 void palRunThreads(void);
00048 
00049 
00050 TEST_SETUP(pal_rtos)
00051 {
00052     palStatus_t status = PAL_SUCCESS;
00053     status = pal_init();
00054     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00055 
00056 }
00057 
00058 TEST_TEAR_DOWN(pal_rtos)
00059 {
00060     if (NULL != recursiveMutexData)
00061     {
00062         if (recursiveMutexData->higherPriorityThread != NULLPTR)
00063         {
00064             pal_osThreadTerminate(&(recursiveMutexData->higherPriorityThread));
00065         }
00066         if (recursiveMutexData->lowerPriorityThread != NULLPTR)
00067         {
00068             pal_osThreadTerminate(&(recursiveMutexData->lowerPriorityThread));
00069         }
00070         if (recursiveMutexData->mtx != NULLPTR)
00071         {
00072             pal_osMutexDelete(&(recursiveMutexData->mtx));
00073         }
00074         if (recursiveMutexData->sem != NULLPTR)
00075         {
00076             pal_osSemaphoreDelete(&recursiveMutexData->sem);
00077         }
00078         free(recursiveMutexData);
00079         recursiveMutexData = NULL;
00080     }
00081     pal_destroy();
00082 }
00083 
00084 /*! \brief Sanity check of the kernel system tick API.
00085  * Fails if system tic value is zero (**note:** this can sometimes happen on wrap-around).
00086  *
00087  * | # |    Step                        |   Expected  |
00088  * |---|--------------------------------|-------------|
00089  * | 1 | Get current tick count using `pal_osKernelSysTick` and check that it is not 0.  | PAL_SUCCESS |
00090  */
00091 TEST(pal_rtos, pal_osKernelSysTick_Unity)
00092 {
00093     uint32_t tick1 = 0, tick2 = 0;
00094     /*#1*/
00095     tick1 = pal_osKernelSysTick();
00096     PAL_PRINTF("%" PRIu32 " %" PRIu32 "\n", tick1, tick2);
00097 
00098     TEST_ASSERT_TRUE(tick2 != tick1);
00099 }
00100 
00101 /*! \brief Sanity check of the kernel system tick API.
00102  * Fails if two calls return the same `sysTick` value.
00103  *
00104  * | # |    Step                        |   Expected  |
00105  * |---|--------------------------------|-------------|
00106  * | 1 | Get current tick count using `pal_osKernelSysTick`.       | PAL_SUCCESS |
00107  * | 2 | Get current tick count using `pal_osKernelSysTick`.       | PAL_SUCCESS |
00108  * | 3 | Check that the two tick count values are not the same. | PAL_SUCCESS |
00109  */
00110 TEST(pal_rtos, pal_osKernelSysTick64_Unity)
00111 {
00112     uint64_t tick1 = 0, tick2 = 0;
00113     /*#1*/
00114     tick1 = pal_osKernelSysTick();
00115     /*#2*/
00116     tick2 = pal_osKernelSysTick();
00117     /*#3*/
00118     TEST_ASSERT_TRUE(tick2 >= tick1);
00119 }
00120 
00121 /*! \brief Check the conversion from a non-zero `sysTick` value to microseconds.
00122  * Verify that the result is not 0.
00123  *
00124  * | # |    Step                        |   Expected  |
00125  * |---|--------------------------------|-------------|
00126  * | 1 | Convert a nubmer in `sysTicks` to microseconds using `pal_osKernelSysTickMicroSec` and check it is not 0. | PAL_SUCCESS |
00127  */
00128 TEST(pal_rtos, pal_osKernelSysTickMicroSec_Unity)
00129 {
00130     uint64_t tick = 0;
00131     uint64_t microSec = 2000 * 1000;
00132     /*#1*/
00133     tick = pal_osKernelSysTickMicroSec(microSec);
00134     TEST_ASSERT_TRUE(0 != tick);
00135 }
00136 
00137 /*! \brief Sanity check of non-zero values conversion between microseconds to ticks to milliseconds.
00138  * Verify that the result is correct when converting the input (microseconds) to the test output (milliseconds).
00139  *
00140  * | # |    Step                        |   Expected  |
00141  * |---|--------------------------------|-------------|
00142  * | 1 | Convert a nubmer in `sysTicks` to mircorseconds using `pal_osKernelSysTickMicroSec` and check it is not 0. | PAL_SUCCESS |
00143  * | 2 | Convert a nubmer in `sysTicks` to milliseconds using `pal_osKernelSysMilliSecTick` and check the returned value. | PAL_SUCCESS |
00144  */
00145 TEST(pal_rtos, pal_osKernelSysMilliSecTick_Unity)
00146 {
00147     uint64_t tick = 0;
00148     uint64_t microSec = 2000 * 1000;
00149     uint64_t milliseconds = 0;
00150     /*#1*/
00151     tick = pal_osKernelSysTickMicroSec(microSec);
00152     TEST_ASSERT_TRUE(0 != tick);
00153     /*#2*/
00154     milliseconds = pal_osKernelSysMilliSecTick(tick);
00155     TEST_ASSERT_EQUAL(microSec/1000, milliseconds);
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 This test does not run by default in the PAL Unity tets.
00805 * It's called "customized" because the purpose of it is to provide a test structure
00806 * for a developer who wants to check a specific API.
00807 *
00808 * | # |    Step                        |   Expected  |
00809 * |---|--------------------------------|-------------|
00810 * | 1 | Create a thread that runs `palThreadFuncCustom1` using `pal_osThreadCreateWithAlloc`.  | PAL_SUCCESS |
00811 * | 2 | Create a thread that runs `palThreadFuncCustom2` using `pal_osThreadCreateWithAlloc`.  | PAL_SUCCESS |
00812 * | 3 | Sleep.                                                                                 | PAL_SUCCESS |
00813 * | 4 | Terminate the first thread.                                                            | PAL_SUCCESS |
00814 * | 5 | Terminate the second thread.                                                           | PAL_SUCCESS |
00815 * | 6 | Create a thread that runs `palThreadFuncCustom1` using `pal_osThreadCreateWithAlloc`.  | PAL_SUCCESS |
00816 * | 7 | Create a thread that runs `palThreadFuncCustom2` using `pal_osThreadCreateWithAlloc`.  | PAL_SUCCESS |
00817 * | 8 | compare threads index                                                                  | PAL_SUCCESS |
00818 * | 9 | check threadIDs are not equal.                                                         | PAL_SUCCESS |
00819 * | 10 | Sleep.                                                                                 | PAL_SUCCESS |
00820 * | 11 | Terminate the first thread.                                                            | PAL_SUCCESS |
00821 * | 12 | Terminate again the first thread.                                                      | PAL_SUCCESS |
00822 * | 13 | Terminate the second thread.                                                          | PAL_SUCCESS |
00823 *
00824 */
00825 
00826 
00827 TEST(pal_rtos, ThreadReCreateSamePriority)
00828 {
00829     palStatus_t status = PAL_SUCCESS;
00830 
00831     palThreadID_t threadID1 = NULLPTR;
00832     palThreadID_t threadID2 = NULLPTR;
00833     palThreadID_t threadIndex = NULLPTR;
00834 
00835     /*#1*/
00836     status = pal_osThreadCreateWithAlloc(palThreadFuncCustom1, NULL, PAL_osPriorityAboveNormal, PAL_TEST_THREAD_STACK_SIZE, NULL, &threadID1);
00837     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00838     threadIndex =  threadID1;
00839     /*#2*/
00840     status = pal_osThreadCreateWithAlloc(palThreadFuncCustom2, NULL, PAL_osPriorityHigh , PAL_TEST_THREAD_STACK_SIZE, NULL, &threadID2);
00841     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00842     /*#3*/
00843     pal_osDelay(3000);
00844     /*#4*/
00845     // We deliberately dont terminate threadID1, it should end by itself
00846     /*#5*/
00847     // We deliberately dont terminate threadID2, it should end by itself
00848     /*#6*/
00849     status = pal_osThreadCreateWithAlloc(palThreadFuncCustom1, NULL, PAL_osPriorityAboveNormal, PAL_TEST_THREAD_STACK_SIZE, NULL, &threadID1);
00850     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00851     /*#7*/
00852     status = pal_osThreadCreateWithAlloc(palThreadFuncCustom2, NULL, PAL_osPriorityHigh , PAL_TEST_THREAD_STACK_SIZE, NULL, &threadID2);
00853     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00854     /*#8*/
00855     TEST_ASSERT_EQUAL_UINT32(PAL_GET_THREAD_INDEX(threadIndex),PAL_GET_THREAD_INDEX(threadID1));
00856     /*#9*/
00857     TEST_ASSERT_NOT_EQUAL(threadIndex,threadID1);
00858     /*#10*/
00859     pal_osDelay(3000);
00860     /*#11*/
00861     status = pal_osThreadTerminate(&threadID1);
00862     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00863     /*#12*/
00864     status = pal_osThreadTerminate(&threadID1);
00865     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00866     /*#13*/
00867     status = pal_osThreadTerminate(&threadID2);
00868     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00869     pal_osDelay(500);
00870 
00871     mutex1 = NULLPTR;
00872     status = pal_osMutexCreate(&mutex1);
00873     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00874 
00875     status = pal_osMutexWait(mutex1, PAL_RTOS_WAIT_FOREVER);
00876     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00877 
00878     status = pal_osThreadCreateWithAlloc(palThreadFuncCustom3, NULL, PAL_osPriorityAboveNormal, PAL_TEST_THREAD_STACK_SIZE, NULL, &threadID1);
00879     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00880 
00881     status = pal_osThreadCreateWithAlloc(palThreadFuncCustom4, NULL, PAL_osPriorityAboveNormal, PAL_TEST_THREAD_STACK_SIZE, NULL, &threadID2);
00882 #if PAL_UNIQUE_THREAD_PRIORITY
00883     TEST_ASSERT_EQUAL_HEX(PAL_ERR_RTOS_PRIORITY , status);
00884 #else
00885     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00886     status = pal_osThreadTerminate(&threadID2);
00887     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00888 #endif
00889        
00890     status = pal_osMutexRelease(mutex1);
00891     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00892 
00893     status = pal_osThreadTerminate(&threadID1);
00894     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00895 
00896     status = pal_osMutexDelete(&mutex1);
00897     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00898     TEST_ASSERT_EQUAL(NULLPTR, mutex1);
00899 
00900 }
00901 
00902 /*! \brief Check derivation of keys from the platform's Root of Trust using the KDF algorithm.
00903  *
00904  * 
00905  *
00906 * | # |    Step                        |   Expected  |
00907 * |---|--------------------------------|-------------|
00908 * | 1 | Start a loop to perform the following steps.                                               |  |
00909 * | 2 | Derive a device key for encryption using `pal_osGetDeviceKey`.                   | PAL_SUCCESS |
00910 * | 3 | Derive a device key for signing using `pal_osGetDeviceKey`.                      | PAL_SUCCESS |
00911 * | 4 | Call `pal_osGetDeviceKey` with invalid arguments.                              | PAL_FAILURE |
00912 * | 5 | Call `pal_osGetDeviceKey` with invalid arguments.                              | PAL_FAILURE |
00913 * | 6 | Check that the derived signing and encryption keys are different.                     | PAL_SUCCESS |
00914 * | 7 | Check that all integrations of each type of derivation return the same value.       | PAL_SUCCESS |
00915  */
00916 TEST(pal_rtos, GetDeviceKeyTest_CMAC)
00917 {
00918     palStatus_t status = PAL_SUCCESS;
00919     size_t keyLenBytes = 16;
00920     uint8_t timesToDerive = 4;
00921     unsigned char encKeyDerive[timesToDerive][keyLenBytes]; //16 bytes=128bit
00922     unsigned char signKeyDerive[timesToDerive][keyLenBytes]; //16 bytes=128bit
00923     /*#1*/
00924     for (int i=0; i < timesToDerive; i++)
00925     {
00926         /*#2*/
00927         status = pal_osGetDeviceKey(palOsStorageEncryptionKey128Bit, encKeyDerive[i], keyLenBytes);
00928         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00929         /*#3*/
00930         status = pal_osGetDeviceKey(palOsStorageSignatureKey128Bit ,  signKeyDerive[i], keyLenBytes);
00931         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00932         /*#4*/
00933         status = pal_osGetDeviceKey(palOsStorageSignatureKey128Bit ,  signKeyDerive[i], keyLenBytes-1);
00934         TEST_ASSERT_NOT_EQUAL(PAL_SUCCESS, status);
00935         /*#5*/
00936         status = pal_osGetDeviceKey(palOsStorageSignatureKey128Bit ,  NULL, keyLenBytes);
00937         TEST_ASSERT_NOT_EQUAL(PAL_SUCCESS, status);
00938         /*#6*/
00939         status = memcmp(encKeyDerive[i], signKeyDerive[i], keyLenBytes);
00940         TEST_ASSERT_NOT_EQUAL(status,0); //The keys MUST be different!
00941         /*#7*/
00942         if (i > 0) //Make sure key derivation is persistent every time
00943         {
00944             TEST_ASSERT_EQUAL_MEMORY(encKeyDerive[i-1], encKeyDerive[i], keyLenBytes);
00945             TEST_ASSERT_EQUAL_MEMORY(signKeyDerive[i-1], signKeyDerive[i], keyLenBytes);
00946 
00947         } //if
00948 
00949     } //for
00950 
00951 }
00952 
00953 /*! \brief Check derivation of keys from the platform's Root of Trust using the KDF algorithm.
00954  *
00955  * 
00956  *
00957 * | # |    Step                                                                        | Expected            |
00958 * |---|--------------------------------------------------------------------------------|---------------------|
00959 * | 1 | Start a loop to perform the following steps.                                   |                     |
00960 * | 2 | Derive a device key for encryption using `pal_osGetDeviceKey`.                 | PAL_SUCCESS         |
00961 * | 3 | Call `pal_osGetDeviceKey` with invalid arguments.                              | PAL_FAILURE         |
00962 * | 4 | Call `pal_osGetDeviceKey` with invalid arguments.                              | PAL_FAILURE         |
00963 * | 5 | Check that all integrations of each type of derivation return the same value.  | PAL_SUCCESS         |
00964 * | 6 | Call `pal_osGetDeviceKey` with invalid palDevKeyType_t.                        | PAL_ERR_GET_DEV_KEY |
00965  */
00966 TEST(pal_rtos, GetDeviceKeyTest_HMAC_SHA256)
00967 {
00968     palStatus_t status = PAL_SUCCESS;
00969     size_t keyLenBytes = 32;
00970     uint8_t timesToDerive = 4;
00971     unsigned char encKeyDerive[timesToDerive][keyLenBytes]; //32 bytes=256bit
00972     /*#1*/
00973     for (int i=0; i < timesToDerive; i++)
00974     {
00975         /*#2*/
00976         status = pal_osGetDeviceKey(palOsStorageHmacSha256 , encKeyDerive[i], keyLenBytes);
00977         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00978 #ifdef DEBUG
00979         /*#3*/
00980         status = pal_osGetDeviceKey(palOsStorageHmacSha256 ,  encKeyDerive[i], keyLenBytes-1);
00981         TEST_ASSERT_NOT_EQUAL(PAL_SUCCESS, status);
00982         /*#4*/
00983         status = pal_osGetDeviceKey(palOsStorageHmacSha256 ,  NULL, keyLenBytes);
00984         TEST_ASSERT_NOT_EQUAL(PAL_SUCCESS, status);
00985 #endif
00986         /*#5*/
00987         if (i > 0) //Make sure key derivation is persistent every time
00988         {
00989             TEST_ASSERT_EQUAL_MEMORY(encKeyDerive[i-1], encKeyDerive[i], keyLenBytes);
00990         } //if
00991 
00992     } //for
00993 
00994 #ifdef DEBUG
00995       /*#6*/
00996     status = pal_osGetDeviceKey((palDevKeyType_t)999, encKeyDerive[0], keyLenBytes);
00997     TEST_ASSERT_EQUAL_HEX(PAL_ERR_GET_DEV_KEY , status);
00998 #endif
00999 }
01000 
01001 /*! \brief Check the APIs `pal_osSetTime()` and `pal_osGetTime()` with different scenarios
01002 * for valid and non-valid scenarios and epoch values.
01003 * The test also checks that the time increases.
01004 *
01005 * | # |    Step                        |   Expected  |
01006 * |---|--------------------------------|-------------|
01007 * | 1 | Start a loop for the following steps.                                                | PAL_SUCCESS |
01008 * | 2 | Set time to invalid value using `pal_osSetTime`.                                 | PAL_ERR_INVALID_TIME |
01009 * | 3 | Get time using `pal_osGetTime`.                                                  | PAL_SUCCESS |
01010 * | 4 | Set time to valid value using `pal_osSetTime`.                                   | PAL_SUCCESS |
01011 * | 5 | Sleep.                                                                         | PAL_SUCCESS |
01012 * | 6 | Get time using `pal_osGetTime` and check that it equals set time + sleep time.   | PAL_SUCCESS |
01013 */
01014 TEST(pal_rtos, RealTimeClockTest1)
01015 {
01016     palStatus_t status;
01017     uint64_t curTime = 0;
01018     uint64_t lastTimeSeen = 0;
01019     const uint64_t minSecSinceEpoch = PAL_MIN_SEC_FROM_EPOCH + 1; //At least 47 years passed from 1.1.1970 in seconds
01020 
01021     /*#1*/
01022     for (int i=0; i < 2; i++)
01023     {
01024     /*#2*/
01025         status = pal_osSetTime(3);
01026         TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_TIME , status); // Less than current epoch time -> error
01027 
01028     /*#3*/
01029         curTime = pal_osGetTime();
01030         TEST_ASSERT_TRUE(lastTimeSeen <= curTime); //Time was not previously set; 0 is acceptable
01031     /*#4*/
01032         status = pal_osSetTime(minSecSinceEpoch);
01033         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); // More than current epoch time -> success
01034     /*#5*/
01035         int milliDelay = 1500;
01036         pal_osDelay(milliDelay); //500 milliseconds
01037     /*#6*/
01038         curTime = pal_osGetTime();
01039         TEST_ASSERT_TRUE(curTime > minSecSinceEpoch);
01040         TEST_ASSERT_TRUE(curTime <= minSecSinceEpoch+(int)ceil((float)milliDelay/1000));
01041         lastTimeSeen = curTime;
01042     }
01043 }
01044 
01045 
01046 /*! \brief Check recursive mutex behavior.
01047 *
01048 * | # |    Step                        |   Expected  |
01049 * |---|--------------------------------|-------------|
01050 * | 1 | Create a mutex using `pal_osMutexCreate`.                                             | PAL_SUCCESS |
01051 * | 2 | Create a semaphore using `pal_osSemaphoreCreate`.                                     | PAL_SUCCESS |
01052 * | 3 | Create a thread running `RecursiveLockThread` using `pal_osThreadCreateWithAlloc`.       | PAL_SUCCESS |
01053 * | 4 | Create a thread running `RecursiveLockThread` using `pal_osThreadCreateWithAlloc`.       | PAL_SUCCESS |
01054 * | 5 | Release the semaphore using `pal_osSemaphoreRelease`.                                    | PAL_SUCCESS |
01055 * | 6 | Release the semaphore using `pal_osSemaphoreRelease`.                                    | PAL_SUCCESS |
01056 * | 7 | Sleep for a short interval.                                                          | PAL_SUCCESS |
01057 * | 8 | Wait for the semaphore using `pal_osSemaphoreWait`.                                      | PAL_SUCCESS |
01058 * | 9 | Wait for the semaphore using `pal_osSemaphoreWait`.                                      | PAL_SUCCESS |
01059 * | 10 | Terminate the first thread using `pal_osThreadTerminate`.                               | PAL_SUCCESS |
01060 * | 11 | Terminate the second thread using `pal_osThreadTerminate`.                              | PAL_SUCCESS |
01061 * | 12 | Delete the mutex using `pal_osMutexDelete`.                                           | PAL_SUCCESS |
01062 * | 13 | Delete the semaphore using `pal_osSemaphoreDelete`.                                   | PAL_SUCCESS |
01063 */
01064 TEST(pal_rtos, Recursive_Mutex_Test)
01065 {
01066     palStatus_t status;
01067     int32_t val = 0;
01068 
01069     recursiveMutexData = malloc(sizeof(palRecursiveMutexParam_t));
01070     TEST_ASSERT_NOT_NULL(recursiveMutexData);
01071     memset(recursiveMutexData, 0, sizeof(palRecursiveMutexParam_t));
01072     /*#1*/
01073     status = pal_osMutexCreate(&(recursiveMutexData->mtx));
01074     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01075     /*#2*/
01076     status = pal_osSemaphoreCreate(0, &(recursiveMutexData->sem));
01077     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01078     /*#3*/
01079     status = pal_osThreadCreateWithAlloc(RecursiveLockThread, (void*)recursiveMutexData, PAL_osPriorityHigh , PAL_TEST_THREAD_STACK_SIZE, NULL, &(recursiveMutexData->higherPriorityThread));
01080     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01081     /*#4*/
01082      status = pal_osThreadCreateWithAlloc(RecursiveLockThread, (void*)recursiveMutexData, PAL_osPriorityAboveNormal, PAL_TEST_THREAD_STACK_SIZE, NULL, &(recursiveMutexData->lowerPriorityThread));
01083      TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01084     /*#5*/
01085     status = pal_osSemaphoreRelease(recursiveMutexData->sem);
01086     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01087     /*#6*/
01088     status = pal_osSemaphoreRelease(recursiveMutexData->sem);
01089     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01090     /*#7*/
01091     pal_osDelay(1000);
01092     /*#8*/
01093     status = pal_osSemaphoreWait(recursiveMutexData->sem, PAL_RTOS_WAIT_FOREVER, &val);
01094     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01095     /*#9*/
01096     status = pal_osSemaphoreWait(recursiveMutexData->sem, PAL_RTOS_WAIT_FOREVER, &val);
01097     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01098     TEST_ASSERT_EQUAL(0, val);
01099     TEST_ASSERT_EQUAL_HEX(NULLPTR, recursiveMutexData->activeThread);
01100     /*#10*/
01101     status = pal_osThreadTerminate(&(recursiveMutexData->higherPriorityThread));
01102     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01103     /*#11*/
01104     status = pal_osThreadTerminate(&(recursiveMutexData->lowerPriorityThread));
01105     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01106     /*#12*/
01107     status = pal_osMutexDelete(&(recursiveMutexData->mtx));
01108     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01109     /*#13*/
01110     status = pal_osSemaphoreDelete(&recursiveMutexData->sem);
01111     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01112 
01113     TEST_ASSERT_EQUAL(400, recursiveMutexData->count);
01114 
01115     free(recursiveMutexData);
01116     recursiveMutexData = NULL;
01117 }
01118 
01119 
01120 
01121 /*! \brief Check Weak Set Time - Forword flow.
01122 *
01123 * | # |    Step                        |   Expected  |
01124 * |---|--------------------------------|-------------|
01125 * | 1 | checking RTC and SOTP flow - not set SOTP SAVED TIME  + LAST TIME BACK + RTC to new time                      | PAL_SUCCESS |
01126 * | 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 |
01127 * | 3 | checking RTC and SOTP flow - set SOTP SAVED TIME  + LAST TIME BACK + RTC to new time                          | PAL_SUCCESS |
01128 */
01129 TEST(pal_rtos, OsWeakSetTime_Forword)
01130 {
01131     palStatus_t status;
01132     sotp_result_e sotpStatus = SOTP_SUCCESS;
01133     uint64_t setTimeInSeconds = 0;
01134     uint64_t curentTimeInSeconds=0;
01135     uint64_t pal_Time = 0;
01136     uint64_t sotpGetTime = 0;
01137     uint16_t actualLenBytes = 0;
01138 
01139 #if (PAL_USE_HW_RTC)
01140     //This code is to preserve system time
01141     uint64_t testStartTime = 0;
01142     status = pal_plat_osGetRtcTime(&testStartTime);
01143 #endif
01144 
01145 
01146     /*#1*/
01147 #if (PAL_USE_HW_RTC)
01148     pal_plat_osSetRtcTime(PAL_MIN_RTC_SET_TIME);
01149 #endif
01150     pal_osSetTime(PAL_MIN_SEC_FROM_EPOCH + PAL_SECONDS_PER_DAY * 100);
01151     curentTimeInSeconds = pal_osGetTime();
01152 
01153     sotpStatus = sotp_set(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t *)&curentTimeInSeconds);
01154     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01155 
01156     sotpStatus = sotp_set(SOTP_TYPE_LAST_TIME_BACK, sizeof(uint64_t), (uint32_t *)&curentTimeInSeconds);
01157     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01158 
01159 #if (PAL_USE_HW_RTC)
01160     uint64_t rtcTime = 0;
01161     status = pal_plat_osSetRtcTime(curentTimeInSeconds);
01162     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01163 #endif//PAL_USE_HW_RTC
01164 
01165     setTimeInSeconds = curentTimeInSeconds + (50 * PAL_ONE_SEC);
01166     status = pal_osSetWeakTime(setTimeInSeconds);
01167 
01168     pal_Time = pal_osGetTime();
01169     if (pal_Time - setTimeInSeconds > 5)
01170     {
01171         status = PAL_ERR_GENERAL_BASE;
01172     }
01173     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01174 #if PAL_USE_INTERNAL_FLASH
01175     sotpStatus = sotp_get(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01176     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01177     TEST_ASSERT_NOT_EQUAL(sotpGetTime, setTimeInSeconds);
01178 
01179     sotpStatus = sotp_get(SOTP_TYPE_LAST_TIME_BACK, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01180     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01181     TEST_ASSERT_NOT_EQUAL(sotpGetTime, setTimeInSeconds);
01182 #endif 
01183 
01184 #if (PAL_USE_HW_RTC)
01185     status = pal_plat_osGetRtcTime(&rtcTime);
01186     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01187     TEST_ASSERT_NOT_EQUAL(rtcTime, setTimeInSeconds);
01188 #endif//PAL_USE_HW_RTC
01189 
01190     /*#2*/
01191     curentTimeInSeconds = pal_osGetTime();
01192 #if (PAL_USE_HW_RTC)
01193     pal_plat_osSetRtcTime(curentTimeInSeconds);
01194 #endif//PAL_USE_HW_RTC
01195     
01196     setTimeInSeconds = curentTimeInSeconds+(200 * PAL_ONE_SEC);
01197 
01198     status = pal_osSetWeakTime(setTimeInSeconds);
01199     pal_Time = pal_osGetTime();
01200     if (pal_Time - setTimeInSeconds > 5)
01201     {
01202         status = PAL_ERR_GENERAL_BASE;
01203     }
01204     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01205 
01206 #if PAL_USE_INTERNAL_FLASH
01207     sotpStatus = sotp_get(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01208     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01209     TEST_ASSERT_NOT_EQUAL(sotpGetTime, setTimeInSeconds);
01210 
01211     sotpStatus = sotp_get(SOTP_TYPE_LAST_TIME_BACK, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01212     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01213     TEST_ASSERT_NOT_EQUAL(sotpGetTime, setTimeInSeconds);
01214 #endif
01215 
01216 #if (PAL_USE_HW_RTC)
01217     status = pal_plat_osGetRtcTime(&rtcTime);
01218     TEST_ASSERT_EQUAL_UINT64(rtcTime, setTimeInSeconds);
01219 #endif//PAL_USE_HW_RTC
01220 
01221     /*#3*/
01222     curentTimeInSeconds = pal_osGetTime();
01223     sotpStatus = sotp_set(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t *)&curentTimeInSeconds);
01224     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01225 
01226     sotpStatus = sotp_set(SOTP_TYPE_LAST_TIME_BACK, sizeof(uint64_t), (uint32_t *)&curentTimeInSeconds);
01227     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01228 
01229 #if (PAL_USE_HW_RTC)
01230     status = pal_plat_osSetRtcTime(curentTimeInSeconds);
01231     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01232 #endif//PAL_USE_HW_RTC
01233 
01234     setTimeInSeconds = curentTimeInSeconds + PAL_MINIMUM_SOTP_FORWARD_LATENCY_SEC + (100 * PAL_ONE_SEC);
01235     status = pal_osSetWeakTime(setTimeInSeconds);
01236     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01237 
01238 #if PAL_USE_INTERNAL_FLASH
01239     sotpStatus = sotp_get(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01240     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01241     TEST_ASSERT_EQUAL_UINT64(sotpGetTime, setTimeInSeconds);
01242 #endif
01243 
01244 #if (PAL_USE_HW_RTC)
01245     status = pal_plat_osGetRtcTime(&rtcTime);
01246     TEST_ASSERT_EQUAL_UINT64(rtcTime, setTimeInSeconds);
01247 #endif//PAL_USE_HW_RTC
01248 
01249 #if (PAL_USE_HW_RTC)
01250     //restore System time
01251     pal_plat_osSetRtcTime(testStartTime + PAL_RUNNING_TEST_TIME);
01252 #endif
01253 }
01254 
01255 /*! \brief Check Weak Set Time - Backword flow.
01256 *
01257 * | # |    Step                        |   Expected  |
01258 * |---|--------------------------------|-------------|
01259 * | 1 | checking SOTP flow - set SOTP SAVED TIME and LAST TIME BACK to new time         | PAL_SUCCESS |
01260 * | 2 | checking SOTP flow - not set SOTP SAVED TIME and LAST TIME BACK to new time     | PAL_SUCCESS |
01261 */
01262 TEST(pal_rtos, OsWeakSetTime_Backword)
01263 {
01264     uint64_t setTimeInSeconds = 0;
01265     uint64_t curentTimeInSeconds = 0;
01266     palStatus_t status;
01267     sotp_result_e sotpStatus = SOTP_SUCCESS;
01268     uint64_t getTimeValueBackword = 0;
01269     uint64_t pal_Time = 0;
01270 #if (PAL_USE_HW_RTC)
01271     //This code is to preserve system time
01272     uint64_t testStartTime = 0;
01273     status = pal_plat_osGetRtcTime(&testStartTime);
01274 #endif
01275 
01276     /*#1*/
01277 #if (PAL_USE_HW_RTC)
01278     pal_plat_osSetRtcTime(PAL_MIN_RTC_SET_TIME);
01279     pal_osSetTime(PAL_MIN_SEC_FROM_EPOCH + PAL_SECONDS_PER_DAY * 100);
01280 #endif
01281     curentTimeInSeconds = pal_osGetTime();
01282 
01283     getTimeValueBackword = curentTimeInSeconds - (3 * PAL_MINIMUM_SOTP_FORWARD_LATENCY_SEC);
01284     sotpStatus = sotp_set(SOTP_TYPE_LAST_TIME_BACK, sizeof(uint64_t), (uint32_t *)&getTimeValueBackword);
01285     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01286 
01287 
01288     setTimeInSeconds = curentTimeInSeconds - (6 * PAL_SECONDS_PER_MIN);
01289     status = pal_osSetWeakTime(setTimeInSeconds);
01290 
01291     pal_Time = pal_osGetTime();
01292     if (pal_Time - setTimeInSeconds > 5)
01293     {
01294         status = PAL_ERR_GENERAL_BASE;
01295     }
01296     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01297 
01298     uint64_t sotpGetTime = 0;
01299     uint16_t actualLenBytes = 0;
01300 
01301 #if PAL_USE_INTERNAL_FLASH
01302     sotpStatus = sotp_get(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01303     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01304     TEST_ASSERT_EQUAL_UINT64(sotpGetTime, setTimeInSeconds);
01305 
01306     sotpStatus = sotp_get(SOTP_TYPE_LAST_TIME_BACK, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01307     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01308     TEST_ASSERT_EQUAL_UINT64(sotpGetTime, setTimeInSeconds);
01309 #endif
01310 
01311     /*#2*/
01312     curentTimeInSeconds = pal_osGetTime();
01313     getTimeValueBackword = curentTimeInSeconds - (3 * PAL_MINIMUM_SOTP_FORWARD_LATENCY_SEC);
01314     sotpStatus = sotp_set(SOTP_TYPE_LAST_TIME_BACK, sizeof(uint64_t), (uint32_t *)&getTimeValueBackword);
01315     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01316 
01317     sotpStatus = sotp_set(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t *)&getTimeValueBackword);
01318     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01319 
01320     setTimeInSeconds = curentTimeInSeconds - (12 * PAL_SECONDS_PER_MIN);
01321 
01322     status = pal_osSetWeakTime(setTimeInSeconds);
01323     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01324 
01325 #if PAL_USE_INTERNAL_FLASH
01326     sotpStatus = sotp_get(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01327     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01328     TEST_ASSERT_NOT_EQUAL(sotpGetTime, setTimeInSeconds);
01329     sotpStatus = sotp_get(SOTP_TYPE_LAST_TIME_BACK, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01330     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01331     TEST_ASSERT_NOT_EQUAL(sotpGetTime, setTimeInSeconds);
01332 #endif
01333 
01334 #if (PAL_USE_HW_RTC)
01335     //restore System time
01336     pal_plat_osSetRtcTime(testStartTime + PAL_RUNNING_TEST_TIME);
01337 #endif
01338 }
01339 
01340 /*! \brief Weak Strong Set Time- minimalStoredLag flow.
01341 *
01342 * | # |    Step                        |   Expected  |
01343 * |---|--------------------------------|-------------|
01344 * | 1 | checking SOTP flow- set SOTP SAVED TIME to new time                         | PAL_SUCCESS |
01345 * | 2 | checking SOTP flow- not set SOTP SAVED TIME to new time                     | PAL_SUCCESS |
01346 */
01347 TEST(pal_rtos, OsWeakSetTime_minimalStoredLag)
01348 {
01349     palStatus_t status;
01350     sotp_result_e sotpStatus = SOTP_SUCCESS;
01351     uint64_t setTimeInSeconds = 0;
01352     uint64_t curentTimeInSeconds = 0;
01353     uint64_t sotpGetTime = 0;
01354     uint16_t actualLenBytes = 0;
01355     uint64_t setSotpTimeValue = 0;
01356     
01357 #if (PAL_USE_HW_RTC)
01358     //This code is to preserve system time
01359     uint64_t testStartTime = 0;
01360     status = pal_plat_osGetRtcTime(&testStartTime);
01361 #endif
01362 
01363     /*#1*/
01364 #if (PAL_USE_HW_RTC)
01365     pal_plat_osSetRtcTime(PAL_MIN_RTC_SET_TIME);
01366 #endif
01367     pal_osSetTime(PAL_MIN_SEC_FROM_EPOCH + PAL_SECONDS_PER_DAY * 100);
01368     curentTimeInSeconds = pal_osGetTime();
01369     setTimeInSeconds = curentTimeInSeconds;
01370 
01371     setSotpTimeValue = curentTimeInSeconds - (PAL_MINIMUM_STORAGE_LATENCY_SEC + 50);
01372     sotpStatus = sotp_set(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t *)&setSotpTimeValue);
01373     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01374 
01375     status = pal_osSetWeakTime(setTimeInSeconds);
01376     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01377 
01378 #if PAL_USE_INTERNAL_FLASH
01379     sotpStatus = sotp_get(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01380     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01381     TEST_ASSERT_EQUAL_UINT64(sotpGetTime, setTimeInSeconds);
01382 #endif
01383 
01384     /*#2*/
01385     curentTimeInSeconds = pal_osGetTime();
01386     setTimeInSeconds = curentTimeInSeconds - 50;
01387 
01388     setSotpTimeValue = curentTimeInSeconds;
01389     sotpStatus = sotp_set(SOTP_TYPE_LAST_TIME_BACK, sizeof(uint64_t), (uint32_t *)&setSotpTimeValue);
01390     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01391 
01392     status = pal_osSetWeakTime(setTimeInSeconds);
01393     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01394     
01395 #if PAL_USE_INTERNAL_FLASH
01396     sotpStatus = sotp_get(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01397     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01398     TEST_ASSERT_NOT_EQUAL(sotpGetTime, setTimeInSeconds);
01399 #endif
01400 
01401 #if (PAL_USE_HW_RTC)
01402     //restore System time
01403     pal_plat_osSetRtcTime(testStartTime + PAL_RUNNING_TEST_TIME);
01404 #endif
01405 }
01406 
01407 /*! \brief Check Strong Set Time.
01408 *
01409 * | # |    Step                        |   Expected  |
01410 * |---|--------------------------------|-------------|
01411 * | 1 | checking RTC flow - set new RTC time                                            | PAL_SUCCESS |
01412 * | 2 | checking RTC flow - not set RTC new time                                        | PAL_SUCCESS |
01413 * | 3 | checking SOTP flow - set SOTP SAVED TIME and LAST TIME BACK to new time         | PAL_SUCCESS |
01414 * | 4 | checking SOTP flow - not set SOTP SAVED TIME and LAST TIME BACK to new time       | PAL_SUCCESS |
01415 */
01416 TEST(pal_rtos, OsStrongSetTime)
01417 {
01418     palStatus_t status;
01419     sotp_result_e sotpStatus = SOTP_SUCCESS;
01420     uint64_t setTimeInSeconds = 0;
01421     uint64_t curentTimeInSeconds = 0;
01422     uint64_t pal_Time = 0;
01423     uint64_t sotpGetTime = 0;
01424     uint16_t actualLenBytes = 0;
01425     uint64_t setSotpTimeValue = 0;
01426 
01427 #if (PAL_USE_HW_RTC)
01428     //This code is to preserve system time
01429     uint64_t testStartTime = 0;
01430     status = pal_plat_osGetRtcTime(&testStartTime);
01431 #endif
01432 
01433     /*#1*/
01434 #if (PAL_USE_HW_RTC)
01435     pal_plat_osSetRtcTime(PAL_MIN_RTC_SET_TIME);
01436 #endif
01437     pal_osSetTime(PAL_MIN_SEC_FROM_EPOCH + PAL_SECONDS_PER_DAY * 100);
01438     curentTimeInSeconds = pal_osGetTime();
01439     setTimeInSeconds = curentTimeInSeconds;
01440 
01441 #if (PAL_USE_HW_RTC)
01442     uint64_t rtcTime = 0;
01443     rtcTime = curentTimeInSeconds - (50 + PAL_MINIMUM_RTC_LATENCY_SEC);
01444     status = pal_plat_osSetRtcTime(rtcTime);
01445     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01446 #endif//PAL_USE_HW_RTC
01447 
01448     status = pal_osSetStrongTime(setTimeInSeconds);
01449     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01450 
01451 #if (PAL_USE_HW_RTC)
01452     status = pal_plat_osGetRtcTime(&rtcTime);
01453     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01454     TEST_ASSERT_EQUAL_UINT64(rtcTime, setTimeInSeconds);
01455 #endif//PAL_USE_HW_RTC
01456 
01457     pal_Time = pal_osGetTime();
01458     if (pal_Time - setTimeInSeconds > 5)
01459     {
01460         status = PAL_ERR_GENERAL_BASE;
01461     }
01462     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01463 
01464     /*#2*/
01465     curentTimeInSeconds = pal_osGetTime();
01466     setTimeInSeconds = curentTimeInSeconds;
01467 
01468 #if (PAL_USE_HW_RTC)
01469     rtcTime = curentTimeInSeconds;
01470     status = pal_plat_osSetRtcTime(rtcTime - 50);
01471     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01472 #endif//PAL_USE_HW_RTC
01473 
01474     status = pal_osSetStrongTime(setTimeInSeconds);
01475 
01476 #if (PAL_USE_HW_RTC)
01477     status = pal_plat_osGetRtcTime(&rtcTime);
01478     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01479     TEST_ASSERT_NOT_EQUAL(rtcTime, setTimeInSeconds);
01480 #endif//PAL_USE_HW_RTC
01481 
01482     pal_Time = pal_osGetTime();
01483     if (pal_Time - setTimeInSeconds > 5){
01484         status = PAL_ERR_GENERAL_BASE;
01485     }
01486     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01487 
01488     /*#3*/
01489     curentTimeInSeconds = pal_osGetTime();
01490     setTimeInSeconds = curentTimeInSeconds;
01491     setSotpTimeValue = curentTimeInSeconds - (PAL_MINIMUM_SOTP_FORWARD_LATENCY_SEC + 1*PAL_ONE_SEC);
01492     sotpStatus = sotp_set(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t *)&setSotpTimeValue);
01493     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01494 
01495     status = pal_osSetStrongTime(setTimeInSeconds);
01496     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01497 
01498 #if PAL_USE_INTERNAL_FLASH
01499     sotpStatus = sotp_get(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01500     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01501     TEST_ASSERT_EQUAL_UINT64(sotpGetTime, setTimeInSeconds);
01502 
01503     sotpStatus = sotp_get(SOTP_TYPE_LAST_TIME_BACK, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01504     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01505     TEST_ASSERT_EQUAL_UINT64(sotpGetTime, setTimeInSeconds);
01506 #endif
01507 
01508     pal_Time = pal_osGetTime();
01509     if (pal_Time - setTimeInSeconds > 5)
01510     {
01511         status = PAL_ERR_GENERAL_BASE;
01512     }
01513     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01514 
01515     /*#4*/
01516     curentTimeInSeconds = pal_osGetTime();
01517     setTimeInSeconds = curentTimeInSeconds;
01518 
01519     setSotpTimeValue = curentTimeInSeconds - 5;
01520     sotpStatus = sotp_set(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t *)&setSotpTimeValue);
01521     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01522 
01523     sotpStatus = sotp_set(SOTP_TYPE_LAST_TIME_BACK, sizeof(uint64_t), (uint32_t *)&setSotpTimeValue);
01524     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01525 
01526     status = pal_osSetStrongTime(setTimeInSeconds);
01527     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01528 
01529 #if PAL_USE_INTERNAL_FLASH
01530     sotpStatus = sotp_get(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01531     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01532     TEST_ASSERT_NOT_EQUAL(sotpGetTime, setTimeInSeconds);
01533 
01534     sotpStatus = sotp_get(SOTP_TYPE_LAST_TIME_BACK, sizeof(uint64_t), (uint32_t*)&sotpGetTime, &actualLenBytes);
01535     TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus);
01536     TEST_ASSERT_NOT_EQUAL(sotpGetTime, setTimeInSeconds);
01537 #endif
01538 
01539     pal_Time = pal_osGetTime();
01540     if (pal_Time - setTimeInSeconds > 5)
01541     {
01542         status = PAL_ERR_GENERAL_BASE;
01543     }
01544     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01545 
01546 #if (PAL_USE_HW_RTC)
01547     //restore System time
01548     pal_plat_osSetRtcTime(testStartTime + PAL_RUNNING_TEST_TIME);
01549 #endif
01550 }
01551 
01552 
01553 /*! \brief This test verify the functionality of the RTC
01554  *
01555  * | # |    Step                        |   Expected  |
01556  * |---|--------------------------------|-------------|
01557  * | 1 | Get system RTC                           | PAL_SUCCESS |
01558  * | 2 | set new RTC                              | PAL_SUCCESS |
01559  * | 3 | delay for 2 seconds                      | PAL_SUCCESS |
01560  * | 4 | get RTC & compare to RTC from (2)        | PAL_SUCCESS |
01561  * | 5 | restore system time from (1)             | PAL_SUCCESS |
01562  */
01563 TEST(pal_rtos, pal_rtc)
01564 {
01565 #if (PAL_USE_HW_RTC)
01566     palStatus_t status = PAL_SUCCESS;
01567     uint64_t time1 = 0, sysTime = 0;
01568 
01569     /*#1*/
01570     status = pal_plat_osGetRtcTime(&sysTime);
01571     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01572 
01573     /*#2*/
01574     status = pal_plat_osSetRtcTime(PAL_MIN_RTC_SET_TIME);
01575     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01576 
01577     /*#3*/
01578     status = pal_osDelay(2000);
01579     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01580 
01581     /*#4*/
01582     status = pal_plat_osGetRtcTime(&time1);
01583     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01584     TEST_ASSERT_TRUE(time1 - PAL_MIN_RTC_SET_TIME >=  1 * PAL_ONE_SEC);
01585 
01586     /*#5*/
01587     pal_plat_osSetRtcTime(sysTime + time1 - PAL_MIN_RTC_SET_TIME  + 1); //add lost time from delay
01588 
01589 
01590 #endif
01591 }
01592 
01593 // the following functions are not part of PAL's external API hence extern
01594 extern palStatus_t pal_noiseWriteValue(const int32_t* data, uint8_t startBit, uint8_t lenBits, uint8_t* bitsWritten);
01595 extern palStatus_t pal_noiseWriteBuffer(int32_t* buffer, uint16_t lenBits, uint16_t* bitsWritten);
01596 extern palStatus_t pal_noiseRead(int32_t buffer[PAL_NOISE_BUFFER_LEN], bool partial, uint16_t* bitsRead);
01597 
01598 /*! \brief This test verifies the functionality of noise collection
01599 *
01600 * | # |    Step                                                                                    |   Expected  |
01601 * |---|--------------------------------------------------------------------------------------------|-------------|
01602 * | 1 | Reset the noise buffer by reading watever is available                                     | PAL_SUCCESS |
01603 * | 2 | Write an entire int32_t (all bits) and verify writes and that full read not possible       | PAL_SUCCESS |
01604 * | 3 | Write only some bits of the int32_t and verify writes and that full read not possible      | PAL_SUCCESS |
01605 * | 4 | Write only some bits of the int32_t, implicitly causing splitting the value into 2 indexes | PAL_SUCCESS |
01606 * | 5 | Read whatever was collected thus far (partial read) and verify output                      | PAL_SUCCESS |
01607 * | 6 | Try to read again and verify buffer is empty                                               | PAL_SUCCESS |
01608 * | 7 | Write a buffer excluding the last 7 bits of the last index and verify results              | PAL_SUCCESS |
01609 * | 8 | Fill the buffer and try to write some more data into it                                    | PAL_SUCCESS |
01610 */
01611 TEST(pal_rtos, pal_noise)
01612 {
01613     palStatus_t status;
01614     int32_t outBuffer[PAL_NOISE_BUFFER_LEN] = { 0 };
01615     int32_t inBuffer[] = { 0xB76EC265, 0xD16ACE6E, 0xF56AAD6A };
01616     uint16_t bitsWritten = 0;
01617     uint16_t bitsRead = 0;
01618     int32_t writeValue;
01619     uint8_t i;
01620 
01621     /*#1*/
01622     pal_noiseRead(outBuffer, true, &bitsRead);
01623     memset(outBuffer, 0, PAL_NOISE_SIZE_BYTES);
01624 
01625     /*#2*/
01626     writeValue = 0xCB76102A;
01627     status = pal_noiseWriteValue(&writeValue, 0, 32, (uint8_t*)&bitsWritten); // write all bits
01628     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01629     TEST_ASSERT_EQUAL(32, bitsWritten);
01630     status = pal_noiseRead(outBuffer, false, &bitsRead);
01631     TEST_ASSERT_EQUAL_HEX(PAL_ERR_RTOS_NOISE_BUFFER_NOT_FULL , status);
01632     TEST_ASSERT_EQUAL(0, bitsRead);
01633 
01634     /*#3*/
01635     status = pal_noiseWriteValue(&writeValue, 3, 20, (uint8_t*)&bitsWritten); // write some of the bits, starting at bit index 3
01636     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01637     TEST_ASSERT_EQUAL(20, bitsWritten);
01638     status = pal_noiseRead(outBuffer, false, &bitsRead);
01639     TEST_ASSERT_EQUAL_HEX(PAL_ERR_RTOS_NOISE_BUFFER_NOT_FULL , status);
01640     TEST_ASSERT_EQUAL(0, bitsRead);
01641 
01642     /*#4*/
01643     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
01644     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01645     TEST_ASSERT_EQUAL(16, bitsWritten);
01646     status = pal_noiseRead(outBuffer, false, &bitsRead);
01647     TEST_ASSERT_EQUAL_HEX(PAL_ERR_RTOS_NOISE_BUFFER_NOT_FULL , status);
01648     TEST_ASSERT_EQUAL(0, bitsRead);
01649 
01650     /*#5*/
01651     status = pal_noiseRead(outBuffer, true, &bitsRead); // read whatever collected (resets buffer)
01652     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01653     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
01654     TEST_ASSERT_EQUAL_HEX(0xCB76102A, outBuffer[0]);
01655     TEST_ASSERT_EQUAL_HEX(0xB76EC205, outBuffer[1]);
01656     TEST_ASSERT_EQUAL_HEX(0, outBuffer[2]);
01657     memset(outBuffer, 0, PAL_NOISE_SIZE_BYTES);
01658 
01659     /*#6*/
01660     status = pal_noiseRead(outBuffer, false, &bitsRead);
01661     TEST_ASSERT_EQUAL_HEX(PAL_ERR_RTOS_NOISE_BUFFER_EMPTY , status);
01662     TEST_ASSERT_EQUAL(0, bitsRead);
01663 
01664     /*#7*/
01665     status = pal_noiseWriteBuffer(inBuffer, ((sizeof(inBuffer) * CHAR_BIT) - 7), &bitsWritten); // write all except for the last 7 bits of index 2
01666     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01667     TEST_ASSERT_EQUAL(((sizeof(inBuffer) * CHAR_BIT) - 7), bitsWritten);
01668     status = pal_noiseRead(outBuffer, false, &bitsRead);
01669     TEST_ASSERT_EQUAL_HEX(PAL_ERR_RTOS_NOISE_BUFFER_NOT_FULL , status);
01670     TEST_ASSERT_EQUAL(0, bitsRead);
01671     status = pal_noiseRead(outBuffer, true, &bitsRead); // read whatever collected (resets buffer)
01672     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01673     TEST_ASSERT_NOT_EQUAL(0, bitsRead);
01674     TEST_ASSERT_EQUAL_HEX(inBuffer[0], outBuffer[0]);
01675     TEST_ASSERT_EQUAL_HEX(inBuffer[1], outBuffer[1]);
01676     TEST_ASSERT_EQUAL_HEX(0x6AAD6A, outBuffer[2]);
01677 
01678     /*#8*/
01679     for (i = 0; i <= (sizeof(inBuffer) / sizeof(int32_t)); ++i)
01680     {
01681         status = pal_noiseWriteBuffer(inBuffer, (sizeof(inBuffer) * CHAR_BIT), &bitsWritten);
01682         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
01683         TEST_ASSERT_EQUAL_HEX((sizeof(inBuffer) * CHAR_BIT), bitsWritten);
01684     }
01685     status = pal_noiseWriteBuffer(inBuffer, (sizeof(inBuffer) * CHAR_BIT), &bitsWritten);
01686     TEST_ASSERT_EQUAL_HEX(PAL_ERR_RTOS_NOISE_BUFFER_FULL , status);
01687     TEST_ASSERT_EQUAL_HEX(0, bitsWritten);
01688 }