290 likes | 626 Views
TinyOS. Dhanshree Nimje Smita Khartad. TinyOS - Design Design. What is TinyOS?. TinyOS is a highly modular software environment tailored to the requirements of Network Sensors, stressing efficiency, modularity and concurrency. Capable of fine grained concurrency
E N D
TinyOS Dhanshree Nimje Smita Khartad
What is TinyOS? TinyOS is a highly modular software environment tailored to the requirements of Network Sensors, stressing efficiency, modularity and concurrency. • Capable of fine grained concurrency • (event-driven architecture) • Small physical size • Fewer context switches: • (FIFO/non-preemptable scheduling) • Efficient Resource Utilization • (Get done quickly and sleep) • Highly Modular
TinyOS - Features • Event-driven architecture • Lower layer sends events to higher layer • Low overhead– No busy -wait cycles • Interrupt driven.Two kinds of interrupt • Clock • Radio • Component driven programming model • Size - 400 bytes • Extremely flexible component graph • Single Single-shared stack shared stack
Features Contd. • Network management - Active Messaging • No kernel, process management, virtual memory • File management - Matchbox • 2-level FIFO scheduler– events and tasks • Complete integration with hardware
Hardware Kits • Two Board Sandwich • Main CPU board with Radio Communication • Secondary Sensor Board • Allows for expansion and • customization • Current sensors include: • Acceleration, Magnetic Field, • Temperature, Pressure, • Humidity, Light, and RF Signal Strength • Can control RF transmission strength & Sense Reception • Strength
Hardware Abstraction: • LED (pin numbering/HW wiring) • CLOCK (counter interrupt) • UART (baud rate control, transfer) • ADC (ADC interrupt handling) • RFM (abstracts bit level timing, RFM specific control logic)
Communication stack • building up from the RFM bit level • bit level abstracts away radio specifics • byte level radio component collects individual bits into bytes • packet level constructs packets from bytes • messaging layer interprets packets as messages
Sensor stack • photo, and temperature sensing components • sits on top of ADC component • typical request data, wait for data event
TinyOS component model • Component interface: • commands accepts (implemented) • commands uses • events accepts (implemented) • events uses • Component implementation • functions that implement interface • frame: internal state • tasks: concurrency control
comp3 comp1: C code comp4 Programming Model • Components • .comp: specification • .C: behaviour • .desc: select and wire • specification: • accepts commands • uses commands • signals events • handles events comp2: .desc application: .desc
Scheduler : • 2-level scheduling (events and tasks) • single shared stack, used by events and function calls • Tasks: • are preemptable by events • may call commands • may signal events • not preempted by tasks • Events – • Time critical • Shorter duration (hand off to task if need be) • Interrupts task • Last-in first-out semantics (no priority among events) • lowest level events support by hardware interrupt
TinyOS Two-level Scheduling • Tasks do intensive computations • Unpreemptable FIFO scheduling • Bounded number of pending tasks • Events handle interrupts • Interrupts trigger lowest level events • Events can signal events, call commands, or post tasks • Two priorities • Event/command • Tasks
How to handle multiple data flows? • Data/interrupt are handled by interrupt/event • Respond to it quickly: A sequence of non-blocking event/command (function calls) through the component graph • e.g., get bit out of radio hw before it gets lost • Post tasks for long computations • e.g., encoding • • Assumption: long computation are not urgent • New events preempt tasks to handle new data
What are tasks • Requirement of realtime OS: bounded delays between events. • Event handler should run to completion within a short duration. • If a lot of computation is involved in an event handler we defer execution. How? • Implementing it as a task and scheduling it for later execution. • TinyOS has simple FIFO scheduler using which tasks are scheduled. • On occurrence of an event a task that is executing is preempted.
Data Memory Model • STATIC memory allocation! • No heap (malloc) • No function pointers • Global variables • Available on a per-frame basis • Local variables • Saved on the stack • Declared within a method
Application • Is the OS with some specific functionality. • Application is interrupt driven. • List of interrupts handled depend on list of hardware components included in the application (e.g. clock and receiver). • Waits for interrupts. On occurrence of interrupt, calls interrupt handler. invokes Calls Hardware Interrupts ISR Interrupt Handler
Example : Inter-Node Communication • Sender: • Receiver :
Message Buffer Ownership • Transmission: AM gains ownership of the buffer until • sendDone(…) is signaled • Reception: Application’s event handler gains ownership • of the buffer, but it must return a free buffer for the next • message
Potentially Nasty Bug 1 uint8_t globalData; task void processData() { call SendData.send(globalData); } command result_t Foo.bar(uint8_t data) { globalData = data; post processData(); } • What’s wrong with the code? Symptom: data saved in globalData is lost Reason: Race condition between two tasks Solution: Use a queue, or never rely on inter-task communication
Potentially Nasty Bug 2 What’s wrong with the code? Symptom: message is corrupt Reason: TOS_Msg is allocated in the stack, lost when function returns Solution: Declare TOS_Msg msg in component’s frame. command result_t Foo.bar(uint8_t data) { TOS_Msg msg; FooData* foo = (FooData*)msg.data; foo.data = data; call SendMsg.send(0x01, sizeof(FooData), &msg); }
Potentially Nasty Bug 3 command result_t Foo.bar(uint8_t data) { FooData* foo = (FooData*)msg.data; foo.data = data; call SendMsg.send(0x01, sizeof(FooData), &msg); } Component What’s wrong with the code? Symptom: some messages are lost Reason: Race condition between two components trying to share network stack (which is split-phase) Solution: Use a queue to store pending messages Component 2: * command result_t Goo.bar(uint8_t data) { GooData* goo = (GooData*)msg.data; goo.data = data; call SendMsg.send(0x02, sizeof(GooData), &msg); }