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
26 * | |--- Platform_Types.h (std?)
\r
27 * | |--- Compiler.h (std?)
\r
38 * kernel.h (shared types between config and OS source... pointless?)
\r
40 * |------------------|
\r
41 * Os_Cfg.c internal.h
\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
51 * os_types.h - Internal types for the kernel
\r
65 #include "ext_config.h"
\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
76 /* Error handling for functions that take no arguments */
\r
77 #define OS_STD_END(_service_id) \
\r
80 os_error.serviceId=_service_id;\
\r
85 /* Error handling for functions that take one argument */
\r
86 #define OS_STD_END_1(_service_id, _p1) \
\r
89 os_error.serviceId=_service_id;\
\r
90 os_error.param1 = (uint32_t) _p1; \
\r
95 /* Error handling for functions that take two arguments */
\r
96 #define OS_STD_END_2(_service_id, _p1,_p2) \
\r
99 os_error.serviceId=_service_id;\
\r
100 os_error.param1 = (uint32_t) _p1; \
\r
101 os_error.param2 = (uint32_t) _p2; \
\r
106 /* Error handling for functions that take three arguments */
\r
107 #define OS_STD_END_3(_service_id,_p1,_p2,_p3) \
\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
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
125 #define ERRORHOOK(x) \
\r
126 if( Os_Sys.hooks->ErrorHook != NULL ) { \
\r
127 Os_Sys.hooks->ErrorHook(x); \
\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
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
148 * PCB manipulating functions
\r
151 static inline OsTaskidType get_curr_pid( void ) {
\r
152 return Os_Sys.curr_pcb->pid;
\r
155 static inline OsPcbType *get_curr_pcb( void ) {
\r
156 return Os_Sys.curr_pcb;
\r
159 static inline void set_curr_pcb( OsPcbType *pcb ) {
\r
160 Os_Sys.curr_pcb = pcb;
\r
163 static inline _Bool is_idle_task( OsPcbType *pcb ){
\r
164 return (pcb->pid == 0);
\r
167 static inline OsTaskidType get_curr_prio( void ){
\r
168 return Os_Sys.curr_pcb->prio;
\r
171 static inline TickType get_os_tick( void ) {
\r
172 return Os_Sys.tick;
\r
175 static inline struct OsResource *os_get_resource_int_p( void ) {
\r
176 return get_curr_pcb()->resource_int_p;
\r
183 static inline uint32_t os_task_nr_to_mask( uint32_t nr ) {
\r
188 OsPcbType *Os_TaskGetTop( void );
\r
189 OsPcbType *os_find_task( TaskType tid );
\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
197 void Os_ResourceInit( void );
\r
200 static inline void Os_ResourceFreeAll( OsPcbType *pcbPtr ) {
\r
201 OsResourceType *rPtr;
\r
203 /* Pop the queue */
\r
204 TAILQ_FOREACH(rPtr, &pcbPtr->resource_head, listEntry ) {
\r
205 Os_ResourceFree(rPtr,pcbPtr);
\r
212 * @return 1 - if any resources were found.
\r
214 static inline _Bool Os_ResourceCheckAndRelease( OsPcbType *pcb ) {
\r
216 if( !TAILQ_EMPTY(&pcb->resource_head) ) {
\r
217 OsResourceType *rPtr;
\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
224 * For OSEK this is a req.
\r
226 ERRORHOOK(E_OS_RESOURCE);
\r
234 static inline _Bool Os_TaskOccupiesResources( OsPcbType *pcb ) {
\r
235 return !(TAILQ_EMPTY(&pcb->resource_head));
\r
239 static inline void Os_GetSchedulerResource() {
\r
240 Os_Sys.scheduler_lock = 1;
\r
243 static inline void Os_ReleaseSchedulerResource() {
\r
244 Os_Sys.scheduler_lock = 0;
\r
248 static inline _Bool Os_SchedulerResourceIsOccupied() {
\r
250 return (Os_Sys.resScheduler.owner != NO_TASK_OWNER );
\r
252 return (Os_Sys.scheduler_lock == 1);
\r
256 #define NO_TASK_OWNER (TaskType)(~0)
\r
258 static inline _Bool Os_SchedulerResourceIsFree() {
\r
260 return (Os_Sys.resScheduler.owner == NO_TASK_OWNER );
\r
262 return (Os_Sys.scheduler_lock == 0);
\r
267 OsPcbType * os_alloc_new_pcb( void );
\r
269 void os_dispatch(void);
\r
271 void OsTick( void );
\r
273 #if defined(CFG_ARM_CM3)
\r
274 void Os_Isr_cm3( void *isr_p );
\r
275 void TailChaining(void *stack);
\r
278 void *Os_Isr( void *stack, void *pcb_p );
\r
279 void Os_Dispatch( uint32_t op );
\r
281 #define STACK_PATTERN 0x42
\r
283 static inline void *Os_StackGetUsage( OsPcbType *pcb ) {
\r
285 uint8_t *p = pcb->stack.curr;
\r
286 uint8_t *end = pcb->stack.top;
\r
288 while( (*end == STACK_PATTERN) && (end<p)) {
\r
291 return (void *)end;
\r
294 static inline void Os_StackSetEndmark( OsPcbType *pcbPtr ) {
\r
295 uint8_t *end = pcbPtr->stack.top;
\r
296 *end = STACK_PATTERN;
\r
299 static inline _Bool Os_StackIsEndmarkOk( OsPcbType *pcbPtr ) {
\r
301 uint8_t *end = pcbPtr->stack.top;
\r
302 rv = ( *end == STACK_PATTERN);
\r
304 OS_DEBUG(D_TASK,"Stack End Mark is bad for %s curr: %p curr: %p\n",
\r
306 pcbPtr->stack.curr,
\r
307 pcbPtr->stack.top );
\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
317 ShutdownOS(E_OS_STACKFAULT);
\r
319 #warning SC3 or SC4 not supported. Protection hook should be called here
\r
326 int Os_CfgGetTaskCnt(void);
\r
327 void Os_ContextReInit( OsPcbType *pcbPtr );
\r
330 static inline _Bool Os_IrqAnyDisabled( void ) {
\r
331 return ((Os_IntDisableAllCnt | Os_IntSuspendAllCnt | Os_IntSuspendOsCnt) != 0);
\r
334 static inline void Os_IrqClearAll( void ) {
\r
335 Os_IntDisableAllCnt = 0;
\r
336 Os_IntSuspendAllCnt = 0;
\r
337 Os_IntSuspendOsCnt = 0;
\r
341 #endif /*INTERNAL_H_*/
\r