OS?
Based on
Embedded Systems: A Contemporary Design Tool James Peckol
and EE472 Lecture Notes Pack Blake Hannaford, James Peckol, Shwetak Patel
CSE 466 Tasks And Scheduling 1 Why would anyone want an OS?
Goal: run multiple programs on the same HW “simultaneously”
i.e. multi-tasking…it means more than surfing Facebook during lecture Problem: how to share resources & avoid interference
To be shared: processor, memory, GPIOs, PWM, timers, counters, ADCs, etc
In embedded case, we may need to do the sharing while respecting “real time” constraints
OS is responsible for scheduling the various jobs
Also:
OS provides abstractions of HW (e.g. device drivers) that make code more portable & re-usable, as well as enabling sharing
Code re-use a key goal of ROS (“meta-operating system”)
Power: maintain state across power loss, power aware scheduling
CSE 466 Tasks and Scheduling 2 Tasks / Processes, Threads
Task or process
Unit of code and data… a program running in its own memory space Thread
Smaller than a process
A single process can contain several threads
Memory is shared across threads but not across processes
Task 1 Task 2 Task 3
Ready Running Waiting
With just 1 task, it is either Running or Ready Waiting CSE 466 Tasks and Scheduling 3 Types of tasks
Periodic --- Hard real time
Control: sense, compute, & generate new motor cmd every 10ms
Multimedia: sample audio, compute filter, generate DAC output every 22.73 uS
Characterized by P, Period C, Compute time (may differ from instance to instance, but C<=P) D, Deadline (useful if start time of task is variable) C < D < P Intermittent
Characterized by C and D, but no P Background
Soft realtime or non-realtime
Characterized by C only Complex
Examples MS Word, Web server
Continuous need for CPU
Requests for IO or user input free CPU
CSE 466 Tasks and Scheduling 4 Scheduling strategies
Multiprogramming
Running task continues until a stopping point (e.g. waiting for an IO event) Real-time
Tasks must be completed before deadline Time sharing
Running task gives up CPU
Cooperative multitasking App voluntarily gives up control Old versions of Windows & Mac OS Badly behaved apps hang the system
Preemptive multitasking HW timer preempts currently executing task, returns control to OS All versions of Unix Power aware
Research topic
CSE 466 Tasks and Scheduling 5 Context
State must be saved / restored to switch between tasks
Program Counter (PC)
Register values
Processor status flags (Status Register)
Stack Pointer (SP)
Memory state
Peripheral configurations
Etc
CSE 466 Tasks and Scheduling 6 Task states in a time-sharing system
Blocked/ Waiting
Enter
Ready Running Waiting
Exit
CSE 466 Tasks and Scheduling 7 Memory resource management
Address space
Each process has a range of addresses it’s allowed to use Privilege level
Supervisory / kernel mode
User mode Interrupt generated when a user process tries to operate outside its Supervisory Mode address space Address Space “General protection fault” in x86
Supervisor User Mode Mode access Address Space User mode access
CSE 466 Tasks and Scheduling 8 Task Control Block (TCB)
Task Control Block Pointer State Process ID Program Counter Register contents Memory limits Open Files Etc.
Also: scheduling information, memory management information, I/O status info
CSE 466 Tasks and Scheduling 9 Task Control Block (TCB)
// The task control block struct TCB { void (*taskPtr)(void* taskDataPtr); void* taskDataPtr; void* stackPtr; unsigned short priority; struct TCB* nextPtr; struct TCB* prevPtr; };
taskPtr is a pointer to a function The function’s param list has one arg, of type void* stackPtr: each task has its own stack Priority: what is the priority level of this task? nextPtr & prevPtr: pointers to other TCBs
CSE 466 Tasks and Scheduling 10 Scheduling
CSE 466 Tasks and Scheduling 11 Time (for RTOS)
Time slice T, Ticks
Pmin, shortest period of all tasks in system
T < Pmin, sometimes T << Pmin
CSE 466 Tasks and Scheduling 12 Scheduling goals
CPU Utilization
UCPU = 1 – idle / period In mainframe, 100% is best, but 100% not safe for realtime systems Goal: 40% low load, 90% high load Throughput Turnaround time Waiting time Response time
CSE 466 Tasks and Scheduling 13 Scheduler types
Infinite loop, aka non-preemptive Round Robin while(1) { task1_fn(); task2_fn(); task3_fn(); } taskN_fn() { compute a little bit; return(); }
CSE 466 Tasks and Scheduling 14 Scheduler types
Synchronized Infinite loop
Top of loop waits for a HW clock while(1) { wait(CLOCK_PULSE); task1_fn(); task2_fn(); task3_fn(); }
CSE 466 Tasks and Scheduling 15 Scheduler types
Preemptive round robin
AKA cyclic executive
All processes handled without priority
Starvation free
CSE 466 Tasks and Scheduling 16 Scheduler types
Preemptive priority based
Goal in non-RT OS is to allocate resources equitably…no process should perpetually lack necessary resources
Attach priorities to each process Problem: priority inversion A is highest priority process. It is blocked waiting for a result from C B is 2nd highest priority. It never blocks C is 3rd highest priority Now B runs all the time and A never gets to…their priorities are effectively inverted…A is starved Problem: deadlock Catch 22 / Chicken - Egg: A is waiting for B, but B is waiting for A One person has the pencil but needs the rule, the other has ruler but needs pencil You can’t make coffee until you’re alert…but you’re not alert until you’ve had coffee
Ways to avoid priority inversion Make sure every job gets a minimum time slice Priority inheritance Does not prevent deadlock when there are circular dependencies
CSE 466 Tasks and Scheduling 17 Scheduler types
Preemptive priority based
Rate monotonic scheduling (RMS), for RTOS Static priorities set based on job cycle duration---shorter job gets scheduled more often Provide deterministic guarantees about response times (show using Rate Monotonic Analysis) Where Ci is compute time Ti is release period n is # processes to be scheduled
Roughly, RMS can meet deadlines when CPU < 69% used
CSE 466 Tasks and Scheduling 18 End
CSE 466 Tasks and Scheduling 19 Real-Time OSes and their communities
Linux Sensor networks
RTLinux TinyOS
RTAI Contiki Xenomai Computational RFID
Commercial Dewdrop
LynxOS MementOS QNX Robotics [“meta OSes,” VxWorks on top of Linux] Windows CE ROS iRMX for Windows Player / Stage OSE Carmen Embedded systems
FreeRTOS
C/OS-II
CSE 466 Tasks and Scheduling 20 RTLinux
Hard realtime RTOS microkernal runs entire Linux OS as a preemptive process Real time OS is virtual machine “host OS” …Linux kernal runs as “guest OS” Interrupts for realtime processing handled by realtime core Other interrupts forwarded to Linux, handled at lower priority than realtime interrupts Acquired by WindRiver, sold as Wind River Real-Time Core for Wind-River Linux
CSE 466 Tasks and Scheduling 21 RTAI & Xenomai (Real time Linux)
RTAI==Real Time Application Interface
Provides deterministic response to interrupts
Kernel patch allows RT system to take over key interrupts, leaves ordinary Linux to handle others
No patent restrictions (vs RTLinux)
Lowest feasible latencies Xenomai
Emphasizes extensibility rather than lowest latency
CSE 466 Tasks and Scheduling 22 C/OS-II
www.ucos-ii.com Kernal only…supports
Scheduling
Message passing (mailboxes)
Synchronization (semaphores)
Memory management
Supports 64 priority levels…runs highest priority first
Does not support: IO devices, Files, networking Versions
mC/GUI
mC/USB-Bulk
mC/USB-MSD [for Mass Storage Devices] CSE 466 Tasks and Scheduling 23 FreeRTOS
http://www.freertos.org/ Another realtime kernal Many features similar to C/OS-II Supports both tasks and co-routines A co-routine does not have its own stack Smaller memory footprint, more efficient Restrictions on how/when to call etc required Versions
OpenRTOS Commercial, supported
SafeRTOS Documented for safety critical applications
CSE 466 Tasks and Scheduling 24 Contiki and TinyOS
See Contiki slides More info: http://www.sics.se/contiki/wiki/index.php/Main_Page
CSE 466 Tasks and Scheduling 25 DewDrop
Energy-aware runtime (scheduler) for computational RFID Interesting to compare power aware scheduling to RTOS (“time-aware scheduling”)
CSE 466 Tasks and Scheduling 26 ROS
Robot Operating System
Meta-operating system See
ros_overview.pdf
ros_tutorial.pdf
CSE 466 Tasks and Scheduling 27 CSE 466 Tasks and Scheduling 28 Inter-task communication
Shared variables
Global variable
Shared buffer: producer & consumer
Task T0 Task T1
Problems: mismatch in filling & emptying rates can lead to over- or underflow Solution: always check empty / full before reading / writing
CSE 466 Tasks and Scheduling 29 Inter-task communication
Shared variables
Shared double buffer (ping pong buffer)
Task T0 Task T1
One buffer is being filled while the other is being emptied (also used for displays / graphics!)
Can generalize to n buffers…may be useful when producer generates data in fast short bursts
CSE 466 Tasks and Scheduling 30 Inter-task communication
Shared variables Task T0
Ring buffer head
An implementation of a queue, used xx D0 to let 2 processes communicate xx D1
FIFO (First In First Out) xx D2 Need to avoid under/overflow xx D3
tail
Task T1
D0 – D3: valid data xx: junk
CSE 466 Tasks and Scheduling 31 Inter-task communication
Shared variables
Mailbox Interface post(mailbox, data) // post to mailbox pend(mailbox, data) // pend on mailbox
Task T0 Task T1
pend post
A flag indicates that data has been posted…reading clears flag Variants: can implement as a queue of length 1, extensible queue (length n) priority queue A way to share a critical resources Pend differs from poll since during pend, CPU can do other things
CSE 466 Tasks and Scheduling 32 Inter-task communication
Messaging / communication
Generalize mailbox from “agreed-upon memory address accessed by defined interface” to more abstract address (which could be on another processor)
Inter-Process Communication (IPC) send & receive instead of post & pend
CSE 466 Tasks and Scheduling 33 Inter-task communication
Messaging / communication
Direct send (T1, message) // send message to Task T1 receive (T0, message) // receive message from Task T0
Indirect send(M0, message) // send message to mailbox M0 receive(M0, message) // receive message from mailbox M0 Multiple tasks may be able to read from / write to a mailbox
CSE 466 Tasks and Scheduling 34 Inter-task communication
Messaging / communication
Messaging systems can be buffered in 3 different ways Link has 0 capacity rendezvous or Idle RQ protocol RQ: “Repeat reQuest” TX waits for RX to accept message [ACK, NACK, timeout] AKA “stop and wait” or “synchronous” Link has bounded capacity…queue length of n Link has unbounded capacity continuous RQ protocol TX never has to wait TX can send next packet before receiving ACK from previous packets AKA “asynchronous”
NB: Idle RQ and Continuous RQ are examples of “backward error correction” (BEC) protocols, which manage re-transmission when errors are detected. Contrast with Forward Error Correction (FEC), which we discussed earlier with error correcting codes [Hamming, LDPC, Raptor, etc]
CSE 466 Tasks and Scheduling 35 Task cooperation, synchronization, sharing
Concurrent access to common data can result in data inconsistency, unexpected behavior, system failure Need to manage interactions of multiple tasks with common resources
CSE 466 Tasks and Scheduling 36 Task cooperation, synchronization, sharing
Bridge example
Critical section of roadway…can’t be occupied by both cars at once
Need to manage access to shared resource to avoid collisions
Car 0 Car 1
bridge
CSE 466 Tasks and Scheduling 37 Task cooperation, synchronization, sharing
Example: N item buffer Task T0 Task T1
Shared buffer w/ n item capacity Producer Task T0 not full Terminate idle write inc cnt
Consumer Task T1 not empty Terminate idle read dec cnt
CSE 466 Tasks and Scheduling 38 Task cooperation, synchronization, sharing
Example: N item buffer Task T0 Task T1
Shared buffer w/ n item capacity Task T0 --- Producer Task T1 --- Consumer while (1) while (1) if not full if not empty add item get item increment count decrement count else else wait for space wait for item end while end while The variable count is a critical shared resource…its value can depend on how the two processes interleave at the lowest level…see next slide
CSE 466 Tasks and Scheduling 39 Task cooperation, synchronization, sharing
Example of problem count++ implementation: “Race condition” --- result is determined by register1 = count “which input gets to the output first” register1 = register1 + 1 count = register 1 count-- implementation: Any SW or HW situation in which result register2 = count depends critically on timing register2 = register2 - 1 count = register2 Let count = 5 initially. One possible concurrent execution of count++ and count-- is register1 = count {register1 = 5} register1 = register1 + 1 {register1 = 6} register2 = count {register2 = 5} register2 = register2 - 1 {register2 = 4} count = register1 {count = 6} count = register2 {count = 4} count = 4 after count++ and count--, even though we started with count = 5 Question: what other values can count be from doing this incorrectly?
Problem is caused by inter-leaving of read & write operations on the same variable
CSE 466 Tasks and Scheduling 40 Task cooperation, synchronization, sharing
Example of non-problem count++ implementation: register1 = count register1 = register1 + 1 count = register 1 count-- implementation: register2 = count register2 = register2 - 1 count = register2 Let count = 5 initially. One possible concurrent execution of count++ and count-- is register1 = count {register1 = 5} register1 = register1 + 1 {register1 = 6} count = register1 {count = 6} register2 = count {register2 = 6} register2 = register2 - 1 {register2 = 5} count = register2 {count = 5} count = 5, the correct value
This worked correctly because the operations modifying count were not interleaved
CSE 466 Tasks and Scheduling 41 Task cooperation, synchronization, sharing
How to prevent problems due to concurrent access to shared resources? Ensure that access to shared resource is mutually exclusive…only one process can access at time! Mutual exclusion synchronization [locks] Condition synchronization Structure of a critical section while(1) non-critical code entry section critical section exit section non-critical code end while
CSE 466 Tasks and Scheduling 42 Task cooperation, synchronization, sharing
Requirements to solve critical section problem Ensure mutual exclusion in critical region Prevent deadlock Ensure progress through critical section Ensure bounded waiting Upper limit on the number of times a lower priority task can be blocked by a higher priority task
Definition: an atomic operation is guaranteed to terminate without being interrupted…all sub-steps comprising an atomic operation succeed or fail together
CSE 466 Tasks and Scheduling 43 Task cooperation, synchronization, sharing
Mechanisms for implementing mutual exclusion Flags, embedded in an atomic operation
await (condition) { // await is “atomic wait” statements } variable
Other tasks must be able to execute during await, otherwise deadlock can occur
Use T0Flag to mean Task 0 has lock; T1Flag means Task 1 has lock
await (!T1Flag) {T0Flag=True;} await (!T0Flag) {T1Flag=True;}
CSE 466 Tasks and Scheduling 44 Task cooperation, synchronization, sharing
Mechanisms for implementing mutual exclusion Flags count++ implementation: register1 = count register1 = register1 + 1 count = register 1 count-- implementation: register2 = count register2 = register2 - 1 count = register2
Task T0 --- Producer Task T1 --- Consumer while (1) while (1) if not full if not empty add item get item await(!T1Flag){T0Flag=true;} await (!T0Flag) {T1Flag=false;} count++ count— T0Flag = false; T1Flag = false; else else wait for space wait for item end while end while
CSE 466 Tasks and Scheduling 45 Task cooperation, synchronization, sharing
Mechanisms for implementing mutual exclusion Token passing: one token gets passed among tasks…only the task holding the token can access the resource
Task Ti Access buffer [have token] State A State B
Problems: Task holds on to token forever Task with token crashes Token lost or corrupted Task terminates without releasing token How to add new tasks?
Possible solutions? Add a system task which manages token, and has watchdog timer Getting complicated though
CSE 466 Tasks and Scheduling 46 Task cooperation, synchronization, sharing
Mechanisms for implementing mutual exclusion Interrupt management In a single processor system, disable interrupts in critical section Similar problems to token passing: badly behaved code can screw up Similar solutions: use a watchdog timer (with higher priority interrupt level, one that does not get disabled by critical section)
CSE 466 Tasks and Scheduling 47 Task cooperation, synchronization, sharing
Mechanisms for implementing mutual exclusion Semaphores Used to indicate availability of critical variable Simplest example: boolean S with two atomic access operations wait: P(S) P from Dutch proberen, to test . wait tests semaphore value, and if false, sets to true . wait has two parts, test and set, which must occur together atomically signal: V(S) V from Dutch verhogen, to increment . sets value to false
CSE 466 Tasks and Scheduling 48 Task cooperation, synchronization, sharing
Mechanisms for implementing mutual exclusion Semaphores // implementation of semaphore // notes: - wait must happen atomically! // - s should be initialized to false wait(s) { while (s); // do nothing while another process has s set s = TRUE; // now WE set s to be true to warn other processes } signal(s) { s = FALSE; // Turn off warning for other processes }
CSE 466 Tasks and Scheduling 49 Task cooperation, synchronization, sharing
Mechanisms for implementing mutual exclusion Semaphores
// use of semaphores
Task T0 { Task T1 { … … wait(s) wait(s) critical section critical section signal(s) signal(s) … … } }
CSE 466 Tasks and Scheduling 50 Task cooperation, synchronization, sharing
Mechanism for synchronization Semaphores Can also be used to enforce ordered execution of asynchronous tasks Want f(x) to be called before g(y) Use semaphore sync to do this
// semaphores for synchronization sync = true // initialization
Task T0 { Task T1 { … … f(x) … signal(sync) wait(sync) // wait … g(y) } … } Lock on critical section is called a spin lock, because T1 “spins” waiting for sync signal. Other activity can occur on the system while T1 is waiting, but T1 is not accomplishing anything while waiting
CSE 466 Tasks and Scheduling 51 Task cooperation, synchronization, sharing
Mechanisms for implementing mutual exclusion Semaphores Can be non-binary: counting semaphores Useful for managing a pool of identical resources P and V, wait and signal, down and up, and other names used for semaphore access functions vs Mutex [mutual exclusion]: same as binary semaphore, but Mutex often has a notion of an “owner process” who must release mutex; semaphore usually has no owner
CSE 466 Tasks and Scheduling 52 CSE 466 Tasks and Scheduling 53 Example messaging system: ROS
See ROS slides
CSE 466 Tasks and Scheduling 54 ROS & multithreading in roscpp
roscpp is the C++ implementation of ROS
roscpp provides a client library / API for C++ programmers
roscpp is the high performance option
vs rospy, python client library / API roscpp does not specify a threading model for apps
CSE 466 Tasks and Scheduling 55 Single threaded spinning: spin()
1 ros::init(argc, argv, "my_node"); 2 ros::NodeHandle nh; 3 ros::Subscriber sub = nh.subscribe(...); 4 ... 5 ros::spin();
All user callbacks will be called from within ros::spin() ros::spin()does not return until node shuts down…instead, message handling events get processed
CSE 466 Tasks and Scheduling 56 Single threaded spinning: spinonce()
1 ros::Rate r(10); // 10 hz 2 while (should_continue) 3 { 4 ... do some work, publish some messages, etc. ... 5 ros::spinOnce(); 6 r.sleep(); 7 } 8 Call ros::spinonce() periodically ros::spinonce()calls all callbacks that are currently waiting to be processed Note: spin() and spinonce() are intended for single threaded apps
CSE 466 Tasks and Scheduling 57 Multi-threaded spinning: MultiThreadedSpinner()
1 ros::MultiThreadedSpinner spinner(4); // Use 4 threads 2 spinner.spin(); // spin() will not return until node has been shutdown 3
similar Blocking spinner, similar to spin()
You specify a number of threads Defaults to one thread per CPU core
CSE 466 Tasks and Scheduling 58 Multi-threaded spinning: AsyncSpinner()
1 ros::AsyncSpinner spinner(4); // Use 4 threads 2 spinner.start(); 3 ros::waitForShutdown(); 4
This example is equivalent to previous blocking example Call to start() is non-blocking---execution returns right away In a real use, you’d put useful code after the start(), instead of immediately doing waitForShutdown()
CSE 466 Tasks and Scheduling 59 CSE 466 Tasks and Scheduling 60