Example #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.
 *
 * @special
 */
void nilSysInit(void) {
  Thread *tp;
  const ThreadConfig *tcp;

  /* Port layer initialization.*/
  port_init();

  /* Iterates through the list of defined threads.*/
  for (tp = &nil.threads[0], tcp = nil_thd_configs;
#if WHG_MOD
       tp < nil.idlep;
#else  /* WHG_MOD */
       tp < &nil.threads[NIL_CFG_NUM_THREADS];
#endif  /* WHG_MOD */
       tp++, tcp++) {

    /* Port dependent thread initialization.*/
    SETUP_CONTEXT(tcp->wap, tcp->size, tcp->funcp, tcp->arg);
  }

  /* Runs the highest priority thread, the current one becomes the null
     thread.*/
  nil.currp = nil.nextp = nil.threads;
#if WHG_MOD
  port_switch(nil.threads, nil.idlep);
#else  /* WHG_MOD */
  port_switch(nil.threads, &nil.threads[NIL_CFG_NUM_THREADS]);
#endif  /* WHG_MOD */

  /* Interrupts enabled for the idle thread.*/
  nilSysEnable();
}
Example #2
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();
}
Example #3
0
/**
 * @brief   Switches to the first thread on the runnable queue.
 * @note    Not a user function, it is meant to be invoked by the scheduler
 *          itself or from within the port layer.
 *
 * @special
 */
void chSchDoReschedule(void) {
  thread_t *otp = nil.current;

  nil.current = nil.next;
  if (otp == &nil.threads[CH_CFG_NUM_THREADS]) {
    CH_CFG_IDLE_LEAVE_HOOK();
  }
  port_switch(nil.next, otp);
}
Example #4
0
/**
 * @brief   Reschedules if needed.
 *
 * @sclass
 */
void chSchRescheduleS(void) {

  if (chSchIsRescRequiredI()) {
    thread_t *otp = nil.current;

    nil.current = nil.next;
    if (otp == &nil.threads[NIL_CFG_NUM_THREADS]) {
      NIL_CFG_IDLE_LEAVE_HOOK();
    }
    port_switch(nil.next, otp);
  }
}
Example #5
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.
 *
 * @special
 */
void nilSysInit(void) {
  thread_ref_t tr;
  const thread_config_t *tcp;

  /* Port layer initialization.*/
  port_init();

  /* Iterates through the list of defined threads.*/
  for (tr = &nil.threads[0], tcp = nil_thd_configs;
  #if WHG_MOD
       tr < nil.idlep;
#else  /* WHG_MOD */
       tr < &nil.threads[NIL_CFG_NUM_THREADS];
#endif  /* WHG_MOD */
       tr++, tcp++) {
    tr->state = NIL_THD_READY;
    tr->timeout = 0;

    /* Port dependent thread initialization.*/
    SETUP_CONTEXT(tr, tcp->wap, tcp->size, tcp->funcp, tcp->arg);

    /* Initialization hook.*/
#if defined(NIL_CFG_THREAD_EXT_INIT_HOOK)
    NIL_CFG_THREAD_EXT_INIT_HOOK(tr);
#endif
  }

  /* Runs the highest priority thread, the current one becomes the null
     thread.*/
  nil.current = nil.next = nil.threads;
#if WHG_MOD
  port_switch(nil.threads, nil.idlep);
#else  /* WHG_MOD */
  port_switch(nil.threads, &nil.threads[NIL_CFG_NUM_THREADS]);
#endif  /* WHG_MOD */

  /* Interrupts enabled for the idle thread.*/
  nilSysEnable();
}
Example #6
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;

  /* Port layer initialization.*/
  port_init();

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

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

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

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

    tp++;
    tcp++;
  }

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

  /* Runs the highest priority thread, the current one becomes the null
     thread.*/
  nil.current = nil.next = nil.threads;
  port_switch(nil.current, tp);

  /* Interrupts enabled for the idle thread.*/
  chSysEnable();
}
Example #7
0
/**
 * @brief   Puts the current thread to sleep into the specified state with
 *          timeout specification.
 * @details The thread goes into a sleeping state, if it is not awakened
 *          explicitly within the specified system time then it is forcibly
 *          awakened with a @p NIL_MSG_TMO low level message.
 *
 * @param[in] newstate  the new thread state or a semaphore pointer
 * @param[in] timeout   the number of ticks before the operation timeouts.
 *                      the following special values are allowed:
 *                      - @a TIME_INFINITE no timeout.
 *                      .
 * @return              The wakeup message.
 * @retval NIL_MSG_TMO  if a timeout occurred.
 *
 * @sclass
 */
msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) {
  thread_t *ntp, *otp = nil.current;

  chDbgAssert(otp != &nil.threads[NIL_CFG_NUM_THREADS],
               "idle cannot sleep");

  /* Storing the wait object for the current thread.*/
  otp->state = newstate;

#if NIL_CFG_ST_TIMEDELTA > 0
  if (timeout != TIME_INFINITE) {
    systime_t abstime;

    /* TIMEDELTA makes sure to have enough time to reprogram the timer
       before the free-running timer counter reaches the selected timeout.*/
    if (timeout < (systime_t)NIL_CFG_ST_TIMEDELTA) {
      timeout = (systime_t)NIL_CFG_ST_TIMEDELTA;
    }

    /* Absolute time of the timeout event.*/
    abstime = chVTGetSystemTimeX() + timeout;

    if (nil.lasttime == nil.nexttime) {
      /* Special case, first thread asking for a timeout.*/
      port_timer_start_alarm(abstime);
      nil.nexttime = abstime;
    }
    else {
      /* Special case, there are already other threads with a timeout
         activated, evaluating the order.*/
      if (chVTIsTimeWithinX(abstime, nil.lasttime, nil.nexttime)) {
        port_timer_set_alarm(abstime);
        nil.nexttime = abstime;
      }
    }

    /* Timeout settings.*/
    otp->timeout = abstime - nil.lasttime;
  }
#else

  /* Timeout settings.*/
  otp->timeout = timeout;
#endif

  /* Scanning the whole threads array.*/
  ntp = nil.threads;
  while (true) {
    /* Is this thread ready to execute?*/
    if (NIL_THD_IS_READY(ntp)) {
      nil.current = nil.next = ntp;
      if (ntp == &nil.threads[NIL_CFG_NUM_THREADS]) {
        NIL_CFG_IDLE_ENTER_HOOK();
      }
      port_switch(ntp, otp);
      return nil.current->u1.msg;
    }

    /* Points to the next thread in lowering priority order.*/
    ntp++;
    chDbgAssert(ntp <= &nil.threads[NIL_CFG_NUM_THREADS],
                "pointer out of range");
  }
}