Friday, August 28, 2015

Browser controlled RF synthesizer (Part3)

The third step in constructing a simple webpage controlled RF synthesizer is the application level software. (The previous step was described here with the hardware described here)

Since all of the interfacing software is in C/C++, I wanted to use a light weight http server framework that I could build application specific C++ code into.  I did not want to use gateways or other scripts for performance reasons, not so much for this particular activity but for others which might require higher performance between the http command and the hardware.  There are a couple of good packages available for these purposes.  After a small amount of experimentation I decided to use libmicrohttpd.  It is pretty basic and doesn’t get in your way for simple servers like this.

Once you have the hardware control software and an http server framework, the next step is to decide on the building blocks for the actual user interface itself.  In support of this, there are a dizzying array of software packages including jQuery and Dojo.  For this particular application I wanted to start simple and use basic html, css, and javascript.

The browser component is structured as a simple table with a CSS defined border and cell entry formats.  The basic actions buttons with the numeric inputs being text box forms.  An example is shown below.
Browser Control Panel for Synthesizer

The buttons at the top allow the application software to be restarted, the BeagleBone Black to be rebooted, or the current configuration parameters to be saved persistently (and used at next power up).  The shutdown button is only for testing and is not required for use.  The box below that indicates if the browser is actually connected to the device, the time on the device (which should update every second if everything is working), the PLL lock status at the given frequency and the output level as currently read from the device.  The next set of control buttons allows the device to run, sweep, and continuously monitor the output power level.  The “run” actually will just power on or off the synthesizer boards allowing you to quiesce everything in case you are wondering where a certain signal is coming from.  The level monitoring allows an output level update, constant monitoring (~100Hz) or to be completely quiet – again in case there are questions about where a certain signal is coming from.  The final panel allows user inputs of various parameters and shows the currently in effect values.  These allow for a single constant frequency and level setting (start parameters), or a sweep in both frequency and level (from start to stop values) along with step sizes when sweeping for both level and frequency.  While sweeping the time at any given frequency and level can be configured from 0 (as fast as the device can step) to seconds using the “DwellTime” value.

This application is simple enough that it doesn’t merit a full MVC (model view controller) approach, however, a simplified variant is used – mostly to evaluate the approach.  The browser client code is here while the server code is here.

The state coming back from the server is expressed as a single JSON object.  This is easy to parse in javascript.  To keep things responsive the state is requested from the server using http query every 100mS.  The state variable contains all of the elements in the display.  The JSON object is then used to update all of the DIVS in the page.  This represents a single HTTP GET on the “getstate” URL and keeps the client parsing very simple along with the response construction. Each user input generates a HTTP GET on the “setstate” URL with the values being a name/value pair.  Again, this keeps the HTTPD server parsing simple and allows for easy testing with human synthesizable commands.  The network API is then simple enough that control can also be scripted using WGET. An external host can use bash scripts to control the device for automated test setups.

The use of HTTP GET is not in line with network security and best practices, however, there is nothing secure about this device.  It was intended for use on a dedicated and isolated network with other instruments.  There is no login to prevent conflicts among users/sessions. The server will server up any file on the BBB.  I am sure there are numerous other security holes within the configuration of the BBB Linux configuration as I have it setup.  The whole point of this is simplicity and experimentation.

The one final interesting portion to note is the persistent configuration saving feature.  Once you get things setup for a particular measurement it is exceedingly useful to be able to save it and then later just power on the device and have it start working like you wanted to without even having to attach to it with an Ethernet or  browser.  The BBB file system is mounted read only for robustness.  The state parameters are read from a file on startup.  When the server receives a save configuration command, the file system is re-mounted read/write, the configuration file with the current parameters written and then the root file system re-mounted read only.  This produces a small window in time during which the device root file system may be vulnerable to interruptions.  In practice, this has not proven to be a problem as the entire re-mount, write 200 bytes, re-mount operation occurs within milliseconds.  If you are prepared to re-partition the eMMC on the BBB one could create a small spare partition and read/write the configuration file through a raw block device.  This side steps any file system checks and integrity concerns.  

Saturday, August 15, 2015

Browser controlled RF synthesizer (Part2)

The second step in assembling the synthesizer (based on this hardware) is configuring the BBB Linux distribution.

An older rev B BeagleBone Black is used as the primary control board.  This uses Angstrom Linux. I cannot speak to the differences between this and rev C with Debian distributions.  I will say that I find the Angstrom distribution slightly more difficult to work with as I am accustomed to the standard unix utilities and configuration approach.  Angstrom’s use of select packages such as connman and busybox help resource footprint but often send me to the web searching for how to do basic system administration and configuration actions I have done for years.  Said differently, I believe you can do all of these and at least as easily with Debian on a rev C board.

The following steps are in the notes.txt file in the  BREC/SynHttpd software. The text here provides a little more background and narrative beyond the terse command notes.

The first step is to disable a set of default services that are not used and that use the http default port 80.  There are plenty of good tutorials on the web and all boil down to “systemctl disable <svc>”, where <svc> is cloud9.service, gateone.service, bonescript.service, bonescript.socket, bonescript-autorun.service, avahi-daemon.service, gdm.service, and mpd.service.

The next step is to setup the synthesizer application to start automatically at boot time.  Again, there are plenty of good tutorials on the web and there are examples in the BREC/Scripts directory of the software.  I configured a service to start a bash script via systemd.  The main script is placed in /home/root with the rest of the executables and the script launches the actual applications.  To me, systemd has quirks like crond, you don’t have the exact same environment as your normal shell (just enough to throw things off) and the configuration files take some getting used to.  You can use “systemctl status <service you defined>” to check on the application and its children’s status and see any stdio.  It takes some getting used to.  There are items to be aware of like exiting with a good status or having your processes “cleaned up” for you.  You need to start the applications and get them in the background before a predefined time limit or the service process tree is killed as being hung.  All of these things can be adjusted in the configuration files or in your startup script – you just have to pick an approach and understand the subtleties of the configuration you have defined. There are also issues to be aware of with starting so quickly on boot.  One of particular importance is “/dev/uio0” not being present for a brief period of time.  This is the special file the libpru code uses to access the PRU.  I found that startup services I created would randomly seem to not start.  It turned out that sometimes by the time they went to open the pru the special file was available and sometimes not.  By just checking for the existence of the special file in the startup of the service script the service reliably starts every time.

So at this point you have a BBB that lets you start your own web service on startup.  The next step is to safely allow shutdowns without other action.  To do this the root disk is mounted as read only. There are several examples on the web as well as a sample /etc/fstab in the BREC/SynHttpd/fstab-ro file.  To make root writeable you just issue “mount –o remount,rw /” and everything is back to a standard writeable file system. I have to admit this works really well and consider using this on normal development boards where I write to the root partition.  A read only root file system speeds the boot time but also helps when working with a new board and linux gets powered down without warning.  There are posts and comments on the web regarding early perceived issues with a read only file system on BBB (e.g. applications could not access the gpio pins through sysfs), however, I experienced no issues – everything works as expected including all device interfacing and other system services.