Ejemplo n.º 1
0
//----------------------------------------------------------------------------
int tn_fmem_release(TN_FMP * fmp,void * p_data)
{
   TN_INTSAVE_DATA

   CDLL_QUEUE * que;
   TN_TCB * task;

#if TN_CHECK_PARAM
   if(fmp == NULL || p_data == NULL)
      return  TERR_WRONG_PARAM;
   if(fmp->id_fmp != TN_ID_FSMEMORYPOOL)
      return TERR_NOEXS;
#endif

   TN_CHECK_NON_INT_CONTEXT

   tn_disable_interrupt();

   if(!is_queue_empty(&(fmp->wait_queue)))
   {
      que = queue_remove_head(&(fmp->wait_queue));
      task = get_task_by_tsk_queue(que);

      task->data_elem = p_data;

      if(task_wait_complete(task))
      {
         tn_enable_interrupt();
         tn_switch_context();

         return TERR_NO_ERR;
      }
   }
   else
      fm_put(fmp,p_data);

   tn_enable_interrupt();

   return  TERR_NO_ERR;
}
Ejemplo n.º 2
0
//----------------------------------------------------------------------------
int tn_fmem_delete(TN_FMP * fmp)
{
   TN_INTSAVE_DATA
   CDLL_QUEUE * que;
   TN_TCB * task;

#if TN_CHECK_PARAM
   if(fmp == NULL)
      return TERR_WRONG_PARAM;
   if(fmp->id_fmp != TN_ID_FSMEMORYPOOL)
      return TERR_NOEXS;
#endif

   TN_CHECK_NON_INT_CONTEXT

   while(!is_queue_empty(&(fmp->wait_queue)))
   {
      tn_disable_interrupt();

     //--- delete from sem wait queue

      que = queue_remove_head(&(fmp->wait_queue));
      task = get_task_by_tsk_queue(que);
      if(task_wait_complete(task))
      {
         task->task_wait_rc = TERR_DLT;
         tn_enable_interrupt();
         tn_switch_context();
      }
   }

   if(tn_chk_irq_disabled() == 0)
      tn_disable_interrupt();

   fmp->id_fmp = 0;   //-- Fixed-size memory pool not exists now

   tn_enable_interrupt();

   return TERR_NO_ERR;
}
Ejemplo n.º 3
0
//----------------------------------------------------------------------------
int tn_sem_delete(TN_SEM * sem)
{
   TN_INTSAVE_DATA
   CDLL_QUEUE * que;
   TN_TCB * task;

#if TN_CHECK_PARAM
   if(sem == NULL)
      return TERR_WRONG_PARAM;
   if(sem->id_sem != TN_ID_SEMAPHORE)
      return TERR_NOEXS;
#endif

   TN_CHECK_NON_INT_CONTEXT

   while(!is_queue_empty(&(sem->wait_queue)))
   {
      tn_disable_interrupt();

     //--- delete from the sem wait queue

      que = queue_remove_head(&(sem->wait_queue));
      task = get_task_by_tsk_queue(que);
      if(task_wait_complete(task))
      {
         task->task_wait_rc = TERR_DLT;
         tn_enable_interrupt();
         tn_switch_context();
      }
   }

   if(tn_chk_irq_disabled() == 0) // int enable
      tn_disable_interrupt();

   sem->id_sem = 0; // Semaphore not exists now

   tn_enable_interrupt();

   return TERR_NO_ERR;
}
Ejemplo n.º 4
0
Archivo: tn.c Proyecto: ADTL/AFGUI
//----------------------------------------------------------------------------
static void tn_timer_task_func(void * par)
{
   TN_INTSAVE_DATA
   volatile TN_TCB * task;
   volatile CDLL_QUEUE * curr_que;

   //-- User application init - user's objects initial (tasks etc.) creation

   tn_app_init();

   //-- Enable interrupt here ( include tick int)

   tn_cpu_int_enable();

   //-------------------------------------------------------------------------

   for(;;)
   {

     //------------ OS timer tick -------------------------------------

      tn_disable_interrupt();

      curr_que = tn_wait_timeout_list.next;
      while(curr_que != &tn_wait_timeout_list)
      {
         task = get_task_by_timer_queque((CDLL_QUEUE*)curr_que);
         if(task->tick_count != TN_WAIT_INFINITE)
         {
            if(task->tick_count > 0)
            {
               task->tick_count--;
               if(task->tick_count == 0) //-- Time out expiried
               {
                  queue_remove_entry(&(((TN_TCB*)task)->task_queue));
                  task_wait_complete((TN_TCB*)task);
                  task->task_wait_rc = TERR_TIMEOUT;
               }
            }
         }

         curr_que = curr_que->next;
      }

      task_curr_to_wait_action(NULL,
                               TSK_WAIT_REASON_SLEEP,
                               TN_WAIT_INFINITE);
      tn_enable_interrupt();

      tn_switch_context();
   }
}
Ejemplo n.º 5
0
//----------------------------------------------------------------------------
int tn_task_resume(TN_TCB * task)
{
   TN_INTSAVE_DATA
   int rc;

#if TN_CHECK_PARAM
   if(task == NULL)
      return  TERR_WRONG_PARAM;
   if(task->id_task != TN_ID_TASK)
      return TERR_NOEXS;
#endif

   TN_CHECK_NON_INT_CONTEXT

   tn_disable_interrupt();

   if(!(task->task_state & TSK_STATE_SUSPEND))
      rc = TERR_WSTATE;
   else
   {
      if(!(task->task_state & TSK_STATE_WAIT)) //- The task is not in the WAIT-SUSPEND state
      {
         task_to_runnable(task);
         tn_enable_interrupt();
         tn_switch_context();

         return TERR_NO_ERR;
      }
      else  //-- Just remove TSK_STATE_SUSPEND from the task state
      {
         task->task_state &= ~TSK_STATE_SUSPEND;
         rc = TERR_NO_ERR;
      }
   }

   tn_enable_interrupt();

   return rc;
}
Ejemplo n.º 6
0
//----------------------------------------------------------------------------
int tn_task_activate(TN_TCB * task)
{
   TN_INTSAVE_DATA
   int rc;

#if TN_CHECK_PARAM
   if(task == NULL)
      return  TERR_WRONG_PARAM;
   if(task->id_task != TN_ID_TASK)
      return TERR_NOEXS;
#endif

   TN_CHECK_NON_INT_CONTEXT

   tn_disable_interrupt();

   if(task->task_state == TSK_STATE_DORMANT)
   {
      task_to_runnable(task);
      tn_enable_interrupt();
      tn_switch_context();

      return TERR_NO_ERR;
   }
   else
   {
      if(task->activate_count == 0)
      {
         task->activate_count++;
         rc = TERR_NO_ERR;
      }
      else
         rc = TERR_OVERFLOW;
   }

   tn_enable_interrupt();

   return rc;
}
Ejemplo n.º 7
0
//----------------------------------------------------------------------------
int tn_event_wait_polling(TN_EVENT * evf,
                    unsigned int wait_pattern,
                    int wait_mode,
                    unsigned int * p_flags_pattern)
{
   TN_INTSAVE_DATA
   int rc;
   int fCond;

#if TN_CHECK_PARAM
   if(evf == NULL || wait_pattern == 0 || p_flags_pattern == NULL)
      return TERR_WRONG_PARAM;
   if(evf->id_event != TN_ID_EVENT)
      return TERR_NOEXS;
#endif

   TN_CHECK_NON_INT_CONTEXT

   tn_disable_interrupt();

   //-- If event attr is TN_EVENT_ATTR_SINGLE and another task already
   //-- in event wait queue - return ERROR without checking release condition

   if((evf->attr & TN_EVENT_ATTR_SINGLE) && !is_queue_empty(&(evf->wait_queue)))
   {
      rc = TERR_ILUSE;
   }
   else
   {
       //-- Check release condition

      if(wait_mode & TN_EVENT_WCOND_OR) //-- any setted bit is enough for release condition
         fCond = ((evf->pattern & wait_pattern) != 0);
      else                              //-- TN_EVENT_WCOND_AND is default mode
         fCond = ((evf->pattern & wait_pattern) == wait_pattern);

      if(fCond)
      {
         *p_flags_pattern = evf->pattern;
         if(evf->attr & TN_EVENT_ATTR_CLR)
            evf->pattern = 0;
          rc = TERR_NO_ERR;
      }
      else
         rc = TERR_TIMEOUT;
   }

   tn_enable_interrupt();

   return rc;
}
Ejemplo n.º 8
0
//----------------------------------------------------------------------------
int tn_event_delete(TN_EVENT * evf)
{
   TN_INTSAVE_DATA
   CDLL_QUEUE * que;
   TN_TCB * task;

#if TN_CHECK_PARAM
   if(evf == NULL)
      return TERR_WRONG_PARAM;
   if(evf->id_event != TN_ID_EVENT)
      return TERR_NOEXS;
#endif

   TN_CHECK_NON_INT_CONTEXT

   tn_disable_interrupt();    // v.2.7 - thanks to Eugene Scopal

   while(!is_queue_empty(&(evf->wait_queue)))
   {
     //--- delete from sem wait queue

      que = queue_remove_head(&(evf->wait_queue));
      task = get_task_by_tsk_queue(que);
      if(task_wait_complete(task))
      {
         task->task_wait_rc = TERR_DLT;
         tn_enable_interrupt();
         tn_switch_context();
         tn_disable_interrupt();    // v.2.7
      }
   }

   evf->id_event = 0; // Event not exists now

   tn_enable_interrupt();

   return TERR_NO_ERR;
}
//----------------------------------------------------------------------------
int tn_event_delete(TN_EVENT * evf)
{
   TN_INTSAVE_DATA
   CDLL_QUEUE * que;
   TN_TCB * task;
   if(evf == NULL)
      return TERR_WRONG_PARAM;
   if(evf->id_event != TN_ID_EVENT)
      return TERR_NOEXS;

   TN_CHECK_NON_INT_CONTEXT

   while(!is_queue_empty(&(evf->wait_queue)))
   {
      if(tn_chk_irq_disabled() == 0) // int enable
         tn_disable_interrupt();

     //--- delete from sem wait queue
      que = queue_remove_head(&(evf->wait_queue));
      task = get_task_by_tsk_queue(que);
      if(task_wait_complete(task,FALSE))
      {
         task->task_wait_rc = TERR_DLT;
         tn_enable_interrupt();
         tn_switch_context();
      }
   }

   if(tn_chk_irq_disabled() == 0) // int enable
      tn_disable_interrupt();

   evf->id_event = 0; // Event not exists now

   tn_enable_interrupt();

   return TERR_NO_ERR;
}
Ejemplo n.º 10
0
//----------------------------------------------------------------------------
int tn_task_release_wait(TN_TCB * task)
{
   TN_INTSAVE_DATA
   int rc;

#if TN_CHECK_PARAM
   if(task == NULL)
      return  TERR_WRONG_PARAM;
   if(task->id_task != TN_ID_TASK)
      return TERR_NOEXS;
#endif

   TN_CHECK_NON_INT_CONTEXT

   tn_disable_interrupt();

   if((task->task_state & TSK_STATE_WAIT) == 0)
   {
      rc = TERR_WCONTEXT;
   }
   else
   {
      queue_remove_entry(&(task->task_queue));
      if(task_wait_complete(task))
      {
         tn_enable_interrupt();
         tn_switch_context();
         return TERR_NO_ERR;
      }
      rc = TERR_NO_ERR;
   }

   tn_enable_interrupt();

   return rc;
}
Ejemplo n.º 11
0
//----------------------------------------------------------------------------
int tn_fmem_get(TN_FMP * fmp,void ** p_data,unsigned int timeout)
{
   TN_INTSAVE_DATA
   int rc; //-- return code
   void * ptr;

   if(fmp == NULL || p_data == NULL || timeout == 0)
      return  TERR_WRONG_PARAM;
   if(fmp->id_fmp != TN_ID_FSMEMORYPOOL)
      return TERR_NOEXS;

   TN_CHECK_NON_INT_CONTEXT

   tn_disable_interrupt();

   ptr = fm_get(fmp);
   if(ptr != NULL) //-- Get memory
   {
      *p_data = ptr;
      rc = TERR_NO_ERR;
   }
   else
   {
      task_curr_to_wait_action(&(fmp->wait_queue),
                                     TSK_WAIT_REASON_WFIXMEM,timeout);
      tn_enable_interrupt();
      tn_switch_context();
         //-- When return to this point,in data_elem have to be  valid value
      *p_data = tn_curr_run_task->data_elem; //-- Return to caller
      return tn_curr_run_task->task_wait_rc;
     // return  TERR_NO_ERR;
   }

   tn_enable_interrupt();
   return rc;
}
Ejemplo n.º 12
0
//----------------------------------------------------------------------------
//   Acquire Semaphore Resource
//----------------------------------------------------------------------------
int tn_sem_acquire(TN_SEM * sem, unsigned long timeout)
{
   TN_INTSAVE_DATA
   int rc; //-- return code

#if TN_CHECK_PARAM
   if(sem == NULL || timeout == 0)
      return  TERR_WRONG_PARAM;
   if(sem->max_count == 0)
      return  TERR_WRONG_PARAM;
   if(sem->id_sem != TN_ID_SEMAPHORE)
      return TERR_NOEXS;
#endif

   TN_CHECK_NON_INT_CONTEXT

   tn_disable_interrupt();

   if(sem->count >= 1)
   {
      sem->count--;
      rc = TERR_NO_ERR;
   }
   else
   {
      task_curr_to_wait_action(&(sem->wait_queue), TSK_WAIT_REASON_SEM, timeout);
      tn_enable_interrupt();
      tn_switch_context();

      return tn_curr_run_task->task_wait_rc;
   }

   tn_enable_interrupt();

   return rc;
}
Ejemplo n.º 13
0
S32 pushToCirBuf(CIR_BUFFER *circular_buf, U8 *buffer, U32 size )
{
  S32 retval=0;
  U32 i;
  U32 BufSize=0;
  TN_INTSAVE_DATA
  tn_disable_interrupt();
  if ( circular_buf != NULL )
  {
    BufSize = getCirBufAvailableSize (circular_buf);
    if (BufSize >= size)
    {
      for(i=0; i<size ; i++)
      {
	circular_buf->Buffer[ circular_buf->writePos  ] = buffer [i] ;
	if( circular_buf->writePos+1 == circular_buf->size ) 
        {
          circular_buf->overflow = 1 ;
          circular_buf->writePos = 0 ;
	}
        else
        {
          circular_buf->writePos ++ ;
        }
      }
      retval = size;
    }
    else if(BufSize < size )
    {
      retval = BufSize;
    }
  }
  else
  {
    retval = -1;
  }
  tn_enable_interrupt();
  return retval;
}
Ejemplo n.º 14
0
/**
 *
 * @param fmp
 * @param p_data
 *
 * @return TN_RETVAL
 */
TN_RETVAL tnnc_fmem_get_polling (TN_FMP_S *fmp, void **p_data)
{
    TN_UWORD  tn_save_status_reg TN_UNUSED;     /* for SR save */
    TN_RETVAL       rc;
    void     *ptr;
/*
    Not check parameter error

    if (fmp == TN_NULL || p_data == TN_NULL)
        return  TERR_WRONG_PARAM;
*/

    if (fmp->id_fmp != TN_ID_FSMEMORYPOOL)
        return TERR_NOEXS;

    if (tn_is_non_task_context())
    {
        return TERR_WCONTEXT;
    }

    tn_disable_interrupt();

    ptr = fm_get(fmp);
    if (ptr != TN_NULL)
    {
        /* Get memory */
        *p_data = ptr;
        rc      = TERR_NO_ERR;
    }
    else
    {
        rc = TERR_TIMEOUT;
    }

    tn_enable_interrupt();
    return rc;
}
Ejemplo n.º 15
0
//----------------------------------------------------------------------------
int tn_queue_receive_polling(TN_DQUE * dque,void ** data_ptr)
{
   TN_INTSAVE_DATA
   int rc;
   CDLL_QUEUE * que;
   TN_TCB * task;

#if TN_CHECK_PARAM
   if(dque == NULL || data_ptr == NULL)
      return  TERR_WRONG_PARAM;
   if(dque->id_dque != TN_ID_DATAQUEUE)
      return TERR_NOEXS;
#endif

   TN_CHECK_NON_INT_CONTEXT

   tn_disable_interrupt();

   rc = dque_fifo_read(dque,data_ptr);
   if(rc == TERR_NO_ERR)  //-- There was entry(s) in data queue
   {
      if(!is_queue_empty(&(dque->wait_send_list)))
      {
         que  = queue_remove_head(&(dque->wait_send_list));
         task = get_task_by_tsk_queue(que);

         dque_fifo_write(dque,task->data_elem); //-- Put to data FIFO

         if(task_wait_complete(task))
         {
            tn_enable_interrupt();
            tn_switch_context();
            return TERR_NO_ERR;
         }
      }
   }
   else //-- data FIFO is empty
   {
      if(!is_queue_empty(&(dque->wait_send_list)))
      {
         que  = queue_remove_head(&(dque->wait_send_list));
         task = get_task_by_tsk_queue(que);

         *data_ptr = task->data_elem; //-- Return to caller

         if(task_wait_complete(task))
         {
            tn_enable_interrupt();
            tn_switch_context();
            return TERR_NO_ERR;
         }
         rc = TERR_NO_ERR;
      }
      else //--   wait_send_list is empty
         rc = TERR_TIMEOUT;
   }

   tn_enable_interrupt();

   return rc;
}
Ejemplo n.º 16
0
//----------------------------------------------------------------------------
int tn_queue_receive(TN_DQUE * dque,void ** data_ptr,unsigned long timeout)
{
   TN_INTSAVE_DATA
   int rc; //-- return code
   CDLL_QUEUE * que;
   TN_TCB * task;

#if TN_CHECK_PARAM
   if(dque == NULL || timeout == 0 || data_ptr == NULL)
      return  TERR_WRONG_PARAM;
   if(dque->id_dque != TN_ID_DATAQUEUE)
      return TERR_NOEXS;
#endif

   TN_CHECK_NON_INT_CONTEXT

   tn_disable_interrupt();

   rc = dque_fifo_read(dque,data_ptr);
   if(rc == TERR_NO_ERR)  //-- There was entry(s) in data queue
   {
      if(!is_queue_empty(&(dque->wait_send_list)))
      {
         que  = queue_remove_head(&(dque->wait_send_list));
         task = get_task_by_tsk_queue(que);

         dque_fifo_write(dque,task->data_elem); //-- Put to data FIFO

         if(task_wait_complete(task))
         {
            tn_enable_interrupt();
            tn_switch_context();
            return TERR_NO_ERR;
         }
      }
   }
   else //-- data FIFO is empty
   {
      if(!is_queue_empty(&(dque->wait_send_list)))
      {
         que  = queue_remove_head(&(dque->wait_send_list));
         task = get_task_by_tsk_queue(que);

         *data_ptr = task->data_elem; //-- Return to caller

         if(task_wait_complete(task))
         {
            tn_enable_interrupt();
            tn_switch_context();
            return TERR_NO_ERR;
         }
         rc = TERR_NO_ERR;
      }
      else //-- wait_send_list is empty
      {
         task_curr_to_wait_action(&(dque->wait_receive_list),
                                     TSK_WAIT_REASON_DQUE_WRECEIVE,timeout);
         tn_enable_interrupt();
         tn_switch_context();

         //-- When returns to this point, in the data_elem have to be valid value

         *data_ptr = tn_curr_run_task->data_elem; //-- Return to caller

         return tn_curr_run_task->task_wait_rc;
      }
   }

   tn_enable_interrupt();

   return rc;
}
Ejemplo n.º 17
0
//-----------------------------------------------------------------------------
int tn_task_terminate(TN_TCB * task)
{
   TN_INTSAVE_DATA

   int rc;
/* see the structure purpose in tn_task_exit() */
	 struct // v.2.7
	 {
#ifdef USE_MUTEXES
      CDLL_QUEUE * que;
      TN_MUTEX * mutex;
#endif
      volatile int stack_exp[TN_PORT_STACK_EXPAND_AT_EXIT];
   }data; 
	 
#if TN_CHECK_PARAM
   if(task == NULL)
      return  TERR_WRONG_PARAM;
   if(task->id_task != TN_ID_TASK)
      return TERR_NOEXS;
#endif

   TN_CHECK_NON_INT_CONTEXT

   tn_disable_interrupt();


   //--------------------------------------------------

   rc = TERR_NO_ERR;

   if(task->task_state == TSK_STATE_DORMANT || tn_curr_run_task == task)
      rc = TERR_WCONTEXT; //-- Cannot terminate running task
   else
   {
      if(task->task_state == TSK_STATE_RUNNABLE)
         task_to_non_runnable(task);
      else if(task->task_state & TSK_STATE_WAIT)
      {
         //-- Free all queues, involved in the 'waiting'

         queue_remove_entry(&(task->task_queue));

         //-----------------------------------------

         if(task->tick_count != TN_WAIT_INFINITE)
            queue_remove_entry(&(task->timer_queue));
      }

      //-- Unlock all mutexes, locked by the task

#ifdef USE_MUTEXES
      while(!is_queue_empty(&(task->mutex_queue)))
      {
         data.que = queue_remove_head(&(task->mutex_queue));
         data.mutex = get_mutex_by_mutex_queque(data.que);
         do_unlock_mutex(data.mutex);
      }
#endif

      task_set_dormant_state(task);
			//-- Pointer to task top of the stack when not running

      task->task_stk = tn_stack_init(task->task_func_addr,
                                     task->stk_start,
                                     task->task_func_param);
       
      if(task->activate_count > 0) //-- Cannot terminate
      {
         task->activate_count--;

         task_to_runnable(task);
         tn_enable_interrupt();
         tn_switch_context();

         return TERR_NO_ERR;
      }
   }

   tn_enable_interrupt();

   return rc;
}
Ejemplo n.º 18
0
//-----------------------------------------------------------------------------
int tn_task_create(TN_TCB * task,                 //-- task TCB
                 void (*task_func)(void *param),  //-- task function
                 int priority,                    //-- task priority
                 unsigned int * task_stack_start, //-- task stack first addr in memory (bottom)
                 int task_stack_size,             //-- task stack size (in sizeof(void*),not bytes)
                 void * param,                    //-- task function parameter
                 int option)                      //-- Creation option
{
   TN_INTSAVE_DATA
   int rc;

   unsigned int * ptr_stack;
   int i;

   //-- Light weight checking of system tasks recreation

   if((priority == 0 && ((option & TN_TASK_TIMER) == 0)) ||
       (priority == TN_NUM_PRIORITY-1 && (option & TN_TASK_IDLE) == 0))
      return TERR_WRONG_PARAM;

   if((priority < 0 || priority > TN_NUM_PRIORITY-1) ||
        task_stack_size < TN_MIN_STACK_SIZE ||
        task_func == NULL || task == NULL || task_stack_start == NULL ||
        task->id_task != 0)  //-- recreation
      return TERR_WRONG_PARAM;

   rc = TERR_NO_ERR;

   TN_CHECK_NON_INT_CONTEXT

   if(tn_system_state == TN_ST_STATE_RUNNING)
      tn_disable_interrupt();

   //--- Init task TCB

   task->task_func_addr  = (void*)task_func;
   task->task_func_param = param;
   task->stk_start       = (unsigned int*)task_stack_start;  //-- Base address of task stack space
   task->stk_size        = task_stack_size;                  //-- Task stack size (in bytes)
   task->base_priority   = priority;                         //-- Task base priority
   task->activate_count  = 0;                                //-- Activation request count
   task->id_task         = TN_ID_TASK;

   //-- Fill all task stack space by TN_FILL_STACK_VAL - only inside create_task

   for(ptr_stack = task->stk_start,i = 0;i < task->stk_size; i++)
      *ptr_stack-- = TN_FILL_STACK_VAL;

   task_set_dormant_state(task);

   //--- Init task stack

   ptr_stack = tn_stack_init(task->task_func_addr,
                             task->stk_start,
                             task->task_func_param);

   task->task_stk = ptr_stack;    //-- Pointer to task top of stack,
                                  //-- when not running


   //-- Add task to created task queue

   queue_add_tail(&tn_create_queue,&(task->create_queue));
   tn_created_tasks_qty++;

   if((option & TN_TASK_START_ON_CREATION) != 0)
      task_to_runnable(task);

   if(tn_system_state == TN_ST_STATE_RUNNING)
      tn_enable_interrupt();

   return rc;
}
Ejemplo n.º 19
0
/**
 *
 * @param dque
 *
 * @return TN_RETVAL
 */
TN_RETVAL tnnc_queue_delete (TN_DQUE_S *dque)
{
    TN_UWORD      tn_save_status_reg TN_UNUSED;     /* for SR save */
    CDLL_QUEUE_S *que;
    TN_TCB_S     *task;

/*
    Not check parameter error

    if (dque == TN_NULL)
        return TERR_WRONG_PARAM;
*/

    if (dque->id_dque != TN_ID_DATAQUEUE)
        return TERR_NOEXS;

    if (tn_is_non_task_context())
    {
        return TERR_WCONTEXT;
    }

    while (!is_queue_empty(&(dque->wait_send_list)))
    {
/*
        if (tn_chk_irq_disabled() == 0)
        {
            tn_disable_interrupt();
        }

*/
        tn_disable_interrupt();

        que  = queue_remove_head(&(dque->wait_send_list));
        task = get_task_by_tsk_queue(que);

        if (task_wait_complete(task, TN_FALSE))
        {
            task->task_wait_rc = TERR_DLT;
            tn_enable_interrupt();
            tn_switch_context();
        }
    }

    while (!is_queue_empty(&(dque->wait_receive_list)))
    {
/*
        if (tn_chk_irq_disabled() == 0)
        {
            tn_disable_interrupt();
        }

*/
        tn_disable_interrupt();

        que  = queue_remove_head(&(dque->wait_receive_list));
        task = get_task_by_tsk_queue(que);
        if (task_wait_complete(task, TN_FALSE))
        {
            task->task_wait_rc = TERR_DLT;
            tn_enable_interrupt();
            tn_switch_context();
        }
    }

/*
    if (tn_chk_irq_disabled() == 0)
    {
        tn_disable_interrupt();
    }
*/
    tn_disable_interrupt();

    dque->id_dque = TN_ID_UNKNOWN;

    tn_enable_interrupt();
    return TERR_NO_ERR;
}
Ejemplo n.º 20
0
//-----------------------------------------------------------------------------
int tn_task_terminate(TN_TCB * task)
{
   TN_INTSAVE_DATA

   int rc;
   unsigned int * ptr_stack;

#ifdef USE_MUTEXES
   CDLL_QUEUE * que;
   TN_MUTEX * mutex;
#endif

   volatile int stack_exp[TN_PORT_STACK_EXPAND_AT_EXIT];

#if TN_CHECK_PARAM
   if(task == NULL)
      return  TERR_WRONG_PARAM;
   if(task->id_task != TN_ID_TASK)
      return TERR_NOEXS;
#endif

   TN_CHECK_NON_INT_CONTEXT

   tn_disable_interrupt();

   //-- To use stack_exp[] and avoid warning message

   stack_exp[0] = (int)tn_system_state;
   ptr_stack =(unsigned int *)stack_exp[0];

   //--------------------------------------------------

   rc = TERR_NO_ERR;

   if(task->task_state == TSK_STATE_DORMANT || tn_curr_run_task == task)
      rc = TERR_WCONTEXT; //-- Cannot terminate running task
   else
   {
      if(task->task_state == TSK_STATE_RUNNABLE)
         task_to_non_runnable(task);
      else if(task->task_state & TSK_STATE_WAIT)
      {
         //-- Free all queues, involved in the 'waiting'

         queue_remove_entry(&(task->task_queue));

         //-----------------------------------------

         if(task->tick_count != TN_WAIT_INFINITE)
            queue_remove_entry(&(task->timer_queue));
      }
#if (TN_SUPPORT_FPU == 2)
      if (tn_fpu_owner_task == task)
      {
          tn_fpu_owner_task = NULL;
      }
#endif

      //-- Unlock all mutexes, locked by the task

#ifdef USE_MUTEXES
      while(!is_queue_empty(&(task->mutex_queue)))
      {
         que = queue_remove_head(&(task->mutex_queue));
         mutex = get_mutex_by_mutex_queque(que);
         do_unlock_mutex(mutex);
      }
#endif

      task_set_dormant_state(task);
      ptr_stack = tn_stack_init(task->task_func_addr,
                             task->stk_start,
                             task->task_func_param);
      task->task_stk = ptr_stack;  //-- Pointer to task top of the stack
                                   //-- when not running

      if(task->activate_count > 0) //-- Cannot terminate
      {
         task->activate_count--;

         task_to_runnable(task);
         tn_enable_interrupt();
         tn_switch_context();

         return TERR_NO_ERR;
      }
   }

   tn_enable_interrupt();

   return rc;
}
Ejemplo n.º 21
0
/**
 *
 * @param mutex
 * @param timeout
 *
 * @return TN_RETVAL
 */
TN_RETVAL tnec_mutex_lock (TN_MUTEX_S *mutex, TN_TIMEOUT timeout)
{
    TN_UWORD  tn_save_status_reg TN_UNUSED;     /* for SR save */
    TN_TCB_S *blk_task;
    TN_RETVAL       rc;

    if (mutex == TN_NULL || timeout == 0)
        return TERR_WRONG_PARAM;

    if (mutex->id_mutex != TN_ID_MUTEX)
        return TERR_NOEXS;

    if (tn_is_non_task_context())
    {
        return TERR_WCONTEXT;
    }

    tn_disable_interrupt();

    rc = TERR_NO_ERR;

    for (;;)
    {
        if (tn_curr_run_task == mutex->holder)
        {
            rc = TERR_ILUSE;
            break;
        }

        if (mutex->attr == TN_MUTEX_ATTR_CEILING &&
            tn_curr_run_task->base_priority < mutex->ceil_priority)
        {
            rc = TERR_ILUSE;
            break;
        }

        if (mutex->attr == TN_MUTEX_ATTR_CEILING)
        {
            if (mutex->holder == TN_NULL)
            {
                if (enable_lock_mutex(tn_curr_run_task, &blk_task))
                {
                    mutex->holder = tn_curr_run_task;
                    tn_curr_run_task->blk_task = TN_NULL;

                    queue_add_tail(&(tn_curr_run_task->mutex_queue), &(mutex->mutex_queue));
                    queue_add_tail(&tn_locked_mutexes_list, &(mutex->lock_mutex_queue));
                }
                else
                {
                    /*
                       Невозможно заблокировать мютекс

                       Протокол наследования:
                       Если текущий приоритет выполняемой задачи больше приоритета задачи, которая блокирует текущую
                       (удерживает мютекс), то блокирующая задача наследует приоритет текущей
                    */

                    if (blk_task != TN_NULL)
                    {
                        if (tn_curr_run_task->priority < blk_task->priority)
                        {
                            set_current_priority(blk_task, tn_curr_run_task->priority);
                        }
                    }
                    queue_add_tail(&tn_blocked_tasks_list, &(tn_curr_run_task->block_queue));

                    tn_curr_run_task->blk_task = blk_task;

                    task_curr_to_wait_action(&(mutex->wait_queue), TSK_WAIT_REASON_MUTEX_C_BLK, timeout);

                    tn_enable_interrupt();
                    tn_switch_context();
                    return tn_curr_run_task->task_wait_rc;
                }
            }

            else
            {
                if (tn_curr_run_task->priority < mutex->holder->priority)
                {
                    set_current_priority(mutex->holder,tn_curr_run_task->priority);
                }

                task_curr_to_wait_action(&(mutex->wait_queue), TSK_WAIT_REASON_MUTEX_C, timeout);

                tn_enable_interrupt();
                tn_switch_context();
                return tn_curr_run_task->task_wait_rc;
            }
        }

        else if (mutex->attr == TN_MUTEX_ATTR_INHERIT)
        {
            if (mutex->holder == TN_NULL)
            {
                mutex->holder = tn_curr_run_task;

                queue_add_tail(&(tn_curr_run_task->mutex_queue),&(mutex->mutex_queue));
/* --- v.2.3 */
                queue_add_tail(&tn_locked_mutexes_list,&(mutex->lock_mutex_queue));
/* ---       */
                rc = TERR_NO_ERR;
            }
            else
            {
                if (tn_curr_run_task->priority < mutex->holder->priority)
                {
                    set_current_priority(mutex->holder, tn_curr_run_task->priority);
                }

                task_curr_to_wait_action(&(mutex->wait_queue), TSK_WAIT_REASON_MUTEX_I,timeout);

                tn_enable_interrupt();
                tn_switch_context();
                return tn_curr_run_task->task_wait_rc;
            }
        }

        break;
    }

    tn_enable_interrupt();
    return rc;
}
Ejemplo n.º 22
0
//----------------------------------------------------------------------------
int tn_event_wait(TN_EVENT * evf,
                    unsigned int wait_pattern,
                    int wait_mode,
                    unsigned int * p_flags_pattern,
                    unsigned long timeout)
{
   TN_INTSAVE_DATA
   int rc;
   int fCond;

#if TN_CHECK_PARAM
   if(evf == NULL || wait_pattern == 0 ||
          p_flags_pattern == NULL || timeout == 0)
      return TERR_WRONG_PARAM;
   if(evf->id_event != TN_ID_EVENT)
      return TERR_NOEXS;
#endif

   TN_CHECK_NON_INT_CONTEXT

   tn_disable_interrupt();

   //-- If event attr is TN_EVENT_ATTR_SINGLE and another task already
   //-- in event wait queue - return ERROR without checking release condition

   if((evf->attr & TN_EVENT_ATTR_SINGLE) && !is_queue_empty(&(evf->wait_queue)))
   {
      rc = TERR_ILUSE;
   }
   else
   {
       //-- Check release condition

      if(wait_mode & TN_EVENT_WCOND_OR) //-- any setted bit is enough for release condition
         fCond = ((evf->pattern & wait_pattern) != 0);
      else                              //-- TN_EVENT_WCOND_AND is default mode
         fCond = ((evf->pattern & wait_pattern) == wait_pattern);

      if(fCond)
      {
         *p_flags_pattern = evf->pattern;
         if(evf->attr & TN_EVENT_ATTR_CLR)
            evf->pattern = 0;
          rc = TERR_NO_ERR;
      }
      else
      {
         tn_curr_run_task->ewait_mode = wait_mode;
         tn_curr_run_task->ewait_pattern = wait_pattern;
         task_curr_to_wait_action(&(evf->wait_queue),
                                  TSK_WAIT_REASON_EVENT,
                                  timeout);
         tn_enable_interrupt();
         tn_switch_context();

         if(tn_curr_run_task->task_wait_rc == TERR_NO_ERR)
            *p_flags_pattern = tn_curr_run_task->ewait_pattern;
         return tn_curr_run_task->task_wait_rc;
      }
   }

   tn_enable_interrupt();

   return rc;
}
Ejemplo n.º 23
0
/**
 *
 * @param task
 *
 * @return TN_RETVAL
 */
TN_RETVAL tnnc_task_terminate (TN_TCB_S *task)
{
    TN_UWORD       tn_save_status_reg TN_UNUSED;     /* for SR save */
    TN_RETVAL      rc;
    TN_UWORD      *ptr_stack;
    CDLL_QUEUE_S  *que;
    TN_MUTEX_S    *mutex;

/*
    Not check parameter error

    if (task == TN_NULL)
        return TERR_WRONG_PARAM;

*/

    if (task->id_task != TN_ID_TASK)
        return TERR_NOEXS;

    if (tn_is_non_task_context())
    {
        return TERR_WCONTEXT;
    }

    tn_disable_interrupt();

    rc = TERR_NO_ERR;

    if ((task->task_state == TSK_STATE_DORMANT) || (tn_curr_run_task == task))
    {
        rc = TERR_WCONTEXT;
    }
    else
    {
        if (task->task_state == TSK_STATE_RUNNABLE)
        {
            task_to_non_runnable(task);
        }
        else if (task->task_state & TSK_STATE_WAIT)
        {
            queue_remove_entry(&(task->task_queue));

            if (queue_contains_entry(&tn_blocked_tasks_list, &(task->block_queue)))
            {
                queue_remove_entry(&(task->block_queue));
            }
            if (task->tick_count != TN_WAIT_INFINITE)
            {
                queue_remove_entry(&(task->timer_queue));
            }
        }


        while (!is_queue_empty(&(task->mutex_queue)))
        {
            que   = queue_remove_head(&(task->mutex_queue));
            mutex = get_mutex_by_mutex_queue(que);
            do_unlock_mutex(mutex);
        }

        task_set_dormant_state(task);

        ptr_stack = tn_stack_init(task->task_func_addr,
                                  task->stk_start,
                                  task->stk_size,
                                  task->task_func_param
                                 );

        task->task_stk = ptr_stack;

        if (task->activate_count > 0)
        {
            task->activate_count--;

            task_to_runnable(task);
            tn_enable_interrupt();

            if ((tn_next_task_to_run != tn_curr_run_task) && (tn_enable_switch_context != TN_FALSE))
            {
                tn_switch_context();
            }
            return TERR_NO_ERR;
        }
    }
    tn_enable_interrupt();
    return rc;
}
Ejemplo n.º 24
0
/**
 *
 * @param mutex
 *
 * @return TN_RETVAL
 */
TN_RETVAL tnec_mutex_lock_polling (TN_MUTEX_S *mutex)
{
    TN_UWORD tn_save_status_reg TN_UNUSED;     /* for SR save */
    TN_RETVAL      rc;

    if (mutex == TN_NULL)
        return TERR_WRONG_PARAM;

    if (mutex->id_mutex != TN_ID_MUTEX)
        return TERR_NOEXS;

    if (tn_is_non_task_context())
    {
        return TERR_WCONTEXT;
    }

    tn_disable_interrupt();

    rc = TERR_NO_ERR;

    for (;;)
    {
        if (tn_curr_run_task == mutex->holder)
        {
            rc = TERR_ILUSE;
            break;
        }

        if (mutex->attr == TN_MUTEX_ATTR_CEILING &&
            tn_curr_run_task->base_priority < mutex->ceil_priority
           )
        {
            rc = TERR_ILUSE;
            break;
        }

        if (mutex->holder == TN_NULL)
        {
            if (mutex->attr == TN_MUTEX_ATTR_CEILING)
            {
                if (enable_lock_mutex(tn_curr_run_task, TN_NULL))
                {
                    mutex->holder = tn_curr_run_task;
                    tn_curr_run_task->blk_task = TN_NULL;

                    queue_add_tail(&(tn_curr_run_task->mutex_queue),&(mutex->mutex_queue));
                    queue_add_tail(&tn_locked_mutexes_list,&(mutex->lock_mutex_queue));
                }
                else
                {
                    rc = TERR_TIMEOUT;
                }
            }
            else if (mutex->attr == TN_MUTEX_ATTR_INHERIT)
            {
                mutex->holder = tn_curr_run_task;
                queue_add_tail(&(tn_curr_run_task->mutex_queue),&(mutex->mutex_queue));
/* --- v.2.3 */
                queue_add_tail(&tn_locked_mutexes_list,&(mutex->lock_mutex_queue));
/* ---       */
            }
        }
        else
        {
            rc = TERR_TIMEOUT;
        }
        break;
    }

    tn_enable_interrupt();
    return rc;
}
Ejemplo n.º 25
0
/**
 *
 * @param task
 *
 * @return TN_RETVAL
 */
TN_RETVAL tnec_task_suspend (TN_TCB_S *task)
{
    TN_UWORD tn_save_status_reg TN_UNUSED;     /* for SR save */
    TN_RETVAL      rc;

    if (task == TN_NULL)
        return  TERR_WRONG_PARAM;

    if (task->id_task != TN_ID_TASK)
        return TERR_NOEXS;

    if (tn_is_non_task_context())
    {
        return TERR_WCONTEXT;
    }

    tn_disable_interrupt();

    if (task->task_state & TSK_STATE_SUSPEND)
    {
        rc = TERR_OVERFLOW;
    }
    else
    {
        if (task->task_state == TSK_STATE_DORMANT)
        {
            rc = TERR_WSTATE;
        }
        else
        {
            if (task == tn_curr_run_task &&
                !(tn_enable_switch_context)
               )
            {
                rc = TERR_WCONTEXT;
            }
            else
            {
                if (task->task_state == TSK_STATE_RUNNABLE)
                {
                    task->task_state = TSK_STATE_SUSPEND;
                    task_to_non_runnable(task);

                    tn_enable_interrupt();
                    if ((tn_next_task_to_run != tn_curr_run_task) && (tn_enable_switch_context != TN_FALSE))
                    {
                        tn_switch_context();
                    }
                    return  TERR_NO_ERR;
                }
                else
                {
                    task->task_state |= TSK_STATE_SUSPEND;
                    rc = TERR_NO_ERR;
                }
            }
        }
    }

    tn_enable_interrupt();
    return rc;
}
Ejemplo n.º 26
0
/**
 *
 * @param dque
 * @param data_ptr
 * @param timeout
 *
 * @return TN_RETVAL
 */
TN_RETVAL tnnc_queue_receive (TN_DQUE_S * dque, void **data_ptr, TN_TIMEOUT timeout)
{
    TN_UWORD      tn_save_status_reg TN_UNUSED;     /* for SR save */
    TN_RETVAL           rc;
    CDLL_QUEUE_S *que;
    TN_TCB_S     *task;

/*
    Not check parameter error

    if (dque == TN_NULL || timeout == 0 || data_ptr == TN_NULL)
        return  TERR_WRONG_PARAM;
*/
    if (dque->id_dque != TN_ID_DATAQUEUE)
        return TERR_NOEXS;

    if (tn_is_non_task_context())
    {
        return TERR_WCONTEXT;
    }

    tn_disable_interrupt();

    rc = dque_fifo_read(dque,data_ptr);

    if (rc == TERR_NO_ERR)
    {
        if (!is_queue_empty(&(dque->wait_send_list)))
        {
            que  = queue_remove_head(&(dque->wait_send_list));
            task = get_task_by_tsk_queue(que);

            dque_fifo_write(dque,task->data_elem);

            if (task_wait_complete(task, TN_FALSE))
            {
                tn_enable_interrupt();
                tn_switch_context();
                return TERR_NO_ERR;
            }
        }
    }
    else
    {
        if (!is_queue_empty(&(dque->wait_send_list)))
        {
            que  = queue_remove_head(&(dque->wait_send_list));
            task = get_task_by_tsk_queue(que);

            *data_ptr = task->data_elem;

            if (task_wait_complete(task, TN_FALSE))
            {
                tn_enable_interrupt();
                tn_switch_context();
                return TERR_NO_ERR;
            }

            rc = TERR_NO_ERR;
        }
        else
        {
            task_curr_to_wait_action(&(dque->wait_receive_list), TSK_WAIT_REASON_DQUE_WRECEIVE, timeout);
            tn_enable_interrupt();
            tn_switch_context();

            /* When return to this point,in data_elem have to be  valid value */
            *data_ptr = tn_curr_run_task->data_elem;
            return tn_curr_run_task->task_wait_rc;
        }
    }

    tn_enable_interrupt();
    return rc;
}