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

📄 timerd.c

📁 AT91所有开发板的资料 AT91所有开发板的资料
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -*-C-*- * * $Revision: 1.3 $ *   $Author: rivimey $ *     $Date: 1999/03/22 14:44:49 $ * * Copyright (c) 1996 Advanced RISC Machines Limited. * All Rights Reserved. * *   Project: ANGEL * *     Title: Angel Timer driver * */#ifdef TEST#define INLINE_LIST_FNSint Angel_Needschedule;#ifndef bool#define bool int#endif#ifndef NULL#define NULL 0#endif#ifndef FALSE#define FALSE 0#define TRUE 1#endif#else /* not TEST */#include "angel.h"#include "arm.h"#include "devconf.h"#include "serlock.h"#include "logging.h"#endif /* TEST */#if defined(TEST) || (defined(TIMER_SUPPORTED) && TIMER_SUPPORTED > 0)#include "timerd.h"#include "list.h"static volatile unsigned long Timer_currentTime;static bool timer_initialised;typedef struct _timer{    MinNode n;    long interval;    long delay;    short flags;    short index;    union     {        TimerCallback fn;        int taskid;    } obj;    int data; /* the signal or a fn arg */} angel_Timer;#include "timerlist.h"static angel_Timer angel_Timer_Pool[MAX_TIMERS];static List angel_Active_Timers;static List angel_Free_Timers;static void timer_delTimer(angel_Timer *t);static void timer_queueTimer(angel_Timer *this);#ifdef TEST_PRINTvoid timer_printList(char *str);#else#define timer_printList(s)#endif#if 0void timer_printList(char *str){    angel_Timer *tl = Timer_FirstNode(&angel_Active_Timers);    LogInfo(LOG_TIMER, (str));    while(!Timer_AtEndOfList(tl))    {        LogInfo(LOG_TIMER, ("[ 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);    }    LogInfo(LOG_TIMER, ("\n"));}#endif/* *        Function:  Timer_CurrentTime * *         Purpose:  return the current time, measured in *                   milliseconds  *                    *       Arguments:  none. *                    * *          Return:  unsigned long - the time in milliseconds *                                   since 'some point'. * *  Pre-conditions:  none. * * Post-conditions:  none. * */unsigned long Timer_CurrentTime(void){    return Timer_currentTime;}/* *        Function:  Timer_Delay * *         Purpose:  delay the current task for a number of milliseconds. *                    * *       Arguments:  delay - a delay in milliseconds. the routine will. *                           return after at least this number of milliseconds *                           has elapsed. (Note: the actual delay will be  *                           rounded up to a multiple of CLK_TICK milliseconds). * *          Return:  none * *  Pre-conditions:  Only call if interrupts are enabled, Timer_Initialise *                   AngelOS_Initialise have been called, and the scheduler *                   entered. * * Post-conditions:  none. * */void Timer_Delay(unsigned long delay){    int t;    if ((Angel_GetCPSR() & AngelInterruptMask) != 0)    {    	LogWarning(LOG_TIMER, ("Timer_Delay: Interrupts not enabled in Delay"));	return;    }    t = Timer_NewTimer(delay, TF_SIGNALME, (TimerCallback)Angel_TaskID(), SIGBIT_DELAY);    LogInfo(LOG_TIMER, ("Delay: Using timer %d\n", t));    Angel_Wait(SIGBIT_DELAY);    LogInfo(LOG_TIMER, ("Delay: wakeup\n"));}/* *        Function:  Timer_Tick * *         Purpose:  "tick" function, which advances time. *                   Expects to be called regularly, preferably at *                   millisecond intervals *                    *                   Firstly, increment the current time variable *                   by CLK_TCK milliseconds. *                    *                   Second, inspect the timer list. If there are *                   timers, decrement the head timer delay; if it *                   drops to zero the timer has expired. Fire the *                   timer. *                    *                   The next timer could also  * *       Arguments:  empty_stack - the empty stack value which would *                                 be required to serialise a task. * *          Return:  none * *  Pre-conditions:   *                    *                    * * Post-conditions:   * */void Timer_Tick(unsigned empty_stack){    /* increment the current time... */    Timer_currentTime += CLK_TCK;    if (!IsListEmpty(&angel_Active_Timers))    {        register angel_Timer *tl = Timer_FirstNode(&angel_Active_Timers);        timer_printList("tick");        /* decrement the delay until the next event */        tl->delay -= CLK_TCK;        while (tl != NULL && tl->delay <= 0)        {            /* LogInfo(LOG_TIMER, ("FireTimer: %d\n", tl->index)); */                        if (tl->flags & TF_SIGNALME)            {                if (Angel_Signal(tl->obj.taskid, tl->data))                    Angel_Needschedule = 1;            }            else            {                tl->obj.fn(tl->data, empty_stack);            }            /* ... delete the timer (& modify next delay if necessary) ... */            timer_delTimer(tl);            /* ... if reloading, requeue the timer, else free it */            if (tl->flags & TF_RELOAD)                timer_queueTimer(tl);            else                Timer_AddTail(&angel_Free_Timers, tl);            /* and get the new timer head, to check the next delay. */            tl = Timer_FirstNode(&angel_Active_Timers);        }     }    return;}/* *        Function:  Timer_Initialise * *         Purpose:   *                    *                    *                    * *       Arguments:  none * *          Return:  none * *  Pre-conditions:  none *                    * * Post-conditions:   * */void Timer_Initialise(void){    int i;    NewList(&angel_Active_Timers);    NewList(&angel_Free_Timers);    for(i = 0; i < MAX_TIMERS; i++)    {        angel_Timer_Pool[i].index = i;        angel_Timer_Pool[i].flags = 0;        angel_Timer_Pool[i].delay = 0;        angel_Timer_Pool[i].interval = 0;        Timer_AddTail(&angel_Free_Timers, &angel_Timer_Pool[i]);    }    Timer_currentTime = 0;    Angel_TimerDev.timer_init();    timer_initialised = TRUE;    LogInfo(LOG_TIMER, ("Timer Initialised\n"));        /* set the timer going at 1ms interval */    Angel_TimerDev.timer_set_interval(CLK_TCK * 1000);    Angel_TimerDev.timer_start();        LogInfo(LOG_TIMER, ("Timer Started\n"));}/* *        Function:  Timer_NewTimer * *         Purpose:  To create a new timer, which can be used to schedule *                   timed events, for example, the poll event, or the *                   SYS_TIME 1 second clock. * *       Arguments:   *                   interval - time in ms from now to event, and interval *                              from then to next event if RELOAD *                   flags -    TF_SIGNALME - Signal event, else call fn *                              TF_RELOAD   - reload timer on expiry *                   fn -       function to call, or task id to signal *                   arg -      arg of function, or signal bit to signal. * *          Return:  none * *  Pre-conditions:  Timer_Initialse must have been called. * * Post-conditions:   * */int Timer_NewTimer(long interval, int flags, TimerCallback fn, int data){    angel_Timer *tl;        int s = Angel_TimerDev.timer_critical();    LogInfo(LOG_TIMER, ("NewTimer: interval %ld, fn %p\n", interval, fn));        tl = Timer_RemHead(&angel_Free_Timers);    if (tl == NULL)    {        Angel_TimerDev.timer_normal(s);        return -1;    }    tl->flags = TF_ALLOC | flags;    Angel_TimerDev.timer_normal(s);    tl->interval = interval;    tl->delay = 0;    tl->data = data;    if (flags & TF_SIGNALME)        tl->obj.taskid = (int)fn;    else        tl->obj.fn = (TimerCallback)fn;    timer_queueTimer(tl);    LogInfo(LOG_TIMER, ("NewTimer: returning %d\n", tl->index));        timer_printList("new");    return tl->index;}/* *        Function:  timer_queueTimer * *         Purpose:  To add a new timer to the timer queue. The queue is *                   ordered by relative time; the sooner a timer is to *                   going off, the nearer the timer is to the head of the *                   list. The "delay" element of the timer indicates the *                   gap in time between the previous timer (or Now) and *                   this one, thus the 'tick' interrupt only has to *                   modify the head of the list, if any. *                    *                   Thus, if there are no timers in the list, then this *                   one can be added with a delay equal to the interval. *                    *                   If not, then the effective interval (that part of the *                   interval between now and the time a particular timer *                   expires) must be calculated and the interval for the *                   new timer compared to it. When the effective interval *                   becomes larger than the new interval, the new timer *                   can be inserted in front of the list. *                    *                   Finally, if this interval is longer than any other, *                   the new one must be added to the end of the list. *                    * *       Arguments:  this - a partly-initialised angel_Timer_Pool element. *                          it is expected that the interval, obj and data *                          elements are filled in. * *          Return:  none * *  Pre-conditions:  Timer head and tail initialised; "this" members obj, *                   data and interval initialised. *                    * * Post-conditions:  angel_Timer_Pool element added to timer queue. * */static void timer_queueTimer(angel_Timer *this){

⌨️ 快捷键说明

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