Beispiel #1
0
/**
 * Called once on process creation in order to mimic the behaviour a
 * regular hardware timer.
 */
void native_hwtimer_pre_init(void)
{
    /* initialize time delta */
    time_null = 0;
    time_null = hwtimer_arch_now();
    /* need to call hwtimer_arch_now as hwtimer_arch_now uses
     * time_null to delta native_hwtimer_now: */
    hwtimer_arch_now();
}
Beispiel #2
0
static void timer_set_nostart(uint32_t value, short timer)
{
    volatile unsigned int *ptr = &CNT_COMP_BASE_REG + (timer);
    /* ensure we won't set the timer to a "past" tick */
    if (value <= hwtimer_arch_now()) {
        value = hwtimer_arch_now() + 2;
    }
    overflow_interrupt[timer] = (uint16_t)(value >> 16);
    *ptr = (value & 0xFFFF);
}
Beispiel #3
0
/**
 * set next_timer to the next lowest enabled timer index
 */
void schedule_timer(void)
{
    /* try to find *an active* timer */
    next_timer = -1;
    for (int i = 0; i < HWTIMER_MAXTIMERS; i++) {
        if (native_hwtimer_isset[i] == 1) {
            next_timer = i;
            break;
        }
    }
    if (next_timer == -1) {
        DEBUG("schedule_timer(): no valid timer found - nothing to schedule\n");
        struct itimerval null_timer;
        null_timer.it_interval.tv_sec = 0;
        null_timer.it_interval.tv_usec = 0;
        null_timer.it_value.tv_sec = 0;
        null_timer.it_value.tv_usec = 0;
        if (real_setitimer(ITIMER_REAL, &null_timer, NULL) == -1) {
            err(EXIT_FAILURE, "schedule_timer: setitimer");
        }
        return;
    }

    /* find the next pending timer (next_timer now points to *a* valid pending timer) */
    for (int i = 0; i < HWTIMER_MAXTIMERS; i++) {
        if (
            (native_hwtimer_isset[i] == 1) &&
            (tv2ticks(&(native_hwtimer[i].it_value)) < tv2ticks(&(native_hwtimer[next_timer].it_value)))
        ) {
            /* timer in slot i is active and the timeout is more recent than next_timer */
            next_timer = i;
        }
    }

    /* next pending timer is in slot next_timer */
    struct timeval now;
    hwtimer_arch_now(); // update timer
    ticks2tv(native_hwtimer_now, &now);

    struct itimerval result;
    memset(&result, 0, sizeof(result));

    int retval = timeval_subtract(&result.it_value, &native_hwtimer[next_timer].it_value, &now);
    if (retval || (tv2ticks(&result.it_value) < HWTIMERMINOFFSET)) {
        DEBUG("\033[31mschedule_timer(): timer is already due (%i), mitigating.\033[0m\n", next_timer);
        result.it_value.tv_sec = 0;
        result.it_value.tv_usec = 1;
    }

    _native_syscall_enter();
    if (real_setitimer(ITIMER_REAL, &result, NULL) == -1) {
        err(EXIT_FAILURE, "schedule_timer: setitimer");
    }
    else {
        DEBUG("schedule_timer(): set next timer (%i).\n", next_timer);
    }
    _native_syscall_leave();
}
Beispiel #4
0
void hwtimer_arch_set(unsigned long offset, short timer)
{
    DEBUG("hwtimer_arch_set(%lu, \033[31m%i\033[0m)\n", offset, timer);

    hwtimer_arch_now(); /* update native_hwtimer_now */
    offset += native_hwtimer_now;
    hwtimer_arch_set_absolute(offset, timer);

    return;
}
Beispiel #5
0
void hwtimer_spin(unsigned long ticks)
{
    DEBUG("hwtimer_spin ticks=%lu\n", ticks);

    unsigned long start = hwtimer_arch_now();
    /* compute destination time, possibly resulting in an overflow */
    unsigned long stop = start + ticks;

    /*
     * If there is an overflow (that is: stop time is inferior to start),
     * hwtimer_arch_now needs to spin until it has overflowed as well.
     */
    if (stop < start) {
        while (hwtimer_arch_now() > start) /* do nothing */;
    }

    /* wait until we have passed destination (stop) time */
    while (hwtimer_arch_now() < stop) /* do nothing again */;
}
Beispiel #6
0
void hwtimer_arch_init(void (*handler)(int), uint32_t fcpu)
{
    DEBUG("hwtimer_arch_init()\n");

    (void) fcpu;
    hwtimer_arch_disable_interrupt();
    int_handler = handler;

    for (int i = 0; i < ARCH_MAXTIMERS; i++) {
        native_hwtimer_irq[i] = 0;
        native_hwtimer_isset[i] = 0;
        native_hwtimer[i].it_interval.tv_sec = 0;
        native_hwtimer[i].it_interval.tv_usec = 0;
    }

    /* init time delta */
    time_null = 0;
    time_null = hwtimer_arch_now();

    hwtimer_arch_enable_interrupt();
    return;
}
Beispiel #7
0
void hwtimer_arch_set(unsigned long offset, short timer)
{
    uint32_t value = hwtimer_arch_now() + offset;
    hwtimer_arch_set_absolute(value, timer);
}
Beispiel #8
0
unsigned long hwtimer_now(void)
{
    return hwtimer_arch_now();
}