]> rtime.felk.cvut.cz Git - arc.git/blob - system/kernel/include/internal.h
Initial commit of changes to add applications. Nothing works....
[arc.git] / system / kernel / include / internal.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 INTERNAL_H_\r
17 #define INTERNAL_H_\r
18 \r
19 /* Using internal.h\r
20  *\r
21  * Os.h\r
22  *  |\r
23  *  |--- Os_Cfg.h\r
24  *  |\r
25  *  |--- Std_Types.h\r
26  *  |    |--- Platform_Types.h (std?)\r
27  *  |    |--- Compiler.h       (std?)\r
28  *  |\r
29  *  |--- MemMap.h\r
30  *\r
31  *\r
32  * task.c\r
33  *  |--- Os.h\r
34  *  |--- internal.h\r
35  *\r
36  *\r
37  *\r
38  *           kernel.h (shared types between config and OS source... pointless?)\r
39  *              |\r
40  *     |------------------|\r
41  *  Os_Cfg.c          internal.h\r
42  *\r
43  *\r
44  * API's\r
45  * -------------------------------------\r
46  * Os.h                                 - OS API and types\r
47  * os_config_func.h     - Inline API for Os_Cfg.c\r
48  * ext_config.h         - API for os_config_func.h, used by kernel\r
49  * internal.h                   - Internal API for kernel, do NOT expose outside kernel\r
50  *\r
51  * os_types.h           - Internal types for the kernel\r
52  *\r
53  *\r
54  */\r
55 \r
56 \r
57 \r
58 \r
59 #include <stdio.h>\r
60 #include <assert.h>\r
61 #include <stdint.h>\r
62 #include <stdlib.h>\r
63 #include "kernel.h"\r
64 #include "task_i.h"\r
65 #include "ext_config.h"\r
66 \r
67 \r
68 \r
69 /*\r
70  * Macros for error handling\r
71  * Registers service id of the erroneous function and the applicable parameters\r
72  * to os_error. Functions that have less than three parameters do not touch\r
73  * os_error.param3. Same rule follows for other parameter counts.\r
74  */\r
75 \r
76 /* Error handling for functions that take no arguments */\r
77 #define OS_STD_END(_service_id) \\r
78         goto ok;        \\r
79     err:                \\r
80         os_error.serviceId=_service_id;\\r
81         ERRORHOOK(rv);  \\r
82     ok:                 \\r
83         return rv;\r
84 \r
85 /* Error handling for functions that take one argument */\r
86 #define OS_STD_END_1(_service_id, _p1) \\r
87         goto ok;        \\r
88     err:                \\r
89     os_error.serviceId=_service_id;\\r
90         os_error.param1 = (uint32_t) _p1; \\r
91         ERRORHOOK(rv);  \\r
92     ok:                 \\r
93         return rv;\r
94 \r
95 /* Error handling for functions that take two arguments */\r
96 #define OS_STD_END_2(_service_id, _p1,_p2) \\r
97         goto ok;        \\r
98     err:                \\r
99         os_error.serviceId=_service_id;\\r
100         os_error.param1 = (uint32_t) _p1; \\r
101         os_error.param2 = (uint32_t) _p2; \\r
102         ERRORHOOK(rv);  \\r
103     ok:                 \\r
104         return rv;\r
105 \r
106 /* Error handling for functions that take three arguments */\r
107 #define OS_STD_END_3(_service_id,_p1,_p2,_p3) \\r
108         goto ok;        \\r
109     err:                \\r
110         os_error.serviceId=_service_id;\\r
111         os_error.param1 = (uint32_t) _p1; \\r
112         os_error.param2 = (uint32_t) _p2; \\r
113         os_error.param3 = (uint32_t) _p3; \\r
114         ERRORHOOK(rv);  \\r
115     ok:                 \\r
116         return rv;\r
117 \r
118 \r
119 \r
120 /* Called for sequence of error hook calls in case a service\r
121  * does not return with E_OK. Note that in this case the general error hook and the OS-\r
122  * Application specific error hook are called.\r
123  */\r
124 \r
125 #define ERRORHOOK(x) \\r
126         if( Os_Sys.hooks->ErrorHook != NULL  ) { \\r
127                 Os_Sys.hooks->ErrorHook(x); \\r
128         }\r
129 \r
130 \r
131 #define PRETASKHOOK() \\r
132         assert( Os_Sys.curr_pcb->state & ST_RUNNING ); \\r
133         assert( Os_Sys.curr_pcb->flags == SYS_FLAG_HOOK_STATE_EXPECTING_PRE );  \\r
134         Os_Sys.curr_pcb->flags = SYS_FLAG_HOOK_STATE_EXPECTING_POST;   \\r
135         if( Os_Sys.hooks->PreTaskHook != NULL ) { \\r
136                 Os_Sys.hooks->PreTaskHook(); \\r
137         }\r
138 \r
139 #define POSTTASKHOOK() \\r
140         assert( Os_Sys.curr_pcb->state & ST_RUNNING ); \\r
141         assert( Os_Sys.curr_pcb->flags == SYS_FLAG_HOOK_STATE_EXPECTING_POST );  \\r
142         Os_Sys.curr_pcb->flags = SYS_FLAG_HOOK_STATE_EXPECTING_PRE;   \\r
143         if( Os_Sys.hooks->PostTaskHook != NULL ) {      \\r
144                 Os_Sys.hooks->PostTaskHook();                   \\r
145         }\r
146 \r
147 /*\r
148  * PCB manipulating functions\r
149  */\r
150 \r
151 static inline OsTaskidType get_curr_pid( void ) {\r
152         return Os_Sys.curr_pcb->pid;\r
153 }\r
154 \r
155 static inline OsPcbType *get_curr_pcb( void ) {\r
156         return Os_Sys.curr_pcb;\r
157 }\r
158 \r
159 static inline void set_curr_pcb( OsPcbType *pcb ) {\r
160         Os_Sys.curr_pcb = pcb;\r
161 }\r
162 \r
163 static inline _Bool is_idle_task( OsPcbType *pcb ){\r
164         return (pcb->pid == 0);\r
165 }\r
166 \r
167 static inline OsTaskidType get_curr_prio( void ){\r
168         return Os_Sys.curr_pcb->prio;\r
169 }\r
170 \r
171 static inline TickType get_os_tick( void ) {\r
172         return Os_Sys.tick;\r
173 }\r
174 \r
175 static inline struct OsResource *os_get_resource_int_p( void ) {\r
176         return get_curr_pcb()->resource_int_p;\r
177 }\r
178 \r
179 /*\r
180  * Misc\r
181  */\r
182 \r
183 static inline uint32_t os_task_nr_to_mask( uint32_t nr ) {\r
184         return (1<<nr);\r
185 }\r
186 \r
187 // task_i.c\r
188 OsPcbType *Os_TaskGetTop( void );\r
189 OsPcbType *os_find_task( TaskType tid );\r
190 \r
191 // resource.c\r
192 void Os_ResourceGetInternal(void );\r
193 void Os_ResourceReleaseInternal( void );\r
194 void Os_ResourceAlloc( OsResourceType *rPtr, OsPcbType *pcbPtr);\r
195 void Os_ResourceFree( OsResourceType *rPtr , OsPcbType *pcbPtr);\r
196 \r
197 void Os_ResourceInit( void );\r
198 \r
199 \r
200 static inline void Os_ResourceFreeAll( OsPcbType *pcbPtr ) {\r
201         OsResourceType *rPtr;\r
202 \r
203         /* Pop the queue */\r
204         TAILQ_FOREACH(rPtr, &pcbPtr->resource_head, listEntry ) {\r
205                 Os_ResourceFree(rPtr,pcbPtr);\r
206         }\r
207 }\r
208 \r
209 #if 0\r
210 /**\r
211  *\r
212  * @return 1 - if any resources were found.\r
213  */\r
214 static inline _Bool Os_ResourceCheckAndRelease( OsPcbType *pcb )  {\r
215         _Bool rv = 0;\r
216         if( !TAILQ_EMPTY(&pcb->resource_head) ) {\r
217                 OsResourceType *rPtr;\r
218 \r
219                 TAILQ_FOREACH(rPtr, &pcb->resource_head, listEntry ) {\r
220                         ReleaseResource(rPtr->nr);\r
221                         /* Requirements are a little fuzzy here, no explicit\r
222                          * requirement for this.\r
223                          *\r
224                          * For OSEK this is a req.\r
225                          */\r
226                         ERRORHOOK(E_OS_RESOURCE);\r
227                         rv = 1;\r
228                 }\r
229         }\r
230         return rv;\r
231 }\r
232 #endif\r
233 \r
234 static inline _Bool Os_TaskOccupiesResources( OsPcbType *pcb ) {\r
235         return !(TAILQ_EMPTY(&pcb->resource_head));\r
236 }\r
237 \r
238 /*\r
239 static inline void Os_GetSchedulerResource() {\r
240         Os_Sys.scheduler_lock = 1;\r
241 }\r
242 \r
243 static inline void Os_ReleaseSchedulerResource() {\r
244         Os_Sys.scheduler_lock = 0;\r
245 }\r
246 */\r
247 /*\r
248 static inline _Bool Os_SchedulerResourceIsOccupied() {\r
249 #if 0\r
250         return (Os_Sys.resScheduler.owner != NO_TASK_OWNER );\r
251 #else\r
252         return (Os_Sys.scheduler_lock == 1);\r
253 #endif\r
254 }\r
255 */\r
256 #define NO_TASK_OWNER   (TaskType)(~0)\r
257 \r
258 static inline _Bool Os_SchedulerResourceIsFree() {\r
259 #if 1\r
260         return (Os_Sys.resScheduler.owner == NO_TASK_OWNER );\r
261 #else\r
262         return (Os_Sys.scheduler_lock == 0);\r
263 #endif\r
264 }\r
265 \r
266 // Create.c\r
267 OsPcbType * os_alloc_new_pcb( void );\r
268 \r
269 void os_dispatch(void);\r
270 \r
271 void OsTick( void );\r
272 \r
273 #if defined(CFG_ARM_CM3)\r
274 void Os_Isr_cm3( void *isr_p );\r
275 void TailChaining(void *stack);\r
276 #endif\r
277 \r
278 void *Os_Isr( void *stack, void *pcb_p );\r
279 void Os_Dispatch( uint32_t op );\r
280 \r
281 #define STACK_PATTERN   0x42\r
282 \r
283 static inline void *Os_StackGetUsage( OsPcbType *pcb ) {\r
284 \r
285         uint8_t *p = pcb->stack.curr;\r
286         uint8_t *end = pcb->stack.top;\r
287 \r
288         while( (*end == STACK_PATTERN) && (end<p)) {\r
289                         end++;\r
290                 }\r
291         return (void *)end;\r
292 }\r
293 \r
294 static inline void Os_StackSetEndmark( OsPcbType *pcbPtr ) {\r
295         uint8_t *end = pcbPtr->stack.top;\r
296         *end = STACK_PATTERN;\r
297 }\r
298 \r
299 static inline _Bool Os_StackIsEndmarkOk( OsPcbType *pcbPtr ) {\r
300         _Bool rv;\r
301         uint8_t *end = pcbPtr->stack.top;\r
302         rv =  ( *end == STACK_PATTERN);\r
303         if( !rv ) {\r
304                 OS_DEBUG(D_TASK,"Stack End Mark is bad for %s curr: %p curr: %p\n",\r
305                                 pcbPtr->name,\r
306                                 pcbPtr->stack.curr,\r
307                                 pcbPtr->stack.top );\r
308         }\r
309         return rv;\r
310 }\r
311 \r
312 static inline void Os_StackPerformCheck( OsPcbType *pcbPtr ) {\r
313 #if (OS_STACK_MONITORING == 1)\r
314                 if( !Os_StackIsEndmarkOk(pcbPtr) ) {\r
315 #if (  OS_SC1 == 1) || (  OS_SC2 == 1)\r
316                         /** @req OS068 */\r
317                         ShutdownOS(E_OS_STACKFAULT);\r
318 #else\r
319 #warning SC3 or SC4 not supported. Protection hook should be called here\r
320 #endif\r
321                 }\r
322 #endif\r
323 }\r
324 \r
325 \r
326 int Os_CfgGetTaskCnt(void);\r
327 void Os_ContextReInit( OsPcbType *pcbPtr );\r
328 \r
329 \r
330 static inline _Bool Os_IrqAnyDisabled( void ) {\r
331         return ((Os_IntDisableAllCnt | Os_IntSuspendAllCnt | Os_IntSuspendOsCnt) != 0);\r
332 }\r
333 \r
334 static inline void Os_IrqClearAll( void ) {\r
335         Os_IntDisableAllCnt = 0;\r
336         Os_IntSuspendAllCnt = 0;\r
337         Os_IntSuspendOsCnt = 0;\r
338 }\r
339 \r
340 \r
341 #endif /*INTERNAL_H_*/\r