Пример #1
0
/**
 *
 * @brief System clock periodic tick handler
 *
 * This routine handles the system clock periodic tick interrupt. It always
 * announces one tick.
 *
 * @return N/A
 */
void _timer_int_handler(void *unused)
{
	ARG_UNUSED(unused);
	/* clear the interrupt by writing 0 to IP bit of the control register */
	timer0_control_register_set(_ARC_V2_TMR_CTRL_NH | _ARC_V2_TMR_CTRL_IE);

#ifdef CONFIG_TICKLESS_KERNEL
	if (!programmed_ticks) {
		if (_sys_clock_always_on) {
			_sys_clock_tick_count = _get_elapsed_clock_time();
			program_max_cycles();
		}
		return;
	}

	_sys_idle_elapsed_ticks = programmed_ticks;

	/*
	 * Clear programmed ticks before announcing elapsed time so
	 * that recursive calls to _update_elapsed_time() will not
	 * announce already consumed elapsed time
	 */
	programmed_ticks = 0;
	timer_expired = 1;

	_sys_clock_tick_announce();

	/* _sys_clock_tick_announce() could cause new programming */
	if (!programmed_ticks && _sys_clock_always_on) {
		_sys_clock_tick_count = _get_elapsed_clock_time();
		program_max_cycles();
	}
#else
#if defined(CONFIG_TICKLESS_IDLE)
	timer0_limit_register_set(cycles_per_tick - 1);
	__ASSERT_EVAL({},
		      u32_t timer_count = timer0_count_register_get(),
		      timer_count <= (cycles_per_tick - 1),
		      "timer_count: %d, limit %d\n", timer_count, cycles_per_tick - 1);

	_sys_clock_final_tick_announce();
#else
	_sys_clock_tick_announce();
#endif

	update_accumulated_count();
#endif
}
Пример #2
0
/**
 * @brief Enable sys Clock.
 *
 * This is used to program RTC clock to maximum Clock time in case Clock to
 * remain On.
 */
void _enable_sys_clock(void)
{
	if (!expected_sys_ticks) {
		/* Programe sys tick to Maximum possible value*/
		program_max_cycles();
	}
}
Пример #3
0
/*
 * @brief Announces the number of sys ticks that have passed since the last
 * announcement, if any, and programs the RTC to trigger the interrupt on the
 * next sys tick.
 *
 * The ISR is set pending due to a regular sys tick and after exiting idle mode
 * as scheduled.
 *
 * Since this ISR can be preempted, we need to take some provisions to announce
 * all expected sys ticks that have passed.
 *
 * Consider the following example:
 *
 * sys tick timeline:       (1)    (2)    (3)    (4)    (5)    (6)
 * rtc tick timeline : 0----100----200----300----400----500----600
 *                                         !**********
 *                                                  450
 *
 * The last sys tick was anounced at 200, i.e, rtc_past = 200. The ISR is
 * executed at the next sys tick, i.e. 300. The following sys tick is due at
 * 400. However, the ISR is preempted for a number of sys ticks, until 450 in
 * this example. The ISR will then announce the number of sys ticks it was
 * delayed (2), and schedule the next sys tick (5) at 500.
 */
void rtc1_nrf5_isr(void *arg)
{

	ARG_UNUSED(arg);
	RTC_CC_EVENT = 0;

#ifdef CONFIG_EXECUTION_BENCHMARKING
	extern void read_timer_start_of_tick_handler(void);
	read_timer_start_of_tick_handler();
#endif
	sys_trace_isr_enter();

#ifdef CONFIG_TICKLESS_KERNEL
	if (!expected_sys_ticks) {
		if (_sys_clock_always_on) {
			program_max_cycles();
		}
		return;
	}
	_sys_idle_elapsed_ticks = expected_sys_ticks;
	/* Initialize expected sys tick,
	 * It will be later updated based on next timeout.
	 */
	expected_sys_ticks = 0;
	/* Anounce elapsed of _sys_idle_elapsed_ticks systicks*/
	_sys_clock_tick_announce();

	/* _sys_clock_tick_announce() could cause new programming */
	if (!expected_sys_ticks && _sys_clock_always_on) {
		program_max_cycles();
	}
#else
	rtc_announce_set_next();
#endif

#ifdef CONFIG_EXECUTION_BENCHMARKING
	extern void read_timer_end_of_tick_handler(void);
	read_timer_end_of_tick_handler();
#endif
	sys_trace_isr_exit();

}
Пример #4
0
void _timer_idle_exit(void)
{
#ifdef CONFIG_TICKLESS_KERNEL
	if (!programmed_ticks && _sys_clock_always_on) {
		if (!(timer0_control_register_get() & _ARC_V2_TMR_CTRL_IE)) {
			timer0_control_register_set(_ARC_V2_TMR_CTRL_NH |
						    _ARC_V2_TMR_CTRL_IE);
		}
		program_max_cycles();
	}
#else
	if (straddled_tick_on_idle_enter) {
		/* Aborting the tickless idle due to a straddled tick. */
		straddled_tick_on_idle_enter = 0;
		__ASSERT_EVAL({},
			      u32_t timer_count = timer0_count_register_get(),
			      timer_count <= programmed_limit,
			      "timer_count: %d, limit %d\n", timer_count, programmed_limit);
		return;
	}

	u32_t  control;
	u32_t  current_count;

	current_count = timer0_count_register_get();
	control = timer0_control_register_get();
	if (control & _ARC_V2_TMR_CTRL_IP) {
		/*
		 * The timer has expired. The handler _timer_int_handler() is
		 * guaranteed to execute. Track the number of elapsed ticks. The
		 * handler _timer_int_handler() will account for the final tick.
		 */

		_sys_idle_elapsed_ticks = programmed_ticks - 1;
		update_accumulated_count();
		_sys_clock_tick_announce();

		__ASSERT_EVAL({},
			      u32_t timer_count = timer0_count_register_get(),
			      timer_count <= programmed_limit,
			      "timer_count: %d, limit %d\n", timer_count, programmed_limit);
		return;
	}

	/*
	 * A non-timer interrupt occurred.  Announce any
	 * ticks that have elapsed during the tickless idle.
	 */
	_sys_idle_elapsed_ticks = current_count / cycles_per_tick;
	if (_sys_idle_elapsed_ticks > 0) {
		update_accumulated_count();
		_sys_clock_tick_announce();
	}

	/*
	 * Ensure the timer will expire at the end of the next tick in case
	 * the ISR makes any threads ready to run.
	 */
	timer0_limit_register_set(cycles_per_tick - 1);
	timer0_count_register_set(current_count % cycles_per_tick);

	__ASSERT_EVAL({},
		      u32_t timer_count = timer0_count_register_get(),
		      timer_count <= (cycles_per_tick - 1),
		      "timer_count: %d, limit %d\n", timer_count, cycles_per_tick-1);
#endif
}
Пример #5
0
void _enable_sys_clock(void)
{
	if (!programmed_ticks) {
		program_max_cycles();
	}
}