void up_sigdeliver(void)
{
#ifndef CONFIG_DISABLE_SIGNALS
  FAR struct tcb_s *rtcb = (struct tcb_s*)g_readytorun.head;
  chipreg_t regs[XCPTCONTEXT_REGS];
  sig_deliver_t sigdeliver;

  /* Save the errno.  This must be preserved throughout the signal handling
   * so that the user code final gets the correct errno value (probably
   * EINTR).
   */

  int saved_errno = rtcb->pterrno;

  board_led_on(LED_SIGNAL);

  sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n",
        rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head);
  ASSERT(rtcb->xcp.sigdeliver != NULL);

  /* Save the real return state on the stack. */

  ez80_copystate(regs, rtcb->xcp.regs);
  regs[XCPT_PC] = rtcb->xcp.saved_pc;
  regs[XCPT_I]  = rtcb->xcp.saved_i;

  /* Get a local copy of the sigdeliver function pointer.  We do this so
   * that we can nullify the sigdeliver function pointer in the TCB and
   * accept more signal deliveries while processing the current pending
   * signals.
   */

  sigdeliver           = rtcb->xcp.sigdeliver;
  rtcb->xcp.sigdeliver = NULL;

  /* Then restore the task interrupt state. */

  irqrestore(regs[XCPT_I]);

  /* Deliver the signals */

  sigdeliver(rtcb);

  /* Output any debug messages BEFORE restoring errno (because they may
   * alter errno), then disable interrupts again and restore the original
   * errno that is needed by the user logic (it is probably EINTR).
   */

  sdbg("Resuming\n");
  (void)irqsave();
  rtcb->pterrno = saved_errno;

  /* Then restore the correct state for this thread of
   * execution.
   */

  board_led_off(LED_SIGNAL);
  ez80_restorecontext(regs);
#endif
}
int main(void) 
{
    evEntityId_t prev;

    eventviewer_init();
    eventviewer_load(ev_ID_idle, idle);  
    eventviewer_load(ev_ID_systick, SysTick_Handler);  
    eventviewer_load(ev_ID_first_usrdef+1, userdef1); 
    eventviewer_load(ev_ID_first_usrdef+2, userdef2);
    
    // the eventviewer shall stay most of time in idle
    // apart from some specific actions: systick, userdef1 and userdef2
    eventviewer_switch_to(ev_ID_idle);
    
    board_led_init();
    
    systickserv_start_systick(1000, myonsystick);
    
    for(;;)
    {
        prev = eventviewer_switch_to(ev_ID_first_usrdef+1);
        board_led_on(board_led_0);
        eventviewer_switch_to(prev);
        
        systickserv_wait_for(500*1000);
        
        prev = eventviewer_switch_to(ev_ID_first_usrdef+2);
        board_led_off(board_led_0);
        eventviewer_switch_to(prev);
        
        systickserv_wait_for(500*1000);
    }    
}
Beispiel #3
0
void up_decodeirq(uint32_t *regs)
{
#ifdef CONFIG_SUPPRESS_INTERRUPTS
  board_led_on(LED_INIRQ);
  lowsyslog("Unexpected IRQ\n");
  current_regs = regs;
  PANIC();
#else
  unsigned int irq;

  /* Read the IRQ number from the IVR register (Could probably get the same
   * info from CIC register without the setup).
   */

  board_led_on(LED_INIRQ);
  irq = getreg32(STR71X_EIC_IVR);

  /* Verify that the resulting IRQ number is valid */

  if (irq < NR_IRQS)
    {
      uint32_t* savestate;

      /* Current regs non-zero indicates that we are processing an interrupt;
       * current_regs is also used to manage interrupt level context switches.
       */

      savestate     = (uint32_t*)current_regs;
      current_regs = regs;

      /* Mask and acknowledge the interrupt */

      up_maskack_irq(irq);

      /* Deliver the IRQ */

      irq_dispatch(irq, regs);

      /* Restore the previous value of current_regs.  NULL would indicate that
       * we are no longer in an interrupt handler.  It will be non-NULL if we
       * are returning from a nested interrupt.
       */

      current_regs = savestate;

      /* Unmask the last interrupt (global interrupts are still disabled) */

      up_enable_irq(irq);
    }
#if CONFIG_DEBUG
  else
    {
      PANIC(); /* Normally never happens */
    }
#endif
  board_led_off(LED_INIRQ);
#endif
}
int main(void) 
{
    
    board_led_init();
    
    systickserv_start_systick(1000, myonsystick);
    
    for(;;)
    {
        board_led_on(board_led_0);
        board_led_on(board_led_1);
         
        systickserv_wait_for(500*1000);
        
        board_led_off(board_led_0);
        board_led_off(board_led_1);
         
        systickserv_wait_for(500*1000);
    }
    
}
Beispiel #5
0
FAR chipreg_t *up_doirq(int irq, FAR chipreg_t *regs)
{
  FAR chipreg_t *ret = regs;

  board_led_on(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
  PANIC();
#else
  if ((unsigned)irq < NR_IRQS)
    {
      FAR chipreg_t *savestate;

      /* Nested interrupts are not supported in this implementation.  If
       * you want to implement nested interrupts, you would have to (1) change
       * the way that current_regs is handled and (2) the design associated
       * with CONFIG_ARCH_INTERRUPTSTACK.  The savestate variable will not
       * work for that purpose as implemented here because only the outermost
       * nested interrupt can result in a context switch (it can probably be
       * deleted).
       */

      /* Current regs non-zero indicates that we are processing
       * an interrupt; current_regs is also used to manage
       * interrupt level context switches.
       */

      savestate    = (FAR chipreg_t *)current_regs;
      current_regs = regs;

      /* Acknowledge the interrupt */

      up_ack_irq(irq);

      /* Deliver the IRQ */

      irq_dispatch(irq, regs);

      /* Restore the previous value of current_regs.  NULL would indicate that
       * we are no longer in an interrupt handler.  It will be non-NULL if we
       * are returning from a nested interrupt.
       */

      ret          = current_regs;
      current_regs = savestate;
    }

  board_led_off(LED_INIRQ);
#endif

  return ret;
}
Beispiel #6
0
uint32_t *up_doirq(int irq, uint32_t *regs)
{
  board_led_on(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
  PANIC();
#else
  uint32_t *savestate;

  /* Nested interrupts are not supported in this implementation.  If you want
   * to implement nested interrupts, you would have to (1) change the way that
   * current_regs is handled and (2) the design associated with
   * CONFIG_ARCH_INTERRUPTSTACK.  The savestate variable will not work for
   * that purpose as implemented here because only the outermost nested
   * interrupt can result in a context switch (it can probably be deleted).
   */

  /* Current regs non-zero indicates that we are processing an interrupt;
   * current_regs is also used to manage interrupt level context switches.
   */

  savestate    = (uint32_t*)current_regs;
  current_regs = regs;

  /* Acknowledge the interrupt */

  up_ack_irq(irq);

  /* Deliver the IRQ */

  irq_dispatch(irq, regs);

  /* If a context switch occurred while processing the interrupt then
   * current_regs may have change value.  If we return any value different
   * from the input regs, then the lower level will know that a context
   * switch occurred during interrupt processing.
   */

  regs = (uint32_t*)current_regs;

  /* Restore the previous value of current_regs.  NULL would indicate that
   * we are no longer in an interrupt handler.  It will be non-NULL if we
   * are returning from a nested interrupt.
   */

  current_regs = savestate;
#endif
  board_led_off(LED_INIRQ);
  return regs;
}
Beispiel #7
0
uint32_t *isr_handler(uint32_t *regs)
{
#ifdef CONFIG_SUPPRESS_INTERRUPTS
  board_led_on(LED_INIRQ);
  PANIC(); /* Doesn't return */
  return regs;               /* To keep the compiler happy */
#else
  uint32_t *ret;

  /* Dispatch the interrupt */

  board_led_on(LED_INIRQ);
  ret = common_handler((int)regs[REG_IRQNO], regs);
  board_led_off(LED_INIRQ);
  return ret;
#endif
}
void led_off(int led_no)
{
	int idx = decide_led_array_index(led_no);
	int err;

	if (idx == -WM_FAIL)
		return;
	if (os_timer_is_active(&led_data[idx].timer) == WM_SUCCESS) {
		err = os_timer_delete(&led_data[idx].timer);
		if (err != WM_SUCCESS) {
			wmprintf("Unable to delete LED timer\n\r");
			return;
		}
	}
	led_data[idx].curr_state = LED_OFF;
	board_led_off(led_no);
}
static void led_cb(os_timer_arg_t handle)
{
	int tid = (int) os_timer_get_context(&handle);
	if (tid >= LED_COUNT) {
		return;
	}
	if (led_data[tid].curr_state == LED_ON) {
		board_led_off(led_data[tid].led_no);
		led_data[tid].curr_state = LED_OFF;
		os_timer_change(&led_data[tid].timer,
				led_data[tid].off_duty_cycle, -1);
		os_timer_activate(&led_data[tid].timer);
	} else {
		board_led_on(led_data[tid].led_no);
		led_data[tid].curr_state = LED_ON;
		os_timer_change(&led_data[tid].timer,
				led_data[tid].on_duty_cycle, -1);
		os_timer_activate(&led_data[tid].timer);
	}
}
Beispiel #10
0
static void _up_assert(int errorcode)
{
  /* Are we in an interrupt handler or the idle task? */

  if (current_regs || ((struct tcb_s*)g_readytorun.head)->pid == 0)
    {
       (void)irqsave();
        for (;;)
          {
#ifdef CONFIG_ARCH_LEDS
            board_led_on(LED_PANIC);
            up_mdelay(250);
            board_led_off(LED_PANIC);
            up_mdelay(250);
#endif
          }
    }
  else
    {
      exit(errorcode);
    }
}
Beispiel #11
0
static void _up_assert(int errorcode) /* noreturn_function */
{
  /* Are we in an interrupt handler or the idle task? */

  if (up_interrupt_context() || ((FAR struct tcb_s*)g_readytorun.head)->pid == 0)
    {
       (void)irqsave();
        for(;;)
          {
#ifdef CONFIG_ARCH_LEDS
            board_led_on(LED_PANIC);
            up_mdelay(250);
            board_led_off(LED_PANIC);
            up_mdelay(250);
#endif
          }
    }
  else
    {
      exit(errorcode);
    }
}
Beispiel #12
0
uint32_t *irq_handler(uint32_t *regs)
{
#ifdef CONFIG_SUPPRESS_INTERRUPTS
  board_led_on(LED_INIRQ);
  PANIC(); /* Doesn't return */
  return regs;               /* To keep the compiler happy */
#else
  uint32_t *ret;
  int irq;

  board_led_on(LED_INIRQ);

  /* Get the IRQ number */

  irq = (int)regs[REG_IRQNO];

  /* Send an EOI (end of interrupt) signal to the PICs if this interrupt
   * involved the slave.
   */

  if (irq >= IRQ8)
    {
      /* Send reset signal to slave */

      idt_outb(PIC_OCW2_EOI_NONSPEC, PIC2_OCW2);
    }

  /* Send reset signal to master */

  idt_outb(PIC_OCW2_EOI_NONSPEC, PIC1_OCW2);

  /* Dispatch the interrupt */

  ret = common_handler(irq, regs);
  board_led_off(LED_INIRQ);
  return ret;
#endif
}
Beispiel #13
0
void up_idle(void)
{
#if defined(CONFIG_ARCH_LEDS) && defined(CONFIG_ARCH_BRINGUP)
  g_ledtoggle++;
  if (g_ledtoggle == 0x80)
    {
      board_led_on(LED_IDLE);
    }
  else if (g_ledtoggle == 0x00)
    {
      board_led_off(LED_IDLE);
    }
#endif

#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS)
  /* If the system is idle and there are no timer interrupts,
   * then process "fake" timer interrupts. Hopefully, something
   * will wake up.
   */

  sched_process_timer();
#endif
}
Beispiel #14
0
void up_sigdeliver(void)
{
  struct tcb_s *rtcb = (struct tcb_s*)g_readytorun.head;
  uint32_t regs[XCPTCONTEXT_REGS];
  sig_deliver_t sigdeliver;

  /* Save the errno.  This must be preserved throughout the signal handling
   * so that the user code final gets the correct errno value (probably
   * EINTR).
   */

  int saved_errno = rtcb->pterrno;

  board_led_on(LED_SIGNAL);

  sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n",
        rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head);
  ASSERT(rtcb->xcp.sigdeliver != NULL);

  /* Save the real return state on the stack. */

  up_copystate(regs, rtcb->xcp.regs);
  regs[REG_EPC]        = rtcb->xcp.saved_epc;
  regs[REG_STATUS]     = rtcb->xcp.saved_status;

  /* Get a local copy of the sigdeliver function pointer. We do this so that
   * we can nullify the sigdeliver function pointer in the TCB and accept
   * more signal deliveries while processing the current pending signals.
   */

  sigdeliver           = rtcb->xcp.sigdeliver;
  rtcb->xcp.sigdeliver = NULL;

  /* Then restore the task interrupt state */

  irqrestore((irqstate_t)regs[REG_STATUS]);

  /* Deliver the signals */

  sigdeliver(rtcb);

  /* Output any debug messages BEFORE restoring errno (because they may
   * alter errno), then disable interrupts again and restore the original
   * errno that is needed by the user logic (it is probably EINTR).
   */

  svdbg("Resuming EPC: %08x STATUS: %08x\n", regs[REG_EPC], regs[REG_STATUS]);

  (void)irqsave();
  rtcb->pterrno = saved_errno;

  /* Then restore the correct state for this thread of
   * execution.
   */

  board_led_off(LED_SIGNAL);
  up_fullcontextrestore(regs);

  /* up_fullcontextrestore() should not return but could if the software
   * interrupts are disabled.
   */

  PANIC();
}
Beispiel #15
0
void up_sigdeliver(void)
{
    struct tcb_s *rtcb = (struct tcb_s*)g_readytorun.head;
    uint8_t regs[XCPTCONTEXT_REGS];
    sig_deliver_t sigdeliver;

    /* Save the errno.  This must be preserved throughout the signal handling
     * so that the user code final gets the correct errno value (probably EINTR).
     */

    int saved_errno = rtcb->pterrno;

    board_led_on(LED_SIGNAL);

    sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n",
         rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head);
    ASSERT(rtcb->xcp.sigdeliver != NULL);

    /* Save the real return state on the stack. */

    up_copystate(regs, rtcb->xcp.regs);
    regs[REG_PCL]        = rtcb->xcp.saved_pcl;
    regs[REG_PCH]        = rtcb->xcp.saved_pch;
    regs[REG_SREG]       = rtcb->xcp.saved_sreg;

    /* Get a local copy of the sigdeliver function pointer. We do this so that
     * we can nullify the sigdeliver function pointer in the TCB and accept
     * more signal deliveries while processing the current pending signals.
     */

    sigdeliver           = rtcb->xcp.sigdeliver;
    rtcb->xcp.sigdeliver = NULL;

    /* Then restore the task interrupt state */

    irqrestore(regs[REG_SREG]);

    /* Deliver the signals */

    sigdeliver(rtcb);

    /* Output any debug messages BEFORE restoring errno (because they may
     * alter errno), then disable interrupts again and restore the original
     * errno that is needed by the user logic (it is probably EINTR).
     */

    sdbg("Resuming\n");
    (void)irqsave();
    rtcb->pterrno = saved_errno;

    /* Then restore the correct state for this thread of execution. This is an
     * unusual case that must be handled by up_fullcontextresore. This case is
     * unusal in two ways:
     *
     *   1. It is not a context switch between threads.  Rather, up_fullcontextrestore
     *      must behave more it more like a longjmp within the same task, using
     *      he same stack.
     *   2. In this case, up_fullcontextrestore is called with r12 pointing to
     *      a register save area on the stack to be destroyed.  This is
     *      dangerous because there is the very real possibility that the new
     *      stack pointer might overlap with the register save area and hat stack
     *      usage in up_fullcontextrestore might corrupt the register save data
     *      before the state is restored.  At present, there does not appear to
     *      be any stack overlap problems.  If there were, then adding 3 words
     *      to the size of register save structure size will protect its contents.
     */

    board_led_off(LED_SIGNAL);
    up_fullcontextrestore(regs);
}
FAR chipreg_t *up_doirq(uint8_t irq, FAR chipreg_t *regs)
{
  board_led_on(LED_INIRQ);

#ifdef CONFIG_SUPPRESS_INTERRUPTS

  lowsyslog(LOG_ERR, "Unexpected IRQ\n");
  IRQ_ENTER(regs);
  PANIC();
  return NULL; /* Won't get here */

#else
#ifdef CONFIG_ARCH_ADDRENV
  FAR chipreg_t *newregs;
#endif

  if (irq < NR_IRQS)
    {
      DECL_SAVESTATE();

      /* Indicate that we have entered IRQ processing logic */

      IRQ_ENTER(irq, regs);

      /* Deliver the IRQ */

      irq_dispatch(irq, regs);

#ifdef CONFIG_ARCH_ADDRENV
      /* If a context switch occurred, 'newregs' will hold the new context */

      newregs = IRQ_STATE();

      if (newregs != regs)
        {
          /* Make sure that the address environment for the previously
           * running task is closed down gracefully and set up the
           * address environment for the new thread at the head of the
           * ready-to-run list.
           */

          (void)group_addrenv(NULL);
        }

      regs = newregs;

#else
      /* If a context switch occurred, 'regs' will hold the new context */

      regs = IRQ_STATE();
#endif

      /* Indicate that we are no longer in interrupt processing logic */

      IRQ_LEAVE(irq);
    }

  board_led_off(LED_INIRQ);
  return regs;
#endif
}
uint32_t *pic32mx_decodeirq(uint32_t *regs)
{
#ifdef CONFIG_PIC32MX_NESTED_INTERRUPTS
  uint32_t *savestate;
#endif
  uint32_t regval;
  int irq;

  /* If the board supports LEDs, turn on an LED now to indicate that we are
   * processing an interrupt.
   */

  board_led_on(LED_INIRQ);

  /* Save the current value of current_regs (to support nested interrupt
   * handling).  Then set current_regs to regs, indicating that this is
   * the interrupted context that is being processed now.
   */

#ifdef CONFIG_PIC32MX_NESTED_INTERRUPTS
  savestate = (uint32_t*)current_regs;
#else
  DEBUGASSERT(current_regs == NULL);
#endif
  current_regs = regs;

  /* Loop while there are pending interrupts with priority greater than zero */

  for (;;)
    {
      /* Read the INTSTAT register.  This register contains both the priority
       * and the interrupt vector number.
       */

      regval = getreg32(PIC32MX_INT_INTSTAT);
      if ((regval & INT_INTSTAT_RIPL_MASK) == 0)
        {
          /* Break out of the loop when the priority is zero meaning that
           * there are no further pending interrupts.
           */

          break;
        }

      /* Get the vector number.  The IRQ numbers have been arranged so that
       * vector numbers and NuttX IRQ numbers are the same value.
       */

      irq = ((regval) & INT_INTSTAT_VEC_MASK) >> INT_INTSTAT_VEC_SHIFT;

      /* Deliver the IRQ */

      irq_dispatch(irq, regs);
    }

  /* If a context switch occurred while processing the interrupt then
   * current_regs may have change value.  If we return any value different
   * from the input regs, then the lower level will know that a context
   * switch occurred during interrupt processing.
   */

  regs = (uint32_t*)current_regs;

  /* Restore the previous value of current_regs.  NULL would indicate that
   * we are no longer in an interrupt handler.  It will be non-NULL if we
   * are returning from a nested interrupt.
   */

#ifdef CONFIG_PIC32MX_NESTED_INTERRUPTS
  /* I think there are some task switching issues here.  You should not
   * enable nested interrupts unless you are ready to deal with the
   * complexities of nested context switching.  The logic here is probably
   * insufficient.
   */

  current_regs = savestate;
  if (current_regs == NULL)
    {
      board_led_off(LED_INIRQ);
    }
#else
  current_regs = NULL;
  board_led_off(LED_INIRQ);
#endif

  return regs;
}
void up_sigdeliver(void)
{
    /* NOTE the "magic" guard space added to regs.  This is a little kludge
     * because up_fullcontextrestore (called below) will do a stack-to-stack
     * copy an may overwrite the regs[] array contents.  Sorry.
     */

    struct tcb_s  *rtcb = (struct tcb_s*)g_readytorun.head;
    uint32_t regs[XCPTCONTEXT_REGS + 4];
    sig_deliver_t sigdeliver;

    /* Save the errno.  This must be preserved throughout the signal handling
     * so that the user code final gets the correct errno value (probably
     * EINTR).
     */

    int saved_errno = rtcb->pterrno;

    board_led_on(LED_SIGNAL);

    sdbg("rtcb=%p sigdeliver=%p sigpendactionq.head=%p\n",
         rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head);
    ASSERT(rtcb->xcp.sigdeliver != NULL);

    /* Save the real return state on the stack. */

    up_copyfullstate(regs, rtcb->xcp.regs);
    regs[REG_PC]         = rtcb->xcp.saved_pc;
    regs[REG_PRIMASK]    = rtcb->xcp.saved_primask;
    regs[REG_XPSR]       = rtcb->xcp.saved_xpsr;
#ifdef CONFIG_BUILD_PROTECTED
    regs[REG_LR]         = rtcb->xcp.saved_lr;
#endif

    /* Get a local copy of the sigdeliver function pointer. We do this so that
     * we can nullify the sigdeliver function pointer in the TCB and accept
     * more signal deliveries while processing the current pending signals.
     */

    sigdeliver           = rtcb->xcp.sigdeliver;
    rtcb->xcp.sigdeliver = NULL;

    /* Then restore the task interrupt state */

    irqrestore((uint8_t)regs[REG_PRIMASK]);

    /* Deliver the signal */

    sigdeliver(rtcb);

    /* Output any debug messages BEFORE restoring errno (because they may
     * alter errno), then disable interrupts again and restore the original
     * errno that is needed by the user logic (it is probably EINTR).
     */

    sdbg("Resuming\n");
    (void)irqsave();
    rtcb->pterrno = saved_errno;

    /* Then restore the correct state for this thread of
     * execution.
     */

    board_led_off(LED_SIGNAL);
    up_fullcontextrestore(regs);
}
Beispiel #19
0
uint32_t *arm_doirq(int irq, uint32_t *regs)
{
  board_led_on(LED_INIRQ);
#ifdef CONFIG_SUPPRESS_INTERRUPTS
  PANIC();
#else
  /* Nested interrupts are not supported */

  DEBUGASSERT(current_regs == NULL);

  /* Current regs non-zero indicates that we are processing an interrupt;
   * current_regs is also used to manage interrupt level context switches.
   */

  current_regs = regs;

  /* Mask and acknowledge the interrupt */

  up_maskack_irq(irq);

  /* Deliver the IRQ */

  irq_dispatch(irq, regs);

#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV)
  /* Check for a context switch.  If a context switch occurred, then
   * current_regs will have a different value than it did on entry.  If an
   * interrupt level context switch has occurred, then restore the floating
   * point state and the establish the correct address environment before
   * returning from the interrupt.
   */

  if (regs != current_regs)
    {
#ifdef CONFIG_ARCH_FPU
      /* Restore floating point registers */

      up_restorefpu((uint32_t*)current_regs);
#endif

#ifdef CONFIG_ARCH_ADDRENV
      /* Make sure that the address environment for the previously
       * running task is closed down gracefully (data caches dump,
       * MMU flushed) and set up the address environment for the new
       * thread at the head of the ready-to-run list.
       */

      (void)group_addrenv(NULL);
#endif
    }
#endif

  /* Set current_regs to NULL to indicate that we are no longer in an
   * interrupt handler.
   */

  regs         = (uint32_t *)current_regs;
  current_regs = NULL;

  /* Unmask the last interrupt (global interrupts are still disabled) */

  up_enable_irq(irq);
#endif

  board_led_off(LED_INIRQ);
  return regs;
}