mirror of
https://gitee.com/openharmony/drivers_framework
synced 2024-11-23 21:10:02 +00:00
feat: add hdf timer
Signed-off-by: s00442234 <susha@huawei.com>
This commit is contained in:
parent
ef9ef85aa2
commit
60750ad073
100
include/platform/timer_if.h
Executable file
100
include/platform/timer_if.h
Executable file
@ -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 */
|
||||
/** @} */
|
147
support/platform/include/timer/timer_core.h
Executable file
147
support/platform/include/timer/timer_core.h
Executable file
@ -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 */
|
302
support/platform/src/timer/timer_core.c
Executable file
302
support/platform/src/timer/timer_core.c
Executable file
@ -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);
|
109
support/platform/src/timer/timer_if.c
Executable file
109
support/platform/src/timer/timer_if.c
Executable file
@ -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;
|
||||
}
|
140
support/platform/test/unittest/common/hdf_timer_test.cpp
Executable file
140
support/platform/test/unittest/common/hdf_timer_test.cpp
Executable file
@ -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 <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <fcntl.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <string>
|
||||
#include <unistd.h>
|
||||
#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));
|
||||
}
|
@ -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 },
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
380
test/unittest/platform/common/timer_test.c
Executable file
380
test/unittest/platform/common/timer_test.c
Executable file
@ -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);
|
50
test/unittest/platform/common/timer_test.h
Executable file
50
test/unittest/platform/common/timer_test.h
Executable file
@ -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 */
|
30
test/unittest/platform/entry/hdf_timer_entry_test.c
Executable file
30
test/unittest/platform/entry/hdf_timer_entry_test.c
Executable file
@ -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;
|
||||
}
|
16
test/unittest/platform/entry/hdf_timer_entry_test.h
Executable file
16
test/unittest/platform/entry/hdf_timer_entry_test.h
Executable file
@ -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 */
|
Loading…
Reference in New Issue
Block a user