xref: /inferno-os/doc/lego.ms (revision 46439007cf417cbd9ac8049bb4122c890097a0fa)
1*46439007SCharles.Forsyth.TL
2*46439007SCharles.ForsythStyx-on-a-Brick
3*46439007SCharles.Forsyth.AU
4*46439007SCharles.ForsythChris Locke
5*46439007SCharles.Forsyth.br
6*46439007SCharles.Forsythchris@vitanuova.com
7*46439007SCharles.Forsyth.AI
8*46439007SCharles.ForsythVita Nuova
9*46439007SCharles.Forsyth.br
10*46439007SCharles.ForsythJune 2000
11*46439007SCharles.Forsyth.SH
12*46439007SCharles.ForsythBackground
13*46439007SCharles.Forsyth.LP
14*46439007SCharles.ForsythThe aim of the Vita-Nuova ``styx-on-a-brick'' project was
15*46439007SCharles.Forsythto demonstrate the simplicity of the Styx protocol and the ease
16*46439007SCharles.Forsythwith which a Styx `stub' can be implemented on tiny devices.
17*46439007SCharles.ForsythWe also aimed to demonstrate the effectiveness of a protocol based approach
18*46439007SCharles.Forsythto resource management and sharing, whether the resource be a physical device
19*46439007SCharles.Forsythor a software service.
20*46439007SCharles.Forsyth.LP
21*46439007SCharles.ForsythAdopting a protocol-centric view of resource and service management, as opposed to
22*46439007SCharles.Forsytha language-centric approach (as emphasised for instance by Jini™ with Java)
23*46439007SCharles.Forsythgreatly eased the software burden on our tiny target device \-
24*46439007SCharles.Forsythimplementing a simple protocol in firmware required much less work than trying to
25*46439007SCharles.Forsythimplement a virtual machine.  We are confident that if we had adopted a language-centric
26*46439007SCharles.Forsythapproach, we would not have completed the project within our aggressive space and implementation time constraints.†
27*46439007SCharles.Forsyth.FS
28*46439007SCharles.Forsyth.FA
29*46439007SCharles.Forsyth†Indeed, we later discovered that in the application of Jini to load code into an RCX robot no part
30*46439007SCharles.Forsythof Jini was actually on the brick.
31*46439007SCharles.Forsyth.FE
32*46439007SCharles.Forsyth.LP
33*46439007SCharles.ForsythThe project took 2 weeks from start to finish.
34*46439007SCharles.ForsythIn this time the firmware was developed and all client software
35*46439007SCharles.Forsythwas written: firmware download, IR-link protocol support,
36*46439007SCharles.Forsythclockface application and worldclock application.
37*46439007SCharles.ForsythTwo people worked on the project, one full-time, the other (Nigel Roles) part-time.
38*46439007SCharles.Forsyth.LP
39*46439007SCharles.ForsythThe demo was then taken on a Press Conference tour of the US
40*46439007SCharles.Forsythand later appeared at the Usenix2000 Plan 9/Inferno BOF at the request
41*46439007SCharles.Forsythof Dennis Ritchie.
42*46439007SCharles.Forsyth.LP
43*46439007SCharles.ForsythI should stress that the project was a demonstration of the ease of
44*46439007SCharles.Forsythsupporting Styx on small devices \- it was not a demo of robotics!
45*46439007SCharles.Forsyth(Indeed, the design of the IR-link protocol, Styx name space and the
46*46439007SCharles.Forsythservices provided by the firmware would be considerably different for
47*46439007SCharles.Forsythserious robotics.)
48*46439007SCharles.Forsyth.LP
49*46439007SCharles.ForsythThe project used a standard Lego™ Mindstorms™ robotics kit \-
50*46439007SCharles.Forsyththe ``Robotics Invention System''.  This consists of the RCX brick,
51*46439007SCharles.Forsyth2 motors, 2 button sensors, a light sensor and a whole load of
52*46439007SCharles.Forsythlego pieces \- including wheels, gears and axles; which all adds up
53*46439007SCharles.Forsythto a whole load of fun!
54*46439007SCharles.Forsyth.LP
55*46439007SCharles.ForsythThe RCX brick is an Hitachi H8 microcontroller with 32K of RAM and
56*46439007SCharles.Forsytha 16K ROM BIOS.  The RCX provides 3 motor outputs and 3 sensor inputs.
57*46439007SCharles.ForsythCommunication with the RCX is via IR.  An IR tower is supplied with the
58*46439007SCharles.Forsyth``Robotics Invention System'' that connects to a PC via a serial port.
59*46439007SCharles.Forsyth.SH
60*46439007SCharles.ForsythAcknowledgements
61*46439007SCharles.Forsyth.LP
62*46439007SCharles.ForsythBefore going any further I must acknowledge the work of Kekoa Proudfoot at
63*46439007SCharles.ForsythStanford and Russ Nelson at Crynwr Software.
64*46439007SCharles.ForsythWithout their valiant efforts we would not have been able to pursue this project.
65*46439007SCharles.ForsythOur work relied on the documents and librcx suite provided by Kekoa:
66*46439007SCharles.Forsyth.P1
67*46439007SCharles.Forsythhttp://graphics.stanford.edu/~kekoa/rcx/
68*46439007SCharles.Forsyth.P2
69*46439007SCharles.Forsythand on information from Russ Nelson's web site
70*46439007SCharles.Forsyth.P1
71*46439007SCharles.Forsythhttp://www.crynwr.com/lego-robotics/
72*46439007SCharles.Forsyth.P2
73*46439007SCharles.Forsyth.SH
74*46439007SCharles.ForsythFiles
75*46439007SCharles.Forsyth.LP
76*46439007SCharles.ForsythThe files in the
77*46439007SCharles.Forsyth.CW legostyx.tar
78*46439007SCharles.Forsythfile are shown in Table 1.
79*46439007SCharles.Forsyth.KF
80*46439007SCharles.Forsyth.TS
81*46439007SCharles.Forsythcenter;
82*46439007SCharles.Forsythlf(CW) lfR .
83*46439007SCharles.Forsythllp.h	Link level protocol constants
84*46439007SCharles.Forsythstyx.c	The firmware implementation
85*46439007SCharles.Forsythstyx.srec	The firmware image (S-record format)
86*46439007SCharles.Forsythstyx_abp.srec	The firmware with the alternating bit part of the link protocol enabled
87*46439007SCharles.Forsythsend.b	Test app \- sends RCX op codes to the brick
88*46439007SCharles.Forsythfirmdl.b	Firmware download app
89*46439007SCharles.Forsythrcxsend.m	Util module header
90*46439007SCharles.Forsythrcxsend.b	Util module \- supports RCX ROM message format on serial link
91*46439007SCharles.Forsythtimers.m	Timer module header
92*46439007SCharles.Forsythtimers.b	Util module \- general purpose timers
93*46439007SCharles.Forsythlegolink.b	Implements the link protocol via a limbo file2chan()
94*46439007SCharles.Forsythclockface.b	The controller app for our Clockface robot
95*46439007SCharles.Forsyth.TE
96*46439007SCharles.Forsyth.fi
97*46439007SCharles.Forsyth.ce 10
98*46439007SCharles.Forsyth.I "Table 1.\ "\c
99*46439007SCharles.ForsythFiles in the Styx-on-a-Brick package
100*46439007SCharles.Forsyth.ce 0
101*46439007SCharles.Forsyth.KE
102*46439007SCharles.Forsyth.SH
103*46439007SCharles.ForsythProject details
104*46439007SCharles.Forsyth.NH 1
105*46439007SCharles.ForsythFirmware Download
106*46439007SCharles.Forsyth.LP
107*46439007SCharles.ForsythThe RCX brick comes supplied with Lego firmware to be downloaded into the RAM via
108*46439007SCharles.Forsyththe IR link.  The ROM implements a monitor which provides for the firmware download,
109*46439007SCharles.Forsythas well as other 'op-codes'.
110*46439007SCharles.Forsyth.LP
111*46439007SCharles.ForsythWe wrote our own firmware in C using the GNU H8 compiler suite on a FreeBSD machine.
112*46439007SCharles.ForsythThe code used Kekoa's
113*46439007SCharles.Forsyth.CW librcx
114*46439007SCharles.Forsythlibrary for interfacing to the RCX ROM routines.
115*46439007SCharles.Forsyth(We should have liked to have done an H8 code generator for our own compiler suite,
116*46439007SCharles.Forsythbut time did not permit this!)
117*46439007SCharles.ForsythThe
118*46439007SCharles.Forsyth.CW gnuh8
119*46439007SCharles.Forsythlist is accessible via:
120*46439007SCharles.Forsyth.P1
121*46439007SCharles.Forsythhttp://www.pcserv.demon.co.uk/
122*46439007SCharles.Forsyth.P2
123*46439007SCharles.ForsythFirst up we had to write a Limbo application to communicate with the ROM, via
124*46439007SCharles.Forsyththe IR tower in order that we could get our firmware downloaded onto the RCX.
125*46439007SCharles.ForsythThis is the firmdl application.  Source files:
126*46439007SCharles.Forsyth.CW firmdl.b ,
127*46439007SCharles.Forsyth.CW rcxsend.b
128*46439007SCharles.Forsythand
129*46439007SCharles.Forsyth.CW timers.b
130*46439007SCharles.Forsyth.NH 1
131*46439007SCharles.ForsythStyx Comms Link
132*46439007SCharles.Forsyth.LP
133*46439007SCharles.ForsythHaving got a means of installing our firmware we needed a means of delivering
134*46439007SCharles.ForsythStyx messages to and from the Brick.
135*46439007SCharles.Forsyth.LP
136*46439007SCharles.ForsythStyx makes certain demands of its transport media:
137*46439007SCharles.Forsyth.TS
138*46439007SCharles.Forsythl l .
139*46439007SCharles.ForsythReliable	messages must not get 'lost'
140*46439007SCharles.ForsythOrdered	messages must not get transposed
141*46439007SCharles.Forsyth.TE
142*46439007SCharles.ForsythThe RCX ROM provides a couple of functions for IR comms \- a routine to check
143*46439007SCharles.Forsythfor message reception and a routine for message delivery.
144*46439007SCharles.ForsythThe message reception routine receives the data of a RCX "Transfer Data"
145*46439007SCharles.Forsythmessage (RCX op-code 0x45)
146*46439007SCharles.Forsyth.LP
147*46439007SCharles.ForsythWe chose to use this facility as a means of delivering Styx messages to our Firmware
148*46439007SCharles.Forsython the Brick.  But it did not provide the Transport properties that Styx requires.
149*46439007SCharles.ForsythTo meet the Styx requirements we implemented a simple 'alternating bit' protocol whose
150*46439007SCharles.Forsythpayload was the Styx messages themselves.  These Link protocol messages become the
151*46439007SCharles.Forsythpayload of the RCX "Transfer Data" messages.
152*46439007SCharles.Forsyth.LP
153*46439007SCharles.ForsythThe IR link is very slow, the baud rate of the IR tower serial link is 2400
154*46439007SCharles.Forsythand the ROM message format requires that every byte of a message be doubled up with
155*46439007SCharles.Forsythits complement. (e.g. the byte 0x7e is transmitted as 0x7e, 0x81)
156*46439007SCharles.ForsythThis is because of the simple way that the RCX ROM and hardware handle elimination
157*46439007SCharles.Forsythof the ambient IR signal level \- all message have the same number of 1s and 0s so
158*46439007SCharles.Forsyththe ambient IR level can be negated by subtracting the average level.
159*46439007SCharles.ForsythAll RCX messages are also prefixed by a header and suffixed with a checksum:
160*46439007SCharles.Forsyth.P1
161*46439007SCharles.Forsyth0x55 0xff 0x00 \fID1 ~D1 D2 ~D2 ... Dn ~Dn C ~C\fP
162*46439007SCharles.Forsyth.P2
163*46439007SCharles.Forsythwhere
164*46439007SCharles.Forsyth.I D1
165*46439007SCharles.Forsyth\&...
166*46439007SCharles.Forsyth.I Dn
167*46439007SCharles.Forsythare the bytes in the message body and \fIC = D1+D2+ ... Dn\fP.
168*46439007SCharles.Forsyth.LP
169*46439007SCharles.ForsythTherefore, the effective data rate is considerably less than 1200 baud.
170*46439007SCharles.Forsyth.LP
171*46439007SCharles.ForsythWe noted that many Styx messages, especially
172*46439007SCharles.Forsyth.CW Twstat
173*46439007SCharles.Forsythand
174*46439007SCharles.Forsyth.CW Rstat ,
175*46439007SCharles.Forsythcontained a high
176*46439007SCharles.Forsythproportion of 0 byte values.†
177*46439007SCharles.Forsyth.FS
178*46439007SCharles.Forsyth.FA
179*46439007SCharles.ForsythThe protocol has since been revised to reduce that.
180*46439007SCharles.Forsyth.FE
181*46439007SCharles.ForsythConsequently, we decided to incorporate a 0-run-length
182*46439007SCharles.Forsythcompression scheme in our simple link protocol.
183*46439007SCharles.Forsyth.LP
184*46439007SCharles.ForsythWithin the payload of the link messages:
185*46439007SCharles.Forsyth.TS
186*46439007SCharles.Forsythl l .
187*46439007SCharles.Forsyth0x88 0x00	represents 0x88
188*46439007SCharles.Forsyth0x88 n	represents n + 2 0's
189*46439007SCharles.Forsythothers	represent themselves
190*46439007SCharles.Forsyth.TE
191*46439007SCharles.Forsyth.LP
192*46439007SCharles.ForsythAn additional burden is that communication with the Brick via the IR tower has to be strictly
193*46439007SCharles.Forsythsynchronous.  The IR tower echoes back all data transmitted to it on the serial link
194*46439007SCharles.Forsythas well as any data received on the IR link.  Therefore the brick must not send IR data
195*46439007SCharles.Forsythwhile the PC is sending serial data to the tower.  In order to achieve this a 'ping-pong'
196*46439007SCharles.Forsythcommunication scheme must be employed.  The PC is the master, the brick is the slave.
197*46439007SCharles.ForsythThe master sends a request and waits for the reply from the slave.
198*46439007SCharles.ForsythOnly the master is allowed to start an exchange.
199*46439007SCharles.Forsyth.LP
200*46439007SCharles.ForsythThe problem with the master/slave style of communication is that a Styx Server
201*46439007SCharles.Forsythimplements blocking requests, e.g. reads and writes, by simply not responding to the
202*46439007SCharles.Forsythrequest until the operation is completed.  This does not fit with the link protocol
203*46439007SCharles.Forsythrequirement that the server (slave) always respond and the requirement that the brick
204*46439007SCharles.Forsythcannot instigate a data exchange.
205*46439007SCharles.ForsythThe firmware could simply reply with an empty Link protocol message but it then has no
206*46439007SCharles.Forsythway of giving timely notification of the completion of a pending Styx request as it is not
207*46439007SCharles.Forsythallowed to start a link-protocol message exchange.
208*46439007SCharles.Forsyth.LP
209*46439007SCharles.ForsythTo get around the pending Styx reply problem, the link protocol header incorporates a flag
210*46439007SCharles.Forsyththat the slave (brick) can set to indicate that it is holding outstanding requests and that the
211*46439007SCharles.Forsythmaster (PC) should continue to poll the slave in order to receive their replies in a timely
212*46439007SCharles.Forsythfashion.
213*46439007SCharles.Forsyth.LP
214*46439007SCharles.ForsythThe link protocol message format is as follows.
215*46439007SCharles.ForsythRequest from Master (PC) to Slave (RCX):
216*46439007SCharles.Forsyth.LP
217*46439007SCharles.Forsyth.TS
218*46439007SCharles.Forsythl l .
219*46439007SCharles.Forsyth0x45/4d	RCX Transfer Data op-code  (including RCX alternating bit)
220*46439007SCharles.Forsyth0	LSB of "Data" block number
221*46439007SCharles.Forsyth0	MSB of "Data" block number
222*46439007SCharles.Forsyth*	LSB of "Data" payload length (lost to ROM firmware)
223*46439007SCharles.Forsyth*	MSB of "Data" payload length (lost to ROM firmware) (n+2)
224*46439007SCharles.Forsyth*	LSB of Link protocol payload length
225*46439007SCharles.Forsyth*	MSB of Link protocol payload length (n+1)
226*46439007SCharles.Forsyth*	Link protocol header
227*46439007SCharles.Forsyth*[n-1]	Link protocol payload (0 or 1 Styx messages)
228*46439007SCharles.Forsyth*	"Transfer Data" cksum (Last byte of Link protocol payload)
229*46439007SCharles.Forsyth.TE
230*46439007SCharles.Forsyth.LP
231*46439007SCharles.ForsythNote that the 0x45 ROM op-code ("Transfer Data") message incorporates a checksum byte at the
232*46439007SCharles.Forsythend, but the ROM doesn't bother to check it so we moved the last byte of the Link protocol
233*46439007SCharles.Forsythpayload (or the link header if the payload is empty) into the checksum position of
234*46439007SCharles.Forsyththe ROM message.
235*46439007SCharles.Forsyth.LP
236*46439007SCharles.ForsythReply from Slave to Master:
237*46439007SCharles.Forsyth.LP
238*46439007SCharles.Forsyth.TS
239*46439007SCharles.Forsythl l .
240*46439007SCharles.Forsyth?	Junk from ROM
241*46439007SCharles.Forsyth*	LSB of Link protocol payload length
242*46439007SCharles.Forsyth*	MSB of Link protocol payload length (n+1)
243*46439007SCharles.Forsyth*	Link protocol header
244*46439007SCharles.Forsyth*[n]	Link protocol payload
245*46439007SCharles.Forsyth.TE
246*46439007SCharles.Forsyth.LP
247*46439007SCharles.ForsythThe Link protocol header has the following flags:
248*46439007SCharles.Forsyth.LP
249*46439007SCharles.Forsyth.TS
250*46439007SCharles.Forsythl l .
251*46439007SCharles.Forsythbit 0	Alternating bit
252*46439007SCharles.Forsythbit 1	Poll immediate (requested by slave)
253*46439007SCharles.Forsythbit 2	Poll periodic (requested by slave)
254*46439007SCharles.Forsythbit 3	compressed (payload is 0-run-length compressed)
255*46439007SCharles.Forsythbits 4-7	reserved (should be 0)
256*46439007SCharles.Forsyth.TE
257*46439007SCharles.Forsyth.LP
258*46439007SCharles.ForsythThe master flips the
259*46439007SCharles.Forsyth.I Alternating
260*46439007SCharles.Forsyth.I bit
261*46439007SCharles.Forsythfor every message that it successfully delivers.
262*46439007SCharles.ForsythIf a slave reply is lost or corrupted the master will re-send the message using the same
263*46439007SCharles.Forsythalternating bit value.  The slave should not act on a repeated message but should
264*46439007SCharles.Forsythre-send it's last response.  The value of the alternating bit in the slave response
265*46439007SCharles.Forsythis the same as in the request from the master.
266*46439007SCharles.Forsyth.LP
267*46439007SCharles.ForsythThe
268*46439007SCharles.Forsyth.I Poll
269*46439007SCharles.Forsyth.I immediate
270*46439007SCharles.Forsythbit indicates that the slave has more data to send to the master.
271*46439007SCharles.ForsythThe master should immediately send another Link-protocol message, even if it has no
272*46439007SCharles.Forsythdata to send, so as the slave can reply with its pending data.
273*46439007SCharles.Forsyth.LP
274*46439007SCharles.ForsythThe
275*46439007SCharles.Forsyth.I Poll
276*46439007SCharles.Forsyth.I periodic
277*46439007SCharles.Forsythbit indicates that the slave has pending (blocked) requests that
278*46439007SCharles.Forsythit will reply to sometime in the future.  The master should periodically poll the
279*46439007SCharles.Forsythslave, even if the master has no data to send.  The polling period should be small
280*46439007SCharles.Forsythenough that reply latencies are acceptable.
281*46439007SCharles.Forsyth.NH 1
282*46439007SCharles.ForsythThe name space
283*46439007SCharles.Forsyth.LP
284*46439007SCharles.ForsythWe now have a means of getting Styx messages to and from the brick.
285*46439007SCharles.ForsythBut what does the name space provided by the firmware on the brick look like?
286*46439007SCharles.Forsyth.LP
287*46439007SCharles.ForsythWe wanted a generic name space; one that reflected the functions of the brick, not
288*46439007SCharles.Forsyththe model attached to it, so that the same firmware could be used with many
289*46439007SCharles.Forsythdifferent robots.
290*46439007SCharles.Forsyth.LP
291*46439007SCharles.ForsythThe brick has 3 motor outputs and 3 sensor inputs.
292*46439007SCharles.ForsythThe motors can be run forwards or reverse with 8 different power settings.
293*46439007SCharles.ForsythThey can be stalled, also with 8 power levels, and they can be left 'floating'
294*46439007SCharles.Forsyth[A stalled motor presents resistance to turning proportional to the stall power level]
295*46439007SCharles.Forsyth.LP
296*46439007SCharles.ForsythThere are 2 types of sensor \- buttons and light-sensors.
297*46439007SCharles.Forsyth[You can also get a 'rotation sensor', but we had not got one in our kit!]
298*46439007SCharles.Forsyth.LP
299*46439007SCharles.ForsythWe decided on a name space comprised of 2 directories,
300*46439007SCharles.Forsyth.CW motor
301*46439007SCharles.Forsythand
302*46439007SCharles.Forsyth.CW sensor .
303*46439007SCharles.ForsythWe didn't need to use subdirectories for our name space but it was easy, so we did!
304*46439007SCharles.Forsyth.LP
305*46439007SCharles.ForsythThe motor directory contains 4 files \-
306*46439007SCharles.Forsyth.CW 0 ,
307*46439007SCharles.Forsyth.CW 1 ,
308*46439007SCharles.Forsyth.CW 2
309*46439007SCharles.Forsythand
310*46439007SCharles.Forsyth.CW 012 .
311*46439007SCharles.ForsythThe files
312*46439007SCharles.Forsyth.CW 0 ,
313*46439007SCharles.Forsyth.CW 1
314*46439007SCharles.Forsythand
315*46439007SCharles.Forsyth.CW 2
316*46439007SCharles.Forsythrepresent the individual motor outputs and
317*46439007SCharles.Forsythaccept command messages of the form
318*46439007SCharles.Forsyth.I 'XP'
319*46439007SCharles.Forsythwhere
320*46439007SCharles.Forsyth.I X
321*46439007SCharles.Forsythis a direction and
322*46439007SCharles.Forsyth.I P
323*46439007SCharles.Forsythis the power level.
324*46439007SCharles.Forsyth.LP
325*46439007SCharles.Forsyth.I X
326*46439007SCharles.Forsythcan be one of
327*46439007SCharles.Forsyth.TS
328*46439007SCharles.Forsythl l .
329*46439007SCharles.Forsythf	forward
330*46439007SCharles.Forsythr	reverse
331*46439007SCharles.Forsyths	stall
332*46439007SCharles.ForsythF	float
333*46439007SCharles.Forsyth.TE
334*46439007SCharles.Forsyth.LP
335*46439007SCharles.Forsyth.I P
336*46439007SCharles.Forsythis a digit in the range
337*46439007SCharles.Forsyth.CW '0..7'
338*46439007SCharles.Forsyth.LP
339*46439007SCharles.ForsythThe file
340*46439007SCharles.Forsyth.CW 012
341*46439007SCharles.Forsythtakes messages of the form
342*46439007SCharles.Forsyth.I 'XPXPXP'
343*46439007SCharles.Forsythenabling the state of all the motors to be modified with a single message.
344*46439007SCharles.ForsythThe first
345*46439007SCharles.Forsyth.I XP
346*46439007SCharles.Forsythpair affects motor 0, the middle pair affects motor 1 and the
347*46439007SCharles.Forsythlast pair affects motor 2.
348*46439007SCharles.Forsyth.I XP
349*46439007SCharles.Forsythcan be
350*46439007SCharles.Forsyth.CW '--'
351*46439007SCharles.Forsythindicating that the state should remain the same as before.
352*46439007SCharles.Forsyth.LP
353*46439007SCharles.Forsyth.LP
354*46439007SCharles.ForsythThe sensor directory contains three files
355*46439007SCharles.Forsyth.CW 0 ,
356*46439007SCharles.Forsyth.CW 1
357*46439007SCharles.Forsythand
358*46439007SCharles.Forsyth.CW 2 ,
359*46439007SCharles.Forsythcorresponding to the three sensor inputs on the brick.
360*46439007SCharles.Forsyth.LP
361*46439007SCharles.ForsythBefore a sensor file can be read it must be configured by writing a configuration
362*46439007SCharles.Forsythmessage to the file.  These message take the form
363*46439007SCharles.Forsyth.I 'Tv*'
364*46439007SCharles.Forsythwhere
365*46439007SCharles.Forsyth.I T
366*46439007SCharles.Forsythis the sensor type and
367*46439007SCharles.Forsyth.I v*
368*46439007SCharles.Forsythis a threshold value.
369*46439007SCharles.ForsythThe idea of the threshold value is that reads of the sensor file wil block until
370*46439007SCharles.Forsyththe threshold value has been achieved.
371*46439007SCharles.Forsyth.LP
372*46439007SCharles.ForsythReads of a sensor file return its current value.
373*46439007SCharles.ForsythWhen a sensor file is configured any pending reads of the sensor are
374*46439007SCharles.Forsythfailed with the error message
375*46439007SCharles.Forsyth.CW 'reset' .
376*46439007SCharles.Forsyth.LP
377*46439007SCharles.ForsythThe available sensor types are:
378*46439007SCharles.Forsyth.LP
379*46439007SCharles.Forsyth.TS
380*46439007SCharles.Forsythl l .
381*46439007SCharles.Forsythb	button
382*46439007SCharles.Forsythl	light sensor
383*46439007SCharles.Forsyth.TE
384*46439007SCharles.Forsyth.LP
385*46439007SCharles.ForsythThe threshold value for a button sensor is a click count.
386*46439007SCharles.ForsythSo the control message
387*46439007SCharles.Forsyth.CW 'b0'
388*46439007SCharles.Forsythconfigures a sensor to be a button and subsequent reads
389*46439007SCharles.Forsythof the file will yield the current click count.
390*46439007SCharles.Forsyth.br
391*46439007SCharles.ForsythThe message
392*46439007SCharles.Forsyth.CW 'b20'
393*46439007SCharles.Forsythwill cause subsequent reads to block until the click count reaches
394*46439007SCharles.Forsyth20 or more.
395*46439007SCharles.Forsyth.LP
396*46439007SCharles.ForsythThe threshold value for a light sensor is a raw sensor value qualified by
397*46439007SCharles.Forsyth.CW '<'
398*46439007SCharles.Forsythor
399*46439007SCharles.Forsyth.CW '>' .
400*46439007SCharles.Forsyth.LP
401*46439007SCharles.ForsythThe control message
402*46439007SCharles.Forsyth.CW 'l>600'
403*46439007SCharles.Forsythconfigures the input to be a light sensor and subsequent
404*46439007SCharles.Forsythreads will block until the sensor value exceeds 600.
405*46439007SCharles.ForsythIf the
406*46439007SCharles.Forsyth.CW '<'
407*46439007SCharles.Forsythqualifier is used, reads block until the value drops below the threshold.
408*46439007SCharles.Forsyth.SH
409*46439007SCharles.ForsythUsing the Styx firmware
410*46439007SCharles.Forsyth.NH 1
411*46439007SCharles.ForsythDownload the firmware
412*46439007SCharles.Forsyth.LP
413*46439007SCharles.ForsythUse the
414*46439007SCharles.Forsyth.CW firmdl
415*46439007SCharles.Forsythcommand to download the firmware to the brick
416*46439007SCharles.Forsyth.P1
417*46439007SCharles.Forsyth% firmdl 0 styx.srec
418*46439007SCharles.Forsyth%
419*46439007SCharles.Forsyth.P2
420*46439007SCharles.Forsyth.LP
421*46439007SCharles.ForsythThe first argument is the number of the inferno serial port (
422*46439007SCharles.Forsyth.CW /dev/eia0
423*46439007SCharles.Forsythin this example).
424*46439007SCharles.ForsythThe second argument is the file containing the firmware image in s-record format.
425*46439007SCharles.Forsyth.LP
426*46439007SCharles.ForsythThe firmdl app prints the response code from the ROM.
427*46439007SCharles.ForsythOn successful download the ROM reports:
428*46439007SCharles.Forsyth.P1
429*46439007SCharles.ForsythJust a bit off the block!
430*46439007SCharles.Forsyth.P2
431*46439007SCharles.Forsyth.LP
432*46439007SCharles.ForsythOnce the firmware is downloaded it is immediately run.
433*46439007SCharles.ForsythThe RCX display should be showing the 'running man' symbol.
434*46439007SCharles.ForsythIf at any time the Styx firmware encounters an error, the 'running man'
435*46439007SCharles.Forsythis changed to a 'standing man' and the source code line number of the error
436*46439007SCharles.Forsythis displayed on the LCD.
437*46439007SCharles.ForsythThe firmware doesn't stay resident: it monitors the on/off button and
438*46439007SCharles.Forsythrestarts the ROM monitor when it is pressed.
439*46439007SCharles.Forsyth.NH 1
440*46439007SCharles.ForsythStart the link protocol
441*46439007SCharles.Forsyth.LP
442*46439007SCharles.Forsyth.P1
443*46439007SCharles.Forsyth% legolink 0
444*46439007SCharles.Forsyth%
445*46439007SCharles.Forsyth.P2
446*46439007SCharles.Forsyth.LP
447*46439007SCharles.ForsythThe legolink argument is the serial port over which to run the link protocol.
448*46439007SCharles.ForsythThis will be the same as the first argument to the firmdl command.
449*46439007SCharles.Forsyth.LP
450*46439007SCharles.ForsythOnce started the legolink command creates the file
451*46439007SCharles.Forsyth.CW /net/legolink
452*46439007SCharles.Forsythin the Inferno
453*46439007SCharles.Forsythname space.  Any reads/writes of this file are the payload data of the link protocol.
454*46439007SCharles.Forsyth.NH 1
455*46439007SCharles.ForsythMount the brick name space
456*46439007SCharles.Forsyth.LP
457*46439007SCharles.Forsyth.P1
458*46439007SCharles.Forsyth% mount -o -A /net/legolink /n/remote
459*46439007SCharles.Forsyth.P2
460*46439007SCharles.Forsyth.LP
461*46439007SCharles.ForsythThe
462*46439007SCharles.Forsyth.CW -A
463*46439007SCharles.Forsythflag to mount prevents the command from trying to
464*46439007SCharles.Forsythdo authentication
465*46439007SCharles.Forsython the link before running the Styx protocol over it.
466*46439007SCharles.ForsythThe
467*46439007SCharles.Forsyth.CW -o
468*46439007SCharles.Forsythoption uses an older version of Styx.
469*46439007SCharles.ForsythThe second argument to mount is the the file over which the Styx protocol will be run.
470*46439007SCharles.ForsythRaw Styx messages are written to and read from this file.
471*46439007SCharles.ForsythThe third argument is the directory on which to mount the name space presented by the
472*46439007SCharles.ForsythStyx server on the other end of the link \- the firmware on the Brick.
473*46439007SCharles.Forsyth.NH 1
474*46439007SCharles.ForsythExplore the name space
475*46439007SCharles.Forsyth.LP
476*46439007SCharles.Forsyth.P1
477*46439007SCharles.Forsyth% cd /n/remote
478*46439007SCharles.Forsyth% ls
479*46439007SCharles.Forsythmotor
480*46439007SCharles.Forsythsensor
481*46439007SCharles.Forsyth% ls motor
482*46439007SCharles.Forsythmotor/0
483*46439007SCharles.Forsythmotor/1
484*46439007SCharles.Forsythmotor/2
485*46439007SCharles.Forsythmotor/012
486*46439007SCharles.Forsyth% ls sensor
487*46439007SCharles.Forsythsensor/0
488*46439007SCharles.Forsythsensor/1
489*46439007SCharles.Forsythsensor/2
490*46439007SCharles.Forsyth%
491*46439007SCharles.Forsyth.P2
492*46439007SCharles.Forsyth.LP
493*46439007SCharles.ForsythAttach a motor to the first output and a button sensor to the first input
494*46439007SCharles.Forsythand then try the following...
495*46439007SCharles.Forsyth.LP
496*46439007SCharles.ForsythStart motor...
497*46439007SCharles.Forsyth.P1
498*46439007SCharles.Forsyth% cd motor
499*46439007SCharles.Forsyth% echo -n f7 > 0
500*46439007SCharles.Forsyth%
501*46439007SCharles.Forsyth.P2
502*46439007SCharles.Forsyth.LP
503*46439007SCharles.ForsythReverse the motor...
504*46439007SCharles.Forsyth.P1
505*46439007SCharles.Forsyth% echo -n r7 > 0
506*46439007SCharles.Forsyth%
507*46439007SCharles.Forsyth.P2
508*46439007SCharles.Forsyth.LP
509*46439007SCharles.ForsythStop the motor (float)...
510*46439007SCharles.Forsyth.P1
511*46439007SCharles.Forsyth% echo -n F0 > 0
512*46439007SCharles.Forsyth%
513*46439007SCharles.Forsyth.P2
514*46439007SCharles.Forsyth.LP
515*46439007SCharles.ForsythNotice the need for the
516*46439007SCharles.Forsyth.CW -n
517*46439007SCharles.Forsythflag to echo.  The firmware is a bit touchy about
518*46439007SCharles.Forsyththe format of the motor control messages \- they have to be 2 bytes long.
519*46439007SCharles.Forsyth.LP
520*46439007SCharles.ForsythRun the motor for (a little more than) 5 seconds...
521*46439007SCharles.Forsyth.P1
522*46439007SCharles.Forsyth% echo -n r7 > 0; sleep 5; echo -n F0 > 0
523*46439007SCharles.Forsyth%
524*46439007SCharles.Forsyth.P2
525*46439007SCharles.Forsyth.LP
526*46439007SCharles.ForsythIt takes time on the slow link to open the file for the control message to
527*46439007SCharles.Forsythstop the motor.  It should be possible to reduce the delay by keeping the file open:
528*46439007SCharles.Forsyth.P1
529*46439007SCharles.Forsyth% {echo -n r7; sleep 5; echo -n F0} > 0
530*46439007SCharles.Forsyth%
531*46439007SCharles.Forsyth.P2
532*46439007SCharles.Forsythbut the firmware only accepts command messages written to file offset 0.
533*46439007SCharles.Forsyth.br
534*46439007SCharles.Forsyth[Fixing this is left as an exercise for the reader!]
535*46439007SCharles.Forsyth.LP
536*46439007SCharles.ForsythOk, lets play with a sensor...
537*46439007SCharles.Forsyth.P1
538*46439007SCharles.Forsyth% cd /n/remote/sensor
539*46439007SCharles.Forsyth% echo b0 > 0
540*46439007SCharles.Forsyth% cat 0
541*46439007SCharles.Forsyth0%
542*46439007SCharles.Forsyth.P2
543*46439007SCharles.Forsyth.LP
544*46439007SCharles.ForsythNote that the sensor file isn't as fussy about its message format as the motor file.
545*46439007SCharles.Forsyth.LP
546*46439007SCharles.ForsythClick the button a few times and then try reading the sensor file again
547*46439007SCharles.Forsyth.P1
548*46439007SCharles.Forsyth% cat 0
549*46439007SCharles.Forsyth4%
550*46439007SCharles.Forsyth.P2
551*46439007SCharles.Forsyth.LP
552*46439007SCharles.ForsythLet's try a blocking read on the sensor
553*46439007SCharles.Forsyth.P1
554*46439007SCharles.Forsyth% echo b5 > 0
555*46439007SCharles.Forsyth% cat 0
556*46439007SCharles.Forsyth\fR[click the button 5 times]\fP
557*46439007SCharles.Forsyth5%
558*46439007SCharles.Forsyth.P2
559*46439007SCharles.Forsyth.LP
560*46439007SCharles.ForsythOk, we're done playing \- unmount the brick name space
561*46439007SCharles.Forsyth.P1
562*46439007SCharles.Forsyth% cd
563*46439007SCharles.Forsyth% ls /n/remote
564*46439007SCharles.Forsyth/n/remote/motor
565*46439007SCharles.Forsyth/n/remote/sensor
566*46439007SCharles.Forsyth% unmount /n/remote
567*46439007SCharles.Forsyth% ls /n/remote
568*46439007SCharles.Forsyth%
569*46439007SCharles.Forsyth.P2
570*46439007SCharles.Forsyth.SH
571*46439007SCharles.ForsythThe Clockface robot
572*46439007SCharles.Forsyth.LP
573*46439007SCharles.ForsythSo we have a means of controlling the brick via Styx.
574*46439007SCharles.ForsythWe now needed to design a robot suitable for demonstrating the software.
575*46439007SCharles.Forsyth.LP
576*46439007SCharles.ForsythThe robot needed to be static; the IR link needs to maintain line-of-sight contact
577*46439007SCharles.Forsythbetween the IR tower and the brick.
578*46439007SCharles.ForsythThe operation of the robot needed to be clearly visible to a group of people in a
579*46439007SCharles.Forsythconference room.
580*46439007SCharles.ForsythWe also wanted a robot that we could layer services on top of each other to demonstrate
581*46439007SCharles.Forsyththe versatility of Inferno name spaces.
582*46439007SCharles.Forsyth.LP
583*46439007SCharles.ForsythWe decided on a clock robot.  The robot is static; it doesn't move around the room!
584*46439007SCharles.ForsythThe clockface would be visible and its operation obvious
585*46439007SCharles.Forsythto a group of people in a reasonably large room.
586*46439007SCharles.Forsyth.LP
587*46439007SCharles.ForsythThe clockface robot also allowed us to layer services:
588*46439007SCharles.Forsyth.LP
589*46439007SCharles.ForsythInitially we just mount the Brick name space.
590*46439007SCharles.ForsythThis name space represents the services of the brick \- nothing is known of the
591*46439007SCharles.Forsythrobot model that is attached to the brick.
592*46439007SCharles.Forsyth.LP
593*46439007SCharles.ForsythWe then start the clockface service.  This knows how to use the name space of
594*46439007SCharles.Forsyththe brick to control the motors and sensors of the clockface model.
595*46439007SCharles.ForsythThe clockface service provides a
596*46439007SCharles.Forsyth.CW clockface
597*46439007SCharles.Forsythfile which accepts
598*46439007SCharles.Forsythtime values (e.g.
599*46439007SCharles.Forsyth.CW '14:35' ),
600*46439007SCharles.Forsyththe service then runs motors and reads sensors
601*46439007SCharles.Forsythto set the hands of the robot to the specified time.
602*46439007SCharles.Forsyth.LP
603*46439007SCharles.ForsythOn top of the clockface service we can run a world-clock service.
604*46439007SCharles.ForsythThis periodically reads the system clock and writes time messages to the
605*46439007SCharles.Forsyth.CW clockface
606*46439007SCharles.Forsythfile resented by the clockface service.
607*46439007SCharles.ForsythThe world-clock service also provides a configuration file so that the user
608*46439007SCharles.Forsythcan set the time zone of the clock display.  Writing a time zone abbreviation into
609*46439007SCharles.Forsyththe control file causes the world-clock service to write new time messages into
610*46439007SCharles.Forsyththe
611*46439007SCharles.Forsyth.CW clockface
612*46439007SCharles.Forsythfile to reflect the new time zone setting.
613*46439007SCharles.Forsyth.LP
614*46439007SCharles.ForsythBy using Inferno's ability to export a name space, any of the clock  services
615*46439007SCharles.Forsythcould be running anywhere in the network.
616*46439007SCharles.ForsythThe Lego brick could be attached to machine A.
617*46439007SCharles.ForsythMachine B could be running the legolink application using
618*46439007SCharles.Forsyth.CW /dev/eia0
619*46439007SCharles.Forsythimported from machine A.
620*46439007SCharles.ForsythMachine C could mount the
621*46439007SCharles.Forsyth.CW /net/legolink
622*46439007SCharles.Forsythfile imported from machine B's
623*46439007SCharles.Forsythname space.
624*46439007SCharles.ForsythMachine D could then run the clockface service over the brick's name space
625*46439007SCharles.Forsythimported from machine C, etc. etc.
626*46439007SCharles.Forsyth.LP
627*46439007SCharles.ForsythThe source of the clockface service is
628*46439007SCharles.Forsyth.CW clockface.b .
629*46439007SCharles.Forsyth.br
630*46439007SCharles.ForsythThe source of the world-clock service is
631*46439007SCharles.Forsyth.CW worldclock.b .
632*46439007SCharles.Forsyth.SH
633*46439007SCharles.ForsythFinal Notes
634*46439007SCharles.Forsyth.LP
635*46439007SCharles.ForsythThe firmware could do with some more work on it, such as the overly strict
636*46439007SCharles.Forsythlength restriction on motor control messages, or the fact that control messages
637*46439007SCharles.Forsythmust be written at offset 0.
638*46439007SCharles.Forsyth.LP
639*46439007SCharles.ForsythPlease feel free to fix problems and make modifications.  I am more than happy
640*46439007SCharles.Forsythto discuss the software and answer any questions you may have.
641*46439007SCharles.Forsyth.LP
642*46439007SCharles.ForsythHave Fun!
643