mirror of
https://github.com/apache/nuttx-apps.git
synced 2026-08-01 20:29:00 +00:00
testing/ostest: add hrtimer API functional tests
Add functional tests for the newly added hrtimer APIs, including hrtimer_init(), hrtimer_start(), and hrtimer_cancel(). Signed-off-by: Chengdong Wang <wangchengdong@lixiang.com>
This commit is contained in:
parent
b78ab0c6e8
commit
4d98ecccaf
5 changed files with 251 additions and 1 deletions
|
|
@ -153,6 +153,10 @@ if(CONFIG_TESTING_OSTEST)
|
|||
list(APPEND SRCS nxevent.c)
|
||||
endif()
|
||||
|
||||
if(CONFIG_HRTIMER AND CONFIG_BUILD_FLAT)
|
||||
list(APPEND SRCS hrtimer.c)
|
||||
endif()
|
||||
|
||||
if(CONFIG_BUILD_FLAT)
|
||||
list(APPEND SRCS wdog.c)
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -150,6 +150,12 @@ CSRCS += nxevent.c
|
|||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_HRTIMER),y)
|
||||
ifeq ($(CONFIG_BUILD_FLAT),y)
|
||||
CSRCS += hrtimer.c
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_BUILD_FLAT),y)
|
||||
CSRCS += wdog.c
|
||||
endif
|
||||
|
|
|
|||
228
testing/ostest/hrtimer.c
Normal file
228
testing/ostest/hrtimer.c
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
/****************************************************************************
|
||||
* apps/testing/ostest/hrtimer.c
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership. The
|
||||
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <nuttx/hrtimer.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sched.h>
|
||||
|
||||
#include "ostest.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define NSEC_PER_50MS (50 * NSEC_PER_MSEC)
|
||||
|
||||
/* Set a 1ms margin to allow hrtimertest to pass in QEMU.
|
||||
*
|
||||
* QEMU is a virtual platform, and its timer resolution and scheduling
|
||||
* latency may be less precise than on real hardware. Using a larger
|
||||
* margin ensures that tests do not fail due to timing inaccuracies.
|
||||
*
|
||||
* On real hardware (verified on the a2g-tc397-5v-tft board), this
|
||||
* margin can be reduced to less than 5 ns because timers are precise
|
||||
* and deterministic.
|
||||
*/
|
||||
|
||||
#define HRTIMER_TEST_MARGIN (NSEC_PER_MSEC)
|
||||
|
||||
/* Simple assertion macro for HRTimer test cases */
|
||||
#define HRTIMER_TEST(expr, value) \
|
||||
do \
|
||||
{ \
|
||||
ret = (expr); \
|
||||
if (ret != (value)) \
|
||||
{ \
|
||||
printf("ERROR: HRTimer test failed, line=%d ret=%d\n", \
|
||||
__LINE__, ret); \
|
||||
ASSERT(false); \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* Structure for HRTimer test tracking */
|
||||
|
||||
struct hrtimer_test_s
|
||||
{
|
||||
hrtimer_t timer; /* HRTimer instance */
|
||||
uint64_t previous; /* Previous timestamp in nanoseconds */
|
||||
uint32_t count; /* Number of timer expirations */
|
||||
uint32_t period; /* Expected period between expirations */
|
||||
bool active; /* True while the test is still running */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hrtimer_test_init
|
||||
*
|
||||
* Description:
|
||||
* Initialize a hrtimer_test_s structure for a new test.
|
||||
*
|
||||
* Input Parameters:
|
||||
* hrtimer_test - Pointer to the test structure to initialize
|
||||
* period - Expected timer period in nanoseconds
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void hrtimer_test_init(FAR struct hrtimer_test_s *hrtimer_test,
|
||||
uint32_t period)
|
||||
{
|
||||
hrtimer_test->previous = 0;
|
||||
hrtimer_test->count = 0;
|
||||
hrtimer_test->active = true;
|
||||
hrtimer_test->period = period;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: test_hrtimer_callback
|
||||
*
|
||||
* Description:
|
||||
* HRTimer callback function for test.
|
||||
*
|
||||
* - Verifies the timer interval is exactly 500ms (nanosecond precision)
|
||||
* - Stops the test after 15 expirations
|
||||
* - Re-arms the timer in absolute mode
|
||||
*
|
||||
* Input Parameters:
|
||||
* hrtimer - Pointer to the expired HRTimer instance
|
||||
*
|
||||
* Returned Value:
|
||||
* Timer period in nanoseconds (NSEC_PER_50MS)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static uint32_t test_hrtimer_callback(FAR hrtimer_t *hrtimer)
|
||||
{
|
||||
struct timespec ts;
|
||||
uint32_t diff;
|
||||
uint64_t now;
|
||||
int ret;
|
||||
|
||||
FAR struct hrtimer_test_s *test =
|
||||
(FAR struct hrtimer_test_s *)hrtimer;
|
||||
|
||||
/* Increment expiration count */
|
||||
|
||||
test->count++;
|
||||
|
||||
/* Get current system time */
|
||||
|
||||
clock_systime_timespec(&ts);
|
||||
now = clock_time2nsec(&ts);
|
||||
|
||||
/* Skip comparison for first two invocations */
|
||||
|
||||
if (test->count > 2)
|
||||
{
|
||||
/* Verify the timer interval is exactly
|
||||
* 500ms with nsec resolution
|
||||
*/
|
||||
|
||||
diff = (uint32_t)(now - test->previous);
|
||||
|
||||
HRTIMER_TEST(NSEC_PER_50MS < diff + HRTIMER_TEST_MARGIN, true);
|
||||
HRTIMER_TEST(NSEC_PER_50MS > diff - HRTIMER_TEST_MARGIN, true);
|
||||
}
|
||||
|
||||
test->previous = now;
|
||||
|
||||
/* Stop the test after 15 expirations */
|
||||
|
||||
if (test->count >= 15)
|
||||
{
|
||||
ret = hrtimer_cancel(hrtimer);
|
||||
HRTIMER_TEST(ret, 0);
|
||||
|
||||
test->active = false;
|
||||
}
|
||||
|
||||
return test->period;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: hrtimer_test
|
||||
*
|
||||
* Description:
|
||||
* Entry point for high-resolution timer functional test.
|
||||
*
|
||||
* - Initializes a HRTimer
|
||||
* - Starts it with a 500ms relative timeout
|
||||
* - Verifies subsequent expirations occur at 500ms intervals
|
||||
*
|
||||
* Input Parameters:
|
||||
* None
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void hrtimer_test(void)
|
||||
{
|
||||
int ret;
|
||||
struct hrtimer_test_s hrtimer_test;
|
||||
|
||||
/* Initialize test structure */
|
||||
|
||||
hrtimer_test_init(&hrtimer_test, NSEC_PER_50MS);
|
||||
|
||||
/* Initialize the high-resolution timer */
|
||||
|
||||
hrtimer_init(&hrtimer_test.timer,
|
||||
test_hrtimer_callback,
|
||||
NULL);
|
||||
|
||||
/* Start the timer with 500ms relative timeout */
|
||||
|
||||
ret = hrtimer_start(&hrtimer_test.timer,
|
||||
hrtimer_test.period,
|
||||
HRTIMER_MODE_REL);
|
||||
|
||||
HRTIMER_TEST(ret, OK);
|
||||
|
||||
/* Wait until the test completes */
|
||||
|
||||
while (hrtimer_test.active)
|
||||
{
|
||||
usleep(USEC_PER_MSEC);
|
||||
}
|
||||
}
|
||||
|
|
@ -304,4 +304,8 @@ int sem_nfreeholders(void);
|
|||
void nxevent_test(void);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SCHED_EVENTS) && defined(CONFIG_BUILD_FLAT)
|
||||
void hrtimer_test(void);
|
||||
#endif
|
||||
|
||||
#endif /* __APPS_TESTING_OSTEST_OSTEST_H */
|
||||
|
|
|
|||
|
|
@ -625,6 +625,14 @@ static int user_main(int argc, char *argv[])
|
|||
check_test_memory_usage();
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_HRTIMER) && defined(CONFIG_BUILD_FLAT)
|
||||
/* Verify hrtimer */
|
||||
|
||||
printf("\nuser_main: hrtimer test\n");
|
||||
hrtimer_test();
|
||||
check_test_memory_usage();
|
||||
#endif
|
||||
|
||||
/* Compare memory usage at time ostest_main started until
|
||||
* user_main exits. These should not be identical, but should
|
||||
* be similar enough that we can detect any serious OS memory
|
||||
|
|
@ -705,7 +713,7 @@ int main(int argc, FAR char **argv)
|
|||
stdio_test();
|
||||
|
||||
#ifdef SDCC
|
||||
/* I am not yet certain why SDCC does not like the following initilizers.
|
||||
/* I am not yet certain why SDCC does not like the following initializers.
|
||||
* It involves some issues with 2- vs 3-byte pointer types.
|
||||
*/
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue