TinyOS an operating system for sensor nets

Similar documents
TinyOS an operating system for sensor nets. Embedded Operating Systems

Embedded OS Case Study: TinyOS

% #!" # !" #$ (# ( ' (# (

Programming TinyOS. Lesson 2. Execution Flow. Tasks. commands. Events generated by interrupts preempt tasks Tasks do not preempt tasks

Operating systems for embedded systems. Embedded Operating Systems

Operating systems for embedded systems

Mobile and Ubiquitous Computing Routing Protocols. Niki Trigoni

Programming TinyOS. Lesson 3. Basic Structure. Main.nc

Sensor Network Application Development ZIGBEE CONCEPTS 0

Introduction to Programming Motes

nesc Ø Programming language for TinyOS and applications Ø Support TinyOS components Ø Whole-program analysis at compile time Ø Static language

Programming Sensor Networks

nesc Prof. Chenyang Lu How should network msg be handled? Too much memory for buffering and threads

Group Members: Chetan Fegade Nikhil Mascarenhas. Mentor: Dr. Yann Hang Lee

TinyOS. Lecture Overview. UC Berkeley Family of Motes. Mica2 and Mica2Dot. MTS300CA Sensor Board. Programming Board (MIB510) 1.

Wireless Sensor Networks (WSN)

Sensor Network Application Development ZIGBEE CONCEPTS 2

Politecnico di Milano Advanced Network Technologies Laboratory. Internet of Things. TinyOS Programming and TOSSIM (and Cooja)

Mobile and Ubiquitous Computing TinyOS application example. Niki Trigoni

TinyOS. Jan S. Rellermeyer

Self-Organization in Autonomous Sensor/Actuator Networks [SelfOrg]

TinyOS. Wireless Sensor Networks

Motivation. Introduction to Wireless Sensor Networks. Office Building Fire. EEC173B Lecture:

WSN Programming. Introduction. Olaf Landsiedel

Politecnico di Milano Advanced Network Technologies Laboratory. Internet of Things. TinyOS Programming and TOSSIM

Politecnico di Milano Advanced Network Technologies Laboratory. Internet of Things. TinyOS Programming and TOSSIM (and Cooja)

WSN Programming. Introduction. Olaf Landsiedel. Programming WSNs. ! What do we need to write software for WSNs?! Programming language

Porting TinyOS on to BTnodes

Übersicht. Laufzeitumgebungen Fallstudie TinyOS

Politecnico di Milano Advanced Network Technologies Laboratory. TinyOS

System Architecture Directions for Networked Sensors. Jason Hill et. al. A Presentation by Dhyanesh Narayanan MS, CS (Systems)

Static Analysis of Embedded C

COMP 7860 Embedded Real- Time Systems: Threads

Embedded Systems. 5. Operating Systems. Lothar Thiele. Computer Engineering and Networks Laboratory

SpiNNaker Application Programming Interface (API)

Concurrency, Thread. Dongkun Shin, SKKU

EVENT DRIVEN SENSOR SYSTEMS

Sensors Network Simulators

OCF for resource-constrained environments

Incremental Network Programming for Wireless Sensors. IEEE SECON 2004 Jaein Jeong and David Culler UC Berkeley, EECS

Bluetooth low energy Protocol Stack

Operating Systems (2INC0) 2018/19. Introduction (01) Dr. Tanir Ozcelebi. Courtesy of Prof. Dr. Johan Lukkien. System Architecture and Networking Group

Embedded Systems Programming - PA8001

Short Notes of CS201

Sensors as Software. TinyOS. TinyOS. Dario Rossi Motivation

Four Components of a Computer System

Designing Responsive and Real-Time Systems

CS201 - Introduction to Programming Glossary By

BaseStation Based on GenericComm. Aly El-Osery Electrical Engineering Dept. New Mexico Tech Socorro, NM

Emulation 2. G. Lettieri. 15 Oct. 2014

Developing Reusable Device Drivers for MCU's

WSN PLATFORMS, HARDWARE & SOFTWARE. Murat Demirbas SUNY Buffalo

Chapter 3: Processes. Operating System Concepts 8 th Edition,

Chapter 13: I/O Systems. Operating System Concepts 9 th Edition

Lecture 15: I/O Devices & Drivers

System Architecture Directions for Networked Sensors[1]

Lecture Topics. Announcements. Today: Operating System Overview (Stallings, chapter , ) Next: Processes (Stallings, chapter

Timers 1 / 46. Jiffies. Potent and Evil Magic

Chapter 13: I/O Systems

CS 471 Operating Systems. Yue Cheng. George Mason University Fall 2017

Linux Device Drivers Interrupt Requests

Fundamental concept in computation Interrupt execution of a program to handle an event

Embedded Software TI2726 B. 4. Interrupts. Koen Langendoen. Embedded Software Group

What we will learn. Threaded Systems: Threads. Threads. Threads. Bag of functions & procedures ST OS. AUCs. Threads. AUCs. Processes MT OS MP OS

Advanced use of the C language

AC OB S. Multi-threaded FW framework (OS) for embedded ARM systems Torsten Jaekel, June 2014

Final Exam. 11 May 2018, 120 minutes, 26 questions, 100 points

EL6483: Brief Overview of C Programming Language

Towards a Resilient Operating System for Wireless Sensor Networks

I/O Systems. Amir H. Payberah. Amirkabir University of Technology (Tehran Polytechnic)

Chapter 3: Processes. Operating System Concepts Essentials 2 nd Edition

Operating Systems 2010/2011

CS 160: Interactive Programming

The Big Picture So Far. Chapter 4: Processes

Real-Time Systems Hermann Härtig Real-Time Operating Systems Brief Overview

Processes. Overview. Processes. Process Creation. Process Creation fork() Processes. CPU scheduling. Pål Halvorsen 21/9-2005

The Big Picture So Far. Chapter 4: Processes

Lab Assignment: Interrupt + Lookup Tables + Binary

Roadmap. Tevfik Ko!ar. CSC Operating Systems Fall Lecture - III Processes. Louisiana State University. Processes. September 1 st, 2009

This application note describes the specification of the JPEG codec unit (in the following, JCU) driver of SH7268/SH7269.

Embedded Systems. 6. Real-Time Operating Systems

Lecture notes Lectures 1 through 5 (up through lecture 5 slide 63) Book Chapters 1-4

Wireless Sensor Networks. Introduction to the Laboratory

Lecture 5: Synchronization w/locks

Contiki a Lightweight and Flexible Operating System for Tiny Networked Sensors

Concurrent Programming

Newbie s Guide to AVR Interrupts

Incremental Network Programming for Wireless Sensors

Module 11: I/O Systems

CS 333 Introduction to Operating Systems. Class 3 Threads & Concurrency. Jonathan Walpole Computer Science Portland State University

The Emergence of Networking Abstractions and Techniques in TinyOS

System Call. Preview. System Call. System Call. System Call 9/7/2018

A Fast Review of C Essentials Part I

! The Process Control Block (PCB) " is included in the context,

Chapter 4: Threads. Operating System Concepts 9 th Edit9on

Chapter 3 Processes. Process Concept. Process Concept. Process Concept (Cont.) Process Concept (Cont.) Process Concept (Cont.)

Interrupts and Time. Real-Time Systems, Lecture 5. Martina Maggio 28 January Lund University, Department of Automatic Control

Page 1. Last Time. Today. Embedded Compilers. Compiler Requirements. What We Get. What We Want

Diagram of Process State Process Control Block (PCB)

Chapter 3: Processes. Operating System Concepts 8th Edition

Transcription:

TinyOS an operating system for sensor nets Embedded operating systems How do they differ from desktop operating systems? Event-based programming model How is concurrency handled? How are resource conflicts managed? Programming in TinyOS What new language constructs are useful? CSE 466 Wireless Sensor Networks 1

Embedded Operating Systems Features of all operating systems Abstraction of system resources Managing of system resources Concurrency model Launch applications Desktop operating systems General-purpose all features may be needed Large-scale resources memory, disk, file systems Embedded operating systems Application-specific just use features you need, save memory Small-scale resources sensors, communication ports CSE 466 Wireless Sensor Networks 2

System Resources on Motes Timers Sensors Serial port Radio communications Memory Power management CSE 466 Wireless Sensor Networks 3

Abstraction of System Resources Create virtual components E.g., multiple timers from one timer Allow them to be shared by multiple threads of execution E.g., two applications that want to share radio communication Device drivers provide interface for resource Encapsulate frequently used functions Save device state (if any) Manage interrupt handling CSE 466 Wireless Sensor Networks 4

Very simple device driver Turn LED on/off Parameters: API: port pin on(port_pin) - specifies the port pin (e.g., port D pin 3) off(port_pin) Interactions: only if other devices want to use the same port CSE 466 Wireless Sensor Networks 5

Simple device driver Turning an LED on and off at a fixed rate Parameters: API: port pin rate at which to blink LED on(port_pin, rate) specifies the port pin (e.g., port D pin 3) specifies the rate to use in setting up the timer (what scale?) off(port_pin) Internal state and functions: keep track of state (on or off for a particular pin) of each pin interrupt service routine to handle timer interrupt CSE 466 Wireless Sensor Networks 6

Interesting interactions What if other devices also need to use timer (e.g., PWM device)? timer interrupts now need to be handled differently depending on which device s alarm is going off Benefits of special-purpose output compare peripheral output compare pins used exclusively for one device output compare has a separate interrupt handling routine What if we don t have output compare capability or run out of output compare units? CSE 466 Wireless Sensor Networks 7

Sharing timers Create a new device driver for the timer unit Allow other devices to ask for timer services Manage timer independently so that it can service multiple requests Parameters: Time to wait, address to call when timer reaches that value API: set_timer(time_to_wait, call_back_address) Set call_back_address to correspond to time+time_to_wait Compute next alarm to sound and set timer Update in interrupt service routine for next alarm Internal state and functions: How many alarms can the driver keep track of? How are they organized? FIFO? priority queue? CSE 466 Wireless Sensor Networks 8

Concurrency Multiple programs interleaved as if parallel Each program requests access to devices/services e.g., timers, serial ports, etc. Exclusive or concurrent access to devices allow only one program at a time to access a device (e.g., serial port) arbitrate multiple accesses (e.g., timer) State and arbitration needed keep track of state of devices and concurrent programs using resource arbitrate their accesses (order, fairness, exclusivity) monitors/locks (supported by primitive operations in ISA - test-and-set) Interrupts disabling may affect timing of programs keeping enabled may cause unwanted interactions CSE 466 Wireless Sensor Networks 9

Handling concurrency Traditional operating system multiple threads or processes file system virtual memory and paging input/output (buffering between CPU, memory, and I/O devices) interrupt handling (mostly with I/O devices) resource allocation and arbitration command interface (execution of programs) Embedded operating system lightweight threads input/output interrupt handling real-time guarantees CSE 466 Wireless Sensor Networks 10

Embedded operating systems Lightweight threads basic locks fast context-switches Input/output API for talking to devices buffering Interrupt handling (with I/O devices and UI) translate interrupts into events to be handled by user code trigger new tasks to run (reactive) Real-time issues guarantee task is called at a certain rate guarantee an interrupt will be handled within a certain time priority or deadline driven scheduling of tasks CSE 466 Wireless Sensor Networks 11

Examples ios (what do we mean by embedded system now that an iphone is more powerful than mainframes used to be?) Wind River Systems VxWorks one of the most popular embedded OS kernels highly portable to an even wider variety of processors (tiny to huge) modularized even further than the ones above (basic system under 50K) FreeRTOS TinyOS Contiki DewDrop MementOS embedded operating systems Typically reside in Flash Usually care about power Usually interact with sensors / actuators CSE 466 Wireless Sensor Networks 12

TinyOS Open-source development environment Simple (and tiny) operating system TinyOS Programming language and model nesc Set of services Principal elements Scheduler/event model of concurrency Software components for efficient modularity Software encapsulation for resources of sensor networks CSE 466 Wireless Sensor Networks 13

TinyOS History www.tinyos.net See Philip Levis, Experiences from a Decade of TinyOS Development. In Proceedings of OSDI 2012 Motivation create Unix analog (circa 1969) Uniform programming language: C Uniform device abstractions Open source: grow with different developers/needs Support creation of many tools Created at UC Berkeley 1st version written by Jason Hill in 2000 Large part of development moved to Intel Research Berkeley in 2001 www.intel-research.net/berkeley Smart Dust, Inc. founded in 2002 Large deployments Great Duck Island (GDI) http://www.greatduckisland.net/ Center for Embedded Network Sensing (CENS) http://www.cens.ucla.edu/ CSE 466 Wireless Sensor Networks 14

TinyOS Design Goals Support networked embedded systems Asleep most of the time, but remain vigilant to stimuli Bursts of events and operations Support UCB mote hardware Power, sensing, computation, communication Easy to port to evolving platforms Support technological advances Keep scaling down Smaller, cheaper, lower power CSE 466 Wireless Sensor Networks 15

TinyOS Design Options Can t use existing RTOS s Microkernel architecture VxWorks, PocketPC, PalmOS Execution similar to desktop systems PDA s, cell phones, embedded PC s More than a order of magnitude too heavyweight and slow Energy hogs CSE 466 Wireless Sensor Networks 16

TinyOS Design Conclusion Similar to building networking interfaces Data driven execution Manage large # of concurrent data flows Manage large # of outstanding events Add: managing application data processing Conclusion: need a multi-threading engine Extremely efficient Extremely simple CSE 466 Wireless Sensor Networks 17

TinyOS Kernel Design Two-level scheduling structure Events Small amount of processing to be done in a timely manner E.g. timer, ADC interrupts Can interrupt longer running tasks Tasks Not time critical Larger amount of processing E.g. computing the average of a set of readings in an array Run to completion with respect to other tasks Only need a single stack CSE 466 Wireless Sensor Networks 18

TinyOS Concurrency Model Tasks FIFO queue Interrupts Two-level of concurrency: tasks and interrupts CSE 466 Wireless Sensor Networks 19

TinyOS Concurrency Model (cont d) Tasks FIFO queue Placed on queue by: Application Other tasks Self-queued Interrupt service routine Run-to-completion No other tasks can run until completed Interruptable, but any new tasks go to end of queue Interrupts Stop running task Post new tasks to queue CSE 466 Wireless Sensor Networks 20

TinyOS Concurrency Model (cont d) Two-levels of concurrency Possible conflicts between interrupts and tasks Atomic statements atomic Asynchronous service routines (as opposed to synchronous tasks) async result_t interface_name.cmd_or_event_name Race conditions detected by compiler Can generated false positives norace keyword to stop warnings, but be careful CSE 466 Wireless Sensor Networks 21

TinyOS Programming Model Separation of construction and composition Programs are built out of components Specification of component behavior in terms of a set of interfaces Components specify interfaces they use and provide Components are statically wired to each other via their interfaces This increases runtime efficiency by enabling compiler optimizations Finite-state-machine-like specifications Thread of control passes into a component through its interfaces to another component CSE 466 Wireless Sensor Networks 22

TinyOS Basic Constructs Commands Events Cause action to be initiated Notify action has occurred Generated by external interrupts Call back to provide results from previous command Tasks Background computation Not time critical Application event command Component event command Hardware Interface task task task CSE 466 Wireless Sensor Networks 23

Flow of Events and Commands Fountain of events leading to commands and tasks (which in turn issue may issue other commands that may cause other events, ) task to get out of async tasks events commands interrupts Software Hardware CSE 466 Wireless Sensor Networks 24

TinyOS File Types Interfaces (xxx.nc) Specifies functionality to outside world what commands can be called what events need handling Module (xxxm.nc) Code implementation Code for Interface functions Configuration (xxxc.nc) Wiring of components When top level app, drop C from filename xxx.nc interfacea.nc comp1c.nc (wires) interfaceb.nc main.nc interfacem.nc interfacem.nc app.nc (wires) interfacea.nc interfacea.nc comp2m.nc (code) interfaceb.nc comp3m.nc (code) CSE 466 Wireless Sensor Networks 25

The nesc Language nesc: networks of embedded sensors C Compiler for applications that run on UCB motes Built on top of avr-gcc nesc uses the filename extension ".nc Static Language No dynamic memory (no malloc) No function pointers No heap Influenced by Java Includes task FIFO scheduler Designed to foster code reuse Modules per application range from 8 to 67, mean of 24*** Average lines of code in a module only 120*** Advantages of eliminating monolithic programs Code can be reused more easily Number of errors should decrease TinyOS kernel (C) TinyOS libs (nesc) Application (nesc) nesc Compiler Application & TinyOS (C) C Compiler Application Executable ***The NesC Language: A Holistic Approach to Network of Embedded Systems. David Gay, Phil Levis, Rob von Behren, Matt Welsh, Eric Brewer, and David Culler. Proceedings of Programming Language Design and Implementation (PLDI) 2003, June 2003. CSE 466 Wireless Sensor Networks 26

Commands Commands are issued with call call Timer.start(TIMER_REPEAT, 1000); Cause action to be initiated Bounded amount of work Does not block Act similarly to a function call Execution of a command is immediate CSE 466 Wireless Sensor Networks 27

Events Events are called with signal signal ByteComm.txByteReady(SUCCESS); Used to notify a component an action has occurred Lowest-level events triggered by hardware interrupts Bounded amount of work Do not block Act similarly to a function call Execution of a event is immediate CSE 466 Wireless Sensor Networks 28

Tasks Tasks are queued with post post radioencodethread(); Used for longer running operations Pre-empted by events Initiated by interrupts Tasks run to completion Not pre-empted by other tasks Example tasks High level calculate aggregate of sensor readings Low level encode radio packet for transmission, calculate CRC CSE 466 Wireless Sensor Networks 29

Components Two types of components in nesc: Module Configuration A component provides and uses Interfaces CSE 466 Wireless Sensor Networks 30

Module Provides application code Contains C-like code Must implement the provides interfaces Implement the commands it provides Make sure to actually signal Must implement the uses interfaces Implement the events that need to be handled call commands as needed CSE 466 Wireless Sensor Networks 31

Configuration A configuration is a component that "wires" other components together. Configurations are used to assemble other components together Connects interfaces used by components to interfaces provided by others. CSE 466 Wireless Sensor Networks 32

Interfaces Bi-directional multi-function interaction channel between two components Allows a single interface to represent a complex event E.g., a registration of some event, followed by a callback Critical for non-blocking operation provides interfaces Represent the functionality that the component provides to its user Service commands implemented command functions Issue events signal to user for passing data or signalling done uses interfaces Represent the functionality that the component needs from a provider Service events implement event handling Issue commands ask provider to do something CSE 466 Wireless Sensor Networks 33

Application Consists of one or more components, wired together to form a runnable program Single top-level configuration that specifies the set of components in the application and how they connect to one another Connection (wire) to main component to start execution Must implement init, start, and stop commands CSE 466 Wireless Sensor Networks 34

Components/Wiring Directed wire (an arrow: -> ) connects components Only 2 components at a time point-to-point Connection is across compatible interfaces A <- B is equivalent to B -> A [component using interface] -> [component providing interface] [interface] -> [implementation] = can be used to wire a component directly to the top-level object s interfaces Typically used in a configuration file to use a sub-component directly Unused system components excluded from compilation CSE 466 Wireless Sensor Networks 35

Blink Application What the executable does: 1. Main initializes and starts the application 2. BlinkM initializes ClockC s rate at 1Hz 3. ClockC continuously signals BlinkM at a rate of 1 Hz 4. BlinkM commands LedsC red led to toggle each time it receives a signal from ClockC tos/system/main.nc tos/interfaces/stdcontrol.nc tos/interfaces/stdcontrol.nc BlinkM.nc Note: The StdControl interface is similar to state machines (init, start, stop); used extensively throughout TinyOS apps & libs tos/interfaces/timer.nc tos/interfaces/leds.nc tos/interfaces/singletimer.nc tos/interfaces/timer.nc tos/interfaces/leds.nc tos/system/timerc.nc tos/system/ledsc.nc CSE 466 Wireless Sensor Networks 36

Blink.nc configuration Blink implementation components Main, BlinkM, SingleTimer, LedsC; Main.StdControl -> SingleTimer.StdControl; Main.StdControl -> BlinkM.StdControl; BlinkM.Timer -> SingleTimer.Timer; BlinkM.Leds -> LedsC.Leds; CSE 466 Wireless Sensor Networks 37

StdControl.nc interface StdControl command result_t init(); command result_t start(); command result_t stop(); CSE 466 Wireless Sensor Networks 38

BlinkM.nc BlinkM.nc module BlinkM provides interface StdControl; uses interface Timer; interface Leds; implementation command result_t StdControl.init() call Leds.init(); return SUCCESS; command result_t StdControl.start() return call Timer.start(TIMER_REPEAT, 1000); command result_t StdControl.stop() return call Timer.stop(); event result_t Timer.fired() call Leds.redToggle(); return SUCCESS; CSE 466 Wireless Sensor Networks 39

SingleTimer.nc (should have been SingleTimerC.nc) Parameterized interfaces allows a component to provide multiple instances of an interface that are parameterized by a value Timer implements one level of indirection to actual timer functions Timer module supports many interfaces This module simply creates one unique timer interface and wires it up By wiring Timer to a separate instance of the Timer interface provided by TimerC, each component can effectively get its own "private" timer Uses a compile-time constant function unique() to ensure index is unique configuration SingleTimer provides interface Timer; provides interface StdControl; implementation components TimerC; Timer = TimerC.Timer[unique("Timer")]; StdControl = TimerC.StdControl; CSE 466 Wireless Sensor Networks 40

Blink.nc without SingleTimer configuration Blink implementation components Main, BlinkM, TimerC, LedsC; Main.StdControl -> TimerC.StdControl; Main.StdControl -> BlinkM.StdControl; BlinkM.Timer -> TimerC.Timer[unique("Timer")]; BlinkM.Leds -> LedsC.Leds; CSE 466 Wireless Sensor Networks 41

Timer.nc interface Timer command result_t start(char type, uint32_t interval); command result_t stop(); event result_t fired(); CSE 466 Wireless Sensor Networks 42

TimerC.nc Implementation of multiple timer interfaces to a single shared timer Each interface is named Each interface connects to one other module CSE 466 Wireless Sensor Networks 43

Leds.nc (partial) interface Leds /** * Initialize the LEDs; among other things, initialization turns them all off. */ async command result_t init(); /** * Turn the red LED on. */ async command result_t redon(); /** * Turn the red LED off. */ async command result_t redoff(); /** * Toggle the red LED. If it was on, turn it off. If it was off, * turn it on. */ async command result_t redtoggle();... CSE 466 Wireless Sensor Networks 44

LedsC.nc (partial) module LedsC provides interface Leds; implementation uint8_t ledson; enum RED_BIT = 1, GREEN_BIT = 2, YELLOW_BIT = 4 ; async command result_t Leds.init() atomic ledson = 0; dbg(dbg_boot, "LEDS: initialized.\n"); TOSH_MAKE_RED_LED_OUTPUT(); TOSH_MAKE_YELLOW_LED_OUTPUT(); TOSH_MAKE_GREEN_LED_OUTPUT(); TOSH_SET_RED_LED_PIN(); TOSH_SET_YELLOW_LED_PIN(); TOSH_SET_GREEN_LED_PIN(); return SUCCESS; async command result_t Leds.redOn() dbg(dbg_led, "LEDS: Red on.\n"); atomic TOSH_CLR_RED_LED_PIN(); ledson = RED_BIT; return SUCCESS; async command result_t Leds.redOff() dbg(dbg_led, "LEDS: Red off.\n"); atomic TOSH_SET_RED_LED_PIN(); ledson &= ~RED_BIT; return SUCCESS; async command result_t Leds.redToggle() result_t rval; atomic if (ledson & RED_BIT) rval = call Leds.redOff(); else rval = call Leds.redOn(); return rval;... CSE 466 Wireless Sensor Networks 45

static inline void TOSH_SET_PIN_DIRECTIONS(void ) static inline void HPLPowerManagementM$doAdjustment(void) Blink Compiled TOSH_MAKE_RED_LED_OUTPUT(); inline static result_t TimerM$Clock$setRate(char arg_0xa33adc0, char uint8_t foo; arg_0xa33af00) TOSH_MAKE_YELLOW_LED_OUTPUT(); uint8_t mcu; unsigned char result; TOSH_MAKE_GREEN_LED_OUTPUT(); foo = HPLPowerManagementM$getPowerLevel(); result = HPLClock$Clock$setRate(arg_0xa33adc0, arg_0xa33af00); TOSH_MAKE_CC_CHP_OUT_INPUT(); mcu = * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char return result; *)(0x35 + 0x20); inline static result_t BlinkM$Leds$redToggle(void) TOSH_MAKE_PW7_OUTPUT(); mcu &= 0xe3; unsigned char result; TOSH_MAKE_PW6_OUTPUT(); static inline result_t TimerM$StdControl$init(void) if (foo == HPLPowerManagementM$EXT_STANDBY foo == result = LedsC$Leds$redToggle(); TOSH_MAKE_PW5_OUTPUT(); HPLPowerManagementM$POWER_SAVE) return result; TOSH_MAKE_PW4_OUTPUT(); TimerM$mState = 0; mcu = HPLPowerManagementM$IDLE; TOSH_MAKE_PW3_OUTPUT(); TimerM$setIntervalFlag = 0; while ((* (volatile unsigned char *)(unsigned int )& * (volatile static unsigned inline result_t BlinkM$Timer$fired(void) TOSH_MAKE_PW2_OUTPUT(); char *)(0x30 + 0x20) & 0x7)!= 0) TimerM$queue_head = TimerM$queue_tail = -1; TOSH_MAKE_PW1_OUTPUT(); asm volatile ("nop"); TimerM$queue_size = 0; BlinkM$Leds$redToggle(); TOSH_MAKE_PW0_OUTPUT(); TimerM$mScale = 3; return SUCCESS; int main(void); TOSH_MAKE_CC_PALE_OUTPUT(); mcu &= 0xe3; TimerM$mInterval = TimerM$maxTimerInterval; static result_t PotM$HPLPot$finalise(void); TOSH_MAKE_CC_PDATA_OUTPUT(); return TimerM$Clock$setRate(TimerM$mInterval, TimerM$mScale); static inline result_t TimerM$Timer$default$fired(uint8_t id) static result_t PotM$HPLPot$decrease(void); TOSH_MAKE_CC_PCLK_OUTPUT(); mcu = foo; static result_t PotM$HPLPot$increase(void); TOSH_MAKE_MISO_INPUT(); * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char inline static result_t RealMain$StdControl$init(void) static inline void TOSH_SET_GREEN_LED_PIN(void) *)(0x35 + 0x20) = mcu; return SUCCESS; uint8_t PotM$potSetting; TOSH_MAKE_SPI_OC1C_INPUT(); unsigned char result; * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char static inline void PotM$setPot(uint8_t value); TOSH_MAKE_SERIAL_ID_INPUT(); #define dbg(mode, format,...) ((void)0) result = TimerM$StdControl$init(); *)(0x35 + 0x20) = 1 << 5; inline static result_t TimerM$Timer$fired(uint8_t arg_0xa31d660) * (volatile unsigned char *)(unsigned int )& * (volatile unsigned static inline result_t PotM$Pot$init(uint8_t initialsetting); TOSH_CLR_SERIAL_ID_PIN(); char *)(0x1B + 0x20) #define dbg_clear(mode, format,...) ((void)0) = 1 << 1; result = rcombine(result, BlinkM$StdControl$init()); unsigned char result; static inline result_t HPLPotC$Pot$decrease(void); TOSH_MAKE_FLASH_SELECT_OUTPUT(); #define dbg_active(mode) 0 return result; static inline void nesc_enable_interrupt(void) switch (arg_0xa31d660) static inline result_t HPLPotC$Pot$increase(void); TOSH_MAKE_FLASH_OUT_OUTPUT(); typedef signed char int8_t; static inline void TOSH_SET_YELLOW_LED_PIN(void) case 0: typedef long long TOS_dbg_mode; static inline result_t HPLPotC$Pot$finalise(void); TOSH_MAKE_FLASH_CLK_OUTPUT(); typedef unsigned char uint8_t; inline static uint8_t TimerM$PowerManagement$adjustPower(void) asm volatile ("sei"); result = BlinkM$Timer$fired(); enum nesc_unnamed4251 static inline result_t HPLInit$init(void); TOSH_SET_FLASH_SELECT_PIN(); typedef int int16_t; * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char *)(0x1B + 0x20) unsigned char result; static inline void TOSH_wait(void) break; DBG_ALL = ~0ULL, static result_t BlinkM$Leds$init(void); = 1 << 0; TOSH_SET_RED_LED_PIN(); typedef unsigned int uint16_t; result = HPLPowerManagementM$PowerManagement$adjustPower(); default: DBG_BOOT = 1ULL << 0, static result_t BlinkM$Leds$redToggle(void); TOSH_SET_YELLOW_LED_PIN(); typedef long int32_t; return result; asm volatile ("nop"); result = TimerM$Timer$default$fired(arg_0xa31d660); DBG_CLOCK = 1ULL << 1, static result_t BlinkM$Timer$start(char arg_0xa2fd578, static uint32_t inline arg_0xa2fd6d0); void TOSH_SET_RED_LED_PIN(void) TOSH_SET_GREEN_LED_PIN(); typedef unsigned long uint32_t; asm volatile ("nop"); DBG_TASK = 1ULL << 2, static inline result_t BlinkM$StdControl$init(void); typedef long long int64_t; static inline void HPLClock$Clock$setInterval(uint8_t value) static inline void TOSH_sleep(void) return result; DBG_SCHED = 1ULL << 3, static inline result_t BlinkM$StdControl$start(void); * (volatile unsigned char *)(unsigned int )& * (volatile unsigned static char inline *)(0x1B result_t + 0x20) HPLInit$init(void) typedef unsigned long long uint64_t; = 1 << 2; DBG_SENSOR = 1ULL << 4, static inline result_t BlinkM$Timer$fired(void); typedef int16_t intptr_t; * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char * (volatile unsigned char *)(unsigned int )& * (volatile unsigned static char inline uint8_t TimerM$dequeue(void) DBG_LED = 1ULL << 5, static uint8_t TimerM$PowerManagement$adjustPower(void); TOSH_SET_PIN_DIRECTIONS(); *)(0x31 + 0x20) = value; *)(0x35 + 0x20) = 1 << 5; typedef uint16_t uintptr_t; static inline void TOSH_SET_FLASH_SELECT_PIN(void) DBG_CRYPTO = 1ULL << 6, static void TimerM$Clock$setInterval(uint8_t arg_0xa33b8c0); return SUCCESS; asm volatile ("sleep"); typedef unsigned int size_t; if (TimerM$queue_size == 0) DBG_ROUTE = 1ULL << 7, static uint8_t TimerM$Clock$readCounter(void); inline static void TimerM$Clock$setInterval(uint8_t arg_0xa33b8c0) inline void nesc_atomic_end( nesc_atomic_t oldsreg) typedef int wchar_t; return NUM_TIMERS; * (volatile unsigned char *)(unsigned int )& * (volatile unsigned DBG_AM = 1ULL << 8, static result_t TimerM$Clock$setRate(char arg_0xa33adc0, char arg_0xa33af00); inline char static *)(0x1B result_t + 0x20) RealMain$hardwareInit(void) HPLClock$Clock$setInterval(arg_0xa33b8c0); typedef struct nesc_unnamed4242 = 1 << 3; DBG_CRC = 1ULL << 9, static result_t TimerM$Timer$fired(uint8_t arg_0xa31d660); unsigned char result; * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char int quot; *)(0x3F + 0x20) = oldsreg; if (TimerM$queue_head == NUM_TIMERS - 1) DBG_PACKET = 1ULL << 10, uint32_t TimerM$mState; result = HPLInit$init(); static inline uint8_t HPLClock$Clock$readCounter(void) int rem; static inline void TOSH_MAKE_FLASH_CLK_OUTPUT(void) TimerM$queue_head = -1; DBG_ENCODE = 1ULL << 11, uint8_t TimerM$setIntervalFlag; return result; div_t; inline nesc_atomic_t nesc_atomic_start(void ) DBG_RADIO = 1ULL << 12, uint8_t TimerM$mScale; return * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char typedef struct nesc_unnamed4243 * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char *)(0x11 + 0x20) DBG_LOG = 1ULL << 13, uint8_t TimerM$mInterval; = 1 << 5; static inline result_t HPLPotC$Pot$finalise(void) *)(0x32 + 0x20); TimerM$queue_head++; long quot; DBG_ADC = 1ULL << 14, int8_t TimerM$queue_head; nesc_atomic_t result = * (volatile unsigned char *)(unsigned int )& TimerM$queue_size--; * (volatile unsigned char *)(0x3F + 0x20); long rem; return TimerM$queue[(uint8_t )TimerM$queue_head]; DBG_I2C = 1ULL << 15, int8_t TimerM$queue_tail; static inline void TOSH_MAKE_FLASH_OUT_OUTPUT(void) return SUCCESS; inline static uint8_t TimerM$Clock$readCounter(void) asm volatile ("cli"); ldiv_t; DBG_UART = 1ULL << 16, uint8_t TimerM$queue_size; unsigned char result; return result; typedef int (* compar_fn_t)(const void *, const void *); static inline void TimerM$signalOneTimer(void) DBG_PROG = 1ULL << 17, uint8_t TimerM$queue[NUM_TIMERS]; * (volatile unsigned char *)(unsigned int )& * (volatile unsigned inline char static *)(0x11 result_t + 0x20) PotM$HPLPot$finalise(void) result = HPLClock$Clock$readCounter(); typedef int ptrdiff_t; = 1 << 3; DBG_SOUNDER = 1ULL << 18, struct TimerM$timer_s unsigned char result; return result; static inline bool TOSH_run_next_task(void) typedef unsigned char bool; uint8_t itimer = TimerM$dequeue(); DBG_TIME = 1ULL << 19, uint8_t type; result = HPLPotC$Pot$finalise(); enum nesc_unnamed4244 if (itimer < NUM_TIMERS) static inline void TOSH_MAKE_FLASH_SELECT_OUTPUT(void) DBG_SIM = 1ULL << 21, int32_t ticks; return result; static inline result_t TimerM$Timer$start(uint8_t id, char type, uint32_t FALSE = 0, interval) nesc_atomic_t finterruptflags; TimerM$Timer$fired(itimer); DBG_QUEUE = 1ULL << 22, int32_t ticksleft; TRUE = 1 uint8_t old_full; * (volatile unsigned char *)(unsigned int )& * (volatile unsigned DBG_SIMRADIO = 1ULL << 23, TimerM$mTimerList[NUM_TIMERS]; static char inline *)(0x1A result_t + 0x20) HPLPotC$Pot$increase(void) ; = 1 << 3; uint8_t diff; void (*func)(void ); DBG_HARD = 1ULL << 24, enum TimerM$ nesc_unnamed4257 enum nesc_unnamed4245 if (id >= NUM_TIMERS) if (TOSH_sched_full == TOSH_sched_free) static inline void TimerM$enqueue(uint8_t value) DBG_MEM = 1ULL << 25, TimerM$maxTimerInterval = 230 return SUCCESS; FAIL = 0, static inline void TOSH_CLR_SERIAL_ID_PIN(void) return FAIL; return 0; DBG_USR1 = 1ULL << 27, ; SUCCESS = 1 else if (TimerM$queue_tail == NUM_TIMERS - 1) DBG_USR2 = 1ULL << 28, static inline result_t TimerM$StdControl$init(void); inline static result_t PotM$HPLPot$increase(void) ; * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char *)(0x1B + 0x20) if (type > 1) finterruptflags = nesc_atomic_start(); TimerM$queue_tail = -1; DBG_USR3 = 1ULL << 29, static inline result_t TimerM$StdControl$start(void); &= ~(1 << 4); unsigned char result; static inline uint8_t rcombine(uint8_t r1, uint8_t r2); return FAIL; old_full = TOSH_sched_full; DBG_TEMP = 1ULL << 30, static inline result_t TimerM$Timer$start(uint8_t id, char type, result = HPLPotC$Pot$increase(); typedef uint8_t result_t; TOSH_sched_full++; TimerM$queue_tail++; DBG_ERROR = 1ULL << 31, uint32_t interval); static inline void TOSH_MAKE_SERIAL_ID_INPUT(void) return result; static inline result_t rcombine(result_t r1, result_t r2); TimerM$mTimerList[id].ticks = interval; TOSH_sched_full &= TOSH_TASK_BITMASK; TimerM$queue_size++; DBG_NONE = 0, static void TimerM$adjustInterval(void); enum nesc_unnamed4246 TimerM$mTimerList[id].type = type; func = TOSH_queue[(int )old_full].tp; TimerM$queue[(uint8_t )TimerM$queue_tail] = value; DBG_DEFAULT = DBG_ALL static inline result_t TimerM$Timer$default$fired(uint8_t * (volatile id); unsigned char *)(unsigned int )& * (volatile unsigned static char inline *)(0x1A result_t + 0x20) HPLPotC$Pot$decrease(void) NULL = 0x0 &= ~(1 << 4); nesc_atomic_t nesc_atomic = nesc_atomic_start(); TOSH_queue[(int )old_full].tp = 0; ; static inline void TimerM$enqueue(uint8_t value); ; nesc_atomic_end(finterruptflags); static inline void TimerM$HandleFire(void) typedef struct nesc_unnamed4252 static inline uint8_t TimerM$dequeue(void); return SUCCESS; typedef void attribute(( progmem )) prog_void; static inline void TOSH_MAKE_SPI_OC1C_INPUT(void) diff = TimerM$Clock$readCounter(); func(); void (*tp)(void); static inline void TimerM$signalOneTimer(void); typedef char attribute(( progmem )) prog_char; interval += diff; return 1; uint8_t i; TOSH_sched_entry_T; static inline void TimerM$HandleFire(void); inline static result_t PotM$HPLPot$decrease(void) typedef unsigned char attribute(( progmem )) prog_uchar; * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char *)(0x17 + 0x20) TimerM$mTimerList[id].ticksLeft = interval; TimerM$setIntervalFlag = 1; enum nesc_unnamed4253 static inline result_t TimerM$Clock$fire(void); &= ~(1 << 7); unsigned char result; typedef int attribute(( progmem )) prog_int; TimerM$mState = 0x1 << id; if (TimerM$mState) TOSH_MAX_TASKS = 8, static result_t HPLClock$Clock$fire(void); result = HPLPotC$Pot$decrease(); typedef long attribute(( progmem )) prog_long; if (interval < TimerM$mInterval) static inline void TOSH_run_task(void) for (i = 0; i < NUM_TIMERS; i++) TOSH_TASK_BITMASK = TOSH_MAX_TASKS - 1 uint8_t HPLClock$set_flag; static inline void TOSH_MAKE_MISO_INPUT(void) return result; typedef long long attribute(( progmem )) prog_long_long; TimerM$mInterval = interval; if (TimerM$mState & (0x1 << i)) ; uint8_t HPLClock$mscale; enum nesc_unnamed4247 TimerM$Clock$setInterval(TimerM$mInterval); while (TOSH_run_next_task()) ; TimerM$mTimerList[i].ticksLeft -= TimerM$mInterval + 1; TOSH_sched_entry_T TOSH_queue[TOSH_MAX_TASKS]; uint8_t HPLClock$nextScale; * (volatile unsigned char *)(unsigned int )& * (volatile unsigned static char inline *)(0x17 void + PotM$setPot(uint8_t 0x20) value) TOSH_period16 = 0x00, TimerM$setIntervalFlag = 0; TOSH_sleep(); if (TimerM$mTimerList[i].ticksLeft <= 2) volatile uint8_t TOSH_sched_full; &= ~(1 << 3); uint8_t HPLClock$minterval; TOSH_period32 = 0x01, TimerM$PowerManagement$adjustPower(); TOSH_wait(); if (TimerM$mTimerList[i].type == TIMER_REPEAT) volatile uint8_t TOSH_sched_free; static inline void HPLClock$Clock$setInterval(uint8_t value); uint8_t i; TOSH_period64 = 0x02, TimerM$mTimerList[i].ticksLeft += TimerM$mTimerList[i].ticks; static inline void TOSH_wait(void ); static inline void TOSH_MAKE_CC_PCLK_OUTPUT(void) static inline uint8_t HPLClock$Clock$readCounter(void); for (i = 0; i < 151; i++) TOSH_period128 = 0x03, static void TimerM$adjustInterval(void) static inline void TOSH_sleep(void ); static inline result_t HPLClock$Clock$setRate(char interval, char scale); PotM$HPLPot$decrease(); TOSH_period256 = 0x04, nesc_atomic_end( nesc_atomic); else static inline void TOSH_sched_init(void ); * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char *)(0x11 + 0x20) void attribute((interrupt)) vector_15(void); for (i = 0; i < value; i++) TOSH_period512 = 0x05, = 1 << 6; return SUCCESS; uint8_t i; bool TOS_post(void (*tp)(void)); bool HPLPowerManagementM$disabled = TRUE; PotM$HPLPot$increase(); TOSH_period1024 = 0x06, uint8_t val = TimerM$maxTimerInterval; TimerM$mState &= ~(0x1 << i); static inline bool TOSH_run_next_task(void); enum HPLPowerManagementM$ nesc_unnamed4258 PotM$HPLPot$finalise(); TOSH_period2048 = 0x07 static inline void TOSH_MAKE_CC_PDATA_OUTPUT(void) inline static result_t BlinkM$Timer$start(char arg_0xa2fd578, uint32_t if (TimerM$mState) static inline void TOSH_run_task(void); HPLPowerManagementM$IDLE = 0, PotM$potSetting = value; arg_0xa2fd6d0) for (i = 0; i < NUM_TIMERS; i++) ; TimerM$enqueue(i); enum nesc_unnamed4254 HPLPowerManagementM$ADC_NR = 1 << 3, unsigned char result; if (TimerM$mState & (0x1 << i) && TimerM$mTimerList[i].ticksLeft < static inline void TOSH_wait(void); * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char *)(0x11 + 0x20) TOS_post(TimerM$signalOneTimer); TIMER_REPEAT = 0, HPLPowerManagementM$POWER_DOWN = 1 << 4, = 1 << 7; static inline result_t PotM$Pot$init(uint8_t initialsetting) result = TimerM$Timer$start(0, arg_0xa2fd578, arg_0xa2fd6d0); val) static inline void TOSH_sleep(void); TIMER_ONE_SHOT = 1, HPLPowerManagementM$POWER_SAVE = (1 << 3) + (1 << 4), return result; val = TimerM$mTimerList[i].ticksLeft; typedef uint8_t nesc_atomic_t; NUM_TIMERS = 1 HPLPowerManagementM$STANDBY = (1 << 2) + (1 << 4), static inline void TOSH_MAKE_CC_PALE_OUTPUT(void) PotM$setPot(initialSetting); inline nesc_atomic_t nesc_atomic_start(void ); ; HPLPowerManagementM$EXT_STANDBY = (1 << 3) + (1 << 4) + (1 << 2) return SUCCESS; static inline result_t BlinkM$StdControl$start(void) inline void nesc_atomic_end( nesc_atomic_t oldsreg); enum nesc_unnamed4255 ; * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char *)(0x11 + 0x20) nesc_atomic_t nesc_atomic = nesc_atomic_start(); static inline void nesc_enable_interrupt(void); TimerM$adjustInterval(); = 1 << 4; TOS_I1000PS = 32, TOS_S1000PS = 1, static inline uint8_t HPLPowerManagementM$getPowerLevel(void); inline static result_t RealMain$Pot$init(uint8_t arg_0xa2ce970) return BlinkM$Timer$start(TIMER_REPEAT, 1000); static inline void TOSH_SET_RED_LED_PIN(void); TOS_I100PS = 40, TOS_S100PS = 2, static inline void HPLPowerManagementM$doAdjustment(void); unsigned char result; TimerM$mInterval = val; static inline void TOSH_CLR_RED_LED_PIN(void); static inline result_t TimerM$Clock$fire(void) static inline void TOSH_MAKE_PW0_OUTPUT(void) TOS_I10PS = 101, TOS_S10PS = 3, static uint8_t HPLPowerManagementM$PowerManagement$adjustPower(void); result = PotM$Pot$init(arg_0xa2ce970); static inline result_t TimerM$StdControl$start(void) TimerM$Clock$setInterval(TimerM$mInterval); static inline void TOSH_MAKE_RED_LED_OUTPUT(void); TOS_I1024PS = 0, TOS_S1024PS = 3, uint8_t LedsC$ledsOn; return result; TimerM$setIntervalFlag = 0; static inline void TOSH_SET_GREEN_LED_PIN(void); TOS_post(TimerM$HandleFire); * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char *)(0x14 + 0x20) TOS_I512PS = 1, TOS_S512PS = 3, enum LedsC$ nesc_unnamed4259 return SUCCESS; static inline void TOSH_MAKE_GREEN_LED_OUTPUT(void); = 1 << 0; return SUCCESS; TOS_I256PS = 3, TOS_S256PS = 3, LedsC$RED_BIT = 1, static inline void TOSH_sched_init(void ) nesc_atomic_end( nesc_atomic); static inline void TOSH_SET_YELLOW_LED_PIN(void); TOS_I128PS = 7, TOS_S128PS = 3, LedsC$GREEN_BIT = 2, inline static result_t RealMain$StdControl$start(void) static inline void TOSH_MAKE_YELLOW_LED_OUTPUT(void); static inline void TOSH_MAKE_PW1_OUTPUT(void) inline static result_t HPLClock$Clock$fire(void) TOS_I64PS = 15, TOS_S64PS = 3, LedsC$YELLOW_BIT = 4 TOSH_sched_free = 0; unsigned char result; else static inline void TOSH_CLR_SERIAL_ID_PIN(void); unsigned char result; TOS_I32PS = 31, TOS_S32PS = 3, ; TOSH_sched_full = 0; result = TimerM$StdControl$start(); nesc_atomic_t nesc_atomic = nesc_atomic_start(); static inline void TOSH_MAKE_SERIAL_ID_INPUT(void); * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char *)(0x14 + 0x20) result = TimerM$Clock$fire(); TOS_I16PS = 63, TOS_S16PS = 3, static inline result_t LedsC$Leds$init(void); = 1 << 1; result = rcombine(result, BlinkM$StdControl$start()); static inline void TOSH_MAKE_CC_CHP_OUT_INPUT(void); return result; TOS_I8PS = 127, TOS_S8PS = 3, static inline result_t LedsC$Leds$redOn(void); static inline result_t rcombine(result_t r1, result_t r2) return result; TimerM$mInterval = TimerM$maxTimerInterval; static inline void TOSH_MAKE_CC_PDATA_OUTPUT(void); TOS_I4PS = 255, TOS_S4PS = 3, static inline result_t LedsC$Leds$redOff(void); static inline void TOSH_MAKE_PW2_OUTPUT(void) TimerM$Clock$setInterval(TimerM$mInterval); static inline void TOSH_MAKE_CC_PCLK_OUTPUT(void); bool TOS_post(void (*tp)(void)) TOS_I2PS = 15, TOS_S2PS = 7, static inline result_t LedsC$Leds$redToggle(void); return r1 == FAIL? FAIL : r2; static inline uint8_t HPLPowerManagementM$getPowerLevel(void) TimerM$setIntervalFlag = 0; static inline void TOSH_MAKE_CC_PALE_OUTPUT(void); TOS_I1PS = 31, TOS_S1PS = 7, * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char *)(0x14 + 0x20) static inline void TOSH_SET_FLASH_SELECT_PIN(void); nesc_atomic_t finterruptflags; = 1 << 2; TOS_I0PS = 0, TOS_S0PS = 0 static inline uint8_t diff; nesc_atomic_end( nesc_atomic); static inline void TOSH_MAKE_FLASH_SELECT_OUTPUT(void); uint8_t tmp; ; result_t LedsC$Leds$init(void) if (* (volatile unsigned char *)(unsigned int )& * (volatile unsigned char static inline void TOSH_MAKE_FLASH_CLK_OUTPUT(void); static inline void TOSH_MAKE_PW3_OUTPUT(void) *)(0x37 + 0x20) & ~((1 << 1) (1 << 0))) finterruptflags = nesc_atomic_start(); enum nesc_unnamed4256 TimerM$PowerManagement$adjustPower(); static inline void TOSH_MAKE_FLASH_OUT_OUTPUT(void); return HPLPowerManagementM$IDLE; tmp = TOSH_sched_free; DEFAULT_SCALE = 3, DEFAULT_INTERVAL = 127 nesc_atomic_t nesc_atomic = nesc_atomic_start(); static inline void TOSH_MAKE_MISO_INPUT(void); * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char *)(0x14 + 0x20) TOSH_sched_free++; ; static inline void TOSH_CLR_RED_LED_PIN(void) static inline void TOSH_MAKE_SPI_OC1C_INPUT(void); = 1 << 3; else TOSH_sched_free &= TOSH_TASK_BITMASK; static result_t PotM$Pot$init(uint8_t arg_0xa2ce970); LedsC$ledsOn = 0; static inline void TOSH_MAKE_PW0_OUTPUT(void); if (* (volatile unsigned char *)(unsigned int )& * (volatile unsigned char if (TOSH_sched_free!= TOSH_sched_full) static result_t HPLPotC$Pot$finalise(void); TOSH_SET_RED_LED_PIN(); * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char static inline void TOSH_MAKE_PW1_OUTPUT(void); static inline void TOSH_MAKE_PW4_OUTPUT(void) *)(0x0D + 0x20) & (1 << 7)) *)(0x1B + 0x20) &= ~(1 << 2); nesc_atomic_end(finterruptflags); static result_t HPLPotC$Pot$decrease(void); TOSH_SET_YELLOW_LED_PIN(); static inline void TOSH_MAKE_PW2_OUTPUT(void); return HPLPowerManagementM$IDLE; TOSH_queue[tmp].tp = tp; static result_t HPLPotC$Pot$increase(void); TOSH_SET_GREEN_LED_PIN(); static inline void TOSH_MAKE_PW3_OUTPUT(void); * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char *)(0x14 + 0x20) static inline result_t LedsC$Leds$redOn(void) return TRUE; static uint8_t HPLPowerManagementM$PowerManagement$adjustPower(void) static result_t HPLInit$init(void); = 1 << 4; else static inline void TOSH_MAKE_PW4_OUTPUT(void); static result_t BlinkM$StdControl$init(void); nesc_atomic_end( nesc_atomic); if (* (volatile unsigned char *)(unsigned int )& * (volatile unsigned static inline void TOSH_MAKE_PW5_OUTPUT(void); nesc_atomic_t nesc_atomic = nesc_atomic_start(); else uint8_t mcu; static result_t BlinkM$StdControl$start(void); static inline void TOSH_MAKE_PW5_OUTPUT(void) return SUCCESS; char *)(0x06 + 0x20) & (1 << 7)) static inline void TOSH_MAKE_PW6_OUTPUT(void); TOSH_sched_free = tmp; if (!HPLPowerManagementM$disabled) static result_t BlinkM$Timer$fired(void); return HPLPowerManagementM$ADC_NR; static inline void TOSH_MAKE_PW7_OUTPUT(void); TOSH_CLR_RED_LED_PIN(); nesc_atomic_end(finterruptflags); TOS_post(HPLPowerManagementM$doAdjustment); static result_t TimerM$Clock$fire(void); * (volatile unsigned char *)(unsigned int )& * (volatile unsigned inline char static *)(0x14 result_t + 0x20) BlinkM$Leds$init(void) static inline void TOSH_SET_PIN_DIRECTIONS(void ); = 1 << 5; LedsC$ledsOn = LedsC$RED_BIT; return FALSE; static result_t TimerM$StdControl$init(void); unsigned char result; else enum nesc_unnamed4248 else static result_t TimerM$StdControl$start(void); result = LedsC$Leds$init(); if (* (volatile unsigned char *)(unsigned int )& * (volatile unsigned TOSH_ADC_PORTMAPSIZE = 12 static inline void TOSH_MAKE_PW6_OUTPUT(void) char *)(0x37 + 0x20) & ((1 << 1) (1 << 0))) nesc_atomic_end( nesc_atomic); static result_t TimerM$Timer$default$fired(uint8_t arg_0xa31d660); return result; ; diff = * (volatile unsigned char *)(unsigned int )& * (volatile return SUCCESS; int main(void) mcu = * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char static result_t TimerM$Timer$start(uint8_t arg_0xa31d660, char arg_0xa2fd578, unsigned char *)(0x31 + 0x20) - * (volatile unsigned char enum nesc_unnamed4249 uint32_t arg_0xa2fd6d0); * (volatile unsigned char *)(unsigned int )& * (volatile unsigned static char inline *)(0x14 result_t + 0x20) *)(0x35 + 0x20); BlinkM$StdControl$init(void) *)(unsigned int )& * (volatile unsigned char *)(0x32 + TOSH_ACTUAL_CC_RSSI_PORT = 0, = 1 << 6; 0x20); static inline result_t LedsC$Leds$redOff(void) RealMain$hardwareInit(); mcu &= 0xe3; static void HPLClock$Clock$setInterval(uint8_t arg_0xa33b8c0); TOSH_ACTUAL_VOLTAGE_PORT = 7, if (diff < 16) RealMain$Pot$init(10); mcu = HPLPowerManagementM$IDLE; static uint8_t HPLClock$Clock$readCounter(void); BlinkM$Leds$init(); TOSH_ACTUAL_BANDGAP_PORT = 30, static inline void TOSH_MAKE_PW7_OUTPUT(void) return HPLPowerManagementM$EXT_STANDBY; nesc_atomic_t nesc_atomic = nesc_atomic_start(); TOSH_sched_init(); * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char *)(0x35 static result_t HPLClock$Clock$setRate(char arg_0xa33adc0, char arg_0xa33af00); return SUCCESS; + 0x20) = mcu; TOSH_ACTUAL_GND_PORT = 31 RealMain$StdControl$init(); static uint8_t HPLPowerManagementM$PowerManagement$adjustPower(void); * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char *)(0x35 ; * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char *)(0x14 + 0x20) return HPLPowerManagementM$POWER_SAVE; TOSH_SET_RED_LED_PIN(); RealMain$StdControl$start(); + 0x20) = 1 << 5; static result_t LedsC$Leds$init(void); = 1 << 7; static inline result_t HPLClock$Clock$setRate(char interval, char scale) enum nesc_unnamed4250 LedsC$ledsOn &= ~LedsC$RED_BIT; nesc_enable_interrupt(); static result_t LedsC$Leds$redOff(void); TOS_ADC_CC_RSSI_PORT = 0, else while (1) return 0; static result_t LedsC$Leds$redToggle(void); static inline void TOSH_MAKE_CC_CHP_OUT_INPUT(void) scale &= 0x7; TOS_ADC_VOLTAGE_PORT = 7, nesc_atomic_end( nesc_atomic); TOSH_run_task(); static result_t LedsC$Leds$redOn(void); scale = 0x8; TOS_ADC_BANDGAP_PORT = 10, return HPLPowerManagementM$POWER_DOWN; return SUCCESS; void attribute((interrupt)) vector_15(void) static result_t RealMain$hardwareInit(void); * (volatile unsigned char *)(unsigned int )& * (volatile unsigned nesc_atomic_t char *)(0x1A + nesc_atomic 0x20) = nesc_atomic_start(); TOS_ADC_GND_PORT = 11 static result_t RealMain$Pot$init(uint8_t arg_0xa2ce970); &= ~(1 << 6); ; static result_t RealMain$StdControl$init(void); static inline result_t LedsC$Leds$redToggle(void) nesc_atomic_t nesc_atomic = nesc_atomic_start(); * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char *)(0x37 static result_t RealMain$StdControl$start(void); static inline void TOSH_MAKE_GREEN_LED_OUTPUT(void) + 0x20) &= ~(1 << 0); * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char *)(0x37 result_t rval; if (HPLClock$set_flag) + 0x20) &= ~(1 << 1); * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char *)(0x1A + 0x20) nesc_atomic_t nesc_atomic = nesc_atomic_start(); HPLClock$mscale = HPLClock$nextScale; = 1 << 1; * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char *)(0x30 HPLClock$nextScale = 0x8; + 0x20) = 1 << 3; if (LedsC$ledsOn & LedsC$RED_BIT) * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char *)(0x33 static inline void TOSH_MAKE_YELLOW_LED_OUTPUT(void) + 0x20) = scale; rval = LedsC$Leds$redOff(); *)(0x33 + 0x20) = HPLClock$nextScale; * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char *)(0x32 else * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char *)(0x1A + 0x20) + 0x20) = 0; rval = LedsC$Leds$redOn(); * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char = 1 << 0; *)(0x31 + 0x20) = HPLClock$minterval; * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char *)(0x31 + 0x20) = interval; HPLClock$set_flag = 0; static inline void TOSH_MAKE_RED_LED_OUTPUT(void) * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char *)(0x37 + 0x20) = 1 << 1; nesc_atomic_end( nesc_atomic); return rval; * (volatile unsigned char *)(unsigned int )& * (volatile unsigned char *)(0x1A + 0x20) nesc_atomic_end( nesc_atomic); = 1 << 2; nesc_atomic_end( nesc_atomic); HPLClock$Clock$fire(); return SUCCESS; 1K lines of C (another 1K lines of comments) = ~1.5K bytes of assembly code CSE 466 Wireless Sensor Networks 46

Blink Compiled a small piece static inline result_t LedsC$Leds$redToggle(void) result_t rval; nesc_atomic_t nesc_atomic = nesc_atomic_start(); if (LedsC$ledsOn & LedsC$RED_BIT) rval = LedsC$Leds$redOff(); else rval = LedsC$Leds$redOn(); nesc_atomic_end( nesc_atomic); return rval; inline static result_t BlinkM$Leds$redToggle(void) unsigned char result; result = LedsC$Leds$redToggle(); return result; static inline result_t BlinkM$Timer$fired(void) BlinkM$Leds$redToggle(); return SUCCESS; static inline result_t LedsC$Leds$redOn(void) nesc_atomic_t nesc_atomic = nesc_atomic_start(); TOSH_CLR_RED_LED_PIN(); LedsC$ledsOn = LedsC$RED_BIT; nesc_atomic_end( nesc_atomic); return SUCCESS; static inline result_t LedsC$Leds$redOff(void) nesc_atomic_t nesc_atomic = nesc_atomic_start(); TOSH_SET_RED_LED_PIN(); LedsC$ledsOn &= ~LedsC$RED_BIT; nesc_atomic_end( nesc_atomic); return SUCCESS; CSE 466 Wireless Sensor Networks 47

Concurrency Model Asynchronous Code (AC) Any code that is reachable from an interrupt handler Synchronous Code (SC) Any code that is ONLY reachable from a task Boot sequence Potential race conditions Asynchronous Code and Synchronous Code Asynchronous Code and Asynchronous Code Non-preemption eliminates data races among tasks nesc reports potential data races to the programmer at compile time (new with version 1.1) Use atomic statement when needed async keyword is used to declare asynchronous code to compiler CSE 466 Wireless Sensor Networks 48

Commands, Events, and Tasks... status = call CmdName(args)... command CmdName(args)... return status; event EvtName)(args)... return status;... post TskName();...... status = signal EvtName(args)... task void TskName... CSE 466 Wireless Sensor Networks 49

Split Phase Operations Component1 Event or task call command, try again if not OK Event handler Check success flag (OK, failed, etc.) Component2 Command post task and return OK, or return busy Task task executes and signals completion with event Phase I call command with parameters command either posts task to do real work or signals busy and to try again later Phase II task completes and uses event (with return parameters) to signal completion event handler checks for success (may cause re-issue of command if failed) CSE 466 Wireless Sensor Networks 50

Naming Convention Use mixed case with the first letter of word capitalized Interfaces (Xxx.nc) Components Configuration (XxxC.nc) Module (XxxM.nc) Application top level component (Xxx.nc) Commands, Events, & Tasks First letter lowercase Task names should start with the word task, commands with cmd, events with evt or event If a command/event pair form a split-phase operation, event name should be same as command name with the suffix Done or Complete Commands with TOSH_ prefix indicate that they touch hardware directly Variables first letter lowercase, caps on first letter of all sub-words Constants all caps CSE 466 Wireless Sensor Networks 51

Interfaces can fan-out and fan-in nesc allows interfaces to fan-out to and fan-in from multiple components One provides can be connected to many uses and vice versa Wiring fans-out, fan-in is done by a combine function that merges results implementation components Main, Counter, IntToLeds, TimerC; Main.StdControl -> IntToLeds.StdControl; Main.StdControl -> Counter.StdControl; Main.StdControl -> TimerC.StdControl; Fan-out by wiring Fan-in using rcombine - rcombine is just a simple logical AND for most cases result_t ok1, ok2, ok3;. ok1 = call UARTControl.init(); ok2 = call RadioControl.init(); ok3 = call Leds.init();. return rcombine3(ok1, ok2, ok3); CSE 466 Wireless Sensor Networks 52

Example configuration CntToLeds implementation components Main, Counter, IntToLeds, TimerC; Main.StdControl -> IntToLeds.StdControl; Main.StdControl -> Counter.StdControl; Main.StdControl -> TimerC.StdControl; Counter.Timer -> TimerC.Timer[unique("Timer")]; Counter.IntOutput -> IntToLeds.IntOutput; M ain.nc StdControl.nc StdControl.nc Counter.nc Timer.nc IntOutput.nc StdControl.nc TimerC.nc Timer.nc IntOutput.nc IntToLeds.nc StdControl.nc CSE 466 Wireless Sensor Networks 53

Exercise Which of the following goes inside the module you are implementing if we assume you are the user of the interface? NOTE: Not all of these choices are exposed through an interface. Assume those that are not exposed are implemented in your module. post taska( ); call commandb(args); signal eventc(args); taska implementation commandb implementation eventc implementation CSE 466 Wireless Sensor Networks 54