Open danhouldsworth opened 9 years ago
RTOS brief
A single real time interrupt is used to derive appropriate service rates for a series of task lists. Each task list runs to completion with no waits. Only in the background task when there is no work does the cpu wait or sleep.
All external activities are polled at an appropriate 'worse case' rate so the zone is guaranteed to work by design for all eventualities. (this must account for tick jitter due to CLI..SEI)
Signal processing algorithms such as filters, time-proportioning now all have a constant, jitter free, iteration rate ensuring correct operation.
The background should include - power on self test, initialisation, refresh routines (to/from eerom) other refresh non time critical stuff (error checking?)
Constants and control regs once initialized should be refreshed ie don't rely on volatile data not being corrupted.
=========== Real Time Exec Structure ======
This real time executive supports a number of task lists
each requiring a particular tick rate. For example -
L1 4k/s 250 us IR_srv
L2 1000/s 1ms adc, motion /4
L3 100/s 10 ms wdg, cycle_count, /10
L4 20/s 50 ms UI_state_machine, jbug ,display /5
/20
Background 1 sec non-critical tasks, Time, ee_cache, pwr_mgmt
Level 1 runs unconditionally to completion on each tick
Levels 2,3,4 are controlled by handshaking with a higher level thru
a combined task state/timer byte
background gets what's left but is required to complete every
1 secs otherwise RTE will dishonor the watchdog after a grace
period. If the background has to wait on L1-5 it may sleep.
State variable format
adcccccc where a = active, d = due, ccccc = count
The ms 2 bits encode the state as follows for Level x
00 not active/not due, return from intrpt
01 not active/due to run start lowest priority due
10 active(busy) return from intrpt
11 still busy and due again x overdue so error trap
All levels are time scheduled as an integer ratio to the level above
allowing upto a 60:1 ratio between rates of adjacent task levels.
The remainder of the byte is used as an upcounter and will automatically
set due when rolling over to zero. When a task starts it subtracts
the count for the desired period and clears 'due'. If
left initialized to 0 will incurr a start up delay of 64 ticks for
each timed level. Note all levels except L1 are interruptable but each
level can only be interrupted by a higher priority. Therfore all use the
same stacks; operations on shared globals are inherently indivisible for
the higher priority. The lower task ensures indivisibility by either
CLI..SEI to hold off L1 upto a max of 3.5 us
or setting and clearing a shared_data_lock to hold off L4 or L5
Note adc data shared between L3 and L4 is timed to be coherent.
Stacks are sized accordingly
Lower levels may become due only when all higher levels become due.
The highest priority which is due/active will start/continue and lower priorities will have
to wait until all higher tasks have run to completion. Since the starting time
of lower levels is uncertain synchronisation with higher tasks may require
extra effort to latch the data according to the phase of the state variable
count of the lower task and not when the task runs.
If there are no due/active levels the rte returns from whence it came which is the
background task.
Overdue levels (still active but due)are considered lost and will error trap.
An overdue background is permitted a grace period to allow for occasional
peak load (ee update etc) since the bkgd is non time critical.
RTE service routine outline:
- always run level 1 tasks
- if (powerfail flag) shed load, save to eerom and shut down
- update counters and trap on overdue task lists
- find highest priority due or active tasklist and start/continue
- otherwise return to background
@CoolSunTech - worth a discussion for revision purposes!!