Figure. 1 shows a top-level block diagram of the cryo board's firmware, from high-level software down to the VHDL.
Fig. 1: Firmware block diagram
The left-hand side shows a crython command (set_heater_switch) traverses the system. It is translated as follows:
from a Python call to a CGI request with JSON-formatted arguments
into a call to the JSON_set_heater_switch C function, which is passed a Jansson array containing the arguments "1" (an integer) and "True" (an integer).
into a call to the set_heater_switch C function, with C-language arguments "1" (an integer) and "1" (an integer)
into a SysFS file write, which traverses the userspace-kernel boundary
into a memory-mapped register interaction
into VHDL
The response traverses the reverse path.
Software Components
In the following sections, we describe the cryo board's software stack. We do so approximately in the order they are involved in e.g. a Python request from a remote PC.
Higher-Level Languages
Remote interaction is possible via Python on a remote PC. In addition, the board itself can execute code written in either Python or Lua.
Python (on a PC)
On a PC, the board is accessed via the crython library. This library includes both a remote-call interface via JSON, and a local library used for reception of streamer packets. Two classes are provided:
crython.CryoBoard (for controlling the board), and
Code for crython.py is actually quite short (see the source code) and, if you're looking for board-level function calls, obscure. Crython itself only does a few things:
relays function calls to the cryo board itself via JSON,
instantiates a stripped-down version of the libcrython shared library, used for constants and the packet interface,
wraps these lower-level interfaces in a friendlier manner, and
tries to present a user-friendly interface (i.e. via tab-completion in ipython)
Python (on the cryo board)
TODO.
Lua
Although on-board interaction with hardware is possible using Python, it is quite slow. Lua is an alternative to Python that is an order of magnitude faster. It is, however, more difficult to code and debug.
Code that is routinely and frequently run on the board should be written in Lua for efficiency reasons.
Web Stack
All remote interactions (both through web browsers and Python) occur through the web stack. This stack consists of:
the webserver (lighttpd),
a fastCGI backend,
static HTML pages, and
a JavaScript library.
Lighttpd
The board uses lighttpd as a webserver. Unlike the DFMUX, no fastpath is present; remote methods are served by a FastCGI backend.
FastCGI Server
The board's FastCGI backend translates JSON requests into C function calls. It does so automatically, using some black magic:
C-language function calls are coded normally (i.e. using c types and sensible function definitions) in cryoboard.c
Wrappers for these C-language functions are instantiated via wrap() macro calls in the same file
The wrap() macro (defined in support.h) automatically parses and translates inputs and outputs into Jansson JSON structures.
The FastCGI server invokes these wrappers instead of the underlying C functions.
Static Pages
Earlier revisions of the cryo board used a template language (mako) to dynamically generate the cryo board's web interface. However, mako and other template languages operated slowly on the old cryo board. As the new cryo board's processor is an order of magnitude slower, an alternative was necessary.
The new cryo board still generates pages from a template language (for example, look at the source for [[http://kingspeak.physics.mcgill.ca/cgi-bin/gitweb.cgi?p=cryo_spartan6/base;a=blob;f=pages/readout.html.tpl][readout.tpl]), but they are pre-compiled during the firmware build process and cannot contain dynamic content.
JavaScript
The pages are animated by a JavaScript library that permits live board interactions. These interactions lean on cryo.js, a JavaScript library that exposes the board's API to JavaScript via JSON function calls. (Note that cryo.js is actually another mako template that is compiled into static JavaScript by the firmware build process.)
Streamer
The cryo board also operates an UDP streamer similar to the DFMUX's. This streamer, however, is capable of streaming to multiple UDP unicast or multicast IPs simultaneously.
SQLite Database
Many method calls (e.g. the set_heater_switch example diagrammed above) interact directly with hardware. However, methods such as get_sensor_name and set_sensor_name involve only software. This state must be shared between different processes on the cryo board (e.g. FastCGI server processes, the streamer, and lua processes). Otherwise, a set_sensor_name call to one process may not be reflected in another process that keeps its own copy of the channel name.
To share non-hardware state, we use a SQLite database. SQLite is not a full-fledged database server, since (for example) it does not permit database connections over a network. It is ideal for embedded applications (such as cell phones) where a lightweight database is needed.
A database schema is available here. On boot-up, the database is copied from the (read-only) MicroSD card to a temporary ramdisk location, where it is used during regular operation. This active database must be copied back to the MicroSD if board settings are to be persistent across reboots.
Device Driver
The cryoelectronics peripheral performs heater and sensor biasing and readout, and is written in VHDL. It is memory-mapped, i.e. it presents itself to software via a number of memory locations the Microblaze can read or write. These memory locations are protected by a memory management unit (MMU), and are only accessible by the Linux kernel. Thus, the cryoelectronics peripheral is accompanied by a device driver.
Hardware is exposed to userspace via the SysFS virtual filesystem. The files it exposes are available on the board at /sys/bus/of_platform/devices/*.cryo-sequencer/.