psBASIC Gathers System Stats
The WallCHIPv2 Control Panel
The Project
For some reason unknown to me a DDP-24 found its way into our backyard when I was growing up. It was funny to see that giant behemoth next to my TRS-80 model I. But all those blinken lights and shiny toggle switches were way cool! The Altair and IMSAI had plenty of toggles and blinken lights too! Recently I wanted to build a steampunk like computer and wanted plenty of toggles and blinken lights like those oldies had!
The big difference between those early "mainframes" and microcomputers were that there was a great deal of internal workings available to be exported to lights. But these SBCs have most everything captured within the SOC package. Where was I to get some status info to flutter my LEDs?
NOTE: While I built this project for fun, the data gathering aspect has practical application in various forms of system monitoring. So does reporting on LEDs as opposed to a shared monitor.
The first question I had was: where was I going to get some status information to show on a row of 8 LEDs. Things like the UNIVACs, DDP-24 and DEC systems of yesteryear put system flags and registers out on the LEDs. These items aren't accessible in any useful way within the closed SOC and are isolated by the Linux process segregation. So I decided to simply show 8 bits of a binary busyness value.
NOTE: These examples require the "professional" edition of Pi Shack BASIC for the DELIMIT
command. Otherwise you have to separate the values out by hand, which is certainly possible.
I had a couple of ideas:
First up was the combined CPU load from all cores:
defint A-Z
dim field$(20)
delimit #10," "+string$(2,0)+"1" : ' Parse variable space separated ASCII tables
' ...
20100 BUSYCT=0
open "I",#10,"/proc/stat"
mat input #10,field$
close #10
BUSYCT=(VAL(field$(2))+val(field$(4))) and 255
return
BUSYCT
will contain the 8 LSBs of both the system and user loads on all CPU cores. This is perfect for printing across 8 LEDs. Obviously you can grab any of the published values and keep the full precision to be stored or displayed where ever you wish.
A second thought: what about network activity?
defint A-Z
dim field$(20)
delimit #10," "+string$(2,0)+"1" : ' Parse variable space separated ASCII tables
' ...
20000 BUSYCT=0
' Open the Linux statistic virtual file
open "I",#10,"/proc/net/dev"
'Skip the 2 header lines
line input #10,X_X$
line input #10,X_X$
' Read the remaining records until I find my NIC (wlan0)
do until eof(10)
mat input #10,field$
if field$(2)="wlan0:" then
' FOUND! Capture the data and get out of here.
' 4=packets in, 12=packets out see proc(5)
BUSYCT=(VAL(field$(4))+VAL(field$(12))) and 255
exit do
end if
loop
close #10
return
The headers of this file document the fields. The file can be a bit tricky to read, since its output formatting gets quite sloppy. But this works for my purposes and is quite simple. As before I mask (AND
) the sum of the incoming and outgoing packets to keep only the 8 LSBs in BUSYCT
.
The MAT INPUT
command is the most flexible way to read columns from some kind of separated value file (comma, colon, tab, space, ...). With a single dimensional array it reads one record and fills the array from it. It won't complain about having too many columns in the file or too many columns in the array. Array elements that don't have matching data are simply filled with their empty value (0 or ""). Excess columns in the file are discarded.
And its convenient, since you don't have to write out all those array elements!
Get your copy of Pi Shack BASIC here!
In the next episode we'll blink some lights!