Code associated with "Designing RTOSs for Embedded Microcontrollers" by Robert Richards, p 48, May 1997 LISTING 1 Global constants and data memory allocation. ***** Global Constants ***** INT_MASK .set 09h ;Enable Timer and INT0 INTs TS_5MSEC .set 50000 ;Time Sensitive Task period - 5 msec (200 Hz) DP_MAIN .set 4 ;Main Variable Data Page DP_ZERO .set 0 ;Context Storage Date Page for ³sst² UART_TBFULL .set 10h ;Bit == 1 ? UART Transmit buffer full UART_RBMPTY .set 20h ;Bit == 1 ? UART Recieve buffer full ***** I/O Space Memory Allocation ***** UART_STATUS .set 3 ;I/O Address - UART status register ***** Data Page 0 (DP_ZERO) Memory Allocation ***** * On-Board Registers ADC .set 0 ;Serial Port Receive DAC .set 1 ;Serial Port Transmit TIM .set 2 ;Timer PRD .set 3 ;Period IMR .set 4 ;Int Mask Register * Storage Variables TSFlag .set 60h ;Timer INT flag (!0 = TINT fired) TCTaskSST .set 61h ;Time Critical Task context storage TSTaskSST .set 62h ;Time Sensitive Task context storage ITaskSST .set 63h ;Idle Task context storage ***** Data Page 4 (DP_MAIN) Memory Allocation ***** Temp .set 0 ;Temporary var LeftOut .set 1 ;Data for left channel D/A RightOut .set 2 ;Data for right channel D/A LeftIn .set 3 ;Data from left channel A/D RightIn .set 4 ;Data from right channel A/D LISTING 2 Program memory jump vector table. ADDR_0000: b RESET ;Jump to initialization routine ADDR_0002: b TC_ISR ;Jump to A/D and D/A service routine .space 20*16 ;skip unused jump vectors ADDR_0018: sst TSFlag ;Set flag on each Timer INT eint ;Enable INTs and return ret listing 3 System initialization routine and mainline code. RESET: ldpk DP_ZERO ;Set INT mask to allow Timer and lack INT_MASK ; Time Critical INTs sacl IMR lalk TS_5MSEC ;Set Time Sensitive Task period to 5 msec sacl TIM ; (200 times per second) sacl PRD { Initialize remaining system software/hardware } eint ;Enable hardware INTs (INT0 and Timer) MAINLINE_LOOP: call Time_Sensitive_Task call Idle_Task { Perform some Mainline routines } call Time_Sensitive_Task call Idle_Task { Perform some Mainline routines } b MAINLINE_LOOP ;Loop forever listing 4 Time sensitive task service routine. * Accumulator not stored in context save Time_Sensitive_Task: sst TSTaskSST ;Save context ldpk DP_ZERO ;Timer Flag == 0 ? Exit - Not time to lac TSFlag ; service task, test again later bz TSTask_Exit * Time to service Time Sensitive Task TSTask_Now: zac ;Reset flag to detect next Timer INT sacl TSFlag TSTASK_TEST1: ldpk DP_MAIN in Temp,UART_STATUS ;UART receive buffer empty ? skip to lack UART_RBMPTY ;next routine and Temp bnz TSTask_TEST2 { Move all characters from UART FIFO to software queue } TSTASK_TEST2: { Perform Switch Debounce } { Update and decay Bargraph LEDs with channel peaks } { Reset each A/D channel peak variables} ldpk DP_ZERO ;Set data page for context variable TSTask_Exit: lst TSTaskSST ;Restore context and return ret LISTING 5 Idle task service routine. * Accumulator not stored in context save Idle_Task: sst ITaskSST ;Save context ldpk DP_MAIN ;Set data page to working space IdleTask_Test1: in Temp,UART_STATUS ;UART transmit buffer full ? skip to lack UART_TBFULL ;next routine and Temp bnz IdleTask_Test2 { Move character from software queue to UART } b IdleTask_Exit ;Jump to exit IdleTask_Test2: { Test for other Idle Tasks } IdleTask_Exit: ldpk DP_ZERO ;Restore context and return lst ITaskSST ret listing 6 Time critical task service routine. TC_ISR: sst TCTaskSST ;Save context ldpk DP_MAIN ;Set data page to working space { Save remaining context - ACC, Status Reg 1 } lac RightOut ;Write right channel D/A data to holding ldpk DP_ZERO ; register sacl DAC lac ADC ;Read right channel A/D data from holding ldpk DP_MAIN ; register sacl RightIn { Compare A/D inputs to stored peaks and save any new peaks } { Execute other DSP routines } DSP_BIO: bioz DSP_BIO ;Loop here until DSP1 INT pin goes high lac LeftOut ;Write left channel D/A data to holding ldpk DP_ZERO ; register sacl DAC lac ADC ;Read left channel A/D data from holding ldpk DP_MAIN ; register sacl LeftIn { Execute remaining DSP routines } DSP_EXIT: { Restore entry ACC and Status Reg 1 } ldpk DP_ZERO ;Restore SST from above lst TCTaskSST eint ;enable INTs and exit ret