Linux编程——定时器
  fgEzWBuBS8L1 2023年11月02日 81 0

定时器是在相关的实时应用中都非常重要的组件,在Linux系统中实际上也提供了丰富的定时器的支持,在Android UWB的底层实现中也被广泛应用,本文进行简单的介绍。

定时器

定时器的基本管理就是创建、设置定时时间、启动定时器、定时器超时处理、停止定时器以及删除定时器,接下来按照流程顺序进行介绍。

1.创建定时器

关于使用POSIX定时器的创建,使用timer_create函数创建,定时以下提供了简单的示例。

#include <time.h>

// 定义定时器结构体,将定时器句柄与相关数据进行绑定,以便定时器超时回调处理
typedef struct {
    timer_t hTimerHandle;
    // 其他定时器相关的成员变量
} TimerData;

// 创建定时器函数
void createTimer() {
    TimerData timerData;
    struct sigevent se;

    // 设置定时器事件
    se.sigev_notify = SIGEV_SIGNAL;  // 定时器到期时发送信号
    se.sigev_signo = SIGALRM;       // 使用SIGALRM信号
    se.sigev_value.sival_ptr = &(timerData.hTimerHandle);  // 传递定时器句柄

    // 创建定时器
    timer_create(CLOCK_REALTIME, &se, &(timerData.hTimerHandle));

    // 其他处理定时器的操作
}

在上述代码中,timer_create函数用于创建一个定时器。它接受三个参数:

  1. clockid_t clockid:指定定时器时钟类型,这里使用CLOCK_REALTIME表示使用实时时钟,可以满足一些应用对于实时性的要求。
  2. struct sigevent *sevp:指向sigevent结构体的指针,该结构体定义了定时器到期时的处理方式。
  3. timer_t *timerid:指向timer_t类型的指针,用于接收创建的定时器句柄。

在代码中,我们可以看到,首先定义了一个TimerData的结构体,用于存储定时器句柄和其他相关的定时器数据。在最后的示例中,可以看到timer_t句柄是如何应用到实际的案例中的。

然后,创建了一个sigevent结构体se,并设置了定时器事件的处理方式。

最后,通过调用timer_create函数,将定时器句柄存储在timerData.hTimerHandle中。

在定时器创建时,还支持一些其他的事件类型,如SIGEV_THREAD等,时间到创建一个新的线程来执行特定的函数。

typedef struct sigevent {
    int sigev_notify;              // 通知方式
    int sigev_signo;               // 信号编号
    union sigval sigev_value;      // 传递的值
    void (*sigev_notify_function)(union sigval);  // 线程处理函数
    pthread_attr_t *sigev_notify_attributes;      // 线程属性
} sigevent_t;
#include <time.h>
#include <pthread.h>

// 定时器线程处理函数
void timerThreadHandler(union sigval value) {
    // 处理定时器到期事件
}

// 创建定时器函数
void createTimer() {
    struct sigevent se;
    timer_t timerid;

    // 设置定时器事件
    se.sigev_notify = SIGEV_THREAD;  // 使用线程处理方式
    se.sigev_notify_function = timerThreadHandler;  // 设置线程处理函数
    se.sigev_notify_attributes = NULL;

    // 创建定时器
    timer_create(CLOCK_REALTIME, &se, &timerid);
    // 其他处理定时器的操作
}

2.设置定时器的时间,启动定时器

struct itimerspec是一个用于设置定时器的结构体,在Linux中定义在<sys/time.h>头文件中。它包含两个成员变量:it_interval和it_value。

struct itimerspec {
    struct timespec it_interval;  // 定时器的间隔时间
    struct timespec it_value;     // 定时器的初始值
};

其中,每个成员变量的含义如下:

  1. it_interval:表示定时器的间隔时间,即定时器周期性触发的时间间隔。它是一个struct timespec结构体类型的变量,包含了秒(tv_sec)和纳秒(tv_nsec)两个字段。如果希望定时器只触发一次,可以将it_interval设置为0。
  2. it_value:表示定时器的初始值,即定时器首次触发的时间。同样,它也是一个struct timespec结构体类型的变量。

通过设置it_interval和it_value的值,可以控制定时器的触发时间和触发频率。

以下是使用struct itimerspec结构体来设置定时器的间隔时间和初始值的示例:

#include <sys/time.h>

void setTimer() {
    timer_t timerid;
    struct itimerspec its;

    // 设置定时器间隔时间为2秒,初始值为3秒
    its.it_interval.tv_sec = 2;
    its.it_interval.tv_nsec = 0;
    its.it_value.tv_sec = 3;
    its.it_value.tv_nsec = 0;

    // 设置定时器
    timer_settime(timerid, 0, &its, NULL);

    // 其他处理定时器的操作
}

首先定义了一个itimerspec结构体变量its,并设置了定时器的间隔时间和初始值。

然后,通过调用timer_settime函数来设置定时器。最后,可以进行其他处理定时器的操作。

需要注意的是,it_interval.tv_nsec和it_value.tv_nsec的时间单位是纳秒。在设置定时器时,可以根据需要将其设为不同的值,以实现所需的定时触发行为。

3.停止定时器

停止定时器相对比较简单,将时间相关参数设置为0即可。

static struct itimerspec its = {{0, 0}, {0, 0}};  
timer_settime(timerData.hTimerHandle, 0, &its, NULL);

4.删除定时器

要删除定时器,需要等定时器停止运行之后才能删除,所以第一步应停止定时器。

timer_delete(timerData.hTimerHandle);
//对于存放定时器相关数据的结构体可以清空
memset(&timeData, (uint8_t)0x00, sizeof(TimerData));

5. Android UWB HAL应用

在Android UWB HAL实现中,对定时器进行了一定的封装,如下:

/*
 **Timer Handle structure containing details of a timer.
 */
typedef struct phOsalUwb_TimerHandle {
    timer_t hTimerHandle; /* Handle of the timer */
    /* Timer callback function to be invoked */
    pphOsalUwb_TimerCallbck_t Application_callback;
    void* pContext; /* Parameter to be passed to the callback function */

    phOsalUwb_TimerStates_t eState; /* Timer states */
    /* Osal Timer message posted on User Thread */
    phLibUwb_Message_t tOsalMessage;
  
    //...

} phOsalUwb_TimerHandle_t, *pphOsalUwb_TimerHandle_t;

在timer_t句柄的基础之上增加了相关的回调函数、消息、上下文参数等等,基于定时器实现相关的访问需求。

在phOsalUwb_Timer的实现中,定义了一个phOsalUwb_TimerHandle_t的定时器数组,可以支持多个定时器,以支持多个定时任务的处理。

// 获取自定义定时器句柄
pTimerHandle = (phOsalUwb_TimerHandle_t*)&apTimerInfo[dwIndex];
// 设置定时时间,略

//启动定时器
timer_settime(pTimerHandle->hTimerHandle, 0, &its, NULL);

// 停止定时器
static struct itimerspec its = {{0, 0}, {0, 0}};
timer_settime(pTimerHandle->hTimerHandle, 0, &its, NULL);

// 删除定时器
timer_delete(pTimerHandle->hTimerHandle)

// 由于自定义了定时器结构,需要清除存储的相关数据,这里直接全部设置为0.
/* Clear Timer structure used to store timer related data */
memset(pTimerHandle, (uint8_t)0x00, sizeof(phOsalUwb_TimerHandle_t));
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  bWLIE0wKp9lo   2024年05月31日   83   0   0 Linux硬件
  qrJHiMhufrJ3   2023年11月13日   29   0   0 嵌入式Linux学习git
fgEzWBuBS8L1