예제 #1
0
/**
 * \brief Forks a separate simple sleep() -&- sync periodic timer
 *
 * Forks a very basic periodic timer process, that just sleep()s for 
 * the specified interval and then calls the timer function.
 * The new "sync timer" process execution start immediately, the sleep()
 * is called first (so the first call to the timer function will happen
 * \<interval\> seconds after the call to fork_sync_timer)
 * @param child_id  @see fork_process()
 * @param desc      @see fork_process()
 * @param make_sock @see fork_process()
 * @param f         timer function/callback
 * @param param     parameter passed to the timer function
 * @param interval  interval in seconds.
 * @return pid of the new process on success, -1 on error
 * (doesn't return anything in the child process)
 */
int fork_sync_timer(int child_id, char* desc, int make_sock,
						timer_function* f, void* param, int interval)
{
	int pid;
	ticks_t ts1 = 0;
	ticks_t ts2 = 0;

	pid=fork_process(child_id, desc, make_sock);
	if (pid<0) return -1;
	if (pid==0){
		/* child */
		interval *= 1000;  /* miliseconds */
		ts2 = interval;
		if (cfg_child_init()) return -1;
		for(;;){
			if (ts2>interval)
				sleep_us(1000);    /* 1 milisecond sleep to catch up */
			else
				sleep_us(ts2*1000); /* microseconds sleep */
			ts1 = get_ticks_raw();
			cfg_update();
			f(TICKS_TO_S(ts1), param); /* ticks in sec for compatibility with old
									  timers */
			/* adjust the next sleep duration */
			ts2 = interval - TICKS_TO_MS(get_ticks_raw()) + TICKS_TO_MS(ts1);
		}
	}
	/* parent */
	return pid;
}
예제 #2
0
파일: sys_arch.c 프로젝트: a3zzat/LAB_AEP
u32_t
sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
{
#define SYS_MSPERTICK (SYSTMR_INTERVAL/SYSTMR_CLK_FREQ_KHZ)
#define TICKS_TO_MS(x) ((x) * SYS_MSPERTICK)


	if (timeout) {	/* Try to acquire the semaphore within timeout. If not return */
		u32_t ticks = xget_clock_ticks();
		u32_t nticks = 0;
		if (!sem_timedwait(sem, timeout)) {	/* sem_timedwait returns 0 on success */
			nticks = xget_clock_ticks();
			if (nticks >= ticks)
				return TICKS_TO_MS(nticks-ticks);
			else {
				/* overflow condition */
				/* we'll assume that this has overflowed just once */
				return TICKS_TO_MS((0xffffffff - ticks) + nticks);
			}
		} else {
			return SYS_ARCH_TIMEOUT;
		}
	} else  {
		sem_wait(sem);
	}

	return 0;
}
예제 #3
0
/* frees all the expired entries until either there are no more of them
 *  or the total memory used is <= target (to free all of them use -1 for
 *  targer)
 *  params:   target  - free expired entries until no more then taget memory
 *                      is used  (use 0 to free all of them)
 *            delta   - consider an entry expired if it expires after delta
 *                      ticks from now
 *            timeout - exit after timeout ticks
 *
 *  returns: number of deleted entries
 *  This function should be called periodically from a timer
 */
inline static int dst_blacklist_clean_expired(unsigned int target,
									  ticks_t delta,
									  ticks_t timeout)
{
	static unsigned int start=0;
	unsigned int h;
	struct dst_blst_entry** crt;
	struct dst_blst_entry** tmp;
	struct dst_blst_entry* e;
	ticks_t start_time;
	ticks_t now;
	int no=0;
	int i;

	now=start_time=get_ticks_raw();
	for(h=start; h!=(start+DST_BLST_HASH_SIZE); h++){
		i=h%DST_BLST_HASH_SIZE;
		if (dst_blst_hash[i].first){
			LOCK_BLST(i);
			for (crt=&dst_blst_hash[i].first, tmp=&(*crt)->next;
					*crt; crt=tmp, tmp=&(*crt)->next){
				e=*crt;
				prefetch_loc_r((*crt)->next, 1);
				if ((s_ticks_t)(now+delta-(*crt)->expire)>=0){
					*crt=(*crt)->next;
					tmp=crt;
					*blst_mem_used-=DST_BLST_ENTRY_SIZE(*e);
					blst_destroy_entry(e);
					BLST_HASH_STATS_DEC(i);
					no++;
					if (*blst_mem_used<=target){
						UNLOCK_BLST(i);
						goto skip;
					}
				}
			}
			UNLOCK_BLST(i);
			/* check for timeout only "between" hash cells */
			now=get_ticks_raw();
			if ((now-start_time)>=timeout){
				DBG("_dst_blacklist_clean_expired_unsafe: timeout: %d > %d\n",
						TICKS_TO_MS(now-start_time), TICKS_TO_MS(timeout));
				goto skip;
			}
		}
	}
skip:
	start=h; /* next time we start where we left */
	if (no){
		DBG("dst_blacklist_clean_expired, %d entries removed\n", no);
	}
	return no;
}
예제 #4
0
u32_t
sys_jiffies( void )
{
    portTickType    xTicks = xTaskGetTickCount(  );

    return ( u32_t )TICKS_TO_MS( xTicks );
}
예제 #5
0
/*
 * Blocks the thread while waiting for the semaphore to be
 * signaled. If the "timeout" argument is non-zero, the thread should
 * only be blocked for the specified time (measured in
 * milliseconds).
 *
 * If the timeout argument is non-zero, the return value is the number of
 * milliseconds spent waiting for the semaphore to be signaled. If the
 * semaphore wasn't signaled within the specified time, the return value is
 * SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore
 * (i.e., it was already signaled), the function may return zero.
 *
 * Notice that lwIP implements a function with a similar name,
 * sys_sem_wait(), that uses the sys_arch_sem_wait() function.
 */
u32_t
sys_arch_sem_wait( sys_sem_t sem, u32_t timeout )
{
    portBASE_TYPE   xStatus;
    portTickType    xTicksStart, xTicksEnd, xTicksElapsed;
    u32_t           timespent;

    LWIP_ASSERT( "sys_arch_sem_wait: sem != SYS_SEM_NULL", sem != SYS_SEM_NULL );
    xTicksStart = xTaskGetTickCount(  );
    if( timeout == 0 )
    {
        do
        {
            xStatus = xSemaphoreTake( sem, MS_TO_TICKS( 100 ) );
        }
        while( xStatus != pdTRUE );
    }
    else
    {
        xStatus = xSemaphoreTake( sem, MS_TO_TICKS( timeout ) );
    }

    /* Semaphore was signaled. */
    if( xStatus == pdTRUE )
    {
        xTicksEnd = xTaskGetTickCount(  );
        xTicksElapsed = xTicksEnd - xTicksStart;
        timespent = TICKS_TO_MS( xTicksElapsed );
    }
    else
    {
        timespent = SYS_ARCH_TIMEOUT;
    }
    return timespent;
}
예제 #6
0
unsigned long
sys_jiffies( void )
{
    portTickType    xTicks = xTaskGetTickCount(  );

    return ( unsigned long )TICKS_TO_MS( xTicks );
}
예제 #7
0
/**
 * \brief Forks a separate simple milisecond-sleep() -&- sync periodic timer
 *
 * Forks a very basic periodic timer process, that just ms-sleep()s for 
 * the specified interval and then calls the timer function.
 * The new "sync timer" process execution start immediately, the ms-sleep()
 * is called first (so the first call to the timer function will happen
 * \<interval\> seconds after the call to fork_basic_utimer)
 * @param child_id  @see fork_process()
 * @param desc      @see fork_process()
 * @param make_sock @see fork_process()
 * @param f         timer function/callback
 * @param param     parameter passed to the timer function
 * @param uinterval  interval in mili-seconds.
 * @return pid of the new process on success, -1 on error
 * (doesn't return anything in the child process)
 */
int fork_sync_utimer(int child_id, char* desc, int make_sock,
						utimer_function* f, void* param, int uinterval)
{
	int pid;
	ticks_t ts1 = 0;
	ticks_t ts2 = 0;

	pid=fork_process(child_id, desc, make_sock);
	if (pid<0) return -1;
	if (pid==0){
		/* child */
		ts2 = uinterval;
		if (cfg_child_init()) return -1;
		for(;;){
			if(ts2>0) sleep_us(uinterval);
			else sleep_us(1);
			ts1 = get_ticks_raw();
			cfg_update();
			f(TICKS_TO_MS(ts1), param); /* ticks in mili-seconds */
			ts2 = uinterval - get_ticks_raw() + ts1;
		}
	}
	/* parent */
	return pid;
}
예제 #8
0
파일: timer.c 프로젝트: kamailio/kamailio
/* gettimeofday(2) equivalent, using ser internal timers (faster
 * but more imprecise)
 * WARNING: ignores tz (it's obsolete anyway)*/
int ser_gettimeofday(struct timeval* tv, struct timezone* tz)
{
	if (likely(tv!=0)){
		tv->tv_sec=last_time.tv_sec+TICKS_TO_S(*ticks-last_ticks);
		tv->tv_usec=last_time.tv_usec+
					(TICKS_TO_MS(*ticks-last_ticks)%1000)*1000;
	}
	return 0;
}
예제 #9
0
파일: sys_arch.c 프로젝트: a3zzat/LAB_AEP
u32_t
sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
{
	u32_t start_ticks = 0;
	u32_t stop_ticks = 0;
	u32_t ticks = 0;

	/* The mutex lock is quick so we don't bother with the timeout stuff here. */
	sem_wait(&mbox->mutex);

	while (mbox->first == mbox->last) {
		/* no messages in mailbox, relinqush control */
		sem_post(&mbox->mutex);

		/* Block w/ timeout while waiting for a mail to arrive in the mailbox. */
		if (timeout) {    /* Try to acquire the semaphore within timeout. If not return */
			int pid;

			start_ticks = xget_clock_ticks();
			pid = get_currentPID();
			if (sem_timedwait(&mbox->mail, timeout)) {
				return SYS_ARCH_TIMEOUT;
			}
			stop_ticks = xget_clock_ticks();
		} else {
			sem_wait (&mbox->mail);
		}

		/* now that there is a message, regain control of mailbox */
		sem_wait (&mbox->mutex);
	}

	/* obtain the first message */
	if (msg != NULL) {
		*msg = mbox->msgs[mbox->first];
	}

	mbox->first++;
	if(mbox->first == SYS_MBOX_SIZE) {
		mbox->first = 0;
	}

	/* relinqush control of the mailbox */
	sem_post(&mbox->mutex);

	/* find out how much time it took us */
	if (stop_ticks >= start_ticks)
		ticks = stop_ticks - start_ticks;
	else
		ticks = (0xffffffff - start_ticks) + stop_ticks;

	return TICKS_TO_MS(ticks);
}
예제 #10
0
static inline int db_do_submit_query(const db1_con_t* _h, const str *_query,
		int (*submit_query)(const db1_con_t*, const str*))
{
	int ret;
	unsigned int ms = 0;

	if(unlikely(cfg_get(core, core_cfg, latency_limit_action)>0))
		ms = TICKS_TO_MS(get_ticks_raw());

	ret = submit_query(_h, _query);

	if(unlikely(cfg_get(core, core_cfg, latency_limit_action)>0)) {
		ms = TICKS_TO_MS(get_ticks_raw()) - ms;
		if(ms >= cfg_get(core, core_cfg, latency_limit_action)) {
				LOG(cfg_get(core, core_cfg, latency_log),
					"alert - query execution too long [%u ms] for [%.*s]\n",
				   ms, _query->len<50?_query->len:50, _query->s);
		}
	}

	return ret;
}
예제 #11
0
/*
 * Blocks the thread until a message arrives in the mailbox, but does
 * not block the thread longer than "timeout" milliseconds (similar to
 * the sys_arch_sem_wait() function). The "msg" argument is a result
 * parameter that is set by the function (i.e., by doing "*msg =
 * ptr"). The "msg" parameter maybe NULL to indicate that the message
 * should be dropped.
 *
 * Note that a function with a similar name, sys_mbox_fetch(), is
 * implemented by lwIP.
 */
u32_t
sys_arch_mbox_fetch( sys_mbox_t mbox, void **msg, u32_t timeout )
{
    void           *ret_msg;
    portBASE_TYPE   xStatus;
    portTickType    xTicksStart, xTicksEnd, xTicksElapsed;
    u32_t           timespent;

    LWIP_ASSERT( "sys_arch_mbox_fetch: mbox != SYS_MBOX_NULL", mbox != SYS_MBOX_NULL );
    xTicksStart = xTaskGetTickCount(  );
    if( timeout == 0 )
    {
        do
        {
            xStatus = xQueueReceive( mbox, &ret_msg, MS_TO_TICKS( 100 ) );
        }
        while( xStatus != pdTRUE );
    }
    else
    {
        xStatus = xQueueReceive( mbox, &ret_msg, MS_TO_TICKS( timeout ) );
    }

    if( xStatus == pdTRUE )
    {
        if( msg )
        {
            *msg = ret_msg;
        }
        xTicksEnd = xTaskGetTickCount(  );
        xTicksElapsed = xTicksEnd - xTicksStart;
        timespent = TICKS_TO_MS( xTicksElapsed );
    }
    else
    {
        if( msg )
        {
            *msg = NULL;
        }
        timespent = SYS_ARCH_TIMEOUT;
    }
    return timespent;
}
예제 #12
0
/**
 * \brief Forks a separate simple milisecond-sleep() periodic timer
 * 
 * Forks a very basic periodic timer process, that just ms-sleep()s for 
 * the specified interval and then calls the timer function.
 * The new "basic timer" process execution start immediately, the ms-sleep()
 * is called first (so the first call to the timer function will happen
 * \<interval\> seconds after the call to fork_basic_utimer)
 * @param child_id  @see fork_process()
 * @param desc      @see fork_process()
 * @param make_sock @see fork_process()
 * @param f         timer function/callback
 * @param param     parameter passed to the timer function
 * @param uinterval  interval in mili-seconds.
 * @return pid of the new process on success, -1 on error
 * (doesn't return anything in the child process)
 */
int fork_basic_utimer(int child_id, char* desc, int make_sock,
						utimer_function* f, void* param, int uinterval)
{
	int pid;
	ticks_t ts;
	
	pid=fork_process(child_id, desc, make_sock);
	if (pid<0) return -1;
	if (pid==0){
		/* child */
		if (cfg_child_init()) return -1;
		for(;;){
			sleep_us(uinterval);
			cfg_update();
			ts = get_ticks_raw();
			f(TICKS_TO_MS(ts), param); /* ticks in mili-seconds */
		}
	}
	/* parent */
	return pid;
}
예제 #13
0
/*!
 * @brief			Berechnet aktuelle Mittelwerte und Varianzen und prueft nach dt ms auf bessere Bewertung
 * @param dt		Zeit in ms bevor eine neue Bewertung erstellt wird
 * @param pid_param	Zeiger auf den veraenderlichen PID-Parameter
 * @param step		Wert, um den *pid_param inkrementiert wird
 * Neue beste Parameter werden gespeichert und vor jeder Parameteraenderung wird der Bot kurz angehalten.
 * Bei neuem besten Wert werden die bisher besten Parameter per LOG ausgegeben
 */
static void compare_weightings(const uint16_t dt, int8_t * pid_param, const int8_t step) {
	/* Mittelwerte und Varianzen aktualisieren */
	float weight = calc_weighting();

	/* nach dt ms aktuelle Bewertung mit bisher bester vergleichen */
	if (timer_ms_passed_32(&ticks, dt)) {
		uint32_t dt_real = TIMER_GET_TICKCOUNT_32 - ticks_start;
		weight = weight / (float)dt_real * (dt*1000.0f/176.0f);		// Bewertung normieren
		if (best_weight >= weight) {
			/* Verbesserung => die aktuellen Parameter merken */
			best_weight = weight;
			best_Kp = Kp;
			best_Ki = Ki;
			best_Kd = Kd;

			/* User per LOG informieren */
			LOG_INFO("Kp=%d\tKi=%d\tKd=%d\tnach %u s", best_Kp, best_Ki, best_Kd, TICKS_TO_MS(TIMER_GET_TICKCOUNT_32)/1000);
//			uint32_t weight_int = weight * 1000000.0f;
			LOG_DEBUG("weight=%lu", (uint32_t)(weight * 1000000.0f));
		}

		/* neuen Parameter einstellen und Nachlauf abwarten */
		*pid_param = (int8_t) (*pid_param + step);

//		uint32_t weight_int = weight * 1000000.0f;
//		LOG_DEBUG("weight=%lu", weight_int);

		wait_for_stop();

		/* alten Daten verwerfen */
		clear_weighting();

		/* verbleibende Zeit aktualisieren */
		cal_pid_ete -= dt / 1000;
	}
}
예제 #14
0
파일: ev_epoll.c 프로젝트: wray/haproxy
/*
 * Linux epoll() poller
 */
REGPRM2 static void _do_poll(struct poller *p, int exp)
{
	int status;
	int fd;
	int count;
	int updt_idx;
	int wait_time;
	int old_fd;

	/* first, scan the update list to find polling changes */
	for (updt_idx = 0; updt_idx < fd_nbupdt; updt_idx++) {
		fd = fd_updt[updt_idx];

		HA_ATOMIC_AND(&fdtab[fd].update_mask, ~tid_bit);
		if (!fdtab[fd].owner) {
			activity[tid].poll_drop++;
			continue;
		}

		_update_fd(fd);
	}
	fd_nbupdt = 0;
	/* Scan the global update list */
	for (old_fd = fd = update_list.first; fd != -1; fd = fdtab[fd].update.next) {
		if (fd == -2) {
			fd = old_fd;
			continue;
		}
		else if (fd <= -3)
			fd = -fd -4;
		if (fd == -1)
			break;
		if (fdtab[fd].update_mask & tid_bit)
			done_update_polling(fd);
		else
			continue;
		if (!fdtab[fd].owner)
			continue;
		_update_fd(fd);
	}

	thread_harmless_now();

	/* compute the epoll_wait() timeout */
	if (!exp)
		wait_time = MAX_DELAY_MS;
	else if (tick_is_expired(exp, now_ms)) {
		activity[tid].poll_exp++;
		wait_time = 0;
	}
	else {
		wait_time = TICKS_TO_MS(tick_remain(now_ms, exp)) + 1;
		if (wait_time > MAX_DELAY_MS)
			wait_time = MAX_DELAY_MS;
	}

	/* now let's wait for polled events */

	gettimeofday(&before_poll, NULL);
	status = epoll_wait(epoll_fd[tid], epoll_events, global.tune.maxpollevents, wait_time);
	tv_update_date(wait_time, status);
	measure_idle();

	thread_harmless_end();

	/* process polled events */

	for (count = 0; count < status; count++) {
		unsigned int n;
		unsigned int e = epoll_events[count].events;
		fd = epoll_events[count].data.fd;

		if (!fdtab[fd].owner) {
			activity[tid].poll_dead++;
			continue;
		}

		if (!(fdtab[fd].thread_mask & tid_bit)) {
			/* FD has been migrated */
			activity[tid].poll_skip++;
			epoll_ctl(epoll_fd[tid], EPOLL_CTL_DEL, fd, &ev);
			HA_ATOMIC_AND(&polled_mask[fd], ~tid_bit);
			continue;
		}

		/* it looks complicated but gcc can optimize it away when constants
		 * have same values... In fact it depends on gcc :-(
		 */
		if (EPOLLIN == FD_POLL_IN && EPOLLOUT == FD_POLL_OUT &&
		    EPOLLPRI == FD_POLL_PRI && EPOLLERR == FD_POLL_ERR &&
		    EPOLLHUP == FD_POLL_HUP) {
			n = e & (EPOLLIN|EPOLLOUT|EPOLLPRI|EPOLLERR|EPOLLHUP);
		}
		else {
			n =	((e & EPOLLIN ) ? FD_POLL_IN  : 0) |
				((e & EPOLLPRI) ? FD_POLL_PRI : 0) |
				((e & EPOLLOUT) ? FD_POLL_OUT : 0) |
				((e & EPOLLERR) ? FD_POLL_ERR : 0) |
				((e & EPOLLHUP) ? FD_POLL_HUP : 0);
		}

		/* always remap RDHUP to HUP as they're used similarly */
		if (e & EPOLLRDHUP) {
			HA_ATOMIC_OR(&cur_poller.flags, HAP_POLL_F_RDHUP);
			n |= FD_POLL_HUP;
		}
		fd_update_events(fd, n);
	}
	/* the caller will take care of cached events */
}
예제 #15
0
void SleepHandler::doHibernate(uint32_t ms, bool interruptible) {
  // First, make sure we configure timer2 and get it running as
  // fast as possible. This makes the total sleep delay as
  // accurate as possible.

  // Backup timer2 settings
  uint8_t timsk2 = TIMSK2;
  uint8_t tccr2a = TCCR2A;
  uint8_t tccr2b = TCCR2B;

  // Disable timer2 interrupts, stop the timer and reset it
  // to normal mode. It seems that for some reason, switching to
  // asynchronous mode without these registers cleared can somehow
  // mess up the OCR2x register values...
  TIMSK2 = 0;
  TCCR2B = 0;
  TCCR2A = 0;

  // Backup the counter. There is a small race condition here
  // where a counter interrupt could be missed, but since we're
  // about to sleep for a while and timer2 probably isn't used by
  // anything else, that's ok.
  uint8_t tcnt2 = TCNT2;

  // Enable asynchronous mode for timer2 (uses external 32kHz
  // crystal. This might corrupt the settings registers, so we'll
  // have to (re-)set them all.
  // TCCR2B.
  uint8_t assr = ASSR;
  ASSR |= (1 << AS2);

  // Outputs disconnected, normal mode
  TCCR2A = 0;//(1 << WGM21) | (1 << WGM20);

  // Count all the way up to 0xff
  TCNT2 = 0;
  OCR2B = 0xff;

  // Clear any pending interrupt
  TIFR2 = (1 << OCF2B);

  // Start timer, prescaler 1024, meaning a single timer increment
  // is 1/32s
  TCCR2B = (1 << CS22) | (1 << CS21) | (1 << CS20);

  // Now that timer2 is running, perform any additional power
  // saving preparations

  // Disable Analag comparator
  uint8_t acsr = ACSR;
  ACSR = (1 << ACD);

  // Disable ADC
  uint8_t adcsra = ADCSRA;
  ADCSRA &= ~(1 << ADEN);
  // TODO: When re-enabling the ADC, wait for the AVDDOK bit

  // Disable the TX side of UART0. If the 16u2 it connects to is
  // powered off, it offers a path to ground, so keeping the pin
  // enabled and high (TTL idle) wastes around 1mA of current. To
  // detect if the 16u2 is powered on, see if it pulls the RX pin
  // high (not 100% reliable, but worst case we'll have extra
  // power usage).
  uint8_t ucsr0b = UCSR0B;
  if (UCSR0B & (1 << TXEN0) && !digitalRead(RX0))
    UCSR0B &= ~(1 << TXEN0);

  // Power save mode disables the main clock, but keeps the
  // external clock for timer2 enabled
  set_sleep_mode(SLEEP_MODE_PWR_SAVE);
  sleep_enable();

  cli();

  // Enable the COMPB interrupt to wake us from sleep
  TIMSK2 |= (1 << OCIE2B);

  while (ms >= TIMER_MAX_MS) {
    // Sleep for a complete timer cycle. If interrupt is
    // false, this will always wait for a full cycle and
    // return true. If interrupt is true, this can return
    // false when another interrupt occurs.
    if (sleepUntilMatch(interruptible)) {
      ms -= TIMER_MAX_MS;
      hibernateMillis += TIMER_MAX_MS;
    } else {
      // Another interrupt occurred, bail out
      ms = 0;
    }
  }

  OCR2B = MS_TO_TICKS(ms);
  while (ASSR & (1 << OCR2BUB)) /* nothing */;

  // If there's sleep time left, wait for the final interrupt
  if (TCNT2 < OCR2B)
    sleepUntilMatch(interruptible);

  // Stop the counter. Waiting for this write to be completed has
  // the side effect that the TCNT2 is also safe to read now
  // (which contains an invalid value shortly after waking up from
  // sleep).
  TCCR2B = 0;
  while (ASSR & (1 << TCR2BUB)) /* nothing */;

  hibernateMillis += TICKS_TO_MS(TCNT2);
  sleep_disable();

  // Clear any pending timer2 interrupts before enabling
  // interrupts globally, just in case
  TIFR2 = 0xff;
  sei();

  // Restore timer2 settings.
  ASSR = assr;
  TCNT2 = tcnt2;
  TCCR2B = tccr2b;
  TCCR2A = tccr2a;
  TIMSK2 = timsk2;

  // Restore other settings
  UCSR0B = ucsr0b;
  ACSR = acsr;
  ADCSRA = adcsra;
  while (ADCSRB & (1 << AVDDOK)) /* nothing */;

  // TODO: Verify precise timings. The datasheet says that the
  // compare match interrupt happens the timer tick after the
  // match, but the asynchronous section also suggests (another?)
  // tick delay. Since a timer tick is fairly long (31ms), this
  // should be measured.
}
예제 #16
0
//
// Polls the lwIP stack.
//
void
cyg_lwip_simple_poll(void)
{
    cyg_tick_count_t ticks;
    cyg_uint32 delta;
    int i;
    
#if LWIP_HAVE_SLIPIF && defined(CYGIMP_LWIP_SLIPIF_INSTANCE)
    // Poll SLIP device
    slipif_poll(&slipif);
#endif

#if PPP_SUPPORT
    // Poll PPP device
#endif

#ifdef CYGPKG_LWIP_ETH
    {
        cyg_netdevtab_entry_t *t;

        // Poll ethernet devices
        for (t = &__NETDEVTAB__[0]; t != &__NETDEVTAB_END__; t++) {
            struct eth_drv_sc *sc = (struct eth_drv_sc *)t->device_instance;
            if (sc->state & ETH_DRV_NEEDS_DELIVERY) {
#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
                cyg_bool was_ctrlc_int;
#endif
                sc->state &= ~ETH_DRV_NEEDS_DELIVERY;
#if defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)
                was_ctrlc_int = HAL_CTRLC_CHECK(sc->funs->int_vector(sc),
                                                (int) sc);
                if (!was_ctrlc_int) // Fall through and run normal code
#endif
                    sc->funs->deliver(sc);
            }
        }

        // Deliver received packets
        while (recv_packet_count > 0) {
            ethernet_input(recv_packet[recv_packet_read].p,
                           recv_packet[recv_packet_read].netif);
            recv_packet_read = (recv_packet_read + 1) % MAX_RECV_PACKETS;
            recv_packet_count--;
        }
    }
#endif

    // Process timers
    ticks = cyg_current_time();
    delta = TICKS_TO_MS(ticks - last_ticks);
    last_ticks = ticks;

    // The following check 'delta > 0' rejects a potential wrap-around in the
    // system ticks counter.
    if (delta > 0) {
        for (i = 0; i < NUM_LWIP_TIMERS; i++) {
            lwip_timers[i].time += delta;
            if (lwip_timers[i].time >= lwip_timers[i].interval) {
                lwip_timers[i].timer_func();
                lwip_timers[i].time -= lwip_timers[i].interval;
            }
        }
    }
}