Hexabus Assembler

myeisha edited this page Sep 20, 2013 · 9 revisions
Clone this wiki locally

This page describes the language of the Hexabus Assembler. Hexabus Assembler programs can be autogenerated using the Hexabus Compiler, which is the recommended way to go. There might be cases however where you might find it useful to manually edit a Hexabus Assembler program manually.

For installation notes, please refer to the Hexabus Compiler page.

Structure of a HBA file

The structure of a HBA file resembles the internal data structures of the state machine interpreter which is part of the firmware of a Hexabus device. There the state machine is split up into several tables, most notably the condition table and the transition table. Therefore a Hexabus Assembler program is made up of two (main) structures: conditions and states (each state is basically defined by its set of outgoing transitions).

As in Hexabus Compiler programs, comments are denoted by an octothorpe and span to the next line break.

The first statement in a Hexabus Assembler program is the definition of the target address, device name, machine ID and the initial state:

target d00f::50:c4ff:fe04:1234;
device_name MyHexabusPlug;
machine 0;
startstate init;

The target address is used by the hexaupload tool which transfers the binary files from the Hexabus Assembler to the Hexabus devices. It can be overridden on the command line when hexaupload is started. The device name is the name the device will appear under in hexinfo and other hexabus tools. If you enter device_name 0, then the device name will not be changed. The machine ID is needed if several devices run the same Hexabus Compiler state machine, so that all devices know which state machine they "belong to" (it is used to reset the whole shared state machine in case one of the devices running it experiences a power outage). If you want to program a single device using Hexabus Assembler, you can set this ID to 0. In this example, the state with the name init is defined as the starting state.

Afterwards, there follow several conditions:

condition toggle_on {
  ip := fe80:0000:0000:0000:0050:c4ff:fe04:020c;
  eid := 25;
  value == 16;
}

condition toggle_off {
  ip := fe80:0000:0000:0000:0050:c4ff:fe04:020c;
  eid := 25;
  value == 32;
}

condition timer {
  timeout := 3;
}

Conditions can be (cf. conditions in Hexabus Compiler):

  • Endpoint conditions
  • Timeout conditions
  • Date/time conditions

Endpoint conditions check the value of an endpoint on a certain device. A condition has to state the IP address of the device where the endpoint is located (shorthand (::) notation is not possible), the endpoint ID, and a value. In the value line, the same comparison operators as in the Hexabus Compiler can be used.

There can be an anyhost condition, which does not check the sender of a broadcast. This can be given by a sender address of all zeroes. An anyhost condition can not be defined when the Hexabus Compiler is used.

Note: There is no sanity checking here, every program is directly translated into bytecode. This means that it is easily possible to write a program which does not make sense (e.g. using an endpoint which never broadcasts its value in a condition). If you need this kind of checks, please consider using the Hexabus Compiler!

Timeout conditions use the keyword timeout and a value. They hold whenever a state machine has remained in a state for the given amount of seconds.

Date/time conditions are given using one of the keywords hour, minute, second, day, month, year, or weekday, then a keyword for the comparison (before or after), and then an integer constant.

After all the conditions are defined, the state definitions follow. They basically correspond to the in and if statements in a Hexabus Compiler program. The conditions however have to be referenced by their name (instead of explicitely defining them in the if statement). This makes it possible to reference the same condition from several if statements. Another difference to the Hexabus Compiler is that there can be only exactly one write action (given using the set keyword) in a transition. If you want to write nothing, you have to issue a write to endpoint 0 (or use data type 0 in the byte code) (this denotes a write-nothing command for the state machine interpreter).

state init {
  if true {
    set 1 := 0;
    goodstate off;
    badstate off;
  }
}
state off {
  if toggle_on {
    set 1 := 1;
    goodstate on;
    badstate off;
  }
}

state on {
  if toggle_off {
    set 1 := 0;
    goodstate off;
    badstate on;
  }
  if timer {
    set 1 := 0;
    goodstate off;
    badstate on;
  }
}

The assembler uses a data type file which has to be given at the command line. This data type definition file is necessary. If it is not given, the data types of all the WRITEs in the resulting byte code are set to 0, which means nothing ever gets written.

After the set command, the target states of the transition follow. There is a goodstate and a badstate. The good state is entered if a the WRITE to the endpoint given in the set command succeeds, the bad state is entered if it fails.

Note: At the moment there is no application which makes use of the badstate mechanism. The badstate therefore is not relevant with current firmware versions.

After the goodstate and badstate keywords, (valid) state names have to be given.

Assembling and upload

Hexabus Assembler can be used to generate a transition graph of a program.

hbasm switchonoff.hba -g switchonoff.dot

The graph of the above program (which can be found in under examples/switchonoff.hba) looks like this:

graph of program switchonoff.hba

(conditions are rectangles. Black arrows point from a state to an outgoing transition's condition. Red arrows point from a condition to a badstate, green arrows point to a goodstate.)

It can be assembled into bytecode with the command

hbasm switchonoff.hba -d datatypes.hb -o switchonoff.hbs

(The Hexabus compiler will generate a datatype file when called with the -d option which contains datatype information of all the endpoint used in the Hexabus Compiler program. Additionally, when installing the assembler, a datatype file which has the datatypes of the endpoints defined in Currently used EIDs is placed in /usr/share/hexabus/std_datatypes.hb)

The resulting file switchonoff.hbs can be uploaded to a device with hexaupload -p switchonoff.hbs. If you want to upload the file to a different device than its target, just add the IP address of that device using the -i command line argument.

Renaming a device

You can rename a device without changing its program: Make a minimal .hba file, that means a file just containing the header, without an actual state machine:

target abcd:0000:0000:0000:0050:c4ff:fe04:1234;
device_name MyNewDevice;
machine 0;

You can then assemble that file (hbasm -i rename.hba -o rename.hbs) and upload it to the device (hexaupload -p rename.hbs). This will change the name of the device without affecting the program running on it.