ソースの整理中ですが、利用はできます。 大きなファイルはできないかもしれません。

Dependencies:   EthernetInterface HttpServer TextLCD expatlib mbed-rpc mbed-rtos mbed Socket lwip-eth lwip-sys lwip

Fork of giken9_HTMLServer_Sample by Yasushi TAUCHI

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers rt_Task.c Source File

rt_Task.c

00001 /*----------------------------------------------------------------------------
00002  *      RL-ARM - RTX
00003  *----------------------------------------------------------------------------
00004  *      Name:    RT_TASK.C
00005  *      Purpose: Task functions and system start up.
00006  *      Rev.:    V4.60
00007  *----------------------------------------------------------------------------
00008  *
00009  * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH
00010  * All rights reserved.
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions are met:
00013  *  - Redistributions of source code must retain the above copyright
00014  *    notice, this list of conditions and the following disclaimer.
00015  *  - Redistributions in binary form must reproduce the above copyright
00016  *    notice, this list of conditions and the following disclaimer in the
00017  *    documentation and/or other materials provided with the distribution.
00018  *  - Neither the name of ARM  nor the names of its contributors may be used 
00019  *    to endorse or promote products derived from this software without 
00020  *    specific prior written permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
00023  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
00024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00025  * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
00026  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00027  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
00028  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00029  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
00030  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
00031  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  * POSSIBILITY OF SUCH DAMAGE.
00033  *---------------------------------------------------------------------------*/
00034 
00035 #include "rt_TypeDef.h"
00036 #include "RTX_Conf.h"
00037 #include "rt_System.h"
00038 #include "rt_Task.h"
00039 #include "rt_List.h"
00040 #include "rt_MemBox.h"
00041 #include "rt_Robin.h"
00042 #include "rt_HAL_CM.h"
00043 
00044 /*----------------------------------------------------------------------------
00045  *      Global Variables
00046  *---------------------------------------------------------------------------*/
00047 
00048 /* Running and next task info. */
00049 struct OS_TSK os_tsk;
00050 
00051 /* Task Control Blocks of idle demon */
00052 struct OS_TCB os_idle_TCB;
00053 
00054 
00055 /*----------------------------------------------------------------------------
00056  *      Local Functions
00057  *---------------------------------------------------------------------------*/
00058 
00059 OS_TID rt_get_TID (void) {
00060   U32 tid;
00061 
00062   for (tid = 1; tid <= os_maxtaskrun; tid++) {
00063     if (os_active_TCB[tid-1] == NULL) {
00064       return ((OS_TID)tid);
00065     }
00066   }
00067   return (0);
00068 }
00069 
00070 #if defined (__CC_ARM) && !defined (__MICROLIB)
00071 /*--------------------------- __user_perthread_libspace ---------------------*/
00072 extern void  *__libspace_start;
00073 
00074 void *__user_perthread_libspace (void) {
00075   /* Provide a separate libspace for each task. */
00076   if (os_tsk.run == NULL) {
00077     /* RTX not running yet. */
00078     return (&__libspace_start);
00079   }
00080   return (void *)(os_tsk.run->std_libspace);
00081 }
00082 #endif
00083 
00084 /*--------------------------- rt_init_context -------------------------------*/
00085 
00086 void rt_init_context (P_TCB p_TCB, U8 priority, FUNCP task_body) {
00087   /* Initialize general part of the Task Control Block. */
00088   p_TCB->cb_type = TCB;
00089   p_TCB->state   = READY;
00090   p_TCB->prio    = priority;
00091   p_TCB->p_lnk   = NULL;
00092   p_TCB->p_rlnk  = NULL;
00093   p_TCB->p_dlnk  = NULL;
00094   p_TCB->p_blnk  = NULL;
00095   p_TCB->delta_time    = 0;
00096   p_TCB->interval_time = 0;
00097   p_TCB->events  = 0;
00098   p_TCB->waits   = 0;
00099   p_TCB->stack_frame = 0;
00100 
00101   rt_init_stack (p_TCB, task_body);
00102 }
00103 
00104 
00105 /*--------------------------- rt_switch_req ---------------------------------*/
00106 
00107 void rt_switch_req (P_TCB p_new) {
00108   /* Switch to next task (identified by "p_new"). */
00109   os_tsk.new_tsk   = p_new;
00110   p_new->state = RUNNING;
00111   DBG_TASK_SWITCH(p_new->task_id);
00112 }
00113 
00114 
00115 /*--------------------------- rt_dispatch -----------------------------------*/
00116 
00117 void rt_dispatch (P_TCB next_TCB) {
00118   /* Dispatch next task if any identified or dispatch highest ready task    */
00119   /* "next_TCB" identifies a task to run or has value NULL (=no next task)  */
00120   if (next_TCB == NULL) {
00121     /* Running task was blocked: continue with highest ready task */
00122     next_TCB = rt_get_first (&os_rdy);
00123     rt_switch_req (next_TCB);
00124   }
00125   else {
00126     /* Check which task continues */
00127     if (next_TCB->prio > os_tsk.run->prio) {
00128       /* preempt running task */
00129       rt_put_rdy_first (os_tsk.run);
00130       os_tsk.run->state = READY;
00131       rt_switch_req (next_TCB);
00132     }
00133     else {
00134       /* put next task into ready list, no task switch takes place */
00135       next_TCB->state = READY;
00136       rt_put_prio (&os_rdy, next_TCB);
00137     }
00138   }
00139 }
00140 
00141 
00142 /*--------------------------- rt_block --------------------------------------*/
00143 
00144 void rt_block (U16 timeout, U8 block_state) {
00145   /* Block running task and choose next ready task.                         */
00146   /* "timeout" sets a time-out value or is 0xffff (=no time-out).           */
00147   /* "block_state" defines the appropriate task state */
00148   P_TCB next_TCB;
00149 
00150   if (timeout) {
00151     if (timeout < 0xffff) {
00152       rt_put_dly (os_tsk.run, timeout);
00153     }
00154     os_tsk.run->state = block_state;
00155     next_TCB = rt_get_first (&os_rdy);
00156     rt_switch_req (next_TCB);
00157   }
00158 }
00159 
00160 
00161 /*--------------------------- rt_tsk_pass -----------------------------------*/
00162 
00163 void rt_tsk_pass (void) {
00164   /* Allow tasks of same priority level to run cooperatively.*/
00165   P_TCB p_new;
00166 
00167   p_new = rt_get_same_rdy_prio();
00168   if (p_new != NULL) {
00169     rt_put_prio ((P_XCB)&os_rdy, os_tsk.run);
00170     os_tsk.run->state = READY;
00171     rt_switch_req (p_new);
00172   }
00173 }
00174 
00175 
00176 /*--------------------------- rt_tsk_self -----------------------------------*/
00177 
00178 OS_TID rt_tsk_self (void) {
00179   /* Return own task identifier value. */
00180   if (os_tsk.run == NULL) {
00181     return (0);
00182   }
00183   return (os_tsk.run->task_id);
00184 }
00185 
00186 
00187 /*--------------------------- rt_tsk_prio -----------------------------------*/
00188 
00189 OS_RESULT rt_tsk_prio (OS_TID task_id, U8 new_prio) {
00190   /* Change execution priority of a task to "new_prio". */
00191   P_TCB p_task;
00192 
00193   if (task_id == 0) {
00194     /* Change execution priority of calling task. */
00195     os_tsk.run->prio = new_prio;
00196 run:if (rt_rdy_prio() > new_prio) {
00197       rt_put_prio (&os_rdy, os_tsk.run);
00198       os_tsk.run->state   = READY;
00199       rt_dispatch (NULL);
00200     }
00201     return (OS_R_OK);
00202   }
00203 
00204   /* Find the task in the "os_active_TCB" array. */
00205   if (task_id > os_maxtaskrun || os_active_TCB[task_id-1] == NULL) {
00206     /* Task with "task_id" not found or not started. */
00207     return (OS_R_NOK);
00208   }
00209   p_task = os_active_TCB[task_id-1];
00210   p_task->prio = new_prio;
00211   if (p_task == os_tsk.run) {
00212     goto run;
00213   }
00214   rt_resort_prio (p_task);
00215   if (p_task->state == READY) {
00216     /* Task enqueued in a ready list. */
00217     p_task = rt_get_first (&os_rdy);
00218     rt_dispatch (p_task);
00219   }
00220   return (OS_R_OK);
00221 }
00222 
00223 /*--------------------------- rt_tsk_delete ---------------------------------*/
00224 
00225 OS_RESULT rt_tsk_delete (OS_TID task_id) {
00226   /* Terminate the task identified with "task_id". */
00227   P_TCB task_context;
00228 
00229   if (task_id == 0 || task_id == os_tsk.run->task_id) {
00230     /* Terminate itself. */
00231     os_tsk.run->state     = INACTIVE;
00232     os_tsk.run->tsk_stack = rt_get_PSP ();
00233     rt_stk_check ();
00234     os_active_TCB[os_tsk.run->task_id-1] = NULL;
00235     
00236     os_tsk.run->stack = NULL;
00237     DBG_TASK_NOTIFY(os_tsk.run, __FALSE);
00238     os_tsk.run = NULL;
00239     rt_dispatch (NULL);
00240     /* The program should never come to this point. */
00241   }
00242   else {
00243     /* Find the task in the "os_active_TCB" array. */
00244     if (task_id > os_maxtaskrun || os_active_TCB[task_id-1] == NULL) {
00245       /* Task with "task_id" not found or not started. */
00246       return (OS_R_NOK);
00247     }
00248     task_context = os_active_TCB[task_id-1];
00249     rt_rmv_list (task_context);
00250     rt_rmv_dly (task_context);
00251     os_active_TCB[task_id-1] = NULL;
00252     
00253     task_context->stack = NULL;
00254     DBG_TASK_NOTIFY(task_context, __FALSE);
00255   }
00256   return (OS_R_OK);
00257 }
00258 
00259 
00260 /*--------------------------- rt_sys_init -----------------------------------*/
00261 
00262 #ifdef __CMSIS_RTOS
00263 void rt_sys_init (void) {
00264 #else
00265 void rt_sys_init (FUNCP first_task, U32 prio_stksz, void *stk) {
00266 #endif
00267   /* Initialize system and start up task declared with "first_task". */
00268   U32 i;
00269 
00270   DBG_INIT();
00271 
00272   /* Initialize dynamic memory and task TCB pointers to NULL. */
00273   for (i = 0; i < os_maxtaskrun; i++) {
00274     os_active_TCB[i] = NULL;
00275   }
00276   
00277   /* Set up TCB of idle demon */
00278   os_idle_TCB.task_id = 255;
00279   os_idle_TCB.priv_stack = idle_task_stack_size;
00280   os_idle_TCB.stack = idle_task_stack;
00281   rt_init_context (&os_idle_TCB, 0, os_idle_demon);
00282 
00283   /* Set up ready list: initially empty */
00284   os_rdy.cb_type = HCB;
00285   os_rdy.p_lnk   = NULL;
00286   /* Set up delay list: initially empty */
00287   os_dly.cb_type = HCB;
00288   os_dly.p_dlnk  = NULL;
00289   os_dly.p_blnk  = NULL;
00290   os_dly.delta_time = 0;
00291 
00292   /* Fix SP and systemvariables to assume idle task is running  */
00293   /* Transform main program into idle task by assuming idle TCB */
00294 #ifndef __CMSIS_RTOS
00295   rt_set_PSP (os_idle_TCB.tsk_stack+32);
00296 #endif
00297   os_tsk.run = &os_idle_TCB;
00298   os_tsk.run->state = RUNNING;
00299 
00300   /* Initialize ps queue */
00301   os_psq->first = 0;
00302   os_psq->last  = 0;
00303   os_psq->size  = os_fifo_size;
00304 
00305   rt_init_robin ();
00306 
00307   /* Intitialize SVC and PendSV */
00308   rt_svc_init ();
00309 
00310 #ifndef __CMSIS_RTOS
00311   /* Intitialize and start system clock timer */
00312   os_tick_irqn = os_tick_init ();
00313   if (os_tick_irqn >= 0) {
00314     OS_X_INIT(os_tick_irqn);
00315   }
00316 
00317   /* Start up first user task before entering the endless loop */
00318   rt_tsk_create (first_task, prio_stksz, stk, NULL);
00319 #endif
00320 }
00321 
00322 
00323 /*--------------------------- rt_sys_start ----------------------------------*/
00324 
00325 #ifdef __CMSIS_RTOS
00326 void rt_sys_start (void) {
00327   /* Start system */
00328 
00329   /* Intitialize and start system clock timer */
00330   os_tick_irqn = os_tick_init ();
00331   if (os_tick_irqn >= 0) {
00332     OS_X_INIT(os_tick_irqn);
00333   }
00334 }
00335 #endif
00336 
00337 /*----------------------------------------------------------------------------
00338  * end of file
00339  *---------------------------------------------------------------------------*/