⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 timerd.c

📁 AT91所有开发板的资料 AT91所有开发板的资料
💻 C
📖 第 1 页 / 共 2 页
字号:
    long cur_sum, prev_sum;    angel_Timer *tel;    /* if no list, it's easy */    if (IsListEmpty(&angel_Active_Timers))    {        this->delay = this->interval;        /* LogInfo(LOG_TIMER, ("queueTimer: Add to EL (%d)\n", this->interval)); */        Timer_AddHead(&angel_Active_Timers, this);        return;    }    /* if our interval is earliest of all list, it's easy too */    tel = Timer_FirstNode(&angel_Active_Timers);    if (tel->delay >= this->interval)    {        /* our delay is simply our interval         */        this->delay = this->interval;        /* set the delay of the next to account for ours coming first         */        tel->delay -= this->interval;        /* LogInfo(LOG_TIMER, ("queueTimer: Add SOL (%d)\n", this->interval)); */        /* add ourselves at the list head         */        Timer_AddHead(&angel_Active_Timers, this);        return;    }    /*     * must find out where to put new timer. Loop to find the first node     * for which the interval is larger, calculating the sum of delays     * for the previous and this node.     *     * almost invariant:   cur_sum := prev_sum + tel->delay     * [ not for first loop, but we have considered those cases anyway]     *     */    cur_sum = 0;    prev_sum = 0;    while(!Timer_AtEndOfList(tel))    {        prev_sum = cur_sum;        cur_sum += tel->delay;                /* wait for a larger delay. If the delays are equal (that is,         * cur_sum == this->interval) we intentionally put the newer         * call after the older by advancing tel to the next node.         */        if ( cur_sum > this->interval )            break;        tel = Timer_Succ(tel);    }    LogInfo(LOG_TIMER, ("queueTimer: this %d cs %d, ps %d\n", this->interval, cur_sum, prev_sum));    /*     * We insert *before* a node: if at end of list, there is no     * before, so add at end.     *     * [I guess in theory InsertBefore can work with tel at eol but     *  this is a lot clearer -- ric]     */    if (Timer_AtEndOfList(tel))    {        /* if tel is at end, it exited the while loop without updating         * prev_sum for the last node; hence we use cur_sum here, not         * prev_sum         */        this->delay = this->interval - cur_sum;        LogInfo(LOG_TIMER, ("queueTimer: Add EOL: %d\n", this->delay));        /* add timer at end of list  */        Timer_AddTail(&angel_Active_Timers, this);    }    else    {        /*         * set the delay of the to-be-inserted node; prev_sum is the         * sum up to the point we want to insert, so the delay from         * there is easy:         */        this->delay = this->interval - prev_sum;        /*         * add timer before 'tel' in list, adjusting tel's delay:         *         *   cur_sum is the delay from now to the time tel fires. If         *   you subtract the new node's interval you get the delay         *   from this node to the next.         */        tel->delay = cur_sum - this->interval;        LogInfo(LOG_TIMER, ("queueTimer: Add MID: this->delay = %s, tel->delay = %d\n", this->delay, tel->delay));        /* Insert 'this' before 'tel' in list */        Timer_Insert(tel, this);    }}/* *        Function:  Timer_DeleteTimer * *         Purpose:  Externally visible function to delete a *                   given timer. Passed the small integer timer *                   id, converts to a timer pointer and *                   passes it to timer_delTimer. * *       Arguments:  timer - the timer id. *                    *          Return:  none * *  Pre-conditions:  Timers initialised. * * Post-conditions:  This timer deleted, if it was valid. * */void Timer_DeleteTimer(int timer){    angel_Timer *t = &angel_Timer_Pool[timer];    int s = Angel_TimerDev.timer_critical();    LogInfo(LOG_TIMER, ("DeleteTimer: timer %d\n", timer));        if (timer < MAX_TIMERS && (t->flags & TF_ALLOC))    {        timer_delTimer(t);        t->flags = 0;        Timer_AddTail(&angel_Free_Timers, t);    }    Angel_TimerDev.timer_normal(s);}/* *        Function:  timer_delTimer * *         Purpose:  delete the given timer  from the *                   timer list. It is more efficient *                   if the timer is the head element. *                    * *       Arguments:  t - pointer to a timer which should be *                       in the timer list. * *          Return:  none * *  Pre-conditions:  t must be part of the timer list and the *                   routine Timer_Initialise called. * * Post-conditions:  t is no longer part of the timer *                   list; delays including 't' adjusted. * */static void timer_delTimer(angel_Timer *t){    /*     * if the delay in t is non-zero, we must add     * that delay to the next element in the     * timer list, or it will happen t->delay ms     * early.     */    if (!Timer_AtEndOfList(t))    {        angel_Timer *nt = Timer_Succ(t);        if (t->delay)            LogInfo(LOG_TIMER, ("delTimer: add delay %d to %d\n", t->delay, nt->delay));        nt->delay += t->delay;    }    /*     * Remove t from the list. Calling code must add it     * to free list if needed.     */    Timer_Remove(t);}#endif /* defined(TEST) || TIMER_SUPPORTED *//**********************************************************************************//* test code for the above using Unix timers  to simulate interrupt events. */#ifdef TEST#undef CLK_TCK#include <signal.h>#include <sys/time.h>static int unix_interval;#ifdef TEST_PRINTvoid timer_printList(char *str){    angel_Timer *tl = Timer_FirstNode(&angel_Active_Timers);    printf(str);    while(!Timer_AtEndOfList(tl))    {        printf("[ i(%d) d(%d) %c%c%c ] ", tl->interval, tl->delay,                                tl->flags & TF_ALLOC ? 'A' : 'a',                                tl->flags & TF_SIGNALME ? 'S' : 's',                                tl->flags & TF_RELOAD ? 'R' : 'r');        tl = Timer_Succ(tl);    }    putchar('\n');}#endif /* TIMER_SUPPORTED */unix_sigalrm(){    Timer_Tick(0);}void unix_timer_init(){    struct sigaction act;    act.sa_handler = SIG_IGN;    sigemptyset(&act.sa_mask);    act.sa_flags = 0;    act.sa_restorer = 0;    if (sigaction(SIGALRM, &act, NULL) < 0)        perror("sigact");}void unix_timer_stop(){    struct sigaction act;    struct itimerval nextv;    nextv.it_interval.tv_sec = 0;    nextv.it_interval.tv_usec = 0;    nextv.it_value = nextv.it_interval;    act.sa_handler = SIG_IGN;    sigemptyset(&act.sa_mask);    sigaddset(&act.sa_mask,SIGALRM);    act.sa_flags = 0;    act.sa_restorer = 0;    if (sigaction(SIGALRM, &act, NULL) < 0)        perror("sigact");    if (setitimer(ITIMER_REAL, &nextv, NULL) < 0)        perror("setitimer");}void unix_timer_start(){    struct itimerval nextv;    struct sigaction act;    act.sa_handler = (__sighandler_t)unix_sigalrm;    sigemptyset(&act.sa_mask);    sigaddset(&act.sa_mask,SIGALRM);    act.sa_flags = 0;    act.sa_restorer = 0;    nextv.it_interval.tv_sec = 0;    nextv.it_interval.tv_usec = unix_interval;    nextv.it_value = nextv.it_interval;    if (sigaction(SIGALRM, &act, NULL) < 0)        perror("sigact");    if (setitimer(ITIMER_REAL, &nextv, NULL) < 0)        perror("setitimer");}int unix_timer_critical(void){}void unix_timer_normal(int s){}void unix_timer_set_interval(long interval){    unix_interval = interval;}long unix_timer_get_interval(void){    return unix_interval;}const struct TimerDev Angel_TimerDev ={    unix_timer_init,    unix_timer_start,    unix_timer_stop,    unix_timer_critical,    unix_timer_normal,    unix_timer_set_interval,    unix_timer_get_interval};static void unix_event(int s){    printf("event %d signalled\n", s);}static int Angel_Signal(int t, int s){    printf("task %d signalled %d\n", t, s);    return 0;}int main(int argc, char *argv[]){    int i;    printf("Init\n");    Timer_Initialise();    printf("Start\n");    while(Timer_currentTime < 200)    {    }    printf("Time: %d\n", Timer_currentTime);    printf("Add timer -- 80ms, Signal, Reload\n");    i = Timer_NewTimer(80, TF_SIGNALME | TF_RELOAD, (TimerCallback)1, 2);    printf("Got timer %d\n", i);    while(Timer_currentTime < 500)    {    }    printf("Del timer\n");    Timer_DeleteTimer(i);    printf("Time: %d\n", Timer_currentTime);    while(Timer_currentTime < 700)    {    }    printf("Time: %d\n", Timer_currentTime);    printf("Add timer -- 80ms, Signal, Reload\n");    i = Timer_NewTimer(80, TF_SIGNALME | TF_RELOAD, (TimerCallback)1, 2);    printf("Got timer %d\n", i);    printf("Add timer -- 200ms, Event, Reload\n");    i = Timer_NewTimer(200, TF_RELOAD, (TimerCallback)unix_event, 2);    printf("Got timer %d\n", i);    while(Timer_currentTime < 2000)    {    }    printf("Time: %d\n", Timer_currentTime);    printf("Stop\n");}#endif /* TEST *//**********************************************************************************//* EOF timer.c */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -