1 /* -------------------------------- Arctic Core ------------------------------
\r
2 * Arctic Core - the open source AUTOSAR platform http://arccore.com
\r
4 * Copyright (C) 2009 ArcCore AB <contact@arccore.com>
\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
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
14 * -------------------------------- Arctic Core ------------------------------*/
\r
19 /* ----------------------------[includes]------------------------------------*/
\r
26 #include "resource_i.h"
\r
27 #include "internal.h"
\r
30 /* ----------------------------[define]--------------------------------------*/
\r
31 /* ----------------------------[macro]---------------------------------------*/
\r
34 struct OsApplication;
\r
37 #define NO_TASK_OWNER (TaskType)(~0)
\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
51 #define ST_ISR_RUNNING 1
\r
52 #define ST_ISR_NOT_RUNNING 2
\r
54 #define TASK_NAME_SIZE 16
\r
57 /* ----------------------------[typedef]-------------------------------------*/
\r
59 typedef uint16_t state_t;
\r
61 /* from Os.h types */
\r
62 typedef TaskType OsTaskidType;
\r
63 typedef EventMaskType OsEventType;
\r
64 /* Lets have 32 priority levels
\r
68 typedef sint8 OsPriorityType;
\r
71 /* STD container : OsHooks
\r
75 * OsProtectionHook: 0..1 Class 2,3,4 it's 1 instance
\r
80 typedef struct OsHooks {
\r
81 #if (OS_USE_APPLICATIONS == STD_ON)
\r
82 ProtectionHookType ProtectionHook;
\r
84 StartupHookType StartupHook;
\r
85 ShutdownHookType ShutdownHook;
\r
86 ErrorHookType ErrorHook;
\r
87 PreTaskHookType PreTaskHook;
\r
88 PostTaskHookType PostTaskHook;
\r
91 /* OsTask/OsTaskSchedule */
\r
92 enum OsTaskSchedule {
\r
97 /*-----------------------------------------------------------------*/
\r
99 typedef uint8_t proc_type_t;
\r
101 #define PROC_PRIO 0x1
\r
102 #define PROC_BASIC 0x1
\r
103 #define PROC_EXTENDED 0x3
\r
106 #define PROC_ISR 0x4
\r
107 #define PROC_ISR1 0x4
\r
108 #define PROC_ISR2 0xc
\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
119 #define SYS_FLAG_HOOK_STATE_EXPECTING_PRE 0
\r
120 #define SYS_FLAG_HOOK_STATE_EXPECTING_POST 1
\r
122 /* We do ISR and TASK the same struct for now */
\r
123 typedef struct OsTaskVar {
\r
124 OsStackType stack; // TASK
\r
126 #if ( OS_SC2 == STD_ON ) || ( OS_SC4 == STD_ON )
\r
127 OsTimingProtectionType *timing_protection;
\r
130 state_t state; // TASK
\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
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
145 // The number of queued activation of a task
\r
146 int8_t activations;
\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
152 TAILQ_HEAD(head,OsResource) resourceHead; // TASK
\r
154 const struct OsTaskConst *constPtr;
\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
162 /* Semaphore list */
\r
163 STAILQ_ENTRY(OsTaskVar) semEntry; // TASK
\r
165 /* List of PCB's */
\r
166 // TAILQ_ENTRY(OsTaskVar) pcb_list; // TASK
\r
168 TAILQ_ENTRY(OsTaskVar) ready_list; // TASK
\r
171 /*-----------------------------------------------------------------*/
\r
174 /*-----------------------------------------------------------------*/
\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
188 typedef struct OsTaskConst {
\r
190 OsPriorityType prio;
\r
191 // uint32 app_mask;
\r
193 proc_type_t proc_type;
\r
196 // int vector; // ISR
\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
206 enum OsTaskSchedule scheduling;
\r
207 uint32_t resourceAccess;
\r
208 uint32_t eventMask;
\r
209 // pointer to internal resource
\r
211 OsResourceType *resourceIntPtr;
\r
212 OsTimingProtectionType *timing_protection;
\r
213 uint8_t activationLimit;
\r
214 // lockingtime_obj_t
\r
218 /* ----------------------------[function prototypes]-------------------------*/
\r
220 extern OsTaskVarType Os_TaskVarList[OS_TASK_CNT];
\r
221 extern GEN_TASK_HEAD;
\r
225 * Set the task to running state and remove from ready list
\r
227 * @params pcb Ptr to pcb
\r
229 static inline void Os_TaskMakeRunning( OsTaskVarType *pcb ) {
\r
230 pcb->state = ST_RUNNING;
\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
239 // Added by Mattias in order to avoid compiler warning
\r
240 TaskType Os_AddTask( OsTaskVarType *pcb );
\r
242 #if 0 // Not used any more
\r
243 OsTaskVarType *os_find_higher_priority_task( OsPriorityType prio );
\r
246 static inline OsTaskVarType * Os_TaskGet( TaskType pid ) {
\r
247 return &Os_TaskVarList[pid];
\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
255 rv = INVALID_OSAPPLICATION;
\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
269 if( rPtr->type != RESOURCE_TYPE_INTERNAL ) {
\r
270 TAILQ_INSERT_TAIL(&pcbPtr->resourceHead, rPtr, listEntry);
\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
279 if( rPtr->type != RESOURCE_TYPE_INTERNAL ) {
\r
280 /* The list can't be empty here */
\r
281 assert( !TAILQ_EMPTY(&pcbPtr->resourceHead) );
\r
283 /* The list should be popped in LIFO order */
\r
284 assert( TAILQ_LAST(&pcbPtr->resourceHead, head) == rPtr );
\r
286 /* Remove the entry */
\r
287 TAILQ_REMOVE(&pcbPtr->resourceHead, rPtr, listEntry);
\r
291 static inline void Os_TaskResourceFreeAll( OsTaskVarType *pcbPtr ) {
\r
292 OsResourceType *rPtr;
\r
294 /* Pop the queue */
\r
295 TAILQ_FOREACH(rPtr, &pcbPtr->resourceHead, listEntry ) {
\r
296 Os_TaskResourceRemove(rPtr,pcbPtr);
\r
301 #define os_pcb_get_state(pcb) ((pcb)->state)
\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
308 #define STACK_PATTERN 0x42
\r
310 static inline void *Os_StackGetUsage( OsTaskVarType *pcb ) {
\r
312 uint8_t *p = pcb->stack.curr;
\r
313 uint8_t *end = pcb->stack.top;
\r
315 while( (*end == STACK_PATTERN) && (end<p)) {
\r
318 return (void *)end;
\r
321 static inline void Os_StackSetEndmark( OsTaskVarType *pcbPtr ) {
\r
322 uint8_t *end = pcbPtr->stack.top;
\r
323 *end = STACK_PATTERN;
\r
326 static inline _Bool Os_StackIsEndmarkOk( OsTaskVarType *pcbPtr ) {
\r
328 uint8_t *end = pcbPtr->stack.top;
\r
329 rv = ( *end == STACK_PATTERN);
\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
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
344 ShutdownOS(E_OS_STACKFAULT);
\r
345 #elif (OS_SC3 == STD_ON) || (OS_SC4 == STD_ON)
\r
347 PROTECTIONHOOK(E_OS_STACKFAULT);
\r
353 static inline _Bool Os_TaskOccupiesResources( OsTaskVarType *pcb ) {
\r
354 return !(TAILQ_EMPTY(&pcb->resourceHead));
\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
363 void Os_TaskMakeReady( OsTaskVarType *pcb );
\r
364 void Os_TaskMakeWaiting( OsTaskVarType *pcb );
\r
367 #endif /*TASK_I_H_*/
\r