/* * Copyright (c) 2006 Christiaan Simons. * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. * * This file is part of and a contribution to the lwIP TCP/IP stack. * * Author: Christiaan Simons */ /** * @file * Simple pre-allocated interval (reload) timers. * @see timer.h */ #include #include #include #include "timer.h" #include "lwip/snmp.h" static struct itimerval tmr; struct itmr { volatile unsigned int interval; volatile unsigned int cnt; volatile unsigned char event; }; static struct itmr timers[TIMER_NUM]; void sigalarm_handler(int sig); /** * Initializes interval timers. */ void timer_init(void) { unsigned char i; struct itmr *tp; tp = &timers[TIMER_NUM-1]; for(i = TIMER_NUM; i > 0; i--) { tp->event = 0; tp->interval = 0; tp->cnt = 0; tp--; } signal(SIGALRM,sigalarm_handler); /* timer reload is in 10msec steps */ tmr.it_interval.tv_sec = 0; tmr.it_interval.tv_usec = 10000; /* set to half period (enables timer) */ tmr.it_value.tv_sec = 0; tmr.it_value.tv_usec = 5000; setitimer(ITIMER_REAL,&tmr,NULL); } /** * Configures timer. * * @param tmr the timer number from timer.h * @param interval when > 0 enables this timer, 0 disables. */ void timer_set_interval(unsigned char tmr_num, unsigned int interval) { if (tmr_num < TIMER_NUM) { timers[tmr_num].interval = interval; } } /** * Returns timer event and restarts timer. */ unsigned char timer_testclr_evt(unsigned char tmr_num) { if (tmr_num < TIMER_NUM) { unsigned char evt; struct itmr *tp; tp = &timers[tmr_num]; evt = tp->event; if (tp->event != 0) { tp->event = 0; tp->cnt = tp->interval; } return evt; } else { return 0; } } /** * interrupting (!) sigalarm handler */ void sigalarm_handler(int sig) { unsigned char i; struct itmr *tp; LWIP_UNUSED_ARG(sig); snmp_inc_sysuptime(); tp = &timers[TIMER_NUM-1]; for(i = TIMER_NUM; i > 0; i--) { if (tp->interval != 0) { /* timer is running */ if (tp->cnt == 0) { /* timer expired */ tp->event |= 1; } else { /* timer ticking */ tp->cnt--; } } tp--; } }