コード例 #1
0
ファイル: cortex_m_systick.c プロジェクト: rsalveti/zephyr
void _enable_sys_clock(void)
{
	if (!(SysTick->CTRL & SysTick_CTRL_ENABLE_Msk)) {
		sysTickStart();
		sys_tick_reload();
	}
}
コード例 #2
0
ファイル: shell.c プロジェクト: siddhugit/Operating-System
int main(int argc,char *argv[])
/*
 * main function of the shell program, calls process_input(). As process_input()
 *	does all the error reporting and does not propagate errors out of it
 *	and shell program does not have to return any failure exit status
 *	to its parent shell, main() simply retuns 0    
*/
{
	//Bootstrap
	bootstrap();
	//flexTimer0Start();

	//process input
	//process_input();
	uint32_t pid;
	struct spawnArgs args;
	args.argc = 1;
	args.argv = NULL;
	args.spawnedPidptr = &pid;
	args.stackSize = STACK_SIZE;
	args.funcPtr = runShell;
	svc_spawn(&args);
	sysTickStart();
	privUnprivileged();
	while(1);
	return 0;
}
コード例 #3
0
ファイル: cortex_m_systick.c プロジェクト: rsalveti/zephyr
/**
 *
 * @brief Place the system timer into idle state
 *
 * Re-program the timer to enter into the idle state for the given number of
 * ticks. It is set to a "one shot" mode where it will fire in the number of
 * ticks supplied or the maximum number of ticks that can be programmed into
 * hardware. A value of -1 will result in the maximum number of ticks.
 *
 * @return N/A
 */
void _timer_idle_enter(s32_t ticks /* system ticks */
				)
{
#ifdef CONFIG_TICKLESS_KERNEL
	if (ticks != K_FOREVER) {
		/* Need to reprogram only if current program is smaller */
		if (ticks > idle_original_ticks) {
			_set_time(ticks);
		}
	} else {
		sysTickStop();
		idle_original_ticks = 0;
	}
	idle_mode = IDLE_TICKLESS;
#else
	sysTickStop();

	/*
	 * We're being asked to have the timer fire in "ticks" from now. To
	 * maintain accuracy we must account for the remaining time left in the
	 * timer. So we read the count out of it and add it to the requested
	 * time out
	 */
	idle_original_count = sysTickCurrentGet() - timer_idle_skew;

	if ((ticks == -1) || (ticks > max_system_ticks)) {
		/*
		 * We've been asked to fire the timer so far in the future that
		 * the required count value would not fit in the 24-bit reload
		 * register.
		 * Instead, we program for the maximum programmable interval
		 * minus one system tick to prevent overflow when the left over
		 * count read earlier is added.
		 */
		idle_original_count += max_load_value - default_load_value;
		idle_original_ticks = max_system_ticks - 1;
	} else {
		/*
		 * leave one tick of buffer to have to time react when coming
		 * back
		 */
		idle_original_ticks = ticks - 1;
		idle_original_count += idle_original_ticks * default_load_value;
	}

	/*
	 * Set timer to virtual "one shot" mode - sysTick does not have multiple
	 * modes, so the reload value is simply changed.
	 */
	timer_mode = TIMER_MODE_ONE_SHOT;
	idle_mode = IDLE_TICKLESS;
	sysTickReloadSet(idle_original_count);
	sysTickStart();
#endif
}
コード例 #4
0
ファイル: cortex_m_systick.c プロジェクト: rsalveti/zephyr
void _set_time(u32_t time)
{
	if (!time) {
		idle_original_ticks = 0;
		return;
	}

	idle_original_ticks = time > max_system_ticks ? max_system_ticks : time;

	_sys_clock_tick_count = _get_elapsed_clock_time();

	/* clear overflow tracking flag as it is accounted */
	timer_overflow = 0;
	sysTickStop();
	sysTickReloadSet(idle_original_ticks * default_load_value);

	sysTickStart();
	sys_tick_reload();
}
コード例 #5
0
ファイル: cortex_m_systick.c プロジェクト: rsalveti/zephyr
/**
 *
 * @brief Handling of tickless idle when interrupted
 *
 * The routine, called by _sys_power_save_idle_exit, is responsible for taking
 * the timer out of idle mode and generating an interrupt at the next
 * tick interval.  It is expected that interrupts have been disabled.
 *
 * Note that in this routine, _sys_idle_elapsed_ticks must be zero because the
 * ticker has done its work and consumed all the ticks. This has to be true
 * otherwise idle mode wouldn't have been entered in the first place.
 *
 * @return N/A
 */
void _timer_idle_exit(void)
{
#ifdef CONFIG_TICKLESS_KERNEL
	if (idle_mode == IDLE_TICKLESS) {
		idle_mode = IDLE_NOT_TICKLESS;
		if (!idle_original_ticks && _sys_clock_always_on) {
			_sys_clock_tick_count = _get_elapsed_clock_time();
			timer_overflow = 0;
			sysTickReloadSet(max_load_value);
			sysTickStart();
			sys_tick_reload();
		}
	}
#else
	u32_t count; /* timer's current count register value */

	if (timer_mode == TIMER_MODE_PERIODIC) {
		/*
		 * The timer interrupt handler is handling a completed tickless
		 * idle or this has been called by mistake; there's nothing to
		 * do here.
		 */
		return;
	}

	sysTickStop();

	/* timer is in idle mode, adjust the ticks expired */

	count = sysTickCurrentGet();

	if ((count == 0) || (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)) {
		/*
		 * The timer expired and/or wrapped around. Re-set the timer to
		 * its default value and mode.
		 */
		sysTickReloadSet(default_load_value);
		timer_mode = TIMER_MODE_PERIODIC;

		/*
		 * Announce elapsed ticks to the kernel. Note we are guaranteed
		 * that the timer ISR will execute before the tick event is
		 * serviced, so _sys_idle_elapsed_ticks is adjusted to account
		 * for it.
		 */
		_sys_idle_elapsed_ticks = idle_original_ticks - 1;
		_sys_clock_tick_announce();
	} else {
		u32_t elapsed;   /* elapsed "counter time" */
		u32_t remaining; /* remaining "counter time" */

		elapsed = idle_original_count - count;

		remaining = elapsed % default_load_value;

		/* ensure that the timer will interrupt at the next tick */

		if (remaining == 0) {
			/*
			 * Idle was interrupted on a tick boundary. Re-set the
			 * timer to its default value and mode.
			 */
			sysTickReloadSet(default_load_value);
			timer_mode = TIMER_MODE_PERIODIC;
		} else if (count > remaining) {
			/*
			 * There is less time remaining to the next tick
			 * boundary than time left for idle. Leave in "one
			 * shot" mode.
			 */
			sysTickReloadSet(remaining);
		}

		_sys_idle_elapsed_ticks = elapsed / default_load_value;

		if (_sys_idle_elapsed_ticks) {
			_sys_clock_tick_announce();
		}
	}

	idle_mode = IDLE_NOT_TICKLESS;
	sysTickStart();
#endif
}
コード例 #6
0
ファイル: cortex_m_systick.c プロジェクト: rsalveti/zephyr
/**
 *
 * @brief System clock tick handler
 *
 * This routine handles the system clock tick interrupt. A TICK_EVENT event
 * is pushed onto the kernel stack.
 *
 * The symbol for this routine is either _timer_int_handler.
 *
 * @return N/A
 */
void _timer_int_handler(void *unused)
{
	ARG_UNUSED(unused);

#ifdef CONFIG_EXECUTION_BENCHMARKING
	extern void read_systick_start_of_tick_handler(void);
	read_systick_start_of_tick_handler();
#endif

#ifdef CONFIG_KERNEL_EVENT_LOGGER_INTERRUPT
	extern void _sys_k_event_logger_interrupt(void);
	_sys_k_event_logger_interrupt();
#endif

#ifdef CONFIG_SYS_POWER_MANAGEMENT
	s32_t numIdleTicks;

	/*
	 * All interrupts are disabled when handling idle wakeup.
	 * For tickless idle, this ensures that the calculation and programming
	 * of
	 * the device for the next timer deadline is not interrupted.
	 * For non-tickless idle, this ensures that the clearing of the kernel
	 * idle
	 * state is not interrupted.
	 * In each case, _sys_power_save_idle_exit is called with interrupts
	 * disabled.
	 */
	__asm__(" cpsid i"); /* PRIMASK = 1 */

#ifdef CONFIG_TICKLESS_IDLE
#if defined(CONFIG_TICKLESS_KERNEL)
	if (!idle_original_ticks) {
		if (_sys_clock_always_on) {
			_sys_clock_tick_count = _get_elapsed_clock_time();
			/* clear overflow tracking flag as it is accounted */
			timer_overflow = 0;
			sysTickStop();
			idle_original_ticks = max_system_ticks;
			sysTickReloadSet(max_load_value);
			sysTickStart();
			sys_tick_reload();
		}
		__asm__(" cpsie i"); /* re-enable interrupts (PRIMASK = 0) */

		_ExcExit();
		return;
	}

	idle_mode = IDLE_NOT_TICKLESS;

	_sys_idle_elapsed_ticks = idle_original_ticks;

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

	_sys_clock_tick_announce();

	/* _sys_clock_tick_announce() could cause new programming */
	if (!idle_original_ticks && _sys_clock_always_on) {
		_sys_clock_tick_count = _get_elapsed_clock_time();
		/* clear overflow tracking flag as it is accounted */
		timer_overflow = 0;
		sysTickStop();
		sysTickReloadSet(max_load_value);
		sysTickStart();
		sys_tick_reload();
	}
#else
	/*
	 * If this a wakeup from a completed tickless idle or after
	 *  _timer_idle_exit has processed a partial idle, return
	 *  to the normal tick cycle.
	 */
	if (timer_mode == TIMER_MODE_ONE_SHOT) {
		sysTickStop();
		sysTickReloadSet(default_load_value);
		sysTickStart();
		timer_mode = TIMER_MODE_PERIODIC;
	}

	/* set the number of elapsed ticks and announce them to the kernel */

	if (idle_mode == IDLE_TICKLESS) {
		/* tickless idle completed without interruption */
		idle_mode = IDLE_NOT_TICKLESS;
		_sys_idle_elapsed_ticks =
			idle_original_ticks + 1; /* actual # of idle ticks */
		_sys_clock_tick_announce();
	} else {
		_sys_clock_final_tick_announce();
	}

	/* accumulate total counter value */
	clock_accumulated_count += default_load_value * _sys_idle_elapsed_ticks;
#endif
#else  /* !CONFIG_TICKLESS_IDLE */
	/*
	 * No tickless idle:
	 * Update the total tick count and announce this tick to the kernel.
	 */
	clock_accumulated_count += sys_clock_hw_cycles_per_tick;

	_sys_clock_tick_announce();
#endif /* CONFIG_TICKLESS_IDLE */

	numIdleTicks = _NanoIdleValGet(); /* get # of idle ticks requested */

	if (numIdleTicks) {
		_NanoIdleValClear(); /* clear kernel idle setting */

		/*
		 * Complete idle processing.
		 * Note that for tickless idle, nothing will be done in
		 * _timer_idle_exit.
		 */
		_sys_power_save_idle_exit(numIdleTicks);
	}

	__asm__(" cpsie i"); /* re-enable interrupts (PRIMASK = 0) */

#else /* !CONFIG_SYS_POWER_MANAGEMENT */

	/* accumulate total counter value */
	clock_accumulated_count += sys_clock_hw_cycles_per_tick;

	/*
	 * one more tick has occurred -- don't need to do anything special since
	 * timer is already configured to interrupt on the following tick
	 */
	_sys_clock_tick_announce();

#endif /* CONFIG_SYS_POWER_MANAGEMENT */

#ifdef CONFIG_EXECUTION_BENCHMARKING
	extern void read_systick_end_of_tick_handler(void);
	read_systick_end_of_tick_handler();
#endif

	extern void _ExcExit(void);
	_ExcExit();
}
コード例 #7
0
ファイル: cortex_m_systick.c プロジェクト: 32bitmicro/zephyr
/**
 *
 * @brief Handling of tickless idle when interrupted
 *
 * The routine, called by _sys_power_save_idle_exit, is responsible for taking
 * the timer out of idle mode and generating an interrupt at the next
 * tick interval.  It is expected that interrupts have been disabled.
 *
 * Note that in this routine, _sys_idle_elapsed_ticks must be zero because the
 * ticker has done its work and consumed all the ticks. This has to be true
 * otherwise idle mode wouldn't have been entered in the first place.
 *
 * @return N/A
 */
void _timer_idle_exit(void)
{
	uint32_t count; /* timer's current count register value */

	if (timer_mode == TIMER_MODE_PERIODIC) {
		/*
		 * The timer interrupt handler is handling a completed tickless
		 * idle
		 * or this has been called by mistake; there's nothing to do
		 * here.
		 */
		return;
	}

	sysTickStop();

	/* timer is in idle mode, adjust the ticks expired */

	count = sysTickCurrentGet();

	if ((count == 0) || (__scs.systick.stcsr.bit.countflag)) {
		/*
		 * The timer expired and/or wrapped around. Re-set the timer to
		 * its default value and mode.
		 */
		sysTickReloadSet(default_load_value);
		timer_mode = TIMER_MODE_PERIODIC;

		/*
		 * Announce elapsed ticks to the microkernel. Note we are
		 * guaranteed
		 * that the timer ISR will execute before the tick event is
		 * serviced,
		 * so _sys_idle_elapsed_ticks is adjusted to account for it.
		 */
		_sys_idle_elapsed_ticks = idle_original_ticks - 1;
		_sys_clock_tick_announce();
	} else {
		uint32_t elapsed;   /* elapsed "counter time" */
		uint32_t remaining; /* remaining "counter time" */

		elapsed = idle_original_count - count;

		remaining = elapsed % default_load_value;

		/* ensure that the timer will interrupt at the next tick */

		if (remaining == 0) {
			/*
			 * Idle was interrupted on a tick boundary. Re-set the
			 * timer to
			 * its default value and mode.
			 */
			sysTickReloadSet(default_load_value);
			timer_mode = TIMER_MODE_PERIODIC;
		} else if (count > remaining) {
			/*
			 * There is less time remaining to the next tick
			 * boundary than
			 * time left for idle. Leave in "one shot" mode.
			 */
			sysTickReloadSet(remaining);
		}

		_sys_idle_elapsed_ticks = elapsed / default_load_value;

		if (_sys_idle_elapsed_ticks) {
			_sys_clock_tick_announce();
		}
	}

	idle_mode = IDLE_NOT_TICKLESS;
	sysTickStart();
}
コード例 #8
0
ファイル: cortex_m_systick.c プロジェクト: 32bitmicro/zephyr
/**
 *
 * @brief System clock tick handler
 *
 * This routine handles the system clock tick interrupt. A TICK_EVENT event
 * is pushed onto the microkernel stack.
 *
 * The symbol for this routine is either _timer_int_handler (for normal
 * system operation) or _real_timer_int_handler (when GDB_INFO is enabled).
 *
 * @return N/A
 */
void _TIMER_INT_HANDLER(void *unused)
{
	ARG_UNUSED(unused);

#ifdef CONFIG_KERNEL_EVENT_LOGGER_INTERRUPT
	extern void _sys_k_event_logger_interrupt(void);
	_sys_k_event_logger_interrupt();
#endif


#ifdef CONFIG_INT_LATENCY_BENCHMARK
	uint32_t value = __scs.systick.val;
	uint32_t delta = __scs.systick.reload - value;

	if (_hw_irq_to_c_handler_latency > delta) {
		/* keep the lowest value observed */
		_hw_irq_to_c_handler_latency = delta;
	}
#endif

#ifdef CONFIG_SYS_POWER_MANAGEMENT
	int32_t numIdleTicks;

	/*
	 * All interrupts are disabled when handling idle wakeup.
	 * For tickless idle, this ensures that the calculation and programming
	 * of
	 * the device for the next timer deadline is not interrupted.
	 * For non-tickless idle, this ensures that the clearing of the kernel
	 * idle
	 * state is not interrupted.
	 * In each case, _sys_power_save_idle_exit is called with interrupts
	 * disabled.
	 */
	__asm__(" cpsid i"); /* PRIMASK = 1 */

#ifdef CONFIG_TICKLESS_IDLE
	/*
	 * If this a wakeup from a completed tickless idle or after
	 *  _timer_idle_exit has processed a partial idle, return
	 *  to the normal tick cycle.
	 */
	if (timer_mode == TIMER_MODE_ONE_SHOT) {
		sysTickStop();
		sysTickReloadSet(default_load_value);
		sysTickStart();
		timer_mode = TIMER_MODE_PERIODIC;
	}

	/* set the number of elapsed ticks and announce them to the kernel */

	if (idle_mode == IDLE_TICKLESS) {
		/* tickless idle completed without interruption */
		idle_mode = IDLE_NOT_TICKLESS;
		_sys_idle_elapsed_ticks =
			idle_original_ticks + 1; /* actual # of idle ticks */
		_sys_clock_tick_announce();
	} else {
		/*
		 * Increment the tick because _timer_idle_exit does not
		 * account for the tick due to the timer interrupt itself.
		 * Also, if not in tickless mode, _sys_idle_elapsed_ticks will be 0.
		 */
		_sys_idle_elapsed_ticks++;

		/*
		 * If we transition from 0 elapsed ticks to 1 we need to
		 * announce the
		 * tick event to the microkernel. Other cases will be covered by
		 * _timer_idle_exit.
		 */

		if (_sys_idle_elapsed_ticks == 1) {
			_sys_clock_tick_announce();
		}
	}

	/* accumulate total counter value */
	clock_accumulated_count += default_load_value * _sys_idle_elapsed_ticks;
#else  /* !CONFIG_TICKLESS_IDLE */
	/*
	 * No tickless idle:
	 * Update the total tick count and announce this tick to the kernel.
	 */
	clock_accumulated_count += sys_clock_hw_cycles_per_tick;

	_sys_clock_tick_announce();
#endif /* CONFIG_TICKLESS_IDLE */

	numIdleTicks = _NanoIdleValGet(); /* get # of idle ticks requested */

	if (numIdleTicks) {
		_NanoIdleValClear(); /* clear kernel idle setting */

		/*
		 * Complete idle processing.
		 * Note that for tickless idle, nothing will be done in
		 * _timer_idle_exit.
		 */
		_sys_power_save_idle_exit(numIdleTicks);
	}

	__asm__(" cpsie i"); /* re-enable interrupts (PRIMASK = 0) */

#else /* !CONFIG_SYS_POWER_MANAGEMENT */

	/* accumulate total counter value */
	clock_accumulated_count += sys_clock_hw_cycles_per_tick;

	/*
	 * one more tick has occurred -- don't need to do anything special since
	 * timer is already configured to interrupt on the following tick
	 */
	_sys_clock_tick_announce();

#endif /* CONFIG_SYS_POWER_MANAGEMENT */

	extern void _ExcExit(void);
	_ExcExit();
}