220 likes | 442 Views
TinyOS. Sandeep Gupta. Operating System (OS). What is an OS? Main functions Process management Memory management Resource management Traditional OSs are monolithic. Sensors. Sensor consists of Processor Limited memory (128kb) Transceiver Peripheral devices (eg. LED)
E N D
TinyOS Sandeep Gupta
Operating System (OS) • What is an OS? • Main functions • Process management • Memory management • Resource management • Traditional OSs are monolithic.
Sensors • Sensor consists of • Processor • Limited memory (128kb) • Transceiver • Peripheral devices (eg. LED) • Limited battery and • Sensing module • Deployed for specific application process and resource management not required
TinyOS Introduction • Written using a component based language called NesC (Nested C). • Hardware devices are represented using components. For example: LedsC for LED • Interrupt driven • Only one application runs on sensors. • Application contains the OS code. Code to control hardware devices. • Application does not contain the whole OS. • To avoid problems due to invalid memory access does not allow dynamic memory allocation.
Components • Each component will provide a set of services (atleast stdcontrol). • stdcontrol provides commands for initializing, starting and stopping the component. • Services provided by a component can be used via interfaces. • Components can use interfaces provided by other components. • Each component is like a state machine.
Interface • Interface is like a header file that defines APIs using which components will interact. • Interfaces are bidirectional. • Interface consists of commands and events. • Commands: • Issued by component that uses an interface provided by another component. • Component that provides an interface will have the implementation for commands. • Events: • Issued by component that provides an interface to a component that uses an interface. • Component that uses an interface will have the implements for events. • Example: LedsC component provides Leds interface to switch on and off the LEDs.
Split-phase operation • To avoid delay in response long latency function calls are executed in split-phase. • For example: Sending a packet. • The application issues a send call which will schedule the actual sending process to be executed at a later time • Upon transmission the application is notified regarding the successful transmission. • Accomplished using commands, events and tasks. • Long latency functions are called tasks.
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. • Upon occurrence of an event a task that is executing is preempted.
Configuration and Modules • Configuration: • Each application will have a main configuration file that wires components together. • Wiring? Wiring is attaching two components together and specifying the interface using which they will exchange information. Eg. BadgeM.Leds LedsC.Leds; The arrow direction indicates the command calling and event signalling flow. Here BadgeM will call commands on LedsC and LedsC will signal events to BadgeM. • Modules: • Each application might contain implementation specific to it.
TinyOS Application • Consists of a set of components and a scheduler • A configuration file represents an application. • 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. • Two threads of execution • Scheduler thread (lower priority) • Interrupt thread (higher priority) invokes Calls Hardware Interrupts ISR Interrupt Handler
Example Application • Badge • Components • Main • BadgeM • TimerC • GenericComm • Leds • Badge application sends a beacon message out every 1000ms • BadgeM contains our application code. • Main is the entry point to any application. • All other components will be wired to Main directly or indirectly. • Main will initially init all components and then call their start functions. • Interrupts used • Clock • Transmitter
Wiring of components Entry point Main stdControl Interface BadgeM implements stdControl interface BadgeM SendMsg Interface GenericComm provides interface to send a messgas and BadgeM implements the sendDone event handler. Timer Interface TimerC provides the interface for Setting timer interrupt parameters BadgeM implements the event handler for fired event GenericComm TimerC All wirings Below this are predetermined Clock Interface HPLClock provides the interface for Setting timer interrupt parameters TimerC implements the event handler for fired event . . . . . . HPLClock Set Interrupt Specific parameters ISR calls clock fired Event handler Transceiver Hardware Clock
Event and Commands in BadgeM stdcontrol Interface Command Main Event Starts FIFO Function stdcontrol Interface Start Start Tasks BadgeM Fired event handler posts sendBadge task FIFO Scheduler Task sendBadge Schedules The task Send SendDone Fired Start Timer Interface SendMsg Interface Leds Interface TimerM GenericComm setInterval Send SendDone Fired . . . . . . . . . . HPLClock greenOn redOff Fired Send SendDone Clock ISR (TOSH_INTERRUPT) Leds Transmitter
Compilation Phase • NesC compiler first converts the application into a c file (app.c. present in build directory of each application). • All commands and events are replaced with function. • Code for clock interrupt service routine is generated. (handout 1). • C file is compiled into an exe format. • avr-objcopy application converts it into a flash programmable format.
Execution phase • Main calls start of BadgeM. • BadgeM sets time interval for timer interrupt via TimerM and HPLClock components. (handout 1) • Main then enables the interrupts. • Main starts the scheduler. • Steps 6 through 11 are repeated every time timer interrupts. • Timer interrupt calls the event handler in BadgeM via HPLClock and TimerM. (handout 1) • BadgeM fired event handler schedules (posts) a sendBadge task. (handout 3) • Scheduler schedules sendBadge when there are no events to be serviced. • sendBadge then calls the send command part of SendMsg interface provided by GenericComm. (handout 3) • send methods transmits the packet. • When packet transmission is complete, sendDone event is sent to BadgeM component. (handout 3)
Problems • If components are not initialized then they will initialize at an arbitrary state which will lead to unpredictable results. • e.g. if BadgeM’s stdControl is not wired to Main then the clock will start generating interrupts at 1ms intervals.
Debugging • Leds are used for debugging applications. • JTAG can also be used for debugging applications loaded onto the motes.
Handout 1 BlinkM initiates the ISR registration and so BlinkM will be the handler for timer interrupt. BlinkM command result_t StdControl.start() { call Timer.start(TIMER_REPEAT, 250); (Execution Phase: Step 2) …. } TimerM command result_t Timer.start (char type, uint32_t interval) { ….. ….. ….. call Clock.setInterval(mInterval); (Execution Phase: Step 2) ….. ….. ….. } HPLClock async command void Clock.setInterval(uint8_t value) (Execution Phase: Step 2) { outp(value, OCR0); } (ISR defined in HPLClock) (Compilation Phase: Step 2) TOSH_INTERRUPT(SIG_OUTPUT_COMPARE0) { …. …. …. signal Clock.fire(); }
Handout1 cont. BadgeM event result_t Timer.fired()(Execution Phase: Step 6) { post sendBadge(); return SUCCESS; } No Code here in TimerM. But how does fired event in BadgeM get called? (Code is inserted by the NesC compiler based on the wiring) TimerM default event result_t Timer.fired[uint8_t id]() (Execution Phase: Step 6) { return SUCCESS; } HPLClock default async event result_t Clock.fire() { return SUCCESS; } (ISR defined in HPLClock) TOSH_INTERRUPT(SIG_OUTPUT_COMPARE0) { …. …. …. signal Clock.fire(); (Execution Phase: Step 6) }
Handout 2 Configuration file includes Badge; configuration Badge { } implementation { components Main, BadgeM, TimerC, GenericComm as Comm, LedsC as Leds, HPLCC1000M; Main.StdControl -> BadgeM; (step 2) Main.StdControl -> TimerC; BadgeM.Timer -> TimerC.Timer[unique("Timer")]; BadgeM.SendMsg -> Comm.SendMsg[AM_BADGEMSG]; BadgeM.Leds -> Leds; BadgeM.HPLChipcon -> HPLCC1000M; }
Handout 3 BadgeM implementation includes Badge; module BadgeM { provides interface StdControl; uses interface Timer; uses interface SendMsg; uses interface Leds; uses interface HPLCC1000 as HPLChipcon; } implementation { uint16_t cur_seqno = 0; BadgeMsg *badge_msg; TOS_Msg send_msg; bool sendBusy = FALSE; uint8_t counter; uint16_t seqNum = 0; task void sendBadge(); // Called when the application is initialized. command result_t StdControl.init() { badge_msg = (BadgeMsg *)send_msg.data; counter++; return SUCCESS; } // Also called when the application is initialized, but after // all modules have had StdControl.init() invoked. command result_t StdControl.start() { call Timer.start(TIMER_REPEAT, 250); call Leds.greenOn(); return SUCCESS; } // Called if another module wishes to stop this one. This will never // happen in practice, but, we still stop the timer here. command result_t StdControl.stop() { call Timer.stop(); return SUCCESS; }
Handout 3 cont. // Send a radio badge. task void sendBadge() { call Leds.greenOn(); call Leds.redOff(); if (!sendBusy) { badge_msg->sourceaddr = TOS_LOCAL_ADDRESS; badge_msg->seqNo = seqNum++; sendBusy = TRUE; if (!call SendMsg.send(TOS_BCAST_ADDR, sizeof(BadgeMsg), &send_msg)) (Step 9) { sendBusy = FALSE; // Can't send message call Leds.redOn(); return; } else { // Message send completed return; } } else { // Can't send message - still sending previous!? call Leds.redOn(); return; } } // Called when the previous message been sent. event result_t SendMsg.sendDone(TOS_MsgPtr msg, result_t success) (Step 11) { call Leds.greenOff(); sendBusy = FALSE; return SUCCESS; } event result_t Timer.fired() { post sendBadge(); (Step 7) return SUCCESS; } }