diff -r a179b74831c9 -r c1f20ce4abcf kerneltest/e32test/timestamp/t_timestamp.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/timestamp/t_timestamp.cpp Tue Aug 31 16:34:26 2010 +0300 @@ -0,0 +1,205 @@ +// Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// +// This test checks the accuracy if NKern::Timestamp (in SMP systems) or +// NKern::Fastcounter (in unicore), when low power modes are being selected +// during idle. +// Platforms requiring this test need to provide a d_timestamp.pdd which +// implements the functions required to test the accurary. If no pdd is +// supplied the test is skipped and claims to succeed. +// Overview: + +//------------------------------------------------------------------------------------------- +//! @SYMTestCaseID KBASE-t_timestamp-2706 +//! @SYMTestCaseDesc verifying that NKern::Timestamp/FastCounter works correctly +//! accross low power modes +//! @SYMPREQ 417-52765 +//! @SYMTestPriority High +//! @SYMTestActions +//! 1. This test harness first gets information about NKern::Timestamp or +//! NKern::FastCounter in particular its frequency. It also obtains +//! the following constants: Number of timer to run the test, number +//! of retries before giving up if no low power modes are detected, +//! and acceptable error percent. Length in nanokernel ticks of each cycle +//! 2. Then it measures the timestamp before and after a time interval +//! controlled by NTimerIntervalInS (constant is in seconds) +//! 2.1 If in period of KTimerInterval a low power mode was entered and +//! the timer underlying NKern::Timestamp had to be restated then before +//! and after time is stored. The cycle is considered successful. +//! 3. If KNMaxentries occur with no successful entries the test fails +//! 4. If any valid entry has an interval as measured with NKern::Timestamp that +//! is outside KNErrPercent of the same interval as measured with nanokernel +//! ticks then the test fails +//! 5. If KNValidRuns valid cycles have an acceptable error the test succeeds +//! +//! @SYMTestExpectedResults +//! test passed +//------------------------------------------------------------------------------------------- + +#include +#include +#include +#define __E32TEST_EXTENSION__ +#include +#include +#include +#include +#include "d_timestamp.h" + +_LIT(KTimestampTestLddFileName,"D_TIMESTAMP.LDD"); +_LIT(KTimestampTestPddFileName,"D_TIMESTAMP.PDD"); + +RTest test(_L("T_TIMESTAMP")); + +LOCAL_C void UnloadDrivers() + { + test.Printf(_L("Unloading LDD\n")); + + TInt r=User::FreeLogicalDevice(RTimestampTest::Name()); + test_KErrNone(r); + + TName pddName(RTimestampTest::Name()); + _LIT(KPddWildcardExtension,".*"); + pddName.Append(KPddWildcardExtension); + TFindPhysicalDevice findPD(pddName); + TFullName findResult; + r=findPD.Next(findResult); + while (r==KErrNone) + { + test.Printf(_L("Unloading PDD: %S\n"),&findResult); + r=User::FreePhysicalDevice(findResult); + test_KErrNone(r); + findPD.Find(pddName); // Reset the find handle now that we have deleted something from the container. + r=findPD.Next(findResult); + } + } + + +GLDEF_C TInt E32Main() + { + + TBool dontFail = (User::CommandLineLength()!=0); + + test.Title(); + + test.Start(_L("Timestamp accuracy test")); + + + TInt r; + TRequestStatus st; + + r = User::LoadPhysicalDevice(KTimestampTestPddFileName); + if (KErrNotFound == r) + { + test.Printf(_L("No timestamp pdd, test skipped\n")); + test.End(); // skip test if this platform does not supply a PDD + return 0; + } + + + r=User::LoadLogicalDevice(KTimestampTestLddFileName); + test(r==KErrNone || r==KErrAlreadyExists); + + RTimestampTest ldd; + r = ldd.Open(); + test_KErrNone(r); + + test.Next(_L("Get timestamp frequency")); + STimestampTestConfig info; + r = ldd.Config(info); + test_KErrNone(r); + + + TUint retries = 0; + TUint validruns = 0; + + test.Next(_L("Get nanotick frequency")); + TInt tickPeriod = 0; + r = HAL::Get(HAL::ENanoTickPeriod, tickPeriod); + test_KErrNone(r); + test.Printf(_L(" tick period in uS== %d\n"), tickPeriod); + + TInt ticks = info.iTimerDurationS*1000000/tickPeriod; + TUint64 expected = info.iTimerDurationS*info.iFreq; + TUint64 acceptError = info.iErrorPercent*expected/100; + + test.Printf(_L("running at %dHz for %d interations, each lasting %d seconds and with %d retries\n"), + info.iFreq, + info.iIterations, + info.iTimerDurationS, + info.iRetries + ); + + test.Printf(_L("expecting %lu with up to %lu error\n"),expected,acceptError); + + test.Next(_L("test timer interval")); + STimestampResult result; + STimestampResult* validResults = new STimestampResult[info.iIterations]; + memset(&validResults[0],0,sizeof(validResults)); + ldd.Start(st,ticks); + User::WaitForRequest(st); + test_KErrNone(st.Int()); + + FOREVER + { + ldd.WaitOnTimer(st,result); + User::WaitForRequest(st); + test_KErrNone(st.Int()); + TUint64 error = (result.iDelta>expected) ? result.iDelta-expected : expected - result.iDelta; + + if (error < acceptError) + { + test.Printf(_L("Got %lu expected %lu, LPM Entered:%d, error %lu is OK \n"), + result.iDelta,expected,result.iLPMEntered,error); + } + else + { + test.Printf(_L("Got %lu expected %lu, LPM Entered:%d, error %lu is BAD\n"), + result.iDelta,expected,result.iLPMEntered,error); + if (!dontFail) + { + delete [] validResults; + ldd.Close(); + UnloadDrivers(); + test(error < acceptError); + } + } + + if (result.iLPMEntered) + { + retries = 0; + validResults[validruns] = result; + if (++validruns==info.iIterations) break; + } + else + { + retries++; + if (retries==info.iRetries) + { + test.Printf(_L("several retries with no power mode entry ... aborting ...\n")); + ldd.Close(); + delete [] validResults; + UnloadDrivers(); + test_Compare(retries,<,info.iRetries); + } + + } + } + + delete [] validResults; + ldd.Close(); + UnloadDrivers(); + test.End(); + return(0); + }