1 /* -------------------------------- Arctic Core ------------------------------
2 * Arctic Core - the open source AUTOSAR platform http://arccore.com
4 * Copyright (C) 2009 ArcCore AB <contact@arccore.com>
6 * This source code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 as published by the
8 * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * -------------------------------- Arctic Core ------------------------------*/
16 #include <sys/types.h>
27 #include <sys/queue.h>
34 // TODO: remove. Make soft links or whatever
35 #if defined(CFG_ARM_CM3)
36 #include "irq_types.h"
37 //#include "stm32f10x.h"
38 //#include "stm32f10x_arc.h"
41 extern caddr_t *sbrk(int);
43 #define os_alloc(_x) sbrk(_x)
45 OsPcbType * os_alloc_new_pcb( void ) {
46 void *h = os_alloc(sizeof(OsPcbType));
47 memset(h,0,sizeof(OsPcbType));
53 typedef void (*Os_IsrEntryType)(void);
56 typedef Os_IsrInfo_s {
57 Os_IsrEntryType entry;
64 extern TaskType Os_AddTask( OsPcbType *pcb );
66 static uint8 stackTop = 0x42;
69 * Creates an ISR dynamically
74 * @return The PID of the ISR created
76 TaskType Os_Arc_CreateIsr( void (*entry)(void ), uint8_t prio, const char *name )
78 OsPcbType *pcb = os_alloc_new_pcb();
79 strncpy(pcb->name,name,TASK_NAME_SIZE);
82 /* TODO: map to interrupt controller priority */
83 assert(prio<=OS_TASK_PRIORITY_MAX);
84 pcb->proc_type = PROC_ISR2;
85 pcb->state = ST_SUSPENDED;
87 pcb->stack.top = &stackTop;
89 return Os_AddTask(pcb);
93 #if defined(CFG_ARM_CM3)
94 extern void Irq_EOI2( void );
99 * Handle ISR type 2 interrupts from interrupt controller.
101 * @param stack Ptr to the current stack
102 * @param vector The vector that took the interrupt
104 void *Os_Isr( void *stack, void *pcb_p ) {
106 struct OsPcb *preempted_pcb;
108 os_sys.int_nest_cnt++;
110 // Save info for preempted pcb
111 preempted_pcb = get_curr_pcb();
112 preempted_pcb->stack.curr = stack;
113 preempted_pcb->state = ST_READY;
114 OS_DEBUG(D_TASK,"Preempted %s\n",preempted_pcb->name);
116 Os_StackPerformCheck(preempted_pcb);
120 pcb = (struct OsPcb *)pcb_p;
121 pcb->state = ST_RUNNING;
126 // We should not get here if we're NON
127 if( pcb->scheduling == NON) {
144 if( Os_IrqAnyDisabled() ) {
146 ERRORHOOK(E_OS_DISABLEDINT);
150 Os_ResourceCheckAndRelease(pcb);
152 pcb->state = ST_SUSPENDED;
157 --os_sys.int_nest_cnt;
159 // TODO: Check stack check marker....
160 // We have preempted a task
161 if( (os_sys.int_nest_cnt == 0) && (os_sys.scheduler_lock==0) ) { //&& is_idle_task() ) {
163 * - the preempted task is saved with large context.
164 * - We are on interrupt stack..( this function )
166 * if we find a new task:
167 * - just switch in the new context( don't save the old because
168 * its already saved )
171 new_pcb = Os_TaskGetTop();
173 Os_StackPerformCheck(new_pcb);
175 if( new_pcb != preempted_pcb ) {
176 OS_DEBUG(D_TASK,"Found candidate %s\n",new_pcb->name);
177 //#warning Os_TaskSwapContextTo should call the pretaskswaphook
178 // TODO: This shuould go away!!!!
179 #if defined(CFG_ARM_CM3)
182 Os_TaskSwapContextTo(NULL,new_pcb);
184 if( new_pcb == NULL ) {
187 preempted_pcb->state = ST_RUNNING;
188 set_curr_pcb(preempted_pcb);
191 set_curr_pcb(preempted_pcb);