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
16 #include <sys/types.h>
\r
19 #include "internal.h"
\r
27 #include <sys/queue.h>
\r
29 #include "internal.h"
\r
34 // TODO: remove. Make soft links or whatever
\r
35 #if defined(CFG_ARM_CM3)
\r
36 #include "irq_types.h"
\r
37 //#include "stm32f10x.h"
\r
38 //#include "stm32f10x_arc.h"
\r
41 extern caddr_t *sbrk(int);
\r
43 #define os_alloc(_x) sbrk(_x)
\r
45 OsPcbType * os_alloc_new_pcb( void ) {
\r
46 void *h = os_alloc(sizeof(OsPcbType));
\r
47 memset(h,0,sizeof(OsPcbType));
\r
53 typedef void (*Os_IsrEntryType)(void);
\r
56 typedef Os_IsrInfo_s {
\r
57 Os_IsrEntryType entry;
\r
64 extern TaskType Os_AddTask( OsPcbType *pcb );
\r
66 static uint8 stackTop = 0x42;
\r
68 TaskType Os_Arc_CreateIsr( void (*entry)(void ), uint8_t prio, const char *name )
\r
70 OsPcbType *pcb = os_alloc_new_pcb();
\r
71 strncpy(pcb->name,name,TASK_NAME_SIZE);
\r
74 /* TODO: map to interrupt controller priority */
\r
75 assert(prio<=OS_TASK_PRIORITY_MAX);
\r
76 pcb->proc_type = PROC_ISR2;
\r
77 pcb->state = ST_SUSPENDED;
\r
79 pcb->stack.top = &stackTop;
\r
81 return Os_AddTask(pcb);
\r
85 #if defined(CFG_ARM_CM3)
\r
86 extern void Irq_EOI2(void *pc);
\r
91 * Handle ISR type 2 interrupts from interrupt controller.
\r
93 * @param stack Ptr to the current stack
\r
94 * @param vector The vector that took the interrupt
\r
96 void *Os_Isr( void *stack, void *pcb_p ) {
\r
98 struct OsPcb *preempted_pcb;
\r
100 os_sys.int_nest_cnt++;
\r
102 // Save info for preempted pcb
\r
103 preempted_pcb = get_curr_pcb();
\r
104 preempted_pcb->stack.curr = stack;
\r
105 preempted_pcb->state = ST_READY;
\r
106 OS_DEBUG(D_TASK,"Preempted %s\n",preempted_pcb->name);
\r
110 pcb = (struct OsPcb *)pcb_p;
\r
111 pcb->state = ST_RUNNING;
\r
116 // We should not get here if we're NON
\r
117 if( pcb->scheduling == NON) {
\r
132 if( Os_IrqAnyDisabled() ) {
\r
134 ERRORHOOK(E_OS_DISABLEDINT);
\r
138 Os_ResourceCheckAndRelease(pcb);
\r
140 pcb->state = ST_SUSPENDED;
\r
145 --os_sys.int_nest_cnt;
\r
147 // TODO: Check stack check marker....
\r
148 // We have preempted a task
\r
149 if( (os_sys.int_nest_cnt == 0) && (os_sys.scheduler_lock==0) ) { //&& is_idle_task() ) {
\r
151 * - the preempted task is saved with large context.
\r
152 * - We are on interrupt stack..( this function )
\r
154 * if we find a new task:
\r
155 * - just switch in the new context( don't save the old because
\r
156 * its already saved )
\r
158 OsPcbType *new_pcb;
\r
159 new_pcb = Os_TaskGetTop();
\r
160 if( new_pcb != preempted_pcb ) {
\r
161 OS_DEBUG(D_TASK,"Found candidate %s\n",new_pcb->name);
\r
162 //#warning Os_TaskSwapContextTo should call the pretaskswaphook
\r
163 // TODO: This shuould go away!!!!
\r
164 #if defined(CFG_ARM_CM3)
\r
170 Os_TaskSwapContextTo(NULL,new_pcb);
\r
172 if( new_pcb == NULL ) {
\r
175 preempted_pcb->state = ST_RUNNING;
\r
176 set_curr_pcb(preempted_pcb);
\r
179 set_curr_pcb(preempted_pcb);
\r