kerneltest/e32test/timestamp/t_timestamp.cpp
branchRCL_3
changeset 257 3e88ff8f41d5
parent 256 c1f20ce4abcf
child 258 880ff05ad710
child 263 9e2d4f7f5028
equal deleted inserted replaced
256:c1f20ce4abcf 257:3e88ff8f41d5
     1 // Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //  
       
    15 // This test checks the accuracy if NKern::Timestamp (in SMP systems) or
       
    16 // NKern::Fastcounter (in unicore), when low power modes are being selected
       
    17 // during idle.
       
    18 // Platforms requiring this test need to provide a d_timestamp.pdd which
       
    19 // implements the functions required to test the accurary. If no pdd is 
       
    20 // supplied the test is skipped and claims to succeed.
       
    21 // Overview:
       
    22 
       
    23 //-------------------------------------------------------------------------------------------
       
    24 //! @SYMTestCaseID				KBASE-t_timestamp-2706
       
    25 //! @SYMTestCaseDesc			verifying that NKern::Timestamp/FastCounter works correctly 
       
    26 //!                             accross low power modes
       
    27 //! @SYMPREQ					417-52765
       
    28 //! @SYMTestPriority			High
       
    29 //! @SYMTestActions				
       
    30 //! 1. This test harness first gets information about NKern::Timestamp or
       
    31 //!     NKern::FastCounter in particular its frequency. It also obtains
       
    32 //!     the following constants: Number of timer to run the test, number
       
    33 //!     of retries before giving up if no low power modes are detected,
       
    34 //!     and acceptable error percent. Length in nanokernel ticks of each cycle
       
    35 //! 2. Then it measures the timestamp before and after a time interval 
       
    36 //!    controlled by NTimerIntervalInS (constant is in seconds)
       
    37 //!    2.1 If in period of KTimerInterval a low power mode was entered and 
       
    38 //!        the timer underlying NKern::Timestamp had to be restated then before
       
    39 //!        and after time is stored. The cycle is considered successful.
       
    40 //! 3. If KNMaxentries occur with no successful entries the test fails
       
    41 //! 4. If any valid entry has an interval as measured with NKern::Timestamp that
       
    42 //!    is outside KNErrPercent of the same interval as measured with nanokernel 
       
    43 //!    ticks then the test fails
       
    44 //! 5. If KNValidRuns valid cycles have an acceptable error the test succeeds
       
    45 //! 
       
    46 //! @SYMTestExpectedResults 
       
    47 //!     test passed
       
    48 //-------------------------------------------------------------------------------------------
       
    49 
       
    50 #include <e32std.h>
       
    51 #include <e32base.h>
       
    52 #include <e32debug.h>
       
    53 #define __E32TEST_EXTENSION__
       
    54 #include <e32test.h>
       
    55 #include <hal.h>
       
    56 #include <u32hal.h>
       
    57 #include <e32svr.h>
       
    58 #include "d_timestamp.h"
       
    59 
       
    60 _LIT(KTimestampTestLddFileName,"D_TIMESTAMP.LDD");
       
    61 _LIT(KTimestampTestPddFileName,"D_TIMESTAMP.PDD");
       
    62 
       
    63 RTest test(_L("T_TIMESTAMP"));
       
    64 
       
    65 LOCAL_C void UnloadDrivers()
       
    66 	{
       
    67     test.Printf(_L("Unloading LDD\n"));
       
    68 
       
    69 	TInt r=User::FreeLogicalDevice(RTimestampTest::Name());
       
    70     test_KErrNone(r);
       
    71     
       
    72 	TName pddName(RTimestampTest::Name());
       
    73 	_LIT(KPddWildcardExtension,".*");
       
    74 	pddName.Append(KPddWildcardExtension);
       
    75 	TFindPhysicalDevice findPD(pddName);
       
    76 	TFullName findResult;
       
    77 	r=findPD.Next(findResult);
       
    78 	while (r==KErrNone)
       
    79 		{
       
    80         test.Printf(_L("Unloading PDD: %S\n"),&findResult);
       
    81 		r=User::FreePhysicalDevice(findResult);
       
    82         test_KErrNone(r);
       
    83 		findPD.Find(pddName); // Reset the find handle now that we have deleted something from the container.
       
    84 		r=findPD.Next(findResult);
       
    85 		} 
       
    86 	}
       
    87 
       
    88 
       
    89 GLDEF_C TInt E32Main()
       
    90     {
       
    91 
       
    92     TBool dontFail = (User::CommandLineLength()!=0);
       
    93     
       
    94     test.Title();
       
    95 
       
    96     test.Start(_L("Timestamp accuracy test"));
       
    97     
       
    98 
       
    99     TInt r;
       
   100     TRequestStatus st;
       
   101     
       
   102     r = User::LoadPhysicalDevice(KTimestampTestPddFileName);
       
   103     if (KErrNotFound == r)
       
   104         {
       
   105         test.Printf(_L("No timestamp pdd, test skipped\n"));
       
   106         test.End(); // skip test if this platform does not supply a PDD
       
   107         return 0;
       
   108         }
       
   109     
       
   110 
       
   111 	r=User::LoadLogicalDevice(KTimestampTestLddFileName);
       
   112 	test(r==KErrNone || r==KErrAlreadyExists);
       
   113     
       
   114     RTimestampTest ldd;
       
   115     r = ldd.Open();
       
   116     test_KErrNone(r);
       
   117     
       
   118     test.Next(_L("Get timestamp frequency"));
       
   119     STimestampTestConfig info;
       
   120     r = ldd.Config(info);
       
   121     test_KErrNone(r);
       
   122     
       
   123 
       
   124     TUint retries = 0;
       
   125     TUint validruns = 0;
       
   126     
       
   127     test.Next(_L("Get nanotick frequency"));
       
   128 	TInt tickPeriod = 0;
       
   129 	r = HAL::Get(HAL::ENanoTickPeriod, tickPeriod);
       
   130     test_KErrNone(r);
       
   131     test.Printf(_L(" tick period in uS== %d\n"), tickPeriod);
       
   132 
       
   133     TInt ticks = info.iTimerDurationS*1000000/tickPeriod;
       
   134     TUint64 expected = info.iTimerDurationS*info.iFreq;
       
   135     TUint64 acceptError = info.iErrorPercent*expected/100;
       
   136     
       
   137     test.Printf(_L("running at %dHz for %d interations, each lasting %d seconds and with %d retries\n"),
       
   138                 info.iFreq,
       
   139                 info.iIterations,
       
   140                 info.iTimerDurationS,
       
   141                 info.iRetries
       
   142         );
       
   143     
       
   144     test.Printf(_L("expecting %lu with up to %lu error\n"),expected,acceptError);
       
   145 
       
   146     test.Next(_L("test timer interval"));
       
   147     STimestampResult result;
       
   148     STimestampResult* validResults = new STimestampResult[info.iIterations];
       
   149     memset(&validResults[0],0,sizeof(validResults));
       
   150     ldd.Start(st,ticks);
       
   151     User::WaitForRequest(st);
       
   152     test_KErrNone(st.Int());
       
   153     
       
   154     FOREVER
       
   155         {
       
   156         ldd.WaitOnTimer(st,result);
       
   157         User::WaitForRequest(st);
       
   158         test_KErrNone(st.Int());
       
   159         TUint64 error = (result.iDelta>expected) ? result.iDelta-expected : expected - result.iDelta;
       
   160 
       
   161         if (error < acceptError)
       
   162             {
       
   163             test.Printf(_L("Got %lu expected %lu, LPM Entered:%d, error %lu is OK \n"),
       
   164                         result.iDelta,expected,result.iLPMEntered,error);
       
   165             }
       
   166         else 
       
   167             {
       
   168             test.Printf(_L("Got %lu expected %lu, LPM Entered:%d, error %lu is BAD\n"),
       
   169                         result.iDelta,expected,result.iLPMEntered,error);
       
   170             if (!dontFail) 
       
   171                 {
       
   172                 delete [] validResults;
       
   173                 ldd.Close();
       
   174                 UnloadDrivers();
       
   175                 test(error < acceptError);
       
   176                 }
       
   177             }
       
   178 
       
   179         if (result.iLPMEntered)
       
   180             {
       
   181             retries = 0;
       
   182             validResults[validruns] = result;
       
   183             if (++validruns==info.iIterations) break;
       
   184             }
       
   185         else
       
   186             {
       
   187             retries++;
       
   188             if (retries==info.iRetries) 
       
   189                 {
       
   190                 test.Printf(_L("several retries with no power mode entry ... aborting ...\n"));
       
   191                 ldd.Close();
       
   192                 delete [] validResults;
       
   193                 UnloadDrivers();
       
   194                 test_Compare(retries,<,info.iRetries);
       
   195                 }
       
   196             
       
   197             }
       
   198         }
       
   199 
       
   200     delete [] validResults;
       
   201     ldd.Close();
       
   202     UnloadDrivers();
       
   203     test.End();
       
   204 	return(0);
       
   205     }