CHRE: create a system_timer on SLPI

system_timer

chre/platform/include/chre/platform/system_timer.h

#include "chre/target_platform/system_timer_base.h"
#include "chre/util/non_copyable.h"
#include "chre/util/time.h"

namespace chre {
/**
 * The function signature of a timer callback.
 *
 * @param The data pointer here is passed in by the entity that requested the
 *        timer and is used to provided a context in the callback.
 */
typedef void (SystemTimerCallback)(void *data);
/**
 * Abstracts a system timer from the underlying platform, which will invoke the
 * supplied callback after at least the given amount of time has passed. The
 * calling context for the callback is undefined, and may be inside an
 * interrupt, or in a different thread, etc. Therefore, the callback is
 * responsible for ensuring that it handles this potential concurrency
 * appropriately.

 */
class SystemTimer : public SystemTimerBase,
                    public NonCopyable {
  /**
   * Initializes the timer. This must be called before other methods in this
   * class are called.
   *
   * @return true on successful, false on failure
   */
  bool init();

  /**
   * Sets the timer to expire after the given delay. If the timer was already
   * running, its expiry time is updated to this value.
   *
   * Note that it is possible for the timer to fire before this function
   * returns.
   *
   * @param callback The callback to invoke when the timer has elapsed.
   * @param data The data to pass to the callback when it is invoked.
   * @param delay The minimum delay until the first firing of the timer.
   * @return true on success, false on failure
   */
  bool set(SystemTimerCallback *callback, void *data, Nanoseconds delay);
private:
  //! The callback to invoke when the timer has elapsed.
  SystemTimerCallback *mCallback;

  //! The data to pass to the callback when invoked.
  void *mData;
}

SystemTimerBase

//chre/platform/slpi/include/chre/target_platform/system_timer_base.h
class SystemTimerBase {
 public:
  //! The underlying QURT timer.
  SlpiTimerHandle mTimerHandle;

  //! Tracks whether the timer has been initialized correctly.
  bool mInitialized = false;

  //! A static method that is invoked by the underlying QURT timer.
  static void systemTimerNotifyCallback(SlpiTimerCallbackDataType data);
};

system_timer的实现

构造函数

SystemTimer::SystemTimer() {}

init

bool SystemTimer::init() {
  if (mInitialized) {
    LOGW("Tried re-initializing timer");
  } else {
    SlpiTimerErrorType status = timer_def_osal(
        &mTimerHandle, &timer_non_defer_group, TIMER_FUNC1_CB_TYPE,
        reinterpret_cast<time_osal_notify_obj_ptr>(systemTimerNotifyCallback),
        reinterpret_cast<time_osal_notify_data>(this));

    if (status != SLPI_TIMER_SUCCESS) {
      LOGE("Error initializing timer %d", status);
    } else {
      mInitialized = true;
    }
  }

  return mInitialized;
}

// core/services/time/src/timer_client.c
  /**
  Defines and initializes a timer.
                                    
  Please refer timer.h
  */
timer_error_type timer_def_osal
(
    timer_ptr_type                  timer,
    timer_group_ptr                 group,
    timer_notify_type               cb_type,
    time_osal_notify_obj_ptr        sigs_func_addr,
    time_osal_notify_data           sigs_mask_data
)
{    
     //group being NULL is allowed for timer_def, timer_def2
     return timer_invoke_def_osal(timer_client_qdi_handle, timer, group, cb_type, sigs_func_addr, sigs_mask_data);
}

//./core/services/time/src/timer_qdi_v.h
static inline timer_error_type timer_invoke_def_osal(                                                                                                                                                     
     int                             handle, 
     timer_ptr_type                  timer,
     timer_group_ptr                 group, 
     timer_notify_type               cb_type,
     time_osal_notify_obj_ptr        sigs_func_addr,
     time_osal_notify_data           sigs_mask_data)
{
     return qurt_qdi_handle_invoke(handle, TIMER_QDI_DEF_OSAL, timer, group, cb_type, sigs_func_addr, sigs_mask_data);
}

// int qurt_qdi_handle_invoke();
#define qurt_qdi_handle_invoke(h,m,...) \
   _QDMPASTE(_QDMHI,_QDMCNT(QDI_HANDLE_LOCAL_CLIENT,h,m,##__VA_ARGS__))(QDI_HANDLE_LOCAL_CLIENT,h,m,##__VA_ARGS__)

//core/api/kernel/qurt/qurt_qdi.h
/**@ingroup driver_interface                                                                                                                                                                                
  Performs a generic driver operation, which (depending on the specified operation) can be
  either be one of the predefined operations listed in Table 2-1, or a driver-specific
  operation.
  The user provides a QDI handle and an integer
  method number, along with 0 to 8 optional 32-bit arguments.
  The device driver invocation function is invoked with the
  same method number and 0 to 8 optional arguments, and the
  return value from the invocation function is passed back to
  the user as the return value of qurt_qdi_handle_invoke.

  @note1hang For reasons related to the Hexagon standard for varargs functions, the
             qurt_qdi_handle_invoke function prototype is not actually defined as a
             varargs function (and in fact would break if it were defined this way).
 
  @param  h   Integer handle to a QDI device driver.
  @param  m   Integer method number passed to the device driver.
  @param  ... Arguments can be passed as operation-specific parameters: \n
               arg1 -- Optional 1st parameter to device driver \n
               arg2   Optional 2nd parameter to device driver \n
               arg3   Optional 3rd parameter to device driver \n
               arg4   Optional 4th parameter to device driver \n
               arg5   Optional 5th parameter to device driver \n
               arg6   Optional 6th parameter to device driver \n
               arg7   Optional 7th parameter to device driver \n
               arg8   Optional 8th parameter to device driver
 
  @return 
  Integer value defined by the device driver itself. \n
  -1 -- Error.

  @dependencies
  None.
 */

set

bool SystemTimer::set(SystemTimerCallback *callback, void *data,
    Nanoseconds delay) {
  bool wasSet = false;
  if (mInitialized) {
    mCallback = callback;
    mData = data;
    SlpiTimerErrorType status = slpiTimerSet64(&mTimerHandle,
        Microseconds(delay).getMicroseconds(), 0, SlpiTimerMicroUnit);
    if (status != SLPI_TIMER_SUCCESS) {
      LOGE("Error setting timer %d", status);
    } else {
      wasSet = true;
    }
  }

  return wasSet;
}

callback

void SystemTimerBase::systemTimerNotifyCallback(SlpiTimerCallbackDataType data) {
  SystemTimer *systemTimer = reinterpret_cast<SystemTimer *>(data);
  systemTimer->mCallback(systemTimer->mData);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值