Addressing multiple B200 devices through the UHD API - usrp

I have 2 B210 radios on USB3 on a Windows 10 system using the UHD USRP C API latest release and Python 3.6 as the programming environment. I can "sort of" run them simultaneously in separate processes but would like to know if it is possible to run them in a single thread? How?
1 Happy to move to Linux if it makes things easier, I'm just more familiar with Windows.
2 "sort of" = I sometimes get errors which might be the two processes colliding somewhere down the stack.
The code below illustrates the race condition, sometimes one or both processes fail with error code 40 (UHD_ERROR_ASSERTION) or occasionally code 11 ( UHD_ERROR_KEY )
from ctypes import (windll, byref, c_void_p, c_char_p)
from multiprocessing import Process, current_process
def pread(argstring):
# get handle for device
usrp = c_void_p(0)
uhdapi = windll.uhd
p_str=c_char_p(argstring.encode("UTF8"))
errNo = uhdapi.uhd_usrp_make(byref(usrp),p_str)
if errNo != 0:
print("\r*****************************************************************")
print("ERROR: ",errNo," IN: ", current_process())
print("=================================================================")
if usrp.value != 0:
uhdapi.uhd_usrp_free(byref(usrp))
return
if __name__ == '__main__':
while True:
p2 = Process(target=pread, args=("",))
p1 = Process(target=pread, args=("",))
p1.start()
p2.start()
p1.join()
p2.join()
print("end")

Yes, you can have multiple multi_usrp handles.
By the way, note that UHD is natively C++, and the C API is just a wrapper around that. It's designed for generating scripting interfaces like the Python thing you're using (don't know which interface between Python and the C API you're using – something self-written?).
While it's possible, there's no good reason to call the recv and send functions from the same thread – most modern machines are multi-threaded, and you should make use of that. Real-time SDR is a CPU-intensive task and you should use all the CPU resources available to get data to and from the driver, as to avoid overflowing buffers.

Related

Test jax.pmap before deploying on multi-device hardware

My question is fairly simple:
I am coding on a single-device small laptop and I am using jax.pmap because my code will run on multiple TPUs. I would like to "fake" having multiple devices to test my code and try different things.
Is there any way to do it? I doubt the solution will be within Jax though. Thanks!
You can spoof multiple XLA devices backed by a single device by setting the following environment variable:
$ set XLA_FLAGS="--xla_force_host_platform_device_count=8"
In Python, you could do it like this
# Note: must set this env variable before jax is imported
import os
os.environ['XLA_FLAGS'] = "--xla_force_host_platform_device_count=8"
import jax
print(jax.devices())
# [CpuDevice(id=0), CpuDevice(id=1), CpuDevice(id=2), CpuDevice(id=3),
# CpuDevice(id=4), CpuDevice(id=5), CpuDevice(id=6), CpuDevice(id=7)]
import jax.numpy as jnp
out = jax.pmap(lambda x: x ** 2)(jnp.arange(8))
print(out)
# [ 0 1 4 9 16 25 36 49]
Note that when a only a single physical device is present, all the "devices" here will be backed by the same threadpool. This will not improve performance of the code, but it can be useful for testing the semantics of parallel implementations on a single-device machine.

How to simulate a TTY while also piping stdio?

I'm looking for a cross-platform solution for simulating a TTY (PTY?) in Rust while also piping stdio.
The frontend is based on web technologies where an interactive terminal is shown. Users can run commands and all their inputs will be sent to the Rust backend, where the commands get executed. Std{in,out,err} are sent back end forth to allow for an interactive experience.
Here's a simplified example (piping only stdout):
let mut child = Command::new(command)
.stdout(Stdio::piped())
.spawn()
.expect("Command failed to start");
loop {
let read = reader.read(&mut chunk);
if let Ok(len) = read {
if len == 0 {
break;
}
let chunk = &chunk[..len];
send_chunk(chunk); // send chunk to frontend
} else {
eprintln!("Err: {}", read.unwrap_err());
}
}
Currently, running the command tty prints: not a tty, but ideally, it should output a file name (e.g /dev/ttys002). And programs, such as atty should return true.
Running only the backend in a terminal, with stdio inherited works, but then I can't send the stdio back to the frontend.
Define "cross platform". As far as PTYs is concerned, those are pseudo devices supported by the kernel, complete with ioctls and everything. As a matter of fact a lot of the things your terminal emulator will have to do, is implementing the receiving end of those ioctls.
As long as you're on a machine with the BSD API (which includes Linux), the best course of action would be to openpty and roll with that. If you want to be portable to non BSD PTY capable systems, you'll have to hook the tty functions in the child process (by preloading a helper library).

How do I use the bluetooth module in conjunction with the multiprocessing module?

I am using python 3.5 and OSX 10.13.2.
I am attempting to gather EEG data from a bluetooth EEG recording device while a human is watching a pygame GUI. Because the bluetooth device sends data at about 512 Hz and the pygame GUI updates at about 25Hz, I'm thinking that including the gathering of the bluetooth data and the updating of the GUI in the same loop/process is not appropriate.
Therefore, I want to create two concurrent processes: one for the gathering of bluetooth input and one for displaying/updating the pygame GUI. I think I have figured out how to run a pygame window in a separate process, but creating a separate process using the multiprocessing module that connects to and reads input from my bluetooth device is not working out well.
When I run the code below, execution seems to stop on this line socket.connect(('B0:B4:48:F6:38:A1', 1)): nothing in the connect() method is printed. Is this a problem with Mac OSX, the bluetooth module, Python, or something else? Does anyone know how I can fix this? If not, does anyone have a different way I could approach my initial problem of gathering data from a bluetooth device and updating a GUI in parallel using python 3.5?
import multiprocessing, time, bluetooth
def connect():
socket = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
try:
socket.connect(('B0:B4:48:F6:38:A1', 1))
print("connected to device!!")
except Exception as e:
print("failed to connect :(")
def wait_and_do_nothing():
print("just sleeping over here in this process")
time.sleep(5)
process1 = multiprocessing.Process(target=connect, args=())
process2 = multiprocessing.Process(target=wait_and_do_nothing, args=())
process1.start()
process2.start()
process1.join()
process2.join()
print("finished")
The output of the above code is:
finished
I solved my problem. For one, I should have wrapped the multiprocessing code in an if statement like the one below. Two, I should have set the start method to 'spawn' instead of 'fork' like I do below:
if __name__ == '__main__':
multiprocessing.set_start_method('spawn', force=True)
process1 = multiprocessing.Process(target=connect, args=())
process2 = multiprocessing.Process(target=wait_and_do_nothing, args=())
process1.start()
process2.start()
process1.join()
process2.join()

fortran netcdf close parallel deadlock

I am adapting a fortran mpi program from sequential to parallel writing for certain types of files. It uses netcdf 4.3.3.1/hdf5 1.8.9 parallel. I use intel compiler version 14.0.3.174.
When all reads/writes are done it is time to close the files. At this point, the simulations does not continue anymore. So all calls are waiting. When I check the call stack from each processor I can see the master root is different compared to the rest of them.
Mpi Master processor call stack:
__sched_yield, FP=7ffc6aa978b0
opal_progress, FP=7ffc6aa978d0
ompi_request_default_wait_all, FP=7ffc6aa97940
ompi_coll_tuned_sendrecv_actual, FP=7ffc6aa979e0
ompi_coll_tuned_barrier_intra_recursivedoubling, FP=7ffc6aa97a40
PMPI_Barrier, FP=7ffc6aa97a60
H5AC_rsp__dist_md_write__flush, FP=7ffc6aa97af0
H5AC_flush, FP=7ffc6aa97b20
H5F_flush, FP=7ffc6aa97b50
H5F_flush_mounts, FP=7ffc6aa97b80
H5Fflush, FP=7ffc6aa97ba0
NC4_close, FP=7ffc6aa97be0
nc_close, FP=7ffc6aa97c00
restclo, FP=7ffc6aa98660
driver, FP=7ffc6aaa5ef0
main, FP=7ffc6aaa5f90
__libc_start_main, FP=7ffc6aaa6050
_start,
Remaining processors call stack:
__sched_yield, FP=7fffe330cdd0
opal_progress, FP=7fffe330cdf0
ompi_request_default_wait, FP=7fffe330ce50
ompi_coll_tuned_bcast_intra_generic, FP=7fffe330cf30
ompi_coll_tuned_bcast_intra_binomial, FP=7fffe330cf90
ompi_coll_tuned_bcast_intra_dec_fixed, FP=7fffe330cfb0
mca_coll_sync_bcast, FP=7fffe330cff0
PMPI_Bcast, FP=7fffe330d030
mca_io_romio_dist_MPI_File_set_size, FP=7fffe330d080
PMPI_File_set_size, FP=7fffe330d0a0
H5FD_mpio_truncate, FP=7fffe330d0c0
H5FD_truncate, FP=7fffe330d0f0
H5F_dest, FP=7fffe330d110
H5F_try_close, FP=7fffe330d340
H5F_close, FP=7fffe330d360
H5I_dec_ref, FP=7fffe330d370
H5I_dec_app_ref, FP=7fffe330d380
H5Fclose, FP=7fffe330d3a0
NC4_close, FP=7fffe330d3e0
nc_close, FP=7fffe330d400
RESTCOM`restclo, FP=7fffe330de60
driver, FP=7fffe331b6f0
main, FP=7fffe331b7f0
__libc_start_main, FP=7fffe331b8b0
_start,
I do realize one call stack contain bcast an the other a barrier. This might cause a deadlock. Yet I do not foresee how to continue from here. If a mpi call is not properly done (e.g only called in 1 proc), I would expect an error message instead of such behaviour.
Update: the source code is around 100k lines.
The files are opened this way:
cmode = ior(NF90_NOCLOBBER,NF90_NETCDF4)
cmode = ior(cmode, NF90_MPIIO)
CALL ipslnc( NF90_CREATE(fname,cmode=cmode,ncid=ncfid, comm=MPI_COMM, info=MPI_INFO))
And closed as:
iret = NF90_CLOSE(ncfid)
It turns out when writting NF90_PUT_ATT, the root processor has a different value compared to the others. Once solved, the program runs as expected.

Where do I start when creating a microcontroller interfacing program with a GUI?

I'm in a senior design class for my college's computer engineering program. I'm not very good with Embedded Systems. I need to create a program that can send instruction to a microcontroller and it should have a GUI. Someone else is programming the microcontroller so I'm mostly just responding to what they will output to me. I really have no idea where to start with this, I'm a little swamped/overwhelmed on my final semester. Would someone mind pointing me in the right direction?
Additional info: We are using a TI-msp430f2274 for the device and it's really just outputting the readings of 3 gyroscopes. I'm thinking about using GTK to create the GUI but I am looking to see if there's something better.
Edit: My project is a roller alignment tool that uses gyroscopes to compare two rollers. The program would send an instruction to "zero" the tool to one roller and receive a stream of data that says the offset difference of the next roller.
We are using a TTL-232R cable with a UART interface and the program should work on Windows. I have no idea how you talk to it. College has crushed me.
If you're using a windows machine then Visual Studio and a Windows Forms Application could do the trick. I've used it previously to interface with temperature sensors and other control equipment via USB and other projects involving reading from USB Human Interface Devices. So without understanding the specifics of your project, as an IDE Visual Studio, I think, is the best and most intuitive and using the Windows API you can achieve a lot with your code.
Visual Studio 2012
HTH.
p.s. I write most of my code in VB using VS but it will support other languages too...
Edit: some example code of reading from a com port:
Sub ReceiveSerialData()
' Receive strings from a com port
Dim comport as string = "COM 6" 'or whatever com you want...
Dim baud as integer = 9600 'or whatever baud you want...
Try
com = My.Computer.Ports.OpenSerialPort(comport)
com.ReadTimeout = 10000
com.BaudRate = baud
While (com.IsOpen)
Dim Incoming As String = com.ReadLine()
If Incoming Is Nothing Then
Exit While
Else
'do something here with your com data
'i.e. display it in a rich text box, or whatever...
End If
End While
Catch ex As Exception
' display your errors here if you wish....
End Try
End Sub
I think the other answers though, esp about using tcl probably make more sense from an embedded systems point of view. I simply have no experience with them whatsoever hence my VB'ness. :-)
Since you mentioned that you've used tcl before, I'm giving my answer in tcl since IMHO it's the easiest way to do this and therefor the right tool for the right job.
The core advantage of tcl (and indeed one of the reasons it's loved by its fans) is that it's very, very cross-platform. While in other languages cross platform simply means "can run on multiple platforms" but still requires you to use different API depending on the platform, tcl smooths out platform differences providing a unified API across platforms.
Tcl treats serial ports like files so you just open it to talk to it. Granted, different platforms provides different ways of naming the ports. So on Windows, to talk to the serial port you simply do:
set rs232 [open COM1 w+]
On unixen (Linux, MacOSX etc.) you'd do:
set rs232 [open /dev/ttyS0 w+]
To set the baud rate and parity bits you can now do
fconfigure $rs232 -mode "9600,n,8,1"
Be sure to also configure the serial port to binary mode otherwise tcl will re-interpret "\n" for you depending on your OS:
fconfigure $rs232 -mode "9600,n,8,1" -translation binary -blocking 0
The "blocking" bit is to set it to non-blocking mode so that we can write event oriented code which is critical for UI apps since we don't want the IO to block our UI.
So now for a simple program that reads data from the serial port:
package require Tk ;# in case we're running in tclsh
if {[catch {set rs232 [open COM1 w+] err}]} {
tk_dialog .error Error "Could not open COM1: $err" error 0 OK
}
fconfigure $rs232 -mode "9600,n,8,1" -translation binary -blocking 0
# Draw a simple UI do dump data to:
pack [label .l -text "Gyroscope outputs:"]
pack [label .g1 -textvariable gyro1]
pack [label .g2 -textvariable gyro2]
pack [label .g3 -textvariable gyro3]
# Now the fun part, read from the serial continuously with fileevent:
set buffer ""
fileevent $rs232 readable {
append buffer [read $rs232]
# Here, you need to parse the data returned.
# Due to the byte-wise nature of serial ports the data read may not be
# complete so we need to check if it's complete. "Completeness" depends
# on you. For example the data packet may end with a newline. Or it may
# simply be a timeout between data packets.
if {[message_is_complete $buffer]} {
set gyros [parse_message $buffer]
set buffer ""
# Update the UI:
foreach x $gyros y {gyro1 gyro2 gyro2} {
set $y $x
}
}
}
Minus the comments and empty lines that's just 16 lines of code. You can of course go further and implement a more fancy UI rather than just text labels.
If you need to send data to the microcontroller simply puts to it. Just remember to override tcl's automatic newline termination:
puts -nonewline $rs232 $somedata
Use tcl's binary command if you need to format to and from binary.
I personally still prefer tcl for this because you can get a prototype up and running to read the output from your hardware in under 5 minutes. But you also mentioned interest in a node.js solution. So here's an alternative starting point for node.js
First you need to install node.js. This may or may not be trivial depending on your OS. You will need Python 2.x (not 3.0) installed on your system in order to compile node.js modules writen in C (and even node.js itself). Even if you're installing a binary distribution of node you will still have to compile the serial port library since it's not included in the core.
Next you will need to install the serialport module. The instructions vary depending on your OS. See the npm page for the module: https://npmjs.org/package/serialport
Once you've got things up and running you can simply communicate with your serial port using the serialport module:
var SerialPort = require("serialport").SerialPort
var rs232 = new SerialPort("COM1", {
baudrate: 57600
}, false);
Again, like the tcl case, the name of the serial port depends on your OS. The above is an example for Windows. For unixen you'd do:
var rs232 = new SerialPort("/dev/ttyS0", {
baudrate: 57600
}, false);
For UI, node doesn't have a core toolkit like tcl. There are many libraries on npm available allowing you to use QT or GTK or some other widget set. But the most common way of doing UI on node is to simply run it as a web server and connect to it with your web browser. The downside of this is a little additional complexity and the need to mess with HTML. The upside is HTML & CSS! Which means you can leverage tools like CSS3 effects and jQuery to create a really slick UI with very little effort.
Unfortunately, writing an interactive webapp (even a simple one) is fairly involved so I won't be providing a "simple" example implementation. I'd only suggest you read up on the more popular frameworks like express.js and templating libraries like dust or handlebars. You may also want to take a look at socket.io to simplify the implementation of real-time communications between your server and the web browser.

Resources