We recommend using OS_EnterIntStack() and OS_LeaveIntStack() even if there is currently no additionalbenefit for your specific CPU, because code that uses them might reduce stack size on another CPU or a new versionof <strong>IAR</strong> <strong>PowerPac</strong> <strong>RTOS</strong> with support for an interrupt stack for your CPU. For details about interrupt stacks, see theCPU & Compiler Specifics manual of <strong>IAR</strong> <strong>PowerPac</strong> <strong>RTOS</strong> documentation.Stacks API function overviewRoutineOS_GetStackSpace()Table 112: Stacks API overviewOS_GetStackSpace()DescriptionReturns the unused portion of a task stack.Prototypeint OS_GetStackSpace (OS_TCB* pTask);ParameterDescriptionpTaskTable 113: OS_GetStackSpace() parameter listReturn valueThe unused portion of the task stack in bytes.Additional InformationIn most cases, the stack size required by a task cannot be easily calculated, because it takes quite some time to calculatethe worst-case nesting and the calculation itself is difficult.However, the required stack size can be calculated using the function OS_GetStackSpace(), which returns thenumber of unused bytes on the stack. If there is a lot of space left, you can reduce the size of this stack and vice versa.This function is only available in the debug and stack check builds of <strong>IAR</strong> <strong>PowerPac</strong> <strong>RTOS</strong>, because only these buildsinitialize the stack space used for the tasks.ImportantThis routine does not reliably detect the amount of stack space left, because it can only detect modified bytes on thestack. Unfortunately, space used for register storage or local variables is not always modified. In most cases, thisroutine will detect the correct amount of stack bytes, but in case of doubt, be generous with your stack space or useother means to verify that the allocated stack space is sufficient.ExampleDescriptionReturns the unused portion of a task stack.The task who's stack space is to be checked.NULL means current task.void CheckSpace(void) {printf("Unused Stack[0] %d", OS_GetStackSpace(&TCB[0]);OS_Delay(1000);printf("Unused Stack[1] %d", OS_GetStackSpace(&TCB[1]);OS_Delay(1000);}98<strong>IAR</strong> <strong>PowerPac</strong> <strong>RTOS</strong>for ARM CoresPP<strong>RTOS</strong>-2
InterruptsIntroductionIn this chapter, you will find a very basic description about using interrupt service routines (ISRs) in cooperation with<strong>IAR</strong> <strong>PowerPac</strong> <strong>RTOS</strong>. Specific details for your CPU and compiler may be found in the CPU & Compiler Specificsmanual of the <strong>IAR</strong> <strong>PowerPac</strong> <strong>RTOS</strong> documentation.Interrupts are interruptions of a program caused by hardware. When an interrupt occurs, the CPU saves its registers andexecutes a subroutine called an interrupt service routine, or ISR. After the ISR is completed, the program returns tothe highest-priority task in the READY state. Normal interrupts are maskable; they can occur at any time unless theyare disabled with the CPU's "disable interrupt" instruction. ISRs are also nestable - they can be recognized and executedwithin other ISRs.There are several good reasons for using interrupt routines. They can respond very quickly to external events such asthe status change on an input, the expiration of a hardware timer, reception or completion of transmission of a charactervia serial interface, or other types of events. Interrupts effectively allow events to be processed as they occur.Interrupt latencyInterrupt latency is the time between an interrupt request and the execution of the first instruction of the interrupt serviceroutine.Every computer system has an interrupt latency. The latency depends on various factors and differs even on the samecomputer system. The value that one is typically interested in is the worst case interrupt latency.The interrupt latency is the sum of a lot of different smaller delays explained below.CAUSES OF INTERRUPT LATENCIES●●●●●The first delay is typically in the hardware: The interrupt request signal needs to be synchronized to the CPU clock.Depending on the synchronization logic, typically up to 3 CPU cycles can be lost before the interrupt request hasreached the CPU core.The CPU will typically complete the current instruction. This instruction can take a lot of cycles; on most systems,divide, push-multiple, or memory-copy instructions are the instructions which require most clock cycles. On top ofthe cycles required by the CPU, there are in most cases additional cycles required for memory access. In an ARM7system, the instruction STMDB SP!,{R0-R11,LR}; (Push parameters and perm. register) is typically the worstcase instruction. It stores 13 32-bit registers on the stack. The CPU requires 15 clock cycles.The memory system may require additional cycles for wait states.After the current instruction is completet, the CPU performs a mode switch or pushes registers (typically, PC andflag registers) on the stack. In general, modern CPUs (such as ARM) perform a mode switch, which requires lessCPU cycles than saving registers.Pipeline fillMost modern CPUs are pipelined. Execution of an instruction happens in various stages of the pipeline. Aninstruction is executed when it has reached its final stage of the pipeline. Because the mode switch has flushed thepipeline, a few extra cycles are required to refill the pipeline.ADDITIONAL CAUSES FOR INTERRUPT LATENCIESThere can be additional causes for interrupt latencies.These depend on the type of system used, but we list a few of them.●Latencies caused by cache line fill.If the memory system has one or multiple caches, these may not contain the required data. In this case, not only therequired data is loaded from memory, but in a lot of cases a complete line fill needs to be performed, readingmultiple words from memory.PP<strong>RTOS</strong>-2 99