📄 bombilla.tex
字号:
\documentclass[10pt]{article}\usepackage{graphicx}\usepackage{graphics}\usepackage{multicol}\usepackage{epsfig,amsmath,amsfonts}\usepackage{xspace}\makeatletter % Make '@' accessible. \oddsidemargin=0in % Left margin minus 1 inch.\evensidemargin=0in % Same for even-numbered pages.\marginparsep=0pt % Space between margin & text\renewcommand{\baselinestretch}{1} % Double spacing\textwidth=6.5in % Text width (8.5in - margins).\textheight=9in % Body height (incl. footnotes)\topmargin=0in % Top margin minus 1 inch.\headsep=0.0in % Distance from header to body.\skip\footins=4ex % Space above first footnote.\hbadness=10000 % No "underfull hbox" messages.\makeatother % Make '@' special again.\newcommand{\mate}{Mat\'{e}\xspace}\newcommand{\bomb}{Bombilla\xspace}\title{Mat\'{e}: A Tiny Virtual Machine for TinyOS}\author{Philip Levis and Neil Patel\\pal@cs.berkeley.edu}\date{}\begin{document}%\fontfamily{cmss} % Make text sans serif.%\fontseries{m} % Medium spacing.%\fontshape{n} % Normal: not bold, etc.%\fontsize{10}{10} % 10pt font, 10pt line spacing \maketitle\vspace{2in}\begin{center}Version 1.1\\August 21, 2003\end{center}\fontfamily{cmr} % Make text Roman (serif).\fontseries{m} % Medium spacing.\fontshape{n} % Normal: not bold, etc.\fontsize{10}{10} % 10pt font, 10pt line spacing\thispagestyle{empty}\newpage\tableofcontents\newpage\section{Introduction}\mate is a tiny bytecode interpreter that runs on top ofTinyOS. Because it presents a high-level communication-centricinterface, \mate's programs are very short; combined with a safeexecution environment, this makes mote reprogramming rapid anderror-free. Programs can self-propagate through a network; this makesreprogramming mostly autonomous, as once a self-propagating capsule isintroduced, it will eventually install itself over the entire network.\mate has multiple execution contexts; each runs in response to anevent, and they can interleave at instruction granularity. \mateprevents race conditions by implicitly locking all shared state thatis used; as every resource is statically named and \mate programsare short, the set of required locks can be quickly determined with afull program analysis. Program writers can explicitly yield or releaselocks to improve parallelism.One goal of \mate is to provide a programming interface to motesthat is much simpler than TinyOS; a sense-and-send program can be asfew as six instructions in \mate, and \mate's error detectionmechanisms can help novice programmers find the bugs in theirprograms.\mate is a architecture for constructing application specific virtualmachines. Using the architecture, developers can easily changeinstruction sets, execution events, and VM subsystems. The first halfof this document presents \bomb, a specific instance of a \mate VMthat is part of the standard TinyOS distribution, explaining it as acomplete system. The second half explains the \mate architecture,shows how \bomb is an instance of \mate, and gives examples on how\bomb can be used as a template to build other virtual machines.\section{\bomb}\bomb is a set of TinyOS components that sit on top of severalsystem components, including sensors, the network stack, andnon-volatile storage (the ``logger'')\footnote{Support for the loggeris currently not implemented, due to the pending addition of a newlogger interface in TinyOS.}. Code is broken in {\bf capsules} of 24instructions, each of which is a single byte long; larger programs canbe composed of multiple capsules. In addition to bytecodes, capsulescontain identifying and version information. Each \bomb context hastwo stacks: an operand stack and a return address stack. Mostinstructions operate solely on the operand stack, but a fewinstructions control program flow and several have embeddedoperands. There are three execution contexts that can run concurrentlyat instruction granularity. \bomb provides both a built-in ad-hocrouting algorithm (the {\tt send} instruction) as well as mechanismsfor writing new ones (the {\tt sendr} instruction).\begin{figure}\centering\includegraphics[scale=0.4]{fig/bombillamodel.jpg}\caption{\bomb Architecture and Execution Model: Capsules, Contexts, and Stacks}\label{fig:exec}\end{figure}\begin{figure}\begin{center}\def\W{3.25in}\begin{tabular}{|l|l|l|}\hlinebasic &{\tt 00iiiiii} & {\tt i} = instruction\\ \hlinem-class &{\tt 010iixxx} & {\tt i} = instruction, {\tt x} = argument \\ \hlinev-class &{\tt 011ixxxx} & {\tt i} = instruction, {\tt x} = argument \\ \hlinej-class &{\tt 10ixxxxx} & {\tt i} = instruction, {\tt x} = argument \\ \hlinex-class &{\tt 11xxxxxx} & {\tt i} = instruction, {\tt x} = argument\\ \hline\end{tabular}\caption{\bomb Instruction Formats}\label{fig:instr}\end{center}\end{figure}\subsection{Architecture, Instruction Set, and Data Types}\bomb instructions hide the asynchrony (and oft-resulting raceconditions) of TinyOS programming. For example, when the {\tt send}instruction is issued, \bomb calls a command in the ad-hoc routingcomponent to send a packet. \bomb suspends the context until amessage send complete event is received, at which point it resumesexecution. By doing this, \bomb does not need to manage messagebuffers -- the capsule will not resume until the network component isdone with the buffer. Similarly, when the {\tt sense} instruction isissued, \bomb requests data from the sensor TinyOS component andsuspends the context until the component returns data with anevent. This synchronous model makes application level programming muchsimpler and far less prone to bugs than dealing with asynchronousevent notifications. Additionally, \bomb efficiently uses theresources provided by TinyOS; during a split-phase operation, \bombdoes nothing on behalf of the calling context, allowing TinyOS to putthe CPU to sleep or use it freely.\bomb is a stack-based architecture. This allows a conciseinstruction set; most instructions do not have to specify operands, asthey exist on the operand stack. There are five classes of \bombinstructions: basic, m-class, j-class, v-class, and x-class. Figure\ref{fig:instr} shows the instruction formats for each class. Basicinstructions include such operations as arithmetic, halting, andactivating the LEDs on a mote. m-class instructions access messageheaders; they can only be executed within the message send and receivecontexts. v-class instructions access the 16 word \bombheap. j-class instructions are the two jump instructions, for loopsand conditionals. The one x-class instructions is {\tt pushc} (pushconstant). All instruction classes except basic have embedded operands..\bomb's three principal execution contexts, illustrated in Figure\ref{fig:exec}, correspond to three events: clock timers, messagereceptions and message send requests. Inheriting from languages suchas FORTH, each context has two stacks, an operand stack and a returnaddress stack. The former is used for all instructions handling data,while the latter is used for subroutine calls. The operand stack has amaximum depth of 16 while the call stack has a maximum depth of 8. Wehave found this more than adequate for programs we have written.There is an additional context, the ``once'' context. Unlike othercontexts, which run their capsules many times, this context only runsits capsule once, when it is installed; this allows a user toinitialize state, adjust constants, or perform other operations thatonly need a single execution.There are three operands types: values, sensor readings, andbuffers. Some instructions can only operate on certain types. Forexample, the {\tt putled} instruction expects a value on the top ofthe operand stack. However, many instructions are polymorphic. Forexample, the {\tt add} instruction can be used to add any combinationof the types, with different results. Adding buffers results inappending the data in the second operand onto the firstoperand. Adding a value to a message appends the value to the messagedata payload. Sensor readings can be turned into values with the {\ttcast} instruction.Sensor readings are typed, and cannot be modified. For example, inorder to take an average over a set of readings, each reading must befirst be converted to a value; these values can then be averaged. Manyinstructions (e.g. {\tt inv}) automatically cast sensor readings tovalues. This ensures that a sensor reading variable has some meaning;otherwise, it could express some arbitrary quantity. Adding two sensorreadings of the same type (e.g. magnetometer X-axis) produces a value,and adding two sensor readings of different values is an error.Buffers are also typed, and can hold up to ten values. A buffer canonly hold elements of one type, whether they be values or a certainsensor type. An empty buffer has no type; the first element added willset the type of the buffer. Buffers have several access instructions,including {\tt bhead} (copy of the first element of the buffer ontothe operand stack), {\tt byank} (pull the nth element out of thebuffer and push it into the operand stack), and {\tt bsorta} (sort theelements in ascending order.There is a 16 word heap shared among the context. It can be accessedwith the {\tt setvar} and {\tt getvar} instructions, which have a4-bit embedded operand.. This allows the separate contexts tocommunicate shared state (e.g. sensor readings).\subsection{Capsules and Execution}\bomb programs are broken up into capsules of up to 24instructions. This limit allows a capsule to fit into a single TinyOSpacket. By making capsule reception atomic, \bomb does not need tobuffer partial capsules, which conserves RAM. Every code capsuleincludes type and version information. \bomb defines two types of codecapsules: context capsules, which are the root execution of a context,and subroutine capsules, which can be called from context capsules orother subroutine capsule. Subroutine capsules allow programs to bemore complex than what fits in a single capsule. Applications invokeand return from subroutines using the {\tt call} and {\tt return}instructions. There are names for up to $2^{15}$ subroutines; to keep\bomb's RAM requirements small, its current implementation has onlyfour.\bomb begins execution in response to an event -- a timer goingoff, a packet being received, or a packet being sent. Each of theseevents has a capsule and an execution context. Control jumps to thefirst instruction of the capsule and executes until it reaches the{\tt halt} instruction. These three contexts can runconcurrently. Each instruction is executed as a TinyOS task, whichallows execution interleaving at an instructiongranularity. Additionally, underlying TinyOS components can operateconcurrently with \bomb instruction processing. When a subroutine iscalled, the return address (capsule, instruction number) is pushedonto a return address stack and control jumps to the first instructionof the subroutine. When a subroutine returns, it pops an address offthe return stack and jumps to the appropriate instruction.\begin{figure}\begin{center}\scriptsize\begin{tabular}{l}\verb;getvar 0 # Get heap variable 0;\\\verb;pushc 1 # Push one onto operand stack;\\\verb;add # Add the one to the stored counter;\\ \verb;copy # Copy the new counter value;\\\verb;setvar 0 # Set heap variable 0;\\\verb;pushc 7 ;\\ \verb;and # Take bottom three bits of counter;\\\verb;putled # Set the LEDs to these three bits;\\\verb;halt;\\\end{tabular}\normalsize\caption{\bomb {\tt cnt\_to\_leds} -- Shows the bottom 3 bits of a counter on mote LEDs}\label{fig:cnt}\end{center}\end{figure}\begin{figure}\begin{center}\scriptsize\begin{tabular}{l}\verb;pushc 1 # Push one on the operand stack;\\\verb;sense # Read sensor 1 (light);\\\verb;copy # Copy the sensor reading;\\\verb;getvar 0 # Get previous sent reading;\\\verb;;\\\verb;inv # Invert previous reading ;\\\verb;add # Current - previous sent value;\\\verb;copy # 2 copies of difference on top of stack;\\\verb;pushc 32 #;\\\verb;;\\\verb;gt # Is current 32 greater than previous?;\\\verb;swap # Swap result with copy ;\\\verb;pushc 32 #;\\\verb;inv #;\\\verb;;\\\verb;lt # Is current 32 less than previous?;\\\verb;or # Either 32> or 32<;\\\verb;jumps 15 # Jump to send;\\\verb;halt;\\\verb;;\\\verb;copy # Copy new value;\\\verb;setvar 0 # Set current;\\\verb;bpush0 # Push buffer 0 onto stack;\\\verb;bclear # Clear its contents;\\\verb;;\\\verb;add # Add current reading to buffer;\\\verb;send # Send buffer;\\\verb;halt;\\\end{tabular}\normalsize\caption{\bomb Program to Read Light Data and Send a Packet on Reading Change}\label{fig:sense}\end{center}\end{figure}The packet receive and clock capsules execute in response to externalevents; in contrast, the packet send capsule executes in response tothe {\tt sendr} instruction. As {\tt sendr} will probably execute anumber of \bomb instructions in addition to sending a packet, it canbe a lengthy operation. Therefore, when {\tt sendr} is issued, \bombcopies the message buffer onto the send context operand stack andschedules the send context to run. Once the message has been copied,the calling context can resume execution. The send context executesconcurrently to the calling context, preparing a packet and latersending it. This frees up the calling context to handle subsequentevents -- in the case of the receive context, this is very important.The constrained addressing modes of \bomb instructions ensure acontext cannot access the state of a separate context. Every push andpop on the operand and return value stack has bound checks to preventoverrun and underrun. As there is only a single shared variable, heapaddressing is not a problem. Unrecognized instructions result insimple no-ops. All bounds are always checked -- the only way twocontexts can share state is through {\tt gets} and {\ttsets}. Nefarious capsules can at worst clog a network with packets --even in this case, a newer capsule will inevitably be heard. Byproviding such a constrained execution environment and providinghigh-level abstractions to services such as the network layer, \bombensures that it is resilient to buggy or malicious capsules.\subsection{Simple Programs}\label{sec:sub:simple}The \bomb program in Figure \ref{fig:cnt} maintains a counter thatincrements on each clock tick. The bottom three bits of the counterare displayed on the three mote LEDs. The counter is kept as a valuewhich persists at the top of the stack across invocations. Thisprogram could alternatively been implemented by using {\tt gets} and{\tt sets} to modify the shared variable. This code recreates one ofthe simplest TinyOS applications, {\tt cnt\_to\_leds}, implemented inseven bytes.The \bomb program in Figure \ref{fig:sense} reads the light sensoron every clock tick. If the sensor value differs from the last sentvalue by more than a given amount (32 in this example), the programsends the data using \bomb's built-in ad-hoc routing system. Thisprogram is 24 bytes long, fitting in a single capsule.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -