예제 #1
0
static void _sema4_isr(pointer p)
{
    CORE_MUTEX_DEVICE_PTR   device_ptr = (CORE_MUTEX_DEVICE_PTR) p;
    uint_32                 i;
    vuchar_ptr              gate_ptr;
    uchar                   lock = _psp_core_num()+1;
    uint_16                 mask = 0x8000;
    boolean                 waiting;

    for (i=0;i<SEMA4_NUM_GATES;i++) {
        if (*device_ptr->CPNTF_PTR & mask ) {
            // An interrupt is pending on this mutex, the only way to clear it is to lock it (either
            // by this core or another)
            gate_ptr = device_ptr->MUTEX_PTR[idx[i]]->GATE_PTR;
            *gate_ptr = lock;
            if (*gate_ptr == lock) {
                // Now, check to see if any task is waiting for it
                waiting = FALSE;
                if (device_ptr->MUTEX_PTR[idx[i]]) {
                    if (_taskq_get_value(device_ptr->MUTEX_PTR[idx[i]]->WAIT_Q)) {
                        _taskq_resume(device_ptr->MUTEX_PTR[idx[i]]->WAIT_Q, FALSE);
                        waiting = TRUE;
                    }
                }
                if (!waiting) {
                    // No task was waiting, give it back - this can occur due to a failed trylock
                    *gate_ptr = SEMA4_UNLOCK;
                }
            }
        }
        mask >>= 1;
   }
}
예제 #2
0
static _mqx_int _io_serial_mix_nextc
   (
      /* [IN] the interrupt I/O context information */
      IO_SERIAL_INT_DEVICE_STRUCT_PTR int_io_dev_ptr
   )
{ /* Body */
   unsigned char c;

   if (int_io_dev_ptr->HAVE_STOPPED_OUTPUT
      || (! int_io_dev_ptr->OUTPUT_ENABLED))
   {
      return(-1);
   } /* Endif */

   if (_CHARQ_EMPTY(int_io_dev_ptr->OUT_QUEUE)) {
      /* No output */
      int_io_dev_ptr->OUTPUT_ENABLED = FALSE;
      if (_QUEUE_GET_SIZE(int_io_dev_ptr->OUT_WAITING_TASKS)) {
         _taskq_resume(int_io_dev_ptr->OUT_WAITING_TASKS, TRUE);
      } /* Endif */
      return(-1);
   }/* Endif */

   _CHARQ_DEQUEUE(int_io_dev_ptr->OUT_QUEUE, c);
   return((_mqx_int)c);

} /* Endbody */
예제 #3
0
uint_32 _core_mutex_unlock( CORE_MUTEX_PTR core_mutex_ptr )
{
    uchar lock = _psp_core_num()+1;
    vuchar_ptr gate_ptr;

#if MQX_CHECK_ERRORS
    if (core_mutex_ptr == NULL) {
        return MQX_INVALID_POINTER;
    }

    if (core_mutex_ptr->VALID != CORE_MUTEX_VALID) {
        return MQX_INVALID_POINTER;
    }
#endif

    gate_ptr = core_mutex_ptr->GATE_PTR;

    // Make sure it is locked by this core
    if ( *gate_ptr != lock) {
        return MQX_NOT_RESOURCE_OWNER;
    }

#if BSPCFG_CORE_MUTEX_STATS
    core_mutex_ptr->UNLOCKS++;
#endif

    // Unlock if
    *gate_ptr = SEMA4_UNLOCK;


    // See if this core has any other tasks waiting for this lock
    if (_taskq_get_value(core_mutex_ptr->WAIT_Q)) {

        // if so, have to queue the next request
        _sema4_int_disable();
        *gate_ptr = lock;
        if (*gate_ptr == lock) {
            // if we got it, wake up the next task
            _taskq_resume(core_mutex_ptr->WAIT_Q, FALSE);
        }
        _sema4_int_enable();
    }

    return COREMUTEX_OK;
}
예제 #4
0
/*FUNCTION*-------------------------------------------------------------------
*
* Function Name    : _kuart_period_isr
* Returned Value   : void
* Comments         :
*    Periodic interrupt for mix uart.
*
*END*----------------------------------------------------------------------*/
static void _kuart_period_isr(void * data_ptr) {
    IO_SERIAL_INT_DEVICE_STRUCT_PTR        int_io_dev_ptr = data_ptr;
    KUART_INFO_STRUCT_PTR                  sci_info_ptr = int_io_dev_ptr->DEV_INFO_PTR;
    uint32_t dmaUC, dmaC;

    _int_disable();

    dma_channel_status(sci_info_ptr->RX_DCH, &sci_info_ptr->RX_DMA_SEQ, &dmaUC);
    dmaC = int_io_dev_ptr->IQUEUE_SIZE - dmaUC;


    if (_QUEUE_GET_SIZE(int_io_dev_ptr->IN_WAITING_TASKS)) {
        if((int64_t)(dmaC + sci_info_ptr->dmaC - sci_info_ptr->readC) >= sci_info_ptr->rxwakeupnum){
            _taskq_resume(int_io_dev_ptr->IN_WAITING_TASKS, TRUE);
        }
    }

    _int_enable();
}
예제 #5
0
파일: serl_int.c 프로젝트: gxliu/MQX_3.8.0
_mqx_int _io_serial_int_nextc
   (
      /* [IN] the interrupt I/O context information */
      IO_SERIAL_INT_DEVICE_STRUCT_PTR int_io_dev_ptr
   )
{ /* Body */
   uchar c;

   if (int_io_dev_ptr->FLAGS & IO_SERIAL_XON_XOFF) {
      if (int_io_dev_ptr->MUST_STOP_INPUT) {
         int_io_dev_ptr->MUST_STOP_INPUT    = FALSE;
         int_io_dev_ptr->HAVE_STOPPED_INPUT = TRUE;
        return((int_32)CNTL_S);
      } else if (int_io_dev_ptr->MUST_START_INPUT) {
         int_io_dev_ptr->MUST_START_INPUT   = FALSE;
         int_io_dev_ptr->HAVE_STOPPED_INPUT = FALSE;
         return((int_32)CNTL_Q);
      } /* Endif */
   } /* Endif */

   if (int_io_dev_ptr->HAVE_STOPPED_OUTPUT
      || (! int_io_dev_ptr->OUTPUT_ENABLED))
   {
      return(-1);
   } /* Endif */

   if (_CHARQ_EMPTY(int_io_dev_ptr->OUT_QUEUE)) {
      /* No output */
      int_io_dev_ptr->OUTPUT_ENABLED = FALSE;
      if (_QUEUE_GET_SIZE(int_io_dev_ptr->OUT_WAITING_TASKS)) {
         _taskq_resume(int_io_dev_ptr->OUT_WAITING_TASKS, TRUE);
      } /* Endif */
      return(-1);
   }/* Endif */

   _CHARQ_DEQUEUE(int_io_dev_ptr->OUT_QUEUE, c);
   return((_mqx_int)c);

} /* Endbody */
예제 #6
0
파일: serl_int.c 프로젝트: gxliu/MQX_3.8.0
boolean _io_serial_int_addc
   (
      /* [IN] the interrupt I/O context information */
      IO_SERIAL_INT_DEVICE_STRUCT_PTR int_io_dev_ptr,

      /* [IN] the character to add to the input queue */
      char                            c
   )
{ /* Body */
   CHARQ_STRUCT_PTR in_queue;
   _mqx_uint       ioctl_val;

   if (int_io_dev_ptr->FLAGS & IO_SERIAL_XON_XOFF) {
      if (int_io_dev_ptr->HAVE_STOPPED_OUTPUT) {
         if (c == CNTL_Q) {
            int_io_dev_ptr->HAVE_STOPPED_OUTPUT = FALSE;
            return TRUE;
         } /* Endif */
      } else {
         if (c == CNTL_S) {
            int_io_dev_ptr->HAVE_STOPPED_OUTPUT = TRUE;
            return TRUE;
         } /* Endif */
      } /* Endif */
   } /* Endif */

   in_queue = int_io_dev_ptr->IN_QUEUE;
   if (_CHARQ_NOT_FULL(in_queue)) {
      _CHARQ_ENQUEUE(in_queue,c);

      if (int_io_dev_ptr->FLAGS & (IO_SERIAL_XON_XOFF |
         IO_SERIAL_HW_FLOW_CONTROL))
      {
         if (_CHARQ_SIZE(in_queue) > int_io_dev_ptr->INPUT_HIGH_WATER_MARK) {
            if (!int_io_dev_ptr->HAVE_STOPPED_INPUT) {
               if (int_io_dev_ptr->FLAGS & IO_SERIAL_XON_XOFF) {
                  int_io_dev_ptr->MUST_STOP_INPUT = TRUE;
               } else {
                  if (int_io_dev_ptr->DEV_IOCTL != NULL) {
                     ioctl_val = IO_SERIAL_RTS;
                     (*int_io_dev_ptr->DEV_IOCTL)(int_io_dev_ptr->DEV_INFO_PTR, IO_IOCTL_SERIAL_CLEAR_HW_SIGNAL, &ioctl_val);
                  }
                  int_io_dev_ptr->HAVE_STOPPED_INPUT = TRUE;
               } /* Endif */
            } /* Endif */
         } else if (_CHARQ_SIZE(in_queue) < int_io_dev_ptr->INPUT_LOW_WATER_MARK) {
            if (int_io_dev_ptr->HAVE_STOPPED_INPUT) {
               if (int_io_dev_ptr->FLAGS & IO_SERIAL_XON_XOFF) {
                  int_io_dev_ptr->MUST_START_INPUT = TRUE;
               } else {
                  if (int_io_dev_ptr->DEV_IOCTL != NULL) {
                     ioctl_val = IO_SERIAL_RTS;
                     (*int_io_dev_ptr->DEV_IOCTL)(int_io_dev_ptr->DEV_INFO_PTR, IO_IOCTL_SERIAL_SET_HW_SIGNAL, &ioctl_val);
                  }
                  int_io_dev_ptr->HAVE_STOPPED_INPUT = FALSE;
               } /* Endif */
            } /* Endif */
         } /* Endif */
      } /* Endif */
   } else {
      /* indicate that tossed the character */
      return FALSE;
   } /* Endif */

   if (_QUEUE_GET_SIZE(int_io_dev_ptr->IN_WAITING_TASKS)) {
      _taskq_resume(int_io_dev_ptr->IN_WAITING_TASKS, TRUE);
   } /* Endif */
   return TRUE;
   
} /* Endbody */