User`s manual

80 digi.com Multitasking with Dynamic C
5.10.2.3.1 Sample Code for a TA-ISR
Fortunately, the Rabbit BIOS and libraries provide all of the necessary flags to make TA-ISRs work. With
the code found in Listing 1, minimal work is needed to make a TA-ISR function correctly with µC/OS-II.
TA-ISRs allow µC/OS-II the ability to have ISRs that communicate with tasks as well as the ability to let
ISRs nest, thereby reducing interrupt latency.
Just like a standard ISR, the first thing a TA-ISR does is to save the registers that it is going to use (1).
Once the registers are saved, the interrupt source is cleared (2) and the nesting counter is incremented (3).
Note that bios_intnesting is a global interrupt nesting counter provided in the Dynamic C libraries
specifically for tracking the interrupt nesting level. If an ipres instruction is executed (4) other interrupts
can occur before this ISR is completed, making it necessary for this ISR to be a TA-ISR.
If it is possible for the ISR to execute before µC/OS-II has been fully initialized and started multi-tasking,
a check should be made (5) to insure that µC/OS-II is in a known state, especially if the TA-ISR signals a
task to the ready state (6).
After the TA-ISR has done its necessary work (which may include making a higher priority task than is
currently running ready to run), OSIntExit must be called (7). This µC/OS-II function determines the
highest priority task ready to run, sets it as the currently running task, and sets the global flag
bios_swpend if a context switch needs to take place. Interrupts are disabled since a context switch is
treated as a critical section (8).
If the TA-ISR decrements the nesting counter and the count does not go to zero, then the nesting level is
saved in bios_intnesting (9), the registers used by the TA-ISR are restored, interrupts are re-enabled
(if not already done in (4)), and the TA-ISR returns (12). However, if decrementing the nesting counter in
(9) causes the counter to become zero, then bios_swpend must be checked to see if a context switch
needs to occur (10).
If a context switch is not pending, then the nesting level is set (9) and the TA-ISR exits (12). If a context
switch is pending, then the remaining context of the previous task is saved and a long call, which insures
that the xpc is saved and restored properly, is made to bios_intexit (11). bios_intexit is
responsible for switching to the stack of the task that is now ready to run and executing a long call to
switch to the new task. The remainder of (11) is executed when a previously preempted task is allowed to
run again.
Listing 1
#asm
taskaware_isr::
push af ;push regs needed by isr (1)
push hl ;clear interrupt source (2)
ld hl,bios_intnesting ;increase the nesting count (3)
inc (hl)
; ipres (optional) (4)
; do processing necessary for interrupt
ld a,(OSRunning) ;MCOS multitasking yet? (5)
or a
jr z,taisr_decnesting
; possibly signal task to become ready (6)
call OSIntExit ;sets bios_swpend if higher
; prio ready (7)