Esempio n. 1
0
/**
 * @brief   Initializes the kernel.
 * @details Initializes the kernel structures, the current instructions flow
 *          becomes the idle thread upon return. The idle thread must not
 *          invoke any kernel primitive able to change state to not runnable.
 * @note    This function assumes that the @p nil global variable has been
 *          zeroed by the runtime environment. If this is not the case then
 *          make sure to clear it before calling this function.
 *
 * @special
 */
void chSysInit(void) {
  thread_t *tp;
  const thread_config_t *tcp;

#if CH_DBG_SYSTEM_STATE_CHECK == TRUE
  nil.isr_cnt  = (cnt_t)0;
  nil.lock_cnt = (cnt_t)0;
#endif

  /* System initialization hook.*/
  CH_CFG_SYSTEM_INIT_HOOK();

  /* Iterates through the list of defined threads.*/
  tp = &nil.threads[0];
  tcp = nil_thd_configs;
  while (tp < &nil.threads[CH_CFG_NUM_THREADS]) {
#if CH_DBG_ENABLE_STACK_CHECK
    tp->stklimit  = (stkalign_t *)tcp->wbase;
#endif

    /* Port dependent thread initialization.*/
    PORT_SETUP_CONTEXT(tp, tcp->wbase, tcp->wend, tcp->funcp, tcp->arg);

    /* Initialization hook.*/
    CH_CFG_THREAD_EXT_INIT_HOOK(tp);

    tp++;
    tcp++;
  }

#if CH_DBG_ENABLE_STACK_CHECK
  /* The idle thread is a special case because its stack is set up by the
     runtime environment.*/
  tp->stklimit  = THD_IDLE_BASE;
#endif

  /* Interrupts partially enabled. It is equivalent to entering the
     kernel critical zone.*/
  chSysSuspend();
#if CH_DBG_SYSTEM_STATE_CHECK == TRUE
  nil.lock_cnt = (cnt_t)1;
#endif

  /* Heap initialization, if enabled.*/
#if CH_CFG_USE_HEAP == TRUE
  _heap_init();
#endif

  /* Port layer initialization last because it depend on some of the
     initializations performed before.*/
  port_init();

  /* Runs the highest priority thread, the current one becomes the idle
     thread.*/
  nil.current = nil.next = nil.threads;
  port_switch(nil.current, tp);
  chSysUnlock();
}
Esempio n. 2
0
 CriticalSectionLocker() { chSysSuspend(); }
Esempio n. 3
0
void motor_pwm_beep(int frequency, int duration_msec)
{
	static const float DUTY_CYCLE = 0.01;
	static const int ACTIVE_USEC_MAX = 20;

	motor_pwm_set_freewheeling();

	frequency = (frequency < 100)  ? 100  : frequency;
	frequency = (frequency > 5000) ? 5000 : frequency;

	duration_msec = (duration_msec < 1)    ? 1    : duration_msec;
	duration_msec = (duration_msec > 5000) ? 5000 : duration_msec;

	/*
	 * Timing constants
	 */
	const int half_period_hnsec = (HNSEC_PER_SEC / frequency) / 2;

	int active_hnsec = half_period_hnsec * DUTY_CYCLE;

	if (active_hnsec > ACTIVE_USEC_MAX * HNSEC_PER_USEC) {
		active_hnsec = ACTIVE_USEC_MAX * HNSEC_PER_USEC;
	}

	const int idle_hnsec = half_period_hnsec - active_hnsec;

	const uint64_t end_time = motor_timer_hnsec() + duration_msec * HNSEC_PER_MSEC;

	/*
	 * FET round robin
	 * This way we can beep even if some FETs went bananas
	 */
	static unsigned _phase_sel;
	const int low_phase_first  = _phase_sel++ % MOTOR_NUM_PHASES;
	const int low_phase_second = _phase_sel++ % MOTOR_NUM_PHASES;
	const int high_phase       = _phase_sel++ % MOTOR_NUM_PHASES;
	_phase_sel++;              // We need to increment it not by multiple of 3
	assert(low_phase_first != high_phase && low_phase_second != high_phase);

	/*
	 * Commutations
	 * No high side pumping
	 */
	phase_set_i(low_phase_first, 0, false);
	phase_set_i(low_phase_second, 0, false);
	phase_set_i(high_phase, 0, false);
	apply_phase_config();

	while (end_time > motor_timer_hnsec()) {
		chSysSuspend();

		irq_primask_disable();
		phase_set_i(high_phase, _pwm_top, false);
		apply_phase_config();
		irq_primask_enable();

		motor_timer_hndelay(active_hnsec);

		irq_primask_disable();
		phase_set_i(high_phase, 0, false);
		apply_phase_config();
		irq_primask_enable();

		chSysEnable();

		motor_timer_hndelay(idle_hnsec);
	}

	motor_pwm_set_freewheeling();
}