]> rtime.felk.cvut.cz Git - arc.git/blob - system/kernel/include/task_i.h
More application changes
[arc.git] / system / kernel / include / task_i.h
1 /* -------------------------------- Arctic Core ------------------------------\r
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com\r
3  *\r
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>\r
5  *\r
6  * This source code is free software; you can redistribute it and/or modify it\r
7  * under the terms of the GNU General Public License version 2 as published by the\r
8  * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.\r
9  *\r
10  * This program is distributed in the hope that it will be useful, but\r
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
13  * for more details.\r
14  * -------------------------------- Arctic Core ------------------------------*/\r
15 \r
16 #ifndef TASK_I_H_\r
17 #define TASK_I_H_\r
18 \r
19 /* ----------------------------[includes]------------------------------------*/\r
20 \r
21 \r
22 \r
23 #include <stdlib.h>\r
24 #include <assert.h>\r
25 #include "Os.h"\r
26 #include "resource_i.h"\r
27 #include "internal.h"\r
28 #include "Ramlog.h"\r
29 \r
30 /* ----------------------------[define]--------------------------------------*/\r
31 /* ----------------------------[macro]---------------------------------------*/\r
32 \r
33 \r
34 struct OsApplication;\r
35 struct OsTaskConst;\r
36 \r
37 #define NO_TASK_OWNER   (TaskType)(~0)\r
38 \r
39 \r
40 #define PID_IDLE                        0\r
41 #define PRIO_IDLE                       0\r
42 \r
43 #define ST_READY                        1\r
44 #define ST_WAITING                      (1<<1)\r
45 #define ST_SUSPENDED            (1<<2)\r
46 #define ST_RUNNING                      (1<<3)\r
47 #define ST_NOT_STARTED          (1<<4)\r
48 #define ST_SLEEPING                     (1<<5)\r
49 #define ST_WAITING_SEM          (1<<6)\r
50 \r
51 #define ST_ISR_RUNNING                  1\r
52 #define ST_ISR_NOT_RUNNING              2\r
53 \r
54 #define TASK_NAME_SIZE          16\r
55 \r
56 \r
57 /* ----------------------------[typedef]-------------------------------------*/\r
58 \r
59 typedef uint16_t state_t;\r
60 \r
61 /* from Os.h types */\r
62 typedef TaskType                OsTaskidType;\r
63 typedef EventMaskType   OsEventType;\r
64 /* Lets have 32 priority levels\r
65  * 0 - Highest prio\r
66  * 31- Lowest\r
67  */\r
68 typedef sint8 OsPriorityType;\r
69 \r
70 \r
71 /* STD container : OsHooks\r
72  * OsErrorHooks:                        1\r
73  * OsPostTaskHook:                      1\r
74  * OsPreTaskHook:                       1\r
75  * OsProtectionHook:            0..1 Class 2,3,4 it's 1 instance\r
76  * OsShutdownHook:                      1\r
77  * OsStartupkHook:                      1\r
78  * */\r
79 \r
80 typedef struct OsHooks {\r
81 #if     (OS_USE_APPLICATIONS == STD_ON)\r
82         ProtectionHookType      ProtectionHook;\r
83 #endif\r
84         StartupHookType         StartupHook;\r
85         ShutdownHookType        ShutdownHook;\r
86         ErrorHookType           ErrorHook;\r
87         PreTaskHookType         PreTaskHook;\r
88         PostTaskHookType        PostTaskHook;\r
89 } OsHooksType;\r
90 \r
91 /* OsTask/OsTaskSchedule */\r
92 enum OsTaskSchedule {\r
93         FULL,\r
94         NON\r
95 };\r
96 \r
97 /*-----------------------------------------------------------------*/\r
98 \r
99 typedef uint8_t proc_type_t;\r
100 \r
101 #define PROC_PRIO               0x1\r
102 #define PROC_BASIC              0x1\r
103 #define PROC_EXTENDED   0x3\r
104 \r
105 #if 0\r
106 #define PROC_ISR                0x4\r
107 #define PROC_ISR1               0x4\r
108 #define PROC_ISR2               0xc\r
109 #endif\r
110 \r
111 \r
112 typedef struct {\r
113         void            *curr;  // Current stack ptr( at swap time )\r
114         void            *top;   // Top of the stack( low address )\r
115         uint32          size;   // The size of the stack\r
116 } OsStackType;\r
117 \r
118 \r
119 #define SYS_FLAG_HOOK_STATE_EXPECTING_PRE       0\r
120 #define SYS_FLAG_HOOK_STATE_EXPECTING_POST   1\r
121 \r
122 /* We do ISR and TASK the same struct for now */\r
123 typedef struct OsTaskVar {\r
124         OsStackType             stack;                                  // TASK\r
125 \r
126 #if ( OS_SC2 == STD_ON ) || ( OS_SC4 == STD_ON )\r
127         OsTimingProtectionType  *timing_protection;\r
128 #endif\r
129 \r
130         state_t                 state;                                  // TASK\r
131 \r
132         /* Events the task wait for ( what events WaitEvent() was called with) */\r
133         OsEventType     ev_wait;\r
134         /* Events that are set by SetEvent() on the task */\r
135         OsEventType     ev_set;\r
136         /* The events the task may react on */\r
137         OsEventType     ev_react;\r
138 \r
139         uint32_t                flags;\r
140 \r
141         /* Priority of the task, this can be different depening on if the\r
142          * task hold resources. Related to priority inversion */\r
143         OsPriorityType  activePriority;\r
144 \r
145         // The number of queued activation of a task\r
146         int8_t activations;\r
147 \r
148         // What resource that are currently held by this task\r
149         // Typically (1<<RES_xxx) | (1<<RES_yyy)\r
150         uint32_t resourceMaskTaken;\r
151 \r
152         TAILQ_HEAD(head,OsResource) resourceHead; // TASK\r
153 \r
154         const struct OsTaskConst *constPtr;\r
155 \r
156         /* TODO: Arch specific regs .. make space for them later...*/\r
157         uint32_t        regs[16];                               // TASK\r
158 #if defined(USE_KERNEL_EXTRA)\r
159         TAILQ_ENTRY(OsTaskVar) timerEntry;              // TASK\r
160         int32_t            timerDec;\r
161 \r
162         /* Semaphore list */\r
163         STAILQ_ENTRY(OsTaskVar) semEntry;               // TASK\r
164 #endif\r
165         /* List of PCB's */\r
166 //      TAILQ_ENTRY(OsTaskVar) pcb_list;                // TASK\r
167         /* ready list */\r
168         TAILQ_ENTRY(OsTaskVar) ready_list;              // TASK\r
169 } OsTaskVarType;\r
170 \r
171 /*-----------------------------------------------------------------*/\r
172 \r
173 \r
174 /*-----------------------------------------------------------------*/\r
175 \r
176 /* STD container : OsTask\r
177  * OsTaskActivation:                1\r
178  * OsTaskPriority:                          1\r
179  * OsTaskSchedule:                          1\r
180  * OsTaskAccessingApplication:  0..*\r
181  * OsTaskEventRef:                              0..*\r
182  * OsTaskResourceRef:                   0..*\r
183  * OsTaskAutoStart[C]                   0..1\r
184  * OsTaskTimingProtection[C]    0..1\r
185  * */\r
186 \r
187 \r
188 typedef struct OsTaskConst {\r
189         OsTaskidType    pid;\r
190         OsPriorityType  prio;\r
191 //      uint32                  app_mask;\r
192         void                    (*entry)();\r
193         proc_type_t     proc_type;\r
194         uint8                   autostart;\r
195         OsStackType     stack;\r
196 //      int                             vector;                 // ISR\r
197 \r
198 #if     (OS_USE_APPLICATIONS == STD_ON)\r
199         /* Application that owns this task */\r
200         ApplicationType applOwnerId;\r
201         /* Applications that may access task when state is APPLICATION_ACCESSIBLE */\r
202         uint32                  accessingApplMask;\r
203 #endif\r
204 \r
205         char                    name[16];\r
206         enum OsTaskSchedule scheduling;\r
207         uint32_t                resourceAccess;\r
208         uint32_t                eventMask;\r
209         // pointer to internal resource\r
210         // NULL if none\r
211         OsResourceType  *resourceIntPtr;\r
212         OsTimingProtectionType  *timing_protection;\r
213         uint8_t          activationLimit;\r
214 //      lockingtime_obj_t\r
215 } OsTaskConstType;\r
216 \r
217 \r
218 /* ----------------------------[function prototypes]-------------------------*/\r
219 \r
220 extern OsTaskVarType Os_TaskVarList[OS_TASK_CNT];\r
221 extern GEN_TASK_HEAD;\r
222 \r
223 \r
224 /**\r
225  * Set the task to running state and remove from ready list\r
226  *\r
227  * @params pcb Ptr to pcb\r
228  */\r
229 static inline void Os_TaskMakeRunning( OsTaskVarType *pcb ) {\r
230         pcb->state = ST_RUNNING;\r
231 }\r
232 \r
233 _Bool os_pcb_pid_valid( OsTaskVarType *restrict pcb );\r
234 void Os_TaskStartExtended( void );\r
235 void Os_TaskStartBasic( void );\r
236 void Os_TaskContextInit( OsTaskVarType *pcb );\r
237 OsTaskVarType *Os_TaskGetTop( void );\r
238 \r
239 // Added by Mattias in order to avoid compiler warning\r
240 TaskType Os_AddTask( OsTaskVarType *pcb );\r
241 \r
242 #if 0 // Not used any more\r
243 OsTaskVarType  *os_find_higher_priority_task( OsPriorityType prio );\r
244 #endif\r
245 \r
246 static inline OsTaskVarType * Os_TaskGet( TaskType pid ) {\r
247         return &Os_TaskVarList[pid];\r
248 }\r
249 \r
250 static inline ApplicationType Os_TaskGetApplicationOwner( TaskType id ) {\r
251         ApplicationType rv;\r
252         if( id < OS_TASK_CNT ) {\r
253                 rv = Os_TaskGet(id)->constPtr->applOwnerId;\r
254         } else {\r
255                 rv = INVALID_OSAPPLICATION;\r
256         }\r
257         return rv;\r
258 }\r
259 \r
260 \r
261 \r
262 \r
263 static inline void Os_TaskResourceAdd( OsResourceType *rPtr, OsTaskVarType *pcbPtr) {\r
264         /* Save old task prio in resource and set new task prio */\r
265         rPtr->owner = pcbPtr->constPtr->pid;\r
266         rPtr->old_task_prio = pcbPtr->activePriority;\r
267         pcbPtr->activePriority = rPtr->ceiling_priority;\r
268 \r
269         if( rPtr->type != RESOURCE_TYPE_INTERNAL ) {\r
270                 TAILQ_INSERT_TAIL(&pcbPtr->resourceHead, rPtr, listEntry);\r
271         }\r
272 }\r
273 \r
274 static inline  void Os_TaskResourceRemove( OsResourceType *rPtr , OsTaskVarType *pcbPtr) {\r
275         assert( rPtr->owner == pcbPtr->constPtr->pid );\r
276         rPtr->owner = NO_TASK_OWNER;\r
277         pcbPtr->activePriority = rPtr->old_task_prio;\r
278 \r
279         if( rPtr->type != RESOURCE_TYPE_INTERNAL ) {\r
280                 /* The list can't be empty here */\r
281                 assert( !TAILQ_EMPTY(&pcbPtr->resourceHead) );\r
282 \r
283                 /* The list should be popped in LIFO order */\r
284                 assert( TAILQ_LAST(&pcbPtr->resourceHead, head) == rPtr );\r
285 \r
286                 /* Remove the entry */\r
287                 TAILQ_REMOVE(&pcbPtr->resourceHead, rPtr, listEntry);\r
288         }\r
289 }\r
290 \r
291 static inline void Os_TaskResourceFreeAll( OsTaskVarType *pcbPtr ) {\r
292         OsResourceType *rPtr;\r
293 \r
294         /* Pop the queue */\r
295         TAILQ_FOREACH(rPtr, &pcbPtr->resourceHead, listEntry ) {\r
296                 Os_TaskResourceRemove(rPtr,pcbPtr);\r
297         }\r
298 }\r
299 \r
300 \r
301 #define os_pcb_get_state(pcb) ((pcb)->state)\r
302 \r
303 void Os_TaskSwapContext(OsTaskVarType *old_pcb, OsTaskVarType *new_pcb );\r
304 void Os_TaskSwapContextTo(OsTaskVarType *old_pcb, OsTaskVarType *new_pcb );\r
305 OsTaskVarType *Os_TaskGetTop( void );\r
306 OsTaskVarType *Os_TaskGet( TaskType tid );\r
307 \r
308 #define STACK_PATTERN   0x42\r
309 \r
310 static inline void *Os_StackGetUsage( OsTaskVarType *pcb ) {\r
311 \r
312         uint8_t *p = pcb->stack.curr;\r
313         uint8_t *end = pcb->stack.top;\r
314 \r
315         while( (*end == STACK_PATTERN) && (end<p)) {\r
316                         end++;\r
317                 }\r
318         return (void *)end;\r
319 }\r
320 \r
321 static inline void Os_StackSetEndmark( OsTaskVarType *pcbPtr ) {\r
322         uint8_t *end = pcbPtr->stack.top;\r
323         *end = STACK_PATTERN;\r
324 }\r
325 \r
326 static inline _Bool Os_StackIsEndmarkOk( OsTaskVarType *pcbPtr ) {\r
327         _Bool rv;\r
328         uint8_t *end = pcbPtr->stack.top;\r
329         rv =  ( *end == STACK_PATTERN);\r
330         if( !rv ) {\r
331                 OS_DEBUG(D_TASK,"Stack End Mark is bad for %s curr: %p curr: %p\n",\r
332                                 pcbPtr->constPtr->name,\r
333                                 pcbPtr->stack.curr,\r
334                                 pcbPtr->stack.top );\r
335         }\r
336         return rv;\r
337 }\r
338 \r
339 static inline void Os_StackPerformCheck( OsTaskVarType *pcbPtr ) {\r
340 #if (OS_STACK_MONITORING == 1)\r
341                 if( !Os_StackIsEndmarkOk(pcbPtr) ) {\r
342 #if (OS_SC1 == STD_ON) || (OS_SC2 == STD_ON)\r
343                         /** @req OS068 */\r
344                         ShutdownOS(E_OS_STACKFAULT);\r
345 #elif (OS_SC3 == STD_ON) || (OS_SC4 == STD_ON)\r
346                         /** @req OS396 */\r
347                         PROTECTIONHOOK(E_OS_STACKFAULT);\r
348 #endif\r
349                 }\r
350 #endif\r
351 }\r
352 \r
353 static inline _Bool Os_TaskOccupiesResources( OsTaskVarType *pcb ) {\r
354         return !(TAILQ_EMPTY(&pcb->resourceHead));\r
355 }\r
356 \r
357 \r
358 void Os_Dispatch( uint32_t op );\r
359 void Os_ContextReInit( OsTaskVarType *pcbPtr );\r
360 void Os_TaskResourceAdd( OsResourceType *rPtr, OsTaskVarType *pcbPtr);\r
361 void Os_TaskResourceRemove( OsResourceType *rPtr , OsTaskVarType *pcbPtr);\r
362 \r
363 void Os_TaskMakeReady( OsTaskVarType *pcb );\r
364 void Os_TaskMakeWaiting( OsTaskVarType *pcb );\r
365 \r
366 \r
367 #endif /*TASK_I_H_*/\r