⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ar_task.c

📁 Keil开发环境下ARM7内核单片机的ARTX RTOS内核源代码
💻 C
字号:
/*----------------------------------------------------------------------------
 *      A R T X  -  K e r n e l
 *----------------------------------------------------------------------------
 *      Name:    AR_TASK.C
 *      Purpose: Task functions and system start up.
 *      Rev.:    V2.00 / 19-oct-2005
 *----------------------------------------------------------------------------
 *      This code is part of the ARTX-ARM kernel package of Keil Software.
 *      Copyright (c) 2004-2005 Keil Software. All rights reserved. 
 *---------------------------------------------------------------------------*/

#include "Kernel\ARTX_Config.h"
#include "Kernel\AR_List.h"
#include "Kernel\AR_Task.h"

/* AR_Resource.c */
extern P_TCB  os_runtask;
extern struct OS_TCB  os_idle_TCB;
extern struct OS_TCB  os_clock_TCB;
extern struct OS_XCB  os_dly;

/* AR_List.c */
extern U16  os_psq_first;
extern U16  os_psq_last;

/* ARTX_Config.c */
extern U16 const os_maxtaskrun;
extern P_TCB  os_active_TCB[];


/*----------------------------------------------------------------------------
 *      Local Functions
 *---------------------------------------------------------------------------*/

OS_TID os_get_TID (P_TCB task) {
   U32 tid;

   for (tid = 1; tid <= os_maxtaskrun; tid++) {
      if (os_active_TCB[tid-1] == task) {
         return ((OS_TID)tid);
      }
   }
   return (0);
} /* end of os_get_TID */

/*--------------------------- os_dispatch -----------------------------------*/

void os_dispatch (P_TCB next_TCB) {
   /* Dispatch next task if any identified or dispatch highest ready task    */
   /* "next_TCB" identifies a task to run or has value NULL (=no next task)  */
   if (next_TCB == NULL) {
      /* Running task was blocked: continue with highest ready task */
      next_TCB = os_get_first (&os_rdy);
      os_switch_tasks (next_TCB);
      }
   else {
      /* Check which task continues */
      if (next_TCB->prio > os_runtask->prio) {
         /* preempt running task */
         os_put_rdy_first (os_runtask);
         os_runtask->state = READY;
         os_switch_tasks (next_TCB);
         }
      else {
         /* put next task into ready list, no task switch takes place */
         next_TCB->state = READY;
         os_put_prio (&os_rdy, next_TCB);
         };
      };
} /* end of os_dispatch */


/*--------------------------- os_block --------------------------------------*/

OS_RESULT os_block (U16 timeout, U8 block_state) {
   /* Block running task and choose next ready task.                         */
   /* "timeout" sets a time-out value or is 0xffff (=no time-out).           */
   /* "block_state" defines the appropriate task state */
   P_TCB next_TCB;

   if (timeout) {
      if (timeout < 0xffff) {
         os_put_dly (os_runtask, timeout);
         };
      os_runtask->state = block_state;
      next_TCB = os_get_first (&os_rdy);
      os_switch_tasks (next_TCB);
      return (os_runtask->ret_val);
      }
   else {
      return (OS_R_TMO);
      }
} /* end of os_block */


/*--------------------------- os_tsk_pass -----------------------------------*/

void os_tsk_pass (void) {
   /* Allow tasks of same priority level to run cooperatively.*/
   P_TCB p_new;

   tsk_lock();
   p_new = os_get_same_rdy_prio();
   if (p_new != NULL) {
      os_put_prio ((P_XCB)&os_rdy, os_runtask);
      os_runtask->state = READY;
      os_switch_tasks (p_new);
      };
   tsk_unlock();
} /* end of os_tsk_pass */


/*--------------------------- os_tsk_self -----------------------------------*/

OS_TID os_tsk_self (void) {
   /* Return own task identifier value. */
   return (os_get_TID(os_runtask));
} /* end of os_tsk_self */


/*--------------------------- os_tsk_prio -----------------------------------*/

OS_RESULT os_tsk_prio (OS_TID task_id, U8 new_prio) {
   /* Change execution priority of a task to "new_prio". */
   P_TCB task_context;

   tsk_lock();
   if (task_id == 0) {
      /* Change execution priority of calling task. */
      os_runtask->prio = new_prio;
run_t:if (os_rdy_prio() > new_prio) {
         os_put_prio (&os_rdy, os_runtask);
         os_runtask->state = READY;
         os_dispatch (NULL);
         }
      tsk_unlock();
      return (OS_R_OK);
   }

   /* Find the task in the "os_active_TCB" array. */
   if (task_id > os_maxtaskrun || os_active_TCB[task_id-1] == NULL) {
      /* Task with "task_id" not found or not started. */
      tsk_unlock ();
      return (OS_R_NOK);
   }
   task_context = os_active_TCB[task_id-1];
   task_context->prio = new_prio;
   if (task_context == os_runtask) {
      goto run_t;
   }
   if (task_context->state == READY) {
      /* Task enqueued in a ready list. */
      os_rmv_list (task_context);
      /* Check which task continues */
      if (new_prio > os_runtask->prio) {
         os_put_rdy_first (os_runtask);
         os_runtask->state = READY;
         os_switch_tasks (task_context);
      }
      else {
         os_put_prio (&os_rdy, task_context);
      }
   }
   tsk_unlock ();
   return (OS_R_OK);
} /* end of os_tsk_prio */


/*--------------------------- os_tsk_create_user ----------------------------*/

OS_TID os_tsk_create_user (FUNCP task, U8 priority, void *stk, U16 size) {
   /* Start a new task declared with "task". */
   P_TCB task_context;
   U32 i;

   tsk_lock();
   /* Priority 0 is reserved for idle task! */
   if (priority == 0) {
      priority = 1;
   }
   task_context = os_alloc_TCB ();
   if (task_context == NULL) {
      tsk_unlock();
      return (0);
   }

   /* If "size != 0" use a private user provided stack. */
   task_context->stack      = stk;
   task_context->priv_stack = size & ~3;

   /* For 'size == 0' system allocates the user stack from the memory pool. */
   os_init_context (task_context, priority, task, __TRUE);

   /* Find a free entry in 'os_active_TCB' table. */
   i = os_get_TID (NULL);
   os_active_TCB[i-1] = task_context;
   os_dispatch (task_context);
   tsk_unlock();
   return ((OS_TID)i);
} /* end of os_tsk_create_user */


/*--------------------------- os_tsk_create_user_ex -------------------------*/

OS_TID os_tsk_create_user_ex (FUNCPP task, U8 priority,
                              void *stk, U16 size, void *argv) {
   /* Start a new task declared with "task". */
   P_TCB task_context;
   U32 i;

   tsk_lock();
   /* Priority 0 is reserved for idle task! */
   if (priority == 0) {
      priority = 1;
   }
   task_context = os_alloc_TCB ();
   if (task_context == NULL) {
      tsk_unlock();
      return (0);
   }
   /* Use a private user provided stack. */
   task_context->stack      = stk;
   task_context->priv_stack = size & ~3;
   /* Pass parameter 'argv' to 'os_init_context' */
   task_context->p_msg = argv;
   /* For 'size == 0' system allocates the user stack from the memory pool. */
   os_init_context (task_context, priority, (FUNCP)task, __TRUE);
   /* Find a free entry in 'os_active_TCB' table. */
   i = os_get_TID (NULL);
   os_active_TCB[i-1] = task_context;
   os_dispatch (task_context);
   tsk_unlock();
   return ((OS_TID)i);
} /* end of os_tsk_create_user_ex */


/*--------------------------- os_tsk_delete ---------------------------------*/

OS_RESULT os_tsk_delete (OS_TID task_id) {
   /* Terminate the task identified with "task_id". */
   P_TCB task_context;

   tsk_lock();
   if (task_id == 0) {
      /* Terminate itself. */
      task_context = os_runtask;
      task_context->state = INACTIVE;
      os_active_TCB[os_get_TID(os_runtask)-1] = NULL;
      os_free_TCB (task_context);
      os_dispatch (NULL);
      /* The program should never come to this point. */
      }
   else {
      /* Find the task in the "os_active_TCB" array. */
      if (task_id > os_maxtaskrun || os_active_TCB[task_id-1] == NULL) {
         /* Task with "task_id" not found or not started. */
         tsk_unlock ();
         return (OS_R_NOK);
         }
      task_context = os_active_TCB[task_id-1];
      os_rmv_list (task_context);
      os_rmv_dly (task_context);
      os_active_TCB[task_id-1] = NULL;
      os_free_TCB (task_context);
      tsk_unlock ();
      }
   return (OS_R_OK);
} /* end of os_tsk_delete */


/*--------------------------- os_sys_init_user ------------------------------*/

void os_sys_init_user (FUNCP first_task, U8 priority, void *stk, U16 size) {

   /* Initialize system and start up task declared with "first_task". */
   tsk_lock();

   /* Initialize dynamic memory and task TCB pointers to NULL.        */
   os_init_mem ();

   /* Set up TCB of clock demon: will be activated on clock interrupt */
   os_clock_TCB.priv_stack = 0;
   os_init_context (&os_clock_TCB, 255, os_clock_demon, __FALSE);

   /* Set up TCB of idle demon */
   os_idle_TCB.priv_stack = 0;
   os_init_context (&os_idle_TCB, 0, os_idle_demon, __FALSE);

   /* Set up ready list: initially empty */
   os_rdy.cb_type = HCB;
   os_rdy.p_lnk   = NULL;
   /* Set up delay list: initially empty */
   os_dly.cb_type = HCB;
   os_dly.p_dlnk  = NULL;
   os_dly.p_blnk  = NULL;
   os_dly.delta_time = 0;

   /* Fix SP and systemvariables to assume idle task is running  */
   /* Transform main program into idle task by assuming idle TCB */
   os_set_env (&os_idle_TCB);
   os_runtask = &os_idle_TCB;
   os_runtask->state = RUNNING;

   /* Initialize ps queue */
   os_psq_first = 0;
   os_psq_last  = 0;

   /* Intitialize system clock timer */
   os_tmr_init ();

   /* Start up first user task before entering the endless loop */
   tsk_unlock();
   os_tsk_create_user (first_task, priority, stk, size);

   /* Call body of idle task: contains an endless loop */
   tsk_unlock();
   os_idle_demon();

   /* This point never reached if idle task contains endless loop */
   for (;;);

} /* end of os_sys_init */

/*----------------------------------------------------------------------------
 * end of file
 *---------------------------------------------------------------------------*/






⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -