This week I spent some time familiarizing myself with the libsigrok components, and developed bindings for BeagleLogic into libsigrok. The development work walked me through non-blocking I/O, which I implemented into the BeagleLogic kernel module only to realize that it had a major bug that causes the client to sleep uninterrupted and froze my BeagleBone Black everytime. The bug got identified and fixed and after that non-blocking I/O worked as expected.
Memory Mapped Kernel Buffers
This was another optimization I made use of in the sigrok bindings. The sigrok library internally keeps logic data in packets and it is exchanged with the host application via pointers. I exploited this good opportunity to use the mmap() functionality I designed into the kernel driver, so the sigrok implmentation just passes a mmap()’ed pointer to the host application instead of read()-ing the data.
However the currently being read buffer still needs to be updated for poll() to work properly. For this reason I implemented dummy reads. When a NULL pointer is passed as the buffer to read(), it does not read any data from the buffer, and just updates the read state within the drivers so that poll() works fine.
The flow of data is like this:
- libsigrok bindings signal the BeagleLogic module to start the sampling operation, and starts polling on the /dev/beaglelogic node using a GPollFD
- Once the PRU fills up a data buffer, it sends an IRQ that wakes up the the polling thread and the beaglelogic_receive_data() callback in protocol.c executes
- The callback sends a packet with the pointer to that segment of data required, and adjusts the internal offsets for the next callback
The process goes on till the sample limit has been reached. BeagleLogic also supports streaming but…
sigrok-cli on the BeagleBone Black
To test the results of the bindings, I ran a sample operation on BeagleLogic using the sigrok bindings and it worked fine. I was able to decode a wave file from my trusty audio player hardware 🙂 to wav right there on the BeagleBone Black using the article on the sigrok blog as a reference. I got 6 seconds of a wave file directly from the dump. This took ~750 seconds to process from RAM on the BeagleBone Black.
I also tested sampling into a 256 MB buffer in the RAM