embedded software - tu delft...embedded software design overview timing services rtos and isrs...
TRANSCRIPT
Timing Functionality Basic requirement of an embedded RTOS
Suspend task for some time (vs. busy wait) Produce a result at a certain time Timeout (wait for an acknowledgement for some time)
X32: delay(dt) busy waits (loops) until X32 clock has advanced dtms (“polling”)
RTOS: OSTimeDly(n) suspends caller (task) until time has advanced n OS ticks (“interrupt”)
!! set a timer variable to x ticks;!! decrement each tick; !! if zero move task to ready
16
delay()
17
/*---------------------------------------------* delay -- busy-wait for ms milliseconds *-------------------------------------------*/
void delay(int ms) {
int time = X32_clock; while(X32_clock - time < ms)
{}}
Time Delay Functionality OSTimeDly() is more efficient than delay()
schedules other tasks (does useful work) while waiting for time to pass
OS needs a timer interrupt mechanism to periodically check time NOTE: without OS, context switching is initiated by task calls=> no timer interrupts are needed
Timer interrupt => tick => delay resolution (and OS overhead) Timeouts in semaphores, etc.
Blocking with WAIT_FOREVER is simple! Blocking for X timer ticks is more difficult
18time
OSTimeDly(3)OSTimeDly(3)
Accuracy of a tick:
OS Delay Processing
19
Task 2
timer IRQ
timer ISR
Task 1
OS_Delay(2)
RTOS
highest priority task starts first
context switch
delay expired
tick tick
Questions
Is the parameter of OSTimeDly() given in ms? How accurate is the result of OSTimeDly()? How does the RTOS know how to setup the timer HW? What is normal length of a system tick? What if I need very accurate timing?
20
RTOS and Interrupts
RTOS and interrupts are two separate worlds Exception are timers ‐> OS delays Embedded programs use interrupts to react to events(buttons, I/O lines, UART, decoder, ..)
Interrupts and RTOS = trouble! Rule 1: No blocking Rule 2: No RTOS calls without a fair warning
23
RTOS and Interrupts
Rule 1: an ISR must not call any RTOS function that might block the caller
no pend‐type calls no semaphores to protect shared data in ISRs no reading queues, etc … in ISR
Violating this rule may affect response time and may even cause deadlock!
24
Example Violating Rule 1
25
void isr_read_temps(void) // (reactor){
OS_Pend(s);iTemperatures[0] = peripherals[..];iTemperatures[1] = peripherals[..];OS_Post(s);
}
void main(void) {
...OS_Pend(s);iTemp[0] = iTemperatures[0];iTemp[1] = iTemperatures[1];OS_Post(s);
...}
ISR Deadlock!
interrupt
Helping tools for rule 1
System calls that do not block Examples:
Function giving the status of a semaphore Queues: use post() in ISR, use pend() in task code
If queue is full, error is returned in ISR ‐> nonblocking Task code might miss a number of elements This code works only if rule #2 is obeyed
26
RTOS and Interrupts Rule 2:
An ISR must not call any RTOS function that might cause a context switch unless RTOS knows that it’s an ISR (and not a task) that is calling
no post()‐type calls (which is typical use!) unless RTOS knows it’s an ISR No semaphore release events No writing to a queue, etc …
Violate this rule! RTOS will switch to other task ISR may not complete for a long time No guarantees on response time anymore
27
Example Violating Rule 2
28
void isr_buttons(void) // (UTMS){
if (peripherals[BUTTONS] & 0x01) // button 0OS_Post(event); // signal event
}
void vButtonTask(void){
while (TRUE) {OS_Pend(event); // wait for eventprintf(“current float levels: \n”);!! list them
}}
Contextswitch
may blockall lowerpriorityISRs
Example Violating Rule 2
29
vLevelsTask
button ISR
vButtonTaskRTOS
context switchafter ISR finished
How ISRs should work:
OS_Post
vLevelsTask
button ISR
vButtonTaskRTOS
context switchbefore ISR finished!
What would really happen:
OS_Post
Solution to Satisfy Rule 2 (uC/OS)
Let the RTOS know an ISR is in progress by calling OSIntEnter()/OSIntExit() (uC/OS)
30
void isr_buttons(void) // (UTMS){
OSIntEnter(); // warn uC/OS not to rescheduleif (peripherals[BUTTONS] & 0x01) // button 0
OS_Post(event); // signal eventOSIntExit(); // uC/OS free to reschedule
}
vLevelsTask
button ISR
vButtonTaskRTOS
OS_Post but NO context switch
Alternative solution
Specialized functions for ISR Instead of OS_Post() use OS_ISR_Post() …
Not all OSes provide these alternatives
31
Overview Design of an embedded system
Specify the real‐time system can be very difficult What must the system do? How fast should the system serve the inputs?
Example: bar‐code scanner It must send the data to the terminal within reasonable time (fraction of a second – one second)
100% guarantee can be hard A longer delay in a small amount of cases can be tolerated
Choosing the right processor Example: serial port interface
can we run ISR 1000 times a second? Should we go for a processor with DMA support?
34
Principles – general operation System is in “sleep” state most of the time
Tasks are in the blocked state waiting for events Processor may be in a low‐power mode ISR are active
External event triggers ISR that trigger a whole series of tasks to start running
When processing is done, system goes back to sleep
Example: telegraph system
35
Principles – short ISRs Short ISRs are preferred over long ISRs
Lowest‐priority ISR runs before highest‐priority task Longer ISR ‐> slower task response time
ISRs exhibit more bugs/nr. lines of code ISRs are harder to debug
Example: serial port communication System responds to commands coming from serial port Commands always end up with “\n” Commands arrive one at a time, after completion of prev. Serial port has a buffer of one character System can take a long time to respond to commands
36
Trade‐off designs Everything in the ISR
Provides excellent response time for the serial port block System response for other tasks is disaster
ISR for each event – individual tasks for each event “perfect architecture” Will trigger a very low output from the processor
A lot of time spent by RTOS in context switching
Possible solution?
37
Principles – how many tasks?
Advantages of many tasks More tasks ‐> usage of priority ‐> faster system response
1 task versus 8 tasks
Modularity A task for each: the display, printer, buttons, etc.
More tasks ‐> better data encapsulation Network task – the only one that needs to access the HW signals
38
Principles – how many tasks?
Disadvantages of many tasks More tasks = more shared data = more semaphores
More semaphore bugs and RTOS overhead
More tasks = more data passed around in queues, pipes, … More bugs and more RTOS overhead
Each task has a stack ‐> more memory needed General throughput smaller in a system with more tasks
39
Example of time constants
RTOS on 20MHz Intel 80386 Get a semaphore – 10 microsec. Release a semaphore – 6‐38 microsec. Switch tasks – 17‐35 microsec. Write to a queue – 49‐68 microsec. Read from a queue – 12‐38 microsec. Create a task – 158 microsec. Destroy a task – 36‐57 microsec.
40
Principles – task structure
42
!! private static data declared here
void mytask(void) {!! More private data declared here!! either static either on the stack
!! Initialization code here
while(1) {!! wait for signal event
switch(!! type of signal) {case !! signal type 1:...break;
case !! signal type 2:...break;
... };}
}
mytask.c
Create/destroy tasks Most RTOS allow dynamic tasks – dynamic create/destroy Avoid this functionality
Lengthy operation – throughput is minimized Task destruction is dangerous
Task owns a semaphore? Messages on the task input queues?
What if these messages contain pointers to data that needed to be deleted by other tasks?
Alternative: create all the dynamic tasks at the startup If memory is not an issue – do not destroy the task!
43
Time slicing?
Tasks with same priority ‐> one options is to “time slice” Round‐robin scheduling
Time slicing used a lot in desktops ‐> “fairness” Embedded systems ‐> “timely response”! Responses of all tasks with the same priority is needed
Avoid time slicing Avoid having the same priority for two tasks
44