From 60750ad073a1c331ae8ced38bed037070f0419e9 Mon Sep 17 00:00:00 2001 From: s00442234 Date: Fri, 7 Jan 2022 12:51:45 +0800 Subject: [PATCH] feat: add hdf timer Signed-off-by: s00442234 --- include/platform/timer_if.h | 100 +++++ support/platform/include/timer/timer_core.h | 147 +++++++ support/platform/src/timer/timer_core.c | 302 ++++++++++++++ support/platform/src/timer/timer_if.c | 109 +++++ .../test/unittest/common/hdf_timer_test.cpp | 140 +++++++ test/unittest/common/hdf_main_test.c | 6 + test/unittest/common/hdf_main_test.h | 1 + test/unittest/include/hdf_uhdf_test.h | 1 + test/unittest/platform/common/timer_test.c | 380 ++++++++++++++++++ test/unittest/platform/common/timer_test.h | 50 +++ .../platform/entry/hdf_timer_entry_test.c | 30 ++ .../platform/entry/hdf_timer_entry_test.h | 16 + 12 files changed, 1282 insertions(+) create mode 100755 include/platform/timer_if.h create mode 100755 support/platform/include/timer/timer_core.h create mode 100755 support/platform/src/timer/timer_core.c create mode 100755 support/platform/src/timer/timer_if.c create mode 100755 support/platform/test/unittest/common/hdf_timer_test.cpp create mode 100755 test/unittest/platform/common/timer_test.c create mode 100755 test/unittest/platform/common/timer_test.h create mode 100755 test/unittest/platform/entry/hdf_timer_entry_test.c create mode 100755 test/unittest/platform/entry/hdf_timer_entry_test.h diff --git a/include/platform/timer_if.h b/include/platform/timer_if.h new file mode 100755 index 00000000..6dec2a9e --- /dev/null +++ b/include/platform/timer_if.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + + +#ifndef TIMER_IF_H +#define TIMER_IF_H + +#include "platform_if.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +/** + * @brief Defines a callback that will be invoked when a timer's interrupt involved. + */ +typedef int32_t (*TimerHandleCb)(void); + +/** + * @brief Gets a timer. + * This function must be called to get its device handle before operating the timer. + * @param number Indicates a timer id. + * @return If the operation is successful, a pointer to the timer device handle is returned. + * @since 1.0 + */ +DevHandle TimerOpen(const uint32_t number); + +/** + * @brief Close a timer. + * If you no longer need the timer, call this function to close it + * @param handle Represents a pointer to the timer device handle. + * @since 1.0 + */ +void TimerClose(DevHandle handle); + +/** + * @brief Start a timer. + * If you need the timer run, call this function to start it + * @param handle Represents a pointer to the timer device handle. + * @return success or fail + * @since 1.0 + */ +int32_t TimerStart(DevHandle handle); + +/** + * @brief Stop a timer. + * If you no longer need the timer run, call this function to stop it + * @param handle Represents a pointer to the timer device handle. + * @return success or fail + * @since 1.0 + */ +int32_t TimerStop(DevHandle handle); + +/** + * @brief Set a period timer. + * If you need the timer run, call this function to set timer info + * @param handle Represents a pointer to the timer device handle. + * @param useconds Represents the timer interval. + * @param cb Represents the timer callback function. + * @return success or fail + * @since 1.0 + */ +int32_t TimerSet(DevHandle handle, uint32_t useconds, TimerHandleCb cb); + +/** + * @brief Set a oneshot timer. + * If you need the timer run, call this function to set timer info + * @param useconds Represents the timer interval. + * @param cb Represents the timer callback function. + * @return success or fail + * @since 1.0 + */ +int32_t TimerSetOnce(DevHandle handle, uint32_t useconds, TimerHandleCb cb); + +/** + * @brief Get the timer info. + * If you need the timer info, call this function get + * @param handle Represents a pointer to the timer device handle. + * @param useconds Represents the timer interval. + * @param isPeriod Represents whether the timer call once + * @return success or fail + * @since 1.0 + */ +int32_t TimerGet(DevHandle handle, uint32_t *useconds, bool *isPeriod); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif /* TIMER_IF_H */ +/** @} */ diff --git a/support/platform/include/timer/timer_core.h b/support/platform/include/timer/timer_core.h new file mode 100755 index 00000000..dcb9f7f7 --- /dev/null +++ b/support/platform/include/timer/timer_core.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#ifndef TIMER_CORE_H +#define TIMER_CORE_H + +#include "hdf_base.h" +#include "hdf_device_desc.h" +#include "osal_mutex.h" +#include "timer_if.h" + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +#define CHECK_NULL_PTR_RETURN_VALUE(ptr, ret) do { \ + if ((ptr) == NULL) { \ + HDF_LOGE("%s:line %d pointer is null and return ret", __func__, __LINE__); \ + return (ret); \ + } \ +} while (0) + +#define CHECK_NULL_PTR_RETURN(ptr) do { \ + if ((ptr) == NULL) { \ + HDF_LOGE("%s:line %d pointer is null and return", __func__, __LINE__); \ + return; \ + } \ +} while (0) + +#define CHECK_PARSER_RESULT_RETURN_VALUE(ret, str) do { \ + if (ret != HDF_SUCCESS) { \ + HDF_LOGE("%s:line %d %s fail, ret = %d!", __func__, __LINE__, str, ret); \ + return HDF_FAILURE; \ + } \ +} while (0) + +struct TimerInfo { + uint32_t number; + TimerHandleCb cb; + uint32_t useconds; + bool isPeriod; +}; + +struct TimerCntrl { + struct TimerInfo info; + struct DListHead node; + struct TimerCntrlMethod *ops; + void *priv; + struct OsalMutex lock; +}; + +struct TimerCntrlMethod { + int32_t (*Remove)(struct TimerCntrl *cntrl); + int32_t (*Open)(struct TimerCntrl *cntrl); + int32_t (*Close)(struct TimerCntrl *cntrl); + int32_t (*Start)(struct TimerCntrl *cntrl); + int32_t (*Stop)(struct TimerCntrl *cntrl); + int32_t (*Set)(struct TimerCntrl *cntrl, uint32_t useconds, TimerHandleCb cb); + int32_t (*SetOnce)(struct TimerCntrl *cntrl, uint32_t useconds, TimerHandleCb cb); + int32_t (*Get)(struct TimerCntrl *cntrl, uint32_t *useconds, bool *isPeriod); +}; + +/** + * @brief add a timer controller to manager list + * @param cntrl Indicates a timer controller. + * @constraints: + * @return success or fail + */ +int32_t TimerCntrlAdd(struct TimerCntrl *cntrl); + +/** + * @brief remove a timer controller from manager list + * @param number Indicates a timer id. + * @constraints: + * @return success or fail + */ +int32_t TimerCntrlRemoveByNumber(const uint32_t number); + +/** + * @brief Find and return a timer controller by number + * @param number Indicates a timer id. + * @return a timer controller + */ +struct TimerCntrl *TimerCntrlOpen(const uint32_t number); + +/** + * @brief close a timer controller + * @param cntrl Indicates a timer controller. + * @return success or fail + */ +int32_t TimerCntrlClose(struct TimerCntrl *cntrl); + +/** + * @brief set a timer controller + * @param cntrl Indicates a period timer controller. + * @param useconds Indicates a timer timerout time us. + * @param cb Indicates a timer callback. + * @return success or fail + */ +int32_t TimerCntrlSet(struct TimerCntrl *cntrl, uint32_t useconds, TimerHandleCb cb); + +/** + * @brief set a timer controller + * @param cntrl Indicates a timer controller. + * @param useconds Indicates a timer timerout time us. + * @param cb Indicates a timer callback. + * @return success or fail + */ +int32_t TimerCntrlSetOnce(struct TimerCntrl *cntrl, uint32_t useconds, TimerHandleCb cb); + +/** + * @brief get a timer controller + * @param cntrl Indicates a timer controller. + * @param useconds Represents the timer interval. + * @param isPeriod Represents whether the timer call once + * @return success or fail + */ +int32_t TimerCntrlGet(struct TimerCntrl *cntrl, uint32_t *useconds, bool *isPeriod); + +/** + * @brief start a timer controller + * @param cntrl Indicates a timer controller. + * @return success or fail + */ +int32_t TimerCntrlStart(struct TimerCntrl *cntrl); + +/** + * @brief stop a timer controller + * @param cntrl Indicates a timer controller. + * @return success or fail + */ +int32_t TimerCntrlStop(struct TimerCntrl *cntrl); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ + +#endif /* TIMER_CORE_H */ diff --git a/support/platform/src/timer/timer_core.c b/support/platform/src/timer/timer_core.c new file mode 100755 index 00000000..f0482055 --- /dev/null +++ b/support/platform/src/timer/timer_core.c @@ -0,0 +1,302 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#include "timer_core.h" +#include "hdf_log.h" +#include "osal_mem.h" +#include "osal_time.h" +#include "securec.h" + +#define HDF_LOG_TAG timer_core + +struct TimerManager { + struct IDeviceIoService service; + struct HdfDeviceObject *device; + struct DListHead timerListHead; + struct OsalMutex lock; +}; + +static struct TimerManager *g_timerManager = NULL; + +int32_t TimerCntrlAdd(struct TimerCntrl *cntrl) +{ + CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_PARAM); + CHECK_NULL_PTR_RETURN_VALUE(cntrl->ops, HDF_ERR_INVALID_PARAM); + struct TimerCntrl *pos = NULL; + struct TimerCntrl *tmp = NULL; + struct TimerManager *manager = g_timerManager; + CHECK_NULL_PTR_RETURN_VALUE(manager, HDF_FAILURE); + + DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->timerListHead, struct TimerCntrl, node) { + if (cntrl->info.number == pos->info.number) { + HDF_LOGE("%s: timer[%u] existed", __func__, cntrl->info.number); + return HDF_FAILURE; + } + } + + // init info + if (OsalMutexInit(&cntrl->lock) != HDF_SUCCESS) { + HDF_LOGE("%s: OsalMutexInit %u failed", __func__, cntrl->info.number); + return HDF_FAILURE; + } + + if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) { + HDF_LOGE("%s: OsalMutexLock %u failed", __func__, cntrl->info.number); + return HDF_ERR_DEVICE_BUSY; + } + DListInsertTail(&cntrl->node, &manager->timerListHead); + (void)OsalMutexUnlock(&manager->lock); + HDF_LOGI("%s: add timer number[%u] success", __func__, cntrl->info.number); + + return HDF_SUCCESS; +} + +int32_t TimerCntrlRemoveByNumber(const uint32_t number) +{ + struct TimerCntrl *pos = NULL; + struct TimerCntrl *tmp = NULL; + struct TimerManager *manager = g_timerManager; + CHECK_NULL_PTR_RETURN_VALUE(manager, HDF_FAILURE); + + if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) { + HDF_LOGE("%s: OsalMutexLock failed", __func__); + return HDF_ERR_DEVICE_BUSY; + } + + DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->timerListHead, struct TimerCntrl, node) { + if (number == pos->info.number) { + if ((pos->ops->Remove != NULL) && (pos->ops->Remove(pos) != HDF_SUCCESS)) { + HDF_LOGE("%s: remove %u failed", __func__, pos->info.number); + } + (void)OsalMutexDestroy(&pos->lock); + DListRemove(&pos->node); + OsalMemFree(pos); + break; + } + } + + (void)OsalMutexUnlock(&manager->lock); + HDF_LOGI("%s: remove timer %u success", __func__, number); + return HDF_SUCCESS; +} + +struct TimerCntrl *TimerCntrlOpen(const uint32_t number) +{ + struct TimerCntrl *pos = NULL; + struct TimerManager *manager = g_timerManager; + CHECK_NULL_PTR_RETURN_VALUE(manager, NULL); + + if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) { + HDF_LOGE("%s: OsalMutexLock failed", __func__); + return NULL; + } + + DLIST_FOR_EACH_ENTRY(pos, &manager->timerListHead, struct TimerCntrl, node) { + if (number == pos->info.number) { + (void)OsalMutexUnlock(&manager->lock); + return pos; + } + } + + (void)OsalMutexUnlock(&manager->lock); + HDF_LOGE("%s: open %u failed", __func__, number); + return NULL; +} + +int32_t TimerCntrlClose(struct TimerCntrl *cntrl) +{ + CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT); + if (OsalMutexLock(&cntrl->lock) != HDF_SUCCESS) { + HDF_LOGE("%s: OsalMutexLock %u failed", __func__, cntrl->info.number); + return HDF_ERR_DEVICE_BUSY; + } + if ((cntrl->ops->Close != NULL) && (cntrl->ops->Close(cntrl) != HDF_SUCCESS)) { + HDF_LOGE("%s: close %u failed", __func__, cntrl->info.number); + (void)OsalMutexUnlock(&cntrl->lock); + return HDF_FAILURE; + } + (void)OsalMutexUnlock(&cntrl->lock); + return HDF_SUCCESS; +} + +int32_t TimerCntrlSet(struct TimerCntrl *cntrl, uint32_t useconds, TimerHandleCb cb) +{ + CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT); + CHECK_NULL_PTR_RETURN_VALUE(cb, HDF_ERR_INVALID_OBJECT); + if (OsalMutexLock(&cntrl->lock) != HDF_SUCCESS) { + HDF_LOGE("%s: OsalMutexLock %u failed", __func__, cntrl->info.number); + return HDF_ERR_DEVICE_BUSY; + } + if ((cntrl->ops->Set != NULL) && (cntrl->ops->Set(cntrl, useconds, cb) != HDF_SUCCESS)) { + HDF_LOGE("%s: set %u failed", __func__, cntrl->info.number); + (void)OsalMutexUnlock(&cntrl->lock); + return HDF_FAILURE; + } + + (void)OsalMutexUnlock(&cntrl->lock); + return HDF_SUCCESS; +} + +int32_t TimerCntrlSetOnce(struct TimerCntrl *cntrl, uint32_t useconds, TimerHandleCb cb) +{ + CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT); + CHECK_NULL_PTR_RETURN_VALUE(cb, HDF_ERR_INVALID_OBJECT); + + if (OsalMutexLock(&cntrl->lock) != HDF_SUCCESS) { + HDF_LOGE("%s: OsalMutexLock %u failed", __func__, cntrl->info.number); + return HDF_ERR_DEVICE_BUSY; + } + if ((cntrl->ops->SetOnce != NULL) && (cntrl->ops->SetOnce(cntrl, useconds, cb) != HDF_SUCCESS)) { + HDF_LOGE("%s: setOnce %u failed", __func__, cntrl->info.number); + (void)OsalMutexUnlock(&cntrl->lock); + return HDF_FAILURE; + } + + (void)OsalMutexUnlock(&cntrl->lock); + return HDF_SUCCESS; +} + +int32_t TimerCntrlGet(struct TimerCntrl *cntrl, uint32_t *useconds, bool *isPeriod) +{ + CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT); + CHECK_NULL_PTR_RETURN_VALUE(useconds, HDF_ERR_INVALID_OBJECT); + CHECK_NULL_PTR_RETURN_VALUE(isPeriod, HDF_ERR_INVALID_OBJECT); + + if (OsalMutexLock(&cntrl->lock) != HDF_SUCCESS) { + HDF_LOGE("%s: OsalMutexLock %u failed", __func__, cntrl->info.number); + return HDF_ERR_DEVICE_BUSY; + } + *useconds = cntrl->info.useconds; + *isPeriod = cntrl->info.isPeriod; + (void)OsalMutexUnlock(&cntrl->lock); + return HDF_SUCCESS; +} + +int32_t TimerCntrlStart(struct TimerCntrl *cntrl) +{ + CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT); + + if (OsalMutexLock(&cntrl->lock) != HDF_SUCCESS) { + HDF_LOGE("%s: OsalMutexLock %u failed", __func__, cntrl->info.number); + return HDF_ERR_DEVICE_BUSY; + } + if ((cntrl->ops->Start != NULL) && (cntrl->ops->Start(cntrl) != HDF_SUCCESS)) { + HDF_LOGE("%s: start %u failed", __func__, cntrl->info.number); + (void)OsalMutexUnlock(&cntrl->lock); + return HDF_FAILURE; + } + (void)OsalMutexUnlock(&cntrl->lock); + return HDF_SUCCESS; +} + +int32_t TimerCntrlStop(struct TimerCntrl *cntrl) +{ + CHECK_NULL_PTR_RETURN_VALUE(cntrl, HDF_ERR_INVALID_OBJECT); + + if (OsalMutexLock(&cntrl->lock) != HDF_SUCCESS) { + HDF_LOGE("%s: OsalMutexLock %u failed", __func__, cntrl->info.number); + return HDF_ERR_DEVICE_BUSY; + } + if ((cntrl->ops->Stop != NULL) && (cntrl->ops->Stop(cntrl) != HDF_SUCCESS)) { + HDF_LOGE("%s: stop %u failed", __func__, cntrl->info.number); + (void)OsalMutexUnlock(&cntrl->lock); + return HDF_FAILURE; + } + + (void)OsalMutexUnlock(&cntrl->lock); + return HDF_SUCCESS; +} + +int32_t TimerListRemoveAll(void) +{ + struct TimerCntrl *pos = NULL; + struct TimerCntrl *tmp = NULL; + struct TimerManager *manager = g_timerManager; + + if (OsalMutexLock(&manager->lock) != HDF_SUCCESS) { + HDF_LOGE("%s: lock regulator manager fail", __func__); + return HDF_ERR_DEVICE_BUSY; + } + + DLIST_FOR_EACH_ENTRY_SAFE(pos, tmp, &manager->timerListHead, struct TimerCntrl, node) { + if ((pos->ops->Remove != NULL) && (pos->ops->Remove(pos) != HDF_SUCCESS)) { + HDF_LOGE("%s: remove %u failed", __func__, pos->info.number); + } + DListRemove(&pos->node); + (void)OsalMutexDestroy(&pos->lock); + OsalMemFree(pos); + } + + (void)OsalMutexUnlock(&manager->lock); + HDF_LOGI("%s: remove all regulator success", __func__); + return HDF_SUCCESS; +} + +static int32_t TimerManagerBind(struct HdfDeviceObject *device) +{ + int32_t ret; + struct TimerManager *manager = NULL; + + CHECK_NULL_PTR_RETURN_VALUE(device, HDF_ERR_INVALID_OBJECT); + + manager = (struct TimerManager *)OsalMemCalloc(sizeof(*manager)); + if (manager == NULL) { + HDF_LOGE("%s: malloc manager fail!", __func__); + return HDF_ERR_MALLOC_FAIL; + } + + ret = OsalMutexInit(&manager->lock); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: mutex init fail:%d", __func__, ret); + OsalMemFree(manager); + manager = NULL; + return HDF_FAILURE; + } + + manager->device = device; + device->service = &manager->service; + DListHeadInit(&manager->timerListHead); + g_timerManager = manager; + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + +static int32_t TimerManagerInit(struct HdfDeviceObject *device) +{ + (void)device; + + HDF_LOGI("%s: success", __func__); + return HDF_SUCCESS; +} + +static void TimerManagerRelease(struct HdfDeviceObject *device) +{ + HDF_LOGI("%s: Enter!", __func__); + CHECK_NULL_PTR_RETURN(device); + + if (TimerListRemoveAll() != HDF_SUCCESS) { + HDF_LOGE("%s: failed", __func__); + } + + struct TimerManager *manager = (struct TimerManager *)device->service; + CHECK_NULL_PTR_RETURN(manager); + OsalMutexDestroy(&manager->lock); + OsalMemFree(manager); + g_timerManager = NULL; +} + +struct HdfDriverEntry g_timerManagerEntry = { + .moduleVersion = 1, + .Bind = TimerManagerBind, + .Init = TimerManagerInit, + .Release = TimerManagerRelease, + .moduleName = "HDF_PLATFORM_TIMER_MANAGER", +}; + +HDF_INIT(g_timerManagerEntry); diff --git a/support/platform/src/timer/timer_if.c b/support/platform/src/timer/timer_if.c new file mode 100755 index 00000000..e5bf00e2 --- /dev/null +++ b/support/platform/src/timer/timer_if.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ +#include "timer_if.h" +#include "hdf_log.h" +#include "timer_core.h" + +DevHandle TimerOpen(const uint32_t number) +{ + return (DevHandle)TimerCntrlOpen(number); +} + +void TimerClose(DevHandle handle) +{ + struct TimerCntrl *cntrl = (struct TimerCntrl *)handle; + if (cntrl == NULL) { + HDF_LOGE("%s: cntrl is null", __func__); + return; + } + + if (TimerCntrlClose(cntrl) != HDF_SUCCESS) { + HDF_LOGE("%s: TimerCntrlClose fail", __func__); + return; + } +} + +int32_t TimerSet(DevHandle handle, uint32_t useconds, TimerHandleCb cb) +{ + struct TimerCntrl *cntrl = (struct TimerCntrl *)handle; + if (cntrl == NULL || cb == NULL) { + HDF_LOGE("%s: cntrl is null", __func__); + return HDF_FAILURE; + } + + if (TimerCntrlSet(cntrl, useconds, cb) != HDF_SUCCESS) { + HDF_LOGE("%s: TimerCntrlSet fail", __func__); + return HDF_FAILURE; + } + + return HDF_SUCCESS; +} + +int32_t TimerSetOnce(DevHandle handle, uint32_t useconds, TimerHandleCb cb) +{ + struct TimerCntrl *cntrl = (struct TimerCntrl *)handle; + if (cntrl == NULL || cb == NULL) { + HDF_LOGE("%s: cntrl is null", __func__); + return HDF_FAILURE; + } + + if (TimerCntrlSetOnce(cntrl, useconds, cb) != HDF_SUCCESS) { + HDF_LOGE("%s: TimerCntrlSetOnce fail", __func__); + return HDF_FAILURE; + } + + return HDF_SUCCESS; +} + +int32_t TimerGet(DevHandle handle, uint32_t *useconds, bool *isPeriod) +{ + struct TimerCntrl *cntrl = (struct TimerCntrl *)handle; + if (cntrl == NULL || useconds == NULL || isPeriod == NULL) { + HDF_LOGE("%s: param is null", __func__); + return HDF_FAILURE; + } + + if (TimerCntrlGet(cntrl, useconds, isPeriod) != HDF_SUCCESS) { + HDF_LOGE("%s: TimerCntrlGet fail", __func__); + return HDF_FAILURE; + } + + return HDF_SUCCESS; +} + +int32_t TimerStart(DevHandle handle) +{ + struct TimerCntrl *cntrl = (struct TimerCntrl *)handle; + if (cntrl == NULL) { + HDF_LOGE("%s: cntrl is null", __func__); + return HDF_FAILURE; + } + + if (TimerCntrlStart(cntrl) != HDF_SUCCESS) { + HDF_LOGE("%s: TimerCntrlStart fail", __func__); + return HDF_FAILURE; + } + + return HDF_SUCCESS; +} + +int32_t TimerStop(DevHandle handle) +{ + struct TimerCntrl *cntrl = (struct TimerCntrl *)handle; + if (cntrl == NULL) { + HDF_LOGE("%s: cntrl is null", __func__); + return HDF_FAILURE; + } + + if (TimerCntrlStop(cntrl) != HDF_SUCCESS) { + HDF_LOGE("%s: TimerCntrlStop fail", __func__); + return HDF_FAILURE; + } + + return HDF_SUCCESS; +} diff --git a/support/platform/test/unittest/common/hdf_timer_test.cpp b/support/platform/test/unittest/common/hdf_timer_test.cpp new file mode 100755 index 00000000..7877aa21 --- /dev/null +++ b/support/platform/test/unittest/common/hdf_timer_test.cpp @@ -0,0 +1,140 @@ + +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "hdf_uhdf_test.h" +#include "hdf_io_service_if.h" + +using namespace testing::ext; + +enum TimerTestCmd { + TIMER_START_TEST = 1, + TIMER_TEST_SET, + TIMER_TEST_SETONCE, + TIMER_TEST_GET, + TIMER_TEST_START, + TIMER_TEST_STOP, + TIMER_MULTI_THREAD_TEST, + TIMER_RELIABILITY_TEST, +}; + +class HdfLiteTimerTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp(); + void TearDown(); +}; + +void HdfLiteTimerTest::SetUpTestCase() +{ + HdfTestOpenService(); +} + +void HdfLiteTimerTest::TearDownTestCase() +{ + HdfTestCloseService(); +} + +void HdfLiteTimerTest::SetUp() +{ +} + +void HdfLiteTimerTest::TearDown() +{ +} +/** + * @tc.name: TimerTestSet001 + * @tc.desc: timer set test + * @tc.type: FUNC + * @tc.require: NA + */ +HWTEST_F(HdfLiteTimerTest, TimerTestSet001, TestSize.Level1) +{ + struct HdfTestMsg msg = {TEST_PAL_TIMER_TYPE, TIMER_TEST_SET, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +/** + * @tc.name: TimerTestSetOnce001 + * @tc.desc: timer set once test + * @tc.type: FUNC + * @tc.require: NA + */ +HWTEST_F(HdfLiteTimerTest, TimerTestSetOnce001, TestSize.Level1) +{ + struct HdfTestMsg msg = {TEST_PAL_TIMER_TYPE, TIMER_TEST_SETONCE, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +/** + * @tc.name: TimerTestGet001 + * @tc.desc: timer get test + * @tc.type: FUNC + * @tc.require: NA + */ +HWTEST_F(HdfLiteTimerTest, TimerTestGet001, TestSize.Level1) +{ + struct HdfTestMsg msg = {TEST_PAL_TIMER_TYPE, TIMER_TEST_GET, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +/** + * @tc.name: TimerTestStart001 + * @tc.desc: timer start test + * @tc.type: FUNC + * @tc.require: NA + */ +HWTEST_F(HdfLiteTimerTest, TimerTestStart001, TestSize.Level1) +{ + struct HdfTestMsg msg = {TEST_PAL_TIMER_TYPE, TIMER_TEST_START, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +/** + * @tc.name: TimerTestStop001 + * @tc.desc: timer stop test + * @tc.type: FUNC + * @tc.require: NA + */ +HWTEST_F(HdfLiteTimerTest, TimerTestStop001, TestSize.Level1) +{ + struct HdfTestMsg msg = {TEST_PAL_TIMER_TYPE, TIMER_TEST_STOP, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +/** + * @tc.name: TimerTestMultiThread001 + * @tc.desc: timer multi thread test + * @tc.type: FUNC + * @tc.require: NA + */ +HWTEST_F(HdfLiteTimerTest, TimerTestMultiThread001, TestSize.Level1) +{ + struct HdfTestMsg msg = {TEST_PAL_TIMER_TYPE, TIMER_MULTI_THREAD_TEST, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} + +/** + * @tc.name: TimerTestReliability001 + * @tc.desc: timer reliability test + * @tc.type: FUNC + * @tc.require: NA + */ +HWTEST_F(HdfLiteTimerTest, TimerTestReliability001, TestSize.Level1) +{ + struct HdfTestMsg msg = {TEST_PAL_TIMER_TYPE, TIMER_RELIABILITY_TEST, -1}; + EXPECT_EQ(0, HdfTestSendMsgToService(&msg)); +} diff --git a/test/unittest/common/hdf_main_test.c b/test/unittest/common/hdf_main_test.c index 012ff3ae..f4ff294a 100644 --- a/test/unittest/common/hdf_main_test.c +++ b/test/unittest/common/hdf_main_test.c @@ -70,6 +70,9 @@ #if defined(LOSCFG_DRIVERS_HDF_PLATFORM_PWM) || defined(CONFIG_DRIVERS_HDF_PLATFORM_PWM) #include "hdf_pwm_entry_test.h" #endif +#if defined(LOSCFG_DRIVERS_HDF_PLATFORM_TIMER) || defined(CONFIG_DRIVERS_HDF_PLATFORM_TIMER) +#include "hdf_timer_entry_test.h" +#endif #endif #if defined(LOSCFG_DRIVERS_HDF_WIFI) || defined(CONFIG_DRIVERS_HDF_WIFI) #include "hdf_wifi_test.h" @@ -149,6 +152,9 @@ HdfTestFuncList g_hdfTestFuncList[] = { #if defined(LOSCFG_DRIVERS_HDF_PLATFORM_PWM) || defined(CONFIG_DRIVERS_HDF_PLATFORM_PWM) { TEST_PAL_PWM_TYPE, HdfPwmUnitTestEntry }, #endif +#if defined(LOSCFG_DRIVERS_HDF_PLATFORM_TIMER) || defined(CONFIG_DRIVERS_HDF_PLATFORM_TIMER) + { TEST_PAL_TIMER_TYPE, HdfTimerUnitTestEntry }, +#endif #endif { TEST_CONFIG_TYPE, HdfConfigEntry }, { TEST_OSAL_ITEM, HdfOsalEntry }, diff --git a/test/unittest/common/hdf_main_test.h b/test/unittest/common/hdf_main_test.h index 2945e965..db1eaec6 100644 --- a/test/unittest/common/hdf_main_test.h +++ b/test/unittest/common/hdf_main_test.h @@ -60,6 +60,7 @@ typedef enum { TEST_PAL_I3C_TYPE = 22, TEST_PAL_MIPI_CSI_TYPE = 23, TEST_PAL_DAC_TYPE = 24, + TEST_PAL_TIMER_TYPE = 25, TEST_PAL_MANAGER_TYPE = 196, TEST_PAL_DEVICE_TYPE = 197, TEST_PAL_QUEUE_TYPE = 198, diff --git a/test/unittest/include/hdf_uhdf_test.h b/test/unittest/include/hdf_uhdf_test.h index 1d9aea00..fccb0ddb 100644 --- a/test/unittest/include/hdf_uhdf_test.h +++ b/test/unittest/include/hdf_uhdf_test.h @@ -56,6 +56,7 @@ enum HdfTestSubModuleCmd { TEST_PAL_I3C_TYPE = 22, TEST_PAL_MIPI_CSI_TYPE = 23, TEST_PAL_DAC_TYPE = 24, + TEST_PAL_TIMER_TYPE = 25, TEST_PAL_MANAGER_TYPE = 196, TEST_PAL_DEVICE_TYPE = 197, TEST_PAL_QUEUE_TYPE = 198, diff --git a/test/unittest/platform/common/timer_test.c b/test/unittest/platform/common/timer_test.c new file mode 100755 index 00000000..8f930605 --- /dev/null +++ b/test/unittest/platform/common/timer_test.c @@ -0,0 +1,380 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#include "timer_test.h" +#include "device_resource_if.h" +#include "hdf_log.h" +#include "osal_thread.h" +#include "osal_time.h" +#include "timer_if.h" + +#define HDF_LOG_TAG timer_test_c + +static bool g_theard1Flag; +static bool g_theard2Flag; + +struct TimerTestFunc { + enum TimerTestCmd type; + int32_t (*Func)(struct TimerTest *test); +}; + +int32_t TimerTestcaseCb(void) +{ + static uint16_t num = 0; + num++; + if (num >= TIMER_TEST_PERIOD_TIMES) { + HDF_LOGD("->>>>>>>>>>>%s:num exceed max", __func__); + g_theard2Flag = true; + } + return HDF_SUCCESS; +} + +int32_t TimerTestcaseOnceCb(void) +{ + HDF_LOGD("->>>>>>>>>>>%s:", __func__); + g_theard1Flag = true; + return HDF_SUCCESS; +} + +static int32_t TimerSetTest(struct TimerTest *test) +{ + if (test == NULL || test->handle == NULL) { + HDF_LOGE("%s: test null", __func__); + return HDF_ERR_INVALID_OBJECT; + } + + TimerSet(test->handle, test->uSecond, TimerTestcaseCb); + return HDF_SUCCESS; +} + +static int32_t TimerSetOnceTest(struct TimerTest *test) +{ + if (test == NULL || test->handle == NULL) { + HDF_LOGE("%s: test null", __func__); + return HDF_ERR_INVALID_OBJECT; + } + + TimerSetOnce(test->handle, test->uSecond, TimerTestcaseOnceCb); + return HDF_SUCCESS; +} + +static int32_t TimerGetTest(struct TimerTest *test) +{ + if (test == NULL || test->handle == NULL) { + HDF_LOGE("%s: test null", __func__); + return HDF_ERR_INVALID_OBJECT; + } + + uint32_t uSecond; + bool isPeriod; + + TimerGet(test->handle, &uSecond, &isPeriod); + HDF_LOGD("%s:[%d][%d]", __func__, uSecond, isPeriod); + return HDF_SUCCESS; +} + +static int32_t TimerStartTest(struct TimerTest *test) +{ + if (test == NULL || test->handle == NULL) { + HDF_LOGE("%s: test null", __func__); + return HDF_ERR_INVALID_OBJECT; + } + + TimerStart(test->handle); + return HDF_SUCCESS; +} + +static int32_t TimerStopTest(struct TimerTest *test) +{ + if (test == NULL || test->handle == NULL) { + HDF_LOGE("%s: test null", __func__); + return HDF_ERR_INVALID_OBJECT; + } + + TimerStop(test->handle); + return HDF_SUCCESS; +} + +static int TimerOnceTestThreadFunc(void *param) +{ + DevHandle handle = (DevHandle)param; + if (handle == NULL) { + HDF_LOGE("%s: timer test get handle fail", __func__); + g_theard1Flag = true; + return HDF_FAILURE; + } + + if(TimerSetOnce(handle, TIMER_TEST_TIME_USECONDS, TimerTestcaseOnceCb) != HDF_SUCCESS) { + HDF_LOGE("%s: TimerSetOnce fail", __func__); + g_theard1Flag = true; + return HDF_FAILURE; + } + if (TimerStart(handle) != HDF_SUCCESS) { + HDF_LOGE("%s: TimerStart fail", __func__); + g_theard1Flag = true; + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +static int TimerPeriodTestThreadFunc(void *param) +{ + DevHandle handle = (DevHandle)param; + if (handle == NULL) { + HDF_LOGE("%s: timer test get handle fail", __func__); + g_theard2Flag = true; + return HDF_FAILURE; + } + + if(TimerSet(handle, TIMER_TEST_TIME_USECONDS, TimerTestcaseCb) != HDF_SUCCESS) { + HDF_LOGE("%s: TimerSet fail", __func__); + g_theard2Flag = true; + return HDF_FAILURE; + } + if (TimerStart(handle) != HDF_SUCCESS) { + HDF_LOGE("%s: TimerStart fail", __func__); + g_theard2Flag = true; + return HDF_FAILURE; + } + return HDF_SUCCESS; +} + +int32_t TimerTestMultiThread(struct TimerTest *test) +{ + int32_t ret; + uint32_t time = 0; + struct OsalThread thread1, thread2; + struct OsalThreadParam cfg1, cfg2; + DevHandle handle1 = NULL; + DevHandle handle2 = NULL; + if (test == NULL) { + HDF_LOGE("%s: timer test NULL", __func__); + return HDF_FAILURE; + } + thread1.realThread = NULL; + thread2.realThread = NULL; + + do { + handle1 = TimerOpen(TIMER_TEST_TIME_ID_THREAD1); + if (handle1 == NULL) { + HDF_LOGE("%s: timer test get handle1 fail", __func__); + ret = HDF_FAILURE; + break; + } + handle2 = TimerOpen(TIMER_TEST_TIME_ID_THREAD2); + if (handle1 == NULL) { + HDF_LOGE("%s: timer test get handle2 fail", __func__); + ret = HDF_FAILURE; + break; + } + + ret = OsalThreadCreate(&thread1, (OsalThreadEntry)TimerOnceTestThreadFunc, (void *)handle1); + if (ret != HDF_SUCCESS) { + HDF_LOGE("create test once timer fail:%d", ret); + ret = HDF_FAILURE; + break; + } + + ret = OsalThreadCreate(&thread2, (OsalThreadEntry)TimerPeriodTestThreadFunc, (void *)handle2); + if (ret != HDF_SUCCESS) { + HDF_LOGE("create test period timer fail:%d", ret); + ret = HDF_FAILURE; + break; + } + + cfg1.name = "TimerTestThread-once"; + cfg2.name = "TimerTestThread-period"; + cfg1.priority = cfg2.priority = OSAL_THREAD_PRI_DEFAULT; + cfg1.stackSize = cfg2.stackSize = TIMER_TEST_STACK_SIZE; + + ret = OsalThreadStart(&thread1, &cfg1); + if (ret != HDF_SUCCESS) { + HDF_LOGE("start test thread1 fail:%d", ret); + ret = HDF_FAILURE; + break; + } + + ret = OsalThreadStart(&thread2, &cfg2); + if (ret != HDF_SUCCESS) { + HDF_LOGE("start test thread2 fail:%d", ret); + ret = HDF_FAILURE; + break; + } + + while (g_theard1Flag == false || g_theard2Flag == false) { + HDF_LOGD("[%d]waitting testing timer thread finish...", time); + OsalSleep(TIMER_TEST_WAIT_TIMEOUT); + time++; + if (time > TIMER_TEST_WAIT_TIMES) { + break; + } + } + ret = HDF_SUCCESS; + } while(0); + + if (handle1 != NULL) { + TimerClose(handle1); + handle1 = NULL; + } + if (handle2 != NULL) { + TimerClose(handle2); + handle2 = NULL; + } + if (thread1.realThread != NULL) { + (void)OsalThreadDestroy(&thread1); + } + if (thread2.realThread != NULL) { + (void)OsalThreadDestroy(&thread2); + } + g_theard1Flag = false; + g_theard2Flag = false; + return ret; +} + +int32_t TimerTestReliability(struct TimerTest *test) +{ + if (test == NULL || test->handle == NULL) { + HDF_LOGE("%s: test null", __func__); + return HDF_ERR_INVALID_OBJECT; + } + + TimerSet(test->handle, test->uSecond, NULL); + TimerSetOnce(test->handle, test->uSecond, NULL); + TimerStart(NULL); + return HDF_SUCCESS; +} + +static struct TimerTestFunc g_timerTestFunc[] = { + {TIMER_TEST_SET, TimerSetTest}, + {TIMER_TEST_SETONCE, TimerSetOnceTest}, + {TIMER_TEST_GET, TimerGetTest}, + {TIMER_TEST_START, TimerStartTest}, + {TIMER_TEST_STOP, TimerStopTest}, + {TIMER_RELIABILITY_TEST, TimerTestMultiThread}, + {TIMER_MULTI_THREAD_TEST, TimerTestReliability}, +}; + +static int32_t TimerTestEntry(struct TimerTest *test, int32_t cmd) +{ + int32_t i; + int32_t ret = HDF_ERR_NOT_SUPPORT; + + if (test == NULL) { + HDF_LOGE("%s: test null cmd %d", __func__, cmd); + return HDF_ERR_INVALID_OBJECT; + } + + if (cmd != TIMER_MULTI_THREAD_TEST) { + test->handle = TimerOpen(test->number); + if (test->handle == NULL) { + HDF_LOGE("%s: timer test get handle fail", __func__); + return HDF_FAILURE; + } + } + + for (i = 0; i < sizeof(g_timerTestFunc) / sizeof(g_timerTestFunc[0]); i++) { + if (cmd == g_timerTestFunc[i].type && g_timerTestFunc[i].Func != NULL) { + ret = g_timerTestFunc[i].Func(test); + break; + } + } + + if (cmd != TIMER_MULTI_THREAD_TEST) { + TimerClose(test->handle); + } + + return ret; +} + +static int32_t TimerTestBind(struct HdfDeviceObject *device) +{ + static struct TimerTest test; + + if (device != NULL) { + device->service = &test.service; + } else { + HDF_LOGE("%s: device is NULL", __func__); + } + + HDF_LOGD("%s: success", __func__); + return HDF_SUCCESS; +} + +static int32_t TimerTestInitFromHcs(struct TimerTest *test, const struct DeviceResourceNode *node) +{ + int32_t ret; + struct DeviceResourceIface *face = NULL; + + face = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE); + if (face == NULL) { + HDF_LOGE("%s: face is null", __func__); + return HDF_FAILURE; + } + if (face->GetUint32 == NULL) { + HDF_LOGE("%s: GetUint32 not support", __func__); + return HDF_ERR_NOT_SUPPORT; + } + + ret = face->GetUint32(node, "number", &test->number, 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read id fail!", __func__); + return HDF_FAILURE; + } + + ret = face->GetUint32(node, "useconds", &test->uSecond, 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read useconds fail!", __func__); + return HDF_FAILURE; + } + + ret = face->GetUint32(node, "isPeriod", &test->isPeriod, 0); + if (ret != HDF_SUCCESS) { + HDF_LOGE("%s: read isPeriod fail!", __func__); + return HDF_FAILURE; + } + + HDF_LOGD("timer test init:number[%u][%u][%d]", test->number, test->uSecond, test->isPeriod); + return HDF_SUCCESS; +} + +static int32_t TimerTestInit(struct HdfDeviceObject *device) +{ + struct TimerTest *test = NULL; + + if (device == NULL || device->service == NULL || device->property == NULL) { + HDF_LOGE("%s: invalid parameter", __func__); + return HDF_ERR_INVALID_PARAM; + } + test = (struct TimerTest *)device->service; + + if (TimerTestInitFromHcs(test, device->property) != HDF_SUCCESS) { + HDF_LOGE("%s: RegulatorTestInitFromHcs failed", __func__); + return HDF_FAILURE; + } + + test->TestEntry = TimerTestEntry; + g_theard1Flag = false; + g_theard2Flag = false; + HDF_LOGD("%s: success", __func__); + + return HDF_SUCCESS; +} + +static void TimerTestRelease(struct HdfDeviceObject *device) +{ + (void)device; +} + +struct HdfDriverEntry g_timerTestEntry = { + .moduleVersion = 1, + .Bind = TimerTestBind, + .Init = TimerTestInit, + .Release = TimerTestRelease, + .moduleName = "PLATFORM_TIMER_TEST", +}; +HDF_INIT(g_timerTestEntry); diff --git a/test/unittest/platform/common/timer_test.h b/test/unittest/platform/common/timer_test.h new file mode 100755 index 00000000..2a6b9525 --- /dev/null +++ b/test/unittest/platform/common/timer_test.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#ifndef TIMER_TEST_H +#define TIMER_TEST_H + +#include "hdf_device_desc.h" +#include "platform_if.h" + +enum TimerTestCmd { + TIMER_START_TEST = 1, + TIMER_TEST_SET, + TIMER_TEST_SETONCE, + TIMER_TEST_GET, + TIMER_TEST_START, + TIMER_TEST_STOP, + TIMER_MULTI_THREAD_TEST, + TIMER_RELIABILITY_TEST, +}; + +#define TIMER_TEST_STACK_SIZE (1024 * 100) +#define TIMER_TEST_WAIT_TIMES 20 +#define TIMER_TEST_WAIT_TIMEOUT 5 +#define TIMER_TEST_PERIOD_TIMES 2 + +#define TIMER_TEST_TIME_ID_THREAD1 3 +#define TIMER_TEST_TIME_ID_THREAD2 5 +#define TIMER_TEST_TIME_USECONDS 5000 + +struct TimerTest { + struct IDeviceIoService service; + struct HdfDeviceObject *device; + int32_t (*TestEntry)(struct TimerTest *test, int32_t cmd); + DevHandle handle; + uint32_t number; + uint32_t uSecond; + uint32_t isPeriod; +}; + +static inline struct TimerTest *GetTimerTest(void) +{ + return (struct TimerTest *)DevSvcManagerClntGetService("TIMER_TEST"); +} + +#endif /* TIMER_TEST_H */ diff --git a/test/unittest/platform/entry/hdf_timer_entry_test.c b/test/unittest/platform/entry/hdf_timer_entry_test.c new file mode 100755 index 00000000..7763c98d --- /dev/null +++ b/test/unittest/platform/entry/hdf_timer_entry_test.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#include "hdf_timer_entry_test.h" +#include "hdf_log.h" +#include "timer_test.h" + +#define HDF_LOG_TAG hdf_timer_entry_test + +int32_t HdfTimerUnitTestEntry(HdfTestMsg *msg) +{ + struct TimerTest *test = NULL; + + if (msg == NULL) { + return HDF_FAILURE; + } + test = GetTimerTest(); + if (test == NULL || test->TestEntry == NULL) { + HDF_LOGE("%s: tester is NULL!\n", __func__); + msg->result = HDF_FAILURE; + return HDF_FAILURE; + } + msg->result = test->TestEntry(test, msg->subCmd); + return msg->result; +} diff --git a/test/unittest/platform/entry/hdf_timer_entry_test.h b/test/unittest/platform/entry/hdf_timer_entry_test.h new file mode 100755 index 00000000..3655ab0b --- /dev/null +++ b/test/unittest/platform/entry/hdf_timer_entry_test.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ + +#ifndef HDF_TIMER_ENTRY_TEST_H +#define HDF_TIMER_ENTRY_TEST_H + +#include "hdf_main_test.h" + +int32_t HdfTimerUnitTestEntry(HdfTestMsg *msg); + +#endif /* HDF_TIMER_ENTRY_TEST_H */