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 ------------------------------*/
17 #include <sys/types.h>
24 //#include "irq_config.h"
27 extern const uint8_t Os_VectorToIsr[NUMBER_OF_INTERRUPTS_AND_EXCEPTIONS];
28 extern const OsIsrConstType Os_IsrConstList[OS_ISR_CNT];
31 OsIsrVarType Os_IsrVarList[OS_ISR_MAX_CNT];
34 SECTION_BALIGN(0x10) uint8_t Os_IsrStack[OS_INTERRUPT_STACK_SIZE];
36 // TODO: remove. Make soft links or whatever
37 #if defined(CFG_ARM_CM3)
38 #include "irq_types.h"
39 //#include "stm32f10x.h"
40 //#include "stm32f10x_arc.h"
43 extern caddr_t *sbrk(int);
45 #define os_alloc(_x) sbrk(_x)
47 OsTaskVarType * os_alloc_new_pcb( void ) {
48 void *h = os_alloc(sizeof(OsTaskVarType));
49 memset(h,0,sizeof(OsTaskVarType));
55 //extern TaskType Os_AddTask( OsTaskVarType *pcb );
57 //static uint8 stackTop = 0x42;
61 void Os_IsrInit( void ) {
65 /* Attach the interrupts */
66 for (int i = 0; i < sizeof(Os_IsrConstList) / sizeof(OsIsrConstType); i++) {
67 Os_IsrAdd(&Os_IsrConstList[i]);
73 * Adds an ISR to a list of Isr's. The ISRType (id) is returned
74 * for the "created" ISR.
76 * @param isrPtr Pointer to const data holding ISR information.
79 ISRType Os_IsrAdd( const OsIsrConstType * restrict isrPtr ) {
83 /* We have no VAR entires for ISR1 */
84 if( isrPtr->type == ISR_TYPE_2) {
85 Os_IsrVarList[id].constPtr = isrPtr;
88 Irq_EnableVector( isrPtr->vector, isrPtr->priority, Os_ApplGetCore(isrPtr->appOwner ) );
93 const OsIsrConstType * Os_IsrGet( int16_t vector) {
94 return &Os_IsrConstList[Os_VectorToIsr[vector]];
98 void Os_IsrDisable( ISRType isr) {
102 void Os_IsrEnable( ISRType isr) {
112 * Irq_PriorityTable[]
117 * Usual HW resources.
118 * - prio in HW (ppc and arm (even cortex m4))
122 * Irq_VectorTable CONST
123 * Irq_IsrTypeTable CONST
124 * Irq_PriorityTable CONST Can probably be a table with ISR_MAX number
125 * of for a CPU with prio registers. For masking
126 * CPUs it's better to keep an array to that indexing
129 * The problem with this approach is that the tool needs to know everything.
131 * TOOL GENERATES PART
132 * Irq_VectorTable VAR Since we must add vectors later
133 * Irq_IsrTypeTable VAR Since we must add vectors later
134 * Irq_PriorityTable VAR
143 * Before we have proper editor for ISR2 use this function to add resources
150 StatusType Os_IsrAddResource( TaskType isr, ResourceType resource ) {
154 #if defined(CFG_ARM_CM3)
155 extern void Irq_EOI2( void );
157 void TailChaining(void *stack)
159 struct OsTaskVar *pPtr = NULL;
163 /* Save info for preempted pcb */
164 pPtr = get_curr_pcb();
165 pPtr->stack.curr = stack;
166 pPtr->state = ST_READY;
167 OS_DEBUG(D_TASK,"Preempted %s\n",pPtr->name);
169 Os_StackPerformCheck(pPtr);
171 /* We interrupted a task */
172 OsTaskVarType *new_pcb = Os_TaskGetTop();
174 Os_StackPerformCheck(new_pcb);
176 if( (new_pcb == Os_Sys.currTaskPtr) ||
177 (Os_Sys.currTaskPtr->scheduling == NON) ||
178 !Os_SchedulerResourceIsFree() )
180 /* Just bring the preempted task back to running */
181 Os_TaskSwapContextTo(NULL,Os_Sys.currTaskPtr);
183 OS_DEBUG(D_TASK,"Found candidate %s\n",new_pcb->name);
184 Os_TaskSwapContextTo(NULL,new_pcb);
188 void Os_Isr_cm3( void *isr_p ) {
190 struct OsTaskVar *isrPtr;
194 /* Grab the ISR "pcb" */
195 isrPtr = (struct OsTaskVar *)isr_p;
196 isrPtr->state = ST_RUNNING;
198 if( isrPtr->proc_type & ( PROC_EXTENDED | PROC_BASIC ) ) {
206 /* Check so that ISR2 haven't disabled the interrupts */
208 if( Os_IrqAnyDisabled() ) {
210 ERRORHOOK(E_OS_DISABLEDINT);
213 /* Check so that the ISR2 have called ReleaseResource() for each GetResource() */
215 if( Os_TaskOccupiesResources(isrPtr) ) {
216 Os_ResourceFreeAll(isrPtr);
217 ERRORHOOK(E_OS_RESOURCE);
220 isrPtr->state = ST_SUSPENDED;
226 /* Scheduling is done in PendSV handler for ARM CM3 */
227 *((uint32_t volatile *)0xE000ED04) = 0x10000000; // PendSV
231 /*-----------------------------------------------------------------*/
233 void Os_IsrGetStackInfo( OsIsrStackType *stack ) {
234 stack->top = Os_IsrStack;
235 stack->size = sizeof(Os_IsrStack);
240 * Handle ISR type 2 interrupts from interrupt controller.
242 * @param stack Pointer to the current stack
245 void *Os_Isr( void *stack, int16_t vector ) {
246 uint8_t isrId = Os_VectorToIsr[vector];
247 OsTaskVarType *taskPtr = NULL;
249 /* Check if we interrupted a task or ISR */
250 if( Os_Sys.intNestCnt == 0 ) {
251 /* We interrupted a task */
254 /* Save info for preempted pcb */
255 taskPtr = get_curr_pcb();
256 taskPtr->stack.curr = stack;
257 taskPtr->state = ST_READY;
258 OS_DEBUG(D_TASK,"Preempted %s\n",taskPtr->name);
260 Os_StackPerformCheck(taskPtr);
262 /* We interrupted an ISR */
267 /* Grab the ISR "pcb" */
268 Os_IsrVarList[isrId].state = ST_ISR_RUNNING;
272 #if defined(CFG_HCS12D)
273 Os_IsrConstList[isrId].entry();
276 Os_IsrConstList[isrId].entry();
280 /* Check so that ISR2 haven't disabled the interrupts */
282 if( Os_IrqAnyDisabled() ) {
284 ERRORHOOK(E_OS_DISABLEDINT);
287 /* Check so that the ISR2 have called ReleaseResource() for each GetResource() */
289 if( Os_TaskOccupiesResources(taskPtr) ) {
290 Os_ResourceFreeAll(taskPtr);
291 ERRORHOOK(E_OS_RESOURCE);
294 Os_IsrVarList[isrId].state = ST_ISR_NOT_RUNNING;
300 #if defined(CFG_ARM_CM3)
301 /* Scheduling is done in PendSV handler for ARM CM3 */
302 *((uint32_t volatile *)0xE000ED04) = 0x10000000; // PendSV
304 // We have preempted a task
305 if( (Os_Sys.intNestCnt == 0) ) {
306 OsTaskVarType *new_pcb = Os_TaskGetTop();
308 Os_StackPerformCheck(new_pcb);
310 if( (new_pcb == Os_Sys.currTaskPtr) ||
311 (Os_Sys.currTaskPtr->constPtr->scheduling == NON) ||
312 !Os_SchedulerResourceIsFree() )
314 /* Just bring the preempted task back to running */
315 Os_Sys.currTaskPtr->state = ST_RUNNING;
318 OS_DEBUG(D_TASK,"Found candidate %s\n",new_pcb->name);
319 Os_TaskSwapContextTo(NULL,new_pcb);
322 /* We have a nested interrupt, do nothing */