02 Oct 2019 - tsp
Last update 02 Mar 2020
12 mins
This is a really short writeup on what was necessary of bringing OpenHantek6022, a great alternative software used with some USB digital oscilloscopes like the Hantek 6022BE or Hantek 6022BL, (note: The last links are Amazon affilate links, this pages author profits from qualified purchases) to FreeBSD. And also a short story about how everyone can improve open source software with minimal effort. Since development for OpenHantek is done mainly on Linux it turned out to be really easy to port it to FreeBSD (a matter of a few hours including some debugging and mainly writing this story and the files for the port).
I’ve also already generated files for a port at science/openhantek
- but
havent’s submitted them upstream since the upstream repository for OpenHantek
currently has no release tag including the patches. As soon as there is a
release present the setup will be a simple matter of
cd /usr/ports/science/openhantek6022
make install clean
or a package install like
pkg install openhantek6022
Until then - or to build manually one can use the following steps:
pkg install devel/cmake
pkg install math/fftw3
pkg install x11/xorg
pkg install devel/qt5
git clone https://github.com/OpenHantek/OpenHantek6022.git
mkdir -p OpenHantek6022/build
cd OpenHantek6022/build
cmake ../
gmake
./openhantek/OpenHantek
. To be
really usable the udev files described below or found in the source
directory at ../devd_rules_freebsd.conf
or any other solution
to access the ugen
devices is required.So this was one of the easiest ports I’ve ever done. First I’ve just tried to clone the GitHub repository of OpenHanek
git clone https://github.com/OpenHantek/OpenHantek6022.git
Then I tried a simple build
mkdir -p OpenHantek6022/build
cd OpenHantek6022/build
cmake ../
make -j2
As expected that failed. It turned out there was a single thing preventing
the program to compile - the libusb
includes are included in a libusb-1.0
subdirectory on Linux but contained directly in the /usr/include
directory
on FreeBSD. So as a first try I checked if exchanging would help.
find ../openhantek -name "*.cpp" -exec sed -i '.bak' 's#libusb-1.0/libusb.h#libusb.h#g' {} \;
find ../openhantek -name "*.h" -exec sed -i '.bak' 's#libusb-1.0/libusb.h#libusb.h#g' {} \;
find ./ -name "*.bak" -exec rm {} \;
Another build run
make -j2
produced a runable binary. So I simply modified all sourcefiles (to keep them buildable on existing platforms). I moved from
#include <libusb-1.0/libusb.h>
to
#ifdef __FreeBSD__
#include <libusb.h>
#else
#include <libusb-1.0/libusb.h>
#endif
which allows the build system to build the binary at least on Linux, MacOS X and also on FreeBSD.
After that I tried to run the application:
./openhantek/OpenHantek
No USB devices had been discovered.
This was caused by the inability of the application to access the USB devices
by default (a good thing) so I first added a new group usbscope
to the system
pw groupadd usbscope
To use it with my default user I’ve added the user to the group:
pw group mod usbscope -m MYUSERNAME
After that one has to reload identity information (logging out and re-logging in
for example). Now I’ve added a simple devd rule file to change group ownership
of the usb device file on attachment so all members of the usbscope
group
would be able to access the device file. This file
has been added to the /usr/local/etc/devd/openhantek.rules
file:
# Hantek 6022BE (20 MHz, 48 MS/s)
notify 110 {
match "system" "USB";
match "subsystem" "DEVICE";
match "type" "ATTACH";
match "vendor" "0x04b4";
match "product" "0x6022";
action "chgrp usbscope /dev/$ugen; chmod g+rw /dev/$ugen; chgrp -h usbscope /dev/$ugen; chmod -h g+rw /dev/$ugen";
};
notify 110 {
match "system" "USB";
match "subsystem" "DEVICE";
match "type" "ATTACH";
match "vendor" "0x04b5";
match "product" "0x6022";
action "chgrp usbscope /dev/$ugen; chmod g+rw /dev/$ugen; chgrp -h usbscope /dev/$ugen; chmod -h g+rw /dev/$ugen";
};
attach 110 {
match "vendor" "0x04B4";
match "product" "0x6022";
action "chgrp usbscope /dev/$ugen; chmod g+rw /dev/$ugen; chgrp -h usbscope /dev/$ugen; chmod -h g+rw /dev/$ugen";
};
attach 110 {
match "vendor" "0x04B5";
match "product" "0x6022";
action "chgrp usbscope /dev/$ugen; chmod g+rw /dev/$ugen; chgrp -h usbscope /dev/$ugen; chmod -h g+rw /dev/$ugen";
};
After a restart of devd via /etc/rc.d/devd
the device was assigned to
the correct group after reattachment.
Finally the launch of the application succeeded, the device was listet. And the application. Crashed.
Some hours of debugging later it seemed that the release of the usb device list caused the crash - as if the application would keep a reference into undefined memory locations despite it incrementing the descriptor reference count. Since this seemed to be a bug in the systems libusb library I’ve simply decided to remove the release of the device descriptor since this runs exactly once during application startup and memory will be released during shutdown anyways. Since on other platforms everything works correctly I’ve guarded that with an preprocessor statement:
#if !defined(__FreeBSD__)
/*
ToDo: This introduces a potential resource leak if not executed
on FreeBSD. It seems there is a reference counting problem when
using libusb on FreeBSD.
*/
libusb_free_device_list(deviceList, true);
#endif
Now everything compiled and ran fine. The scope is working.
To prepare everything for the pull request into the upstream repository:
git remote set-url git@github.com:tspspi/OpenHantek6022.git
Then for every piece of distinguishable work staged all required parts (in case
of changes at the same file that belong to different commits use git add -p FILENAME
to stage only parts of the changes, to stage everything git add FILENAME
).
After that a Commit including signoff message is created (git commit -S -s
).
The -S
switch is included since I also sign my commits using OpenPGP.
After all commits have been made one can create a pull request using GitHub. Simply select source (never master) and destination branches, wirte a short title and description. And everything is ready. After the pull request has been created projects run some automated tests most of the time - which is also the case for OpenHantek.
Now - since FreeBSD has an excellent ports and package system that allows
users to install software simply by executing a makefile in /usr/ports
or using pkg
to install their packages I’ve decided to create a small
and fast FreeBSD port for openhantek. I’ve tested everything against
my own private copy of the ports tree (and my own github repository).
First one creates a directory at the desired location into a current portstree.
Update with portsnap fetch update
or if there is no portstree
install via portsnap fetch extract
. After that one simply created the
required files at the desired locations:
mkdir -p /usr/ports/science/openhantek6022
Now one creates the Makefile
at /usr/ports/science/openhantek6022/Makefile
# $FreeBSD$
PORTNAME= openhantek6022
DISTVERSIONPREFIX= v
DISTVERSION= 2.16
CATEGORIES= science
MAINTAINER= tspfbsdport@tspi.at
COMMENT= DSO software for Hantek USB digital signal oscilloscopes 6022BE/BL
LICENSE= GPLv3
LIB_DEPENDS= libfftw3.so:math/fftw3
BUILD_DEPENDS= cmake:devel/cmake qmake:devel/qmake
USES= qt:5 gl cmake
USE_QT= printsupport opengl widgets gui core
USE_GL= gl glu
USE_GITHUB= yes
GH_ACCOUNT= OpenHantek
GH_PROJECT= OpenHantek6022
do-install:
${INSTALL_PROGRAM} ${BUILD_WRKSRC}/openhantek/OpenHantek ${STAGEDIR}${PREFIX}/bin
${INSTALL_DATA} ${WRKSRC}/devd_rules_freebsd/openhantek.conf ${STAGEDIR}${PREFIX}/etc/devd
post-install:
${STRIP_CMD} ${STAGEDIR}${PREFIX}/bin/OpenHantek
.include <bsd.port.mk>
Basically this is a simple ports Makefile. Let’s look at it step by step.
The value of PORTNAME
simply identifies the name of the port. This is required
during the provisioning and building process of the real FreeBSD ports tree
since additions are done via PRs - not via an SCM system. The DISTVERSION
identifies the name of the github branch that will be downloaded. If one
just starts on can try with master
but should use a unmodifyable tag
afterwards since the archive will be checksummed.
The fields CATEGORIES
and COMMENT
provide some metadata about the
port, the required field LICENSE
identifies the software license and
of course the MAINTAINER
field allows to contact the port maintainer. This
is also done automatically in case of build failures.
With the USE_GITHUB
property it’s easy to let the FreeBSD ports system
do all of the other stuff, one just has to specify the GH_ACCOUNT
and GH_PROJECT
that should be used as fetch source.
As we have created a group it will be listed at GROUPS
. Note that each of
this groups has to be listed also at /usr/ports/GIDs
. For testing
one can use the value assigned by pw
during creation.
At the end there is a bunch of options that list dependencies of this port.
Since OpenHantek uses qt5 (some modules out of it), opengl and the fftw library
these are listed with USES
, LIB_DEPENDS
as well as USE_QT
and USE_GL
.
Now there are several make targets:
do-install
all files are copied into the staging area.post-install
all binaries are stripped and a short message is shownAll that magic is possible since the default ports Makefile bsd.ports.mk
is
included at the end.
Two other metadata files are required:
pkg-descr
. This is plain ASCII stuff. If it contains
an URL there should be a line with an WWW:
specification. If not,
portlint will complain later on.pkg-plist
file lists all files that are installed by this port:bin/OpenHantek
etc/devd/openhantek.conf
The last missing part for the port is the distinfo
file that contains
checksums. This is not created manually but using make makesum
inside
the ports directory. These checksums are also the root cause why the branch
is not allowed to change anymore. Any further changes would modify the
checksums and prevent the installation or build process to run.
Now one can test the port (after deleting anything that’s already present
using make clean && make distclean
). The build process should run
using make
, installation using make install
.
If everything worked out the program should be available an runable
with OpenHantek
as every user who’s member of the usbscope
group.
As a last step - before submitting the port upstream - one should run portlint to verify everything works as expected:
cd /usr/ports/science/openhantek6022
portlint
If portlint tells us looks fine.
the port is finished successfully we
can simply create either the patch or the shar to submit to the portstree
maintainers. If one wants to push the port upstream one first has to wipe out
everything using make clean && make distclean
. After that one can simply
create the shar
file via:
cd /usr/ports/science
shar `find openhantek6022` > openhantek6022.shar
The generated shar
file can then be uploaded to the FreeBSD bug
submission form. Make sure
to submit as Ports and Packages, Individual Port, add a short decription (like
for example New port: science/openhantek6022 DSO software for Hantek
USB digital signal oscilloscopes 6022BE/BL
of the program as well as the
previously generated shar
file. And then be patient (days, weeks, months).
I’ve continued development of the port Makefile for OpenHantek - to cope
with some problems with the older version. Since I’m using xf86-video-intel
as graphics driver with the i915kms
module and there has been a bug
when using OpenGL I had to launch OpenHantek
using
env LIBGL_ALWAYS_SOFTWARE=1 OpenHantek
The new Makefile for the port in it’s current state:
# $FreeBSD$
PORTNAME= openhantek6022
DISTVERSIONPREFIX=
DISTVERSION= 3.0.2
CATEGORIES= science
MAINTAINER= tspfbsdport@tspi.at
COMMENT= DSO software for Hantek USB digital signal oscilloscopes 6022BE/BL
LICENSE= GPLv3
LIB_DEPENDS= libfftw3.so:math/fftw3
BUILD_DEPENDS= cmake:devel/cmake qmake:devel/qmake
USES= qt:5 gl cmake
USE_QT= printsupport opengl widgets gui core
USE_GL= gl glu
USE_GITHUB= yes
GH_ACCOUNT= OpenHantek
GH_PROJECT= OpenHantek6022
pre-build:
${MKDIR} ${WRKSRC}/build
do-build:
cmake -B${WRKSRC}/build ${WRKSRC}
${GMAKE} -C ${WRKSRC}/build
post-install:
${STRIP_CMD} ${STAGEDIR}${PREFIX}/bin/OpenHantek
${MKDIR} ${STAGEDIR}${PREFIX}/etc/devd
${INSTALL_DATA} ${WRKSRC}/utils/devd_rules_freebsd/openhantek.conf ${STAGEDIR}${PREFIX}/etc/devd
.include <bsd.port.mk>
This article is tagged:
Dipl.-Ing. Thomas Spielauer, Wien (webcomplains389t48957@tspi.at)
This webpage is also available via TOR at http://rh6v563nt2dnxd5h2vhhqkudmyvjaevgiv77c62xflas52d5omtkxuid.onion/