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