Example #1
0
/**
 *
 * @param attr
 */
void tnec_task_exit (TN_UWORD attr)
{
    TN_UWORD       tn_save_status_reg TN_UNUSED;     /* for SR save */
    TN_TCB_S      *task;
    CDLL_QUEUE_S  *que;
    TN_MUTEX_S    *mutex;
    TN_UWORD      *ptr_stack;

    if (tn_is_non_task_context())
        return;

    tn_save_sr();               /* just for PIC24/dsPIC */
    tn_disable_interrupt();

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

    task = tn_curr_run_task;

    task_to_non_runnable(tn_curr_run_task);
    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);
    }
    else
    {
        /* Alex B. - delete task only if activate counter = 0 ! */

        if (attr == TN_EXIT_AND_DELETE_TASK)
        {
            queue_remove_entry(&(task->create_queue));
            tn_created_tasks_qty--;
            task->id_task = TN_ID_UNKNOWN;
        }
    }

    tn_switch_context_exit(tn_save_status_reg); /* Exit from task with restore saved SR*/
}
Example #2
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;
}
Example #3
0
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
void tn_task_exit(int attr)
{
	/*  
	  The structure is used to force GCC compiler properly locate and use
   	'stack_exp' - thanks to Angelo R. Di Filippo
	*/
   struct  // v.2.7
   {	
#ifdef USE_MUTEXES
      CDLL_QUEUE * que;
      TN_MUTEX * mutex;
#endif
      TN_TCB * task;
      volatile int stack_exp[TN_PORT_STACK_EXPAND_AT_EXIT];
   }data;
	 
   TN_CHECK_NON_INT_CONTEXT_NORETVAL

#ifdef TNKERNEL_PORT_MSP430X
   __disable_interrupt();
#else
   tn_cpu_save_sr();  //-- For ARM - disable interrupts without saving SPSR
#endif

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

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

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

   data.task = tn_curr_run_task;
   task_to_non_runnable(tn_curr_run_task);

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

   if(data.task->activate_count > 0)  //-- Cannot exit
   {
      data.task->activate_count--;
      task_to_runnable(data.task);
   }
   else  // V 2.6 Thanks to Alex Borisov
   {
      if(attr == TN_EXIT_AND_DELETE_TASK)
      {
         queue_remove_entry(&(data.task->create_queue));
         tn_created_tasks_qty--;
         data.task->id_task = 0;
      }
   }

   tn_switch_context_exit();  // interrupts will be enabled inside tn_switch_context_exit()
}
Example #4
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;
}
Example #5
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;
}
Example #6
0
//----------------------------------------------------------------------------
void tn_task_exit(int attr)
{

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

   TN_TCB * task;
   unsigned int * ptr_stack;
   volatile int stack_exp[TN_PORT_STACK_EXPAND_AT_EXIT];

   TN_CHECK_NON_INT_CONTEXT_NORETVAL

#ifdef TNKERNEL_PORT_MSP430X
   __disable_interrupt();
#else
   tn_cpu_save_sr();  //-- For ARM - disable interrupts without saving SPSR
#endif

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

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

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

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

   task = tn_curr_run_task;
   task_to_non_runnable(tn_curr_run_task);

   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 stack,when not running

   if(task->activate_count > 0)  //-- Cannot exit
   {
      task->activate_count--;
      task_to_runnable(task);
   }
   else  // V 2.6 Thanks to Alex Borisov
   {
      if(attr == TN_EXIT_AND_DELETE_TASK)
      {
         queue_remove_entry(&(task->create_queue));
         tn_created_tasks_qty--;
         task->id_task = 0;
      }
   }

   tn_switch_context_exit();  // interrupts will be enabled inside tn_switch_context_exit()
}
Example #7
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;
}