# **Taskbus 使用手册** Taskbus 是一款基于C++/Qt的多进程软件合作平台。使用该平台,多个基于标准输入输出设备(Stdio)的进程能够互相交换数据,并共同完成较为复杂的功能。Taskbus 初衷是为不具备良好计算机编程背景的小型团队提供开发SDR软件无线电程序的能力增量,当然也可以用来做非SDR领域的任何事情。关于本软件的技术原理,请参考[taskbus_zh_CN.md](taskbus_zh_CN.md)。本手册主要介绍该软件的使用方法。 [TOC] ## 1. 编译 获取可执行程序的方法主要包括源码编译和直接使用发行版。鉴于TaskBus主要使用Qt C++开发,在Linux环境下,编译比较方便,因此目前[对Windows平台准备了发行版](https://gitcode.net/coloreaglestdio/taskbus/-/releases)。如果使用发行版,则无需编译taskBus项目,因此仅需要参考1.2节配置UHD即可。本节主要介绍在windows平台下的编译和安装,Linux下因为依赖性很容易通过包管理器解决,故而不作为重点。 ### 1.1 获取源码 (**直接下载发行版的用户可忽略本节**) 从下列网址下载最新的代码: [https://gitcode.net/coloreaglestdio/taskbus](https://gitcode.net/coloreaglestdio/taskbus) 也可以直接使用Git签出: ```bash #for Qt5 git clone https://gitcode.net/coloreaglestdio/taskbus.git #for Qt6 git clone -b qt6 https://gitcode.net/coloreaglestdio/taskbus.git ``` ### 1.2 安装 libUHD 并首次驱动USRP设备 #### 1.2.1 安装libUHD库的两种方法 ** 方法(1):直接从官网下载。 ** 从 [https://files.ettus.com/binaries/uhd/](https://files.ettus.com/binaries/uhd/) 下载新版的uhd,2022年后,一般可以安装4.x版本。 下载安装包,直接安装后,请配置UHD的环境变量,PATH路径。配置完毕,打开CMD,运行下面的命令,以确保已经正确设置。 ```dos C:\>echo %UHD_PKG_PATH% [回车] D:\UHD4.1.0 C:\>PATH [回车] C:\WINDOWS\system32;C:\WINDOWS;\...;D:\UHD4.1.0\bin;...; ``` 如果不设置环境变量,编译得时候找不到头文件,运行的时候找不到libuhd.dll ** 方法(2):从Pothos SDR下载。** 如果希望在windows下使用PothosSDR获得GNU-Radio的所有功能,可以使用软件无线电全家桶PothosSDR。从 [https://downloads.myriadrf.org/builds/PothosSDR/](https://downloads.myriadrf.org/builds/PothosSDR/) 下载最新版,直接安装。 直接安装后,请配置UHD的环境变量,PATH路径。配置完毕,打开CMD,运行下面的命令,以确保已经正确设置。 ```dos C:\>echo %UHD_PKG_PATH% [回车] E:\PothosSDR C:\>PATH [回车] C:\WINDOWS\system32;C:\WINDOWS;\...;E:\PothosSDR\bin;...; ``` 而后,使用脚本下载 uhd的FPGA固件。 ```dos #假设Pothos SDR 安装在 E:\,则运行 E:\> python PothosSDR\lib\uhd\utils\uhd_images_downloader.py -i E:\PothosSDR\share\uhd [回车] ``` 运行后,会发现uhd文件夹下多了images文件夹。 #### 1.2.2 确认USRP设备运行正常 在命令行执行: ```dos C:\> uhd_usrp_probe [回车] ``` 不报错,并显示设备的参数了,则说明安装基本正常。**请注意上述命令返回状态中的警告** ,如网卡mtu、send_buffer_size等参数的配置警告。这些警告与正确编译taskBus无关,但与发挥设备最大的吞吐能力有关。为了保证稳定持续的吞吐,需要细致的参考以下几篇文章,解决X310万兆网、千兆网、USB等各种配置。 - [https://files.ettus.com/manual/page_transport.html](https://files.ettus.com/manual/page_transport.html) - [https://goldenhawking.blog.csdn.net/article/details/110727815](https://goldenhawking.blog.csdn.net/article/details/110727815) ### 1.3 安装boost (**直接下载发行版的用户可忽略本节**) 如果您已经有了boost的某个版本,可以直接使用该版本的boost。若没有安装,且仅为了编译 taskBus,则可以使用源码自带的boost. 因为taskBus使用的是libUHD的C语言接口,在C++环境下,仅需要几个boost库的头文件支持。在源码的[modules/3rdlibs/boost_headers_1075.7z](../modules/3rdlibs/boost_headers_1075.7z)中,包含了boost 1.75的头文件。把该压缩包释放到libUHD或者PothosSD的include文件夹下,使得其看起来与uhd的头文件uhd.h平级。 ```txt include-| |- boost |- uhd |... |- uhd.h ``` ### 1.4 检查并配置pthread (**直接下载发行版的用户可忽略本节**) pthread是一个windows下仿POSIX的线程库。pthread.h被libuhd所使用,但可能会和您编译环境中的头文件冲突。该冲突发生在使用PothosSDR和MinGW64编译器的情况下。当您使用的是Mingw64编译器,请执行以下操作: - 找到 PothosSDR\include 文件夹 - 把pthread.h重命名为pthread.hpp ### 1.5 安装Qt (**直接下载发行版的用户可忽略本节**) 目前windows下请在线安装Qt,以及对应的编译器。 - 由于uhd库仅仅使用了C接口,故而编译taskBus的编译器与libuhd的编译器可以是不同的。 - 当编译器不同时,请不要使用uhd库中C接口的 C\+\+ 扩展,如试图直接从 rx_meta->rx_metadata_cpp.time_spec 使用C\+\+/boost的timestamp结构。C++在二进制上的ABI差异可能导致诡异的错误。 以下编译环境是经过测试的: - MSYS2 mingw64 Qt + Pothos SDR \* - mingw64 Qt + Pothos SDR \* - MSVC2019 x64 Qt + Pothos SDR - MSYS2 mingw64 Qt + libUHD - mingw64 Qt + libUHD - MSVC2019 x64 Qt + libUHD (\* 表示需要进行1.4节所说的pthead替换) ### 1.6 编译 (**直接下载发行版的用户可忽略本节**) 打开 QtCreator, 载入工程。 - 若使用的是MSYS2环境,建议载入CMake工程。qmake工程在静态Qt库编译时,会遇到链接错误(2022-04-04测试),使用CMake可以避免错误。 - 请参考下表选择合适的编译配置 |系统|编译环境|编译器(Qt)|UHD安装方式|需配置boost头(1.3节)|需配置pthread.h(1.4节)|须留心libiio版本问题(2.2.2节)|优选项目类型| |--|--|--|--|--|--|--|--| |win|MSVC2019|MSVC2019|libUHD|Y|N|Y|qmake| |win|MSVC2019|MSVC2019|Pothos SDR|Y|N|N|qmake| |win|CMD|MinGW64|libUHD|Y|N|Y|cmake| |win|CMD|MinGW64|Pothos SDR|Y|Y|N|cmake| |win|MSYS2 bash|MinGW64|libUHD|N|N|Y|cmake| |win|MSYS2 bash|MinGW64|Pothos SDR|N|Y|N|cmake| |win|MSYS2 bash|MinGW64-static|libUHD|N|N|Y|cmake| |win|MSYS2 bash|MinGW64-static|Pothos SDR|N|Y|N|cmake| |linux|bash|gcc|apt/yum/pacman|N|N|N|cmake| 如果有真实的非虚拟机linux环境,还是建议在Linux下运行。 ### 1.7 编译后的结果 一旦编译完成,在输出文件夹下会产生 bin文件夹,含有所有的可执行文件。这个文件夹应该类似: ```dos E:\build\bin> tree /F [回车] E:. │ subtask_wrapper.exe │ taskBusPlatform.exe └─modules filter_fir.exe mod_fm.exe mod_fm_dem.exe network_p2p.exe resample_pqfraction.exe sink_file.exe sink_plots.exe sink_plutosdr.exe sink_soundcard.exe sink_SQL.exe source_file.exe source_plutosdr.exe source_soundcard.exe transform_fft.exe uhd_usrp_continous.exe uhd_usrp_io.exe wrapper_scripts.exe wrapper_stdio.exe ``` ## 2 安装 taskBus由若干可执行文件(在windows下就是exe文件)共同完成任务。为脱离编译器环境运行,这些模块所需要的动态链接库都需要位于可发现的位置上。对Linux而言,由于使用的都是官方库,所以不存在安装问题。基本上双击 taskBusPlatform 就能启动。对Windows而言,需要格外注意依赖项。建议下载[https://dependencywalker.com/](https://dependencywalker.com/)以便在出问题时查看依赖。 ### 2.1 执行Qt发布 打开Qt的命令行,在bin文件夹下,执行Qt发布工具。如果是静态链接,则无需本步骤。 ```dos E:\build\bin> windeployqt --compiler-runtime taskBusPlatform.exe E:\build\bin> windeployqt --compiler-runtime --dir . modules/sink_sql.exe E:\build\bin> windeployqt --compiler-runtime --dir . modules/sink_soundcard.exe E:\build\bin> windeployqt --compiler-runtime modules/sink_sql.exe E:\build\bin> windeployqt --compiler-runtime modules/sink_soundcard.exe ``` ### 2.2 确认额外的动态库 即使是静态链接到Qt,还是需要动态库的支持。 #### 2.2.1 fftw 在bin文件夹执行命令: ```dos E:\build\bin> modules\transform_fft.exe ``` 若报错,说明需要拷贝源码文件夹 taskbus\modules\3rdlibs\win32\fftw\x64\libfftw3-3.dll 到bin\modules文件夹下。 #### 2.2.2 解决libiio::libusb冲突 若使用Pluto SDR,请确保libiio不要使用旧版进行安装。旧版会在windows\system32下释放libusb-1.0.dll,与uhd的libusb-1.0.dll冲突。 解决方法: - 把libiio的文件夹 (如taskbus\modules\3rdlibs\win32\libiio\MS64)中所有文件拷贝到一个单独的文件夹下,并把source_plutosdr,sink_plutosdr两个模块移动到本文件夹。 - 直接使用Pothos SDR全家桶,不安装libiio #### 2.2.3 MSYS64环境额外处理 MSYS64环境依赖的开源库,请在msys64 bash下使用ldd查找缺项。 ```bash $ ldd transform_fft.exe | grep "mingw64" libgcc_s_seh-1.dll => /mingw64/bin/libgcc_s_seh-1.dll (0x7ffd1e7f0000) libwinpthread-1.dll => /mingw64/bin/libwinpthread-1.dll (0x7ffd1e110000) //... ``` ### 2.3 加载所有的模块 打开 taskBusPlatform.exe, 点击“载入模块”,定位到modules文件夹,全选除了wrapper_scripts.exe之外的文件,可以看到加载的结果。如果如下图所示,表示加载成功。 ![LoadModules](handbook/1.LoadModules.jpg) ![LoadModules](handbook/2.LoadModulesOk.jpg) ### 2.4 排查问题 如果发现缺少某个模块,请到命令行下,执行 模块名.exe --information,若能够输出json,则表示正常。否则,请对照出错提示,结合[dependencywalker](https://dependencywalker.com/)或者ldd查看依赖。 比如,对fft模块,执行: ```dos E:\build\bin> modules\transform_fft.exe --information [回车] { "transform_fft":{ "name":"libfftw", "parameters":{ "sptype":{ "type":"enum", #... } } ``` 则表示没有问题。 ## 3 设计师界面 taskBus 的工作原理是使用设计师 taskBusPlatform.exe 设计工程,连接各个模块的执行文件。而后,保存工程为.tbj(json)格式,并在设计师内运行。同时,tbj文件也可以通过命令行工具subtask_wrapper.exe封装后,脱离界面运行。本节介绍设计师界面的基本情况。 ###3.1 基本框架 当您下载或者编译了特定的发行版本后,会获得一个含有多个可执行文件、配置文件的文件夹。以发行版 taskbus_win64_20220419_Qt6 为例,这个文件夹的结构大致如下: ```txt ├─bin 设计师可执行文件(主程序) ├─doc 文档文件夹 ├─examples 工程范例文件夹 ├─modules 模块文件夹 │ ├─plutosdr ADALM PlutoSDR模块 │ ├─usrp Ettus USRP UHD模块 │ └─wrapper_scripts 用于脚本(python,node.js)的封装器模块 └─templates 模块模板 ├─cpp 纯C++模板 ├─csharp C#模板 ├─FMDem C语言FM解调器(二次封装,需要wrapper_stdio) ├─matlab Matlab语言 ├─mfc MFC框架 ├─nodejs node.js+wrapper_scripts ├─python python 3脚本+wrapper_scripts └─python2 python 2脚本+wrapper_scripts ``` ####3.1.1 自带模块一览表 在模块modules文件夹里,是编译好的各个模块,以发行版 taskbus_win64_20220419_Qt6 为例,主要包括: |模块可执行文件夹|模块功能|备注| |--|--|--| |filter_fir.exe|Fir滤波器|时域Fir滤波| |mod_fm.exe|调频FM广播调制器|可产生广播| |mod_fm_dem.exe|调频FM广播解调器|可还原音乐| |network_p2p.exe|分布式点对点TCP模块|可以把两台计算机联动起来| |resample_pqfraction.exe|分数倍重采样|与Matlab resample(p,q)类似| |sink_file.exe|文件信宿|可把数据保存为文本或者二进制| |sink_plots.exe|画图信宿|包括简单的1D,2D,时频图| |sink_plutosdr.exe|PlutoSDR信宿|发行版中在独立的文件夹,避免libiio和usrp的冲突| |sink_soundcard.exe|声卡信宿|可播放声音| |sink_SQL.exe|SQL信宿|用于执行SQL,也可以用wrapper_stdio+命令行数据库客户端代替| |source_file.exe|文件信源|可以按照灵活的方式批量读取文件| |source_plutosdr.exe|PlutoSDR信源|| |source_soundcard.exe|声卡信源|可以进行录音并把波形带入平台| |transform_fft.exe|FFT变换|使用libfftw| |uhd_usrp_continous.exe|UHD连续吞吐|不带时戳的USRP吞吐| |uhd_usrp_io.exe|UHD突发/连续吞吐|带时戳的USRP吞吐,可获取每份数据的时戳,并为每份发射数据准备预告的时戳| |wrapper_scripts.exe|脚本包装器|用于包装python,node.js等脚本制作的模块。相关例子见templates中python文件夹| |wrapper_stdio.exe|标准命令行包装器|用于包装简单的基本命令行程序,构成1输入(Stdin),两输出(stdout, stderr)模块。见examples里的usrp_fm_wrapper.tbj| #### 3.1.2 模块加载历史记录 一旦模块加载成功,会记录在default_mods.text中。其可能的内容如下: ```text ../modules/sink_soundcard.exe ../modules/source_file.exe ../modules/usrp/uhd_usrp_continous.exe ../templates/python2/example_python2.exe ../templates/nodejs/example_nodejs.exe ../modules/sink_plots.exe ../modules/source_soundcard.exe ../modules/sink_SQL.exe ../modules/mod_fm_dem.exe ../modules/filter_fir.exe ../modules/plutosdr/source_plutosdr.exe ../modules/mod_fm.exe ../modules/plutosdr/sink_plutosdr.exe ../modules/network_p2p.exe ../modules/usrp/uhd_usrp_io.exe ../modules/transform_fft.exe ../modules/resample_pqfraction.exe ../templates/python/example_python.exe ../examples/voice_spec.exe ../modules/wrapper_stdio.exe ../modules/sink_file.exe ``` 对封装的子项目,在对应的子项目名.text里,也会设置加载的文件名。如: [examples/voice_spec.text](../examples/voice_spec.text) ###3.2 界面元素 双击bin/taskBusPlatform.exe 启动程序,主要界面元素如下: ![mainGUI](handbook/3.MainGUI.jpg) ####3.2.1 主工具栏按钮 各个按钮的意义如下: |图标|文字|作用|行为| |--|--|--|--| |![载入模块](handbook/buttons/load_module.png)|载入模块|载入一个符合taskBus接口定义标准的模块(JSON描述)|弹出对话框,选择EXE文件后,会试图用 --information 开关启动程序。如果失败,则试图寻找 程序文件名.json文件。如果失败,则不会加载。| |![新建工程](handbook/buttons/new_project.png)|新建工程|新建空白工程|| |![打开工程](handbook/buttons/open_project.png)|打开工程|打开存在的工程|如果工程对应的某个模块没有预先加载,则打开工程后看不到对应的模块图标。| |![保存工程](handbook/buttons/save_project.png)|保存工程|保存目前的修改|| |![执行](handbook/buttons/start_project.png)|执行|执行工程|会依次启动各个进程,并吞吐stdio数据| |![停止执行](handbook/buttons/ddimg_exit.png)|停止执行|中止执行当前工程|会发quit()指令到所有进程,并等待。超时后会强制终止相关进程。| |![隐藏](handbook/buttons/ticon2.png)|隐藏|隐藏主界面|最小化到任务栏,变成图标。| #### 3.2.2 “编辑”工具栏按钮 各个按钮的意义如下: |图标|文字|作用|快捷键|行为| |--|--|--|--|--| |![放大](handbook/buttons/zoomIn.png)|放大|Ctrl+‘=’|放大视图。|点击按钮后,视图被放大。| |![缩小](handbook/buttons/zoomOut.png)|缩小|Ctrl+‘-’|缩小视图。|点击按钮后,视图被缩小。| |![还原](handbook/buttons/038-2.png)|还原||还原视图|点击按钮后,视图比例重新回到100%。| |![复制](handbook/buttons/Copy.png)|复制|Ctrl+‘c’|复制元素。|点击按钮后,当前被选中模块的信息会被复制到剪贴板。| |![剪切](handbook/buttons/Cut-2.png)|复制|Ctrl+‘x’|剪切元素。|点击按钮后,当前被选中模块被删除,信息会被复制到剪贴板。| |![删除](handbook/buttons/delete_node.png)|删除|Del|删除元素。|点击按钮后,当前元素会被删除。| |![粘贴](handbook/buttons/Paste.png)|粘贴|Ctrl+‘v’|粘贴元素。|点击按钮后,当前剪贴板里的元素会被插入到工程里。| |![撤销](handbook/buttons/undo-1.png)|粘贴|Ctrl+‘z’|撤销操作。|点击按钮后,会不断撤销操作。| |![重做](handbook/buttons/Redo.png)|重做|Ctrl+Shift+‘z’|重做操作。|点击按钮后,重做刚刚被撤销的操作。| |![断开](handbook/buttons/D. line.png)|断开管脚|Ctrl+‘d’|断开选中的管脚。|点击按钮后,被鼠标选中的管脚会被断开。| |![上移](handbook/buttons/up.png)|向上一格|Ctrl+‘上方向’|管脚布局向上移动一格。|点击按钮后,被选中的管脚会向上移动。但由于管脚布局的限制,当无法上移时,请下移其他管脚达到相同作用。| |![下移](handbook/buttons/down.png)|向下一格|Ctrl+‘下方向’|管脚布局向下移动一格。|点击按钮后,被选中的管脚会向下移动。但由于管脚布局的限制,当无法下移时,请上移其他管脚达到相同作用。| |![翻转](handbook/buttons/side.png)|翻转位置|Ctrl+‘左/右’|管脚移动到绘图块的另一边。|点击按钮后,被选中的管脚会翻转到另一边。| |![调试启动](handbook/buttons/ddimg_debug.png)|启动调试||启动对选中模块的调试。|相应模块的输入、输出会被记录在debug文件夹中,这样允许离线调试独立的模块。| |![调试终止](handbook/buttons/ddimg_debugoff.png)|停止调试||停止对选中模块的调试。||| |![提高优先级](handbook/buttons/Process busy.png)|提高优先级||提高选中模块的进程优先级(nice)。|对实时性要求高的模块请使用高的优先级。在Linux下,优先级越高,数字越小。| |![降低优先级](handbook/buttons/Process idle.png)|降低优先级||降低选中模块的进程优先级(nice)。|对实时性要求高的模块请使用高的优先级。| ### 3.3 主进程优先级 设置主进程的配置文件taskBusPlatform.exe.ini,可配置优先级。 ```ini [settings] nice=2 ``` **注意:相同的工程,切换平台(Linux<->Windows)后,要注意优先级的取值变化。** ## 4. 从范例工程开始 ### 4.1 打开范例工程 点击“打开”按钮 |图标|文字|作用|行为| |--|--|--|--| |![打开工程](handbook/buttons/open_project.png)|打开工程|打开存在的工程|如果工程对应的某个模块没有预先加载,则打开工程后看不到对应的模块图标。| 加载现有的工程。以 [examples/soundcard.tbj](../examples/soundcard.tbj)为例,打开后,将看到如下界面: ![Example](handbook/4.Example.jpg) ### 4.2 配置范例工程 #### 4.2.1 配置优先级 可以试着使用按钮: |图标|文字|作用|快捷键|行为| |--|--|--|--|--| |![提高优先级](handbook/buttons/Process busy.png)|提高优先级||提高选中模块的进程优先级(nice)。|对实时性要求高的模块请使用高的优先级。在Linux下,优先级越高,数字越小。| |![降低优先级](handbook/buttons/Process idle.png)|降低优先级||降低选中模块的进程优先级(nice)。|对实时性要求高的模块请使用高的优先级。| 调整各个模块优先级,直到满足平台所需。Linux下,0为正常,<1为高优先级,>0为低优先级。Windows下,0为最低,5为最高。 - 调整前,要选中模块 - 这样的调整操作在切换Windows/Linux平台时尤为重要。因为这两个平台的优先级算数范围不同,且大小相反。 #### 4.2.2 配置模块参数表 可以查看,并试着修改模块参数表。 ![Example](handbook/5.Props.jpg) - 双击彩色的“实例值”,进入编辑状态 - 修改相应的数值。所有被修改的值,都会以命令行的参数方式传给进程。 ### 4.3 拖入模块 双击或者拖拽模块,以便引入新的模块。我们可以加入采样率变换模块 resample_pqfraction模块。而后,配置其属性。 ![6.NewMod.jpg](handbook/6.NewMod.jpg) ### 4.4 修改连线 选中管脚,右键单击弹出菜单,或者直接按工具栏按钮 |图标|文字|作用|快捷键|行为| |--|--|--|--|--| |![断开](handbook/buttons/D. line.png)|断开管脚|Ctrl+‘d’|断开选中的管脚。|点击按钮后,被鼠标选中的管脚会被断开。| 删除连线。 ![7.DelLine.jpg](handbook/7.DelLine.jpg) 删除后,工程类似: ![8.AfterDel.jpg](handbook/8.AfterDel.jpg) 而后,分别单击下图中的管脚,完成连接,类似: ![9.AfterConn.jpg](handbook/9.AfterConn.jpg) ### 4.5 优化布局 通过拖动方块位置,并利用按钮 |图标|文字|作用|快捷键|行为| |--|--|--|--|--| |![上移](handbook/buttons/up.png)|向上一格|Ctrl+‘上方向’|管脚布局向上移动一格。|点击按钮后,被选中的管脚会向上移动。但由于管脚布局的限制,当无法上移时,请下移其他管脚达到相同作用。| |![下移](handbook/buttons/down.png)|向下一格|Ctrl+‘下方向’|管脚布局向下移动一格。|点击按钮后,被选中的管脚会向下移动。但由于管脚布局的限制,当无法下移时,请上移其他管脚达到相同作用。| |![翻转](handbook/buttons/side.png)|翻转位置|Ctrl+‘左/右’|管脚移动到绘图块的另一边。|点击按钮后,被选中的管脚会翻转到另一边。| 调整布局,调整后,布局如下: ![a.AfterFormat.jpg](handbook/a.AfterFormat.jpg) ### 4.6 运行工程 点击按钮 |图标|文字|作用|行为| |--|--|--|--| |![执行](handbook/buttons/start_project.png)|执行|执行工程|会依次启动各个进程,并吞吐stdio数据| 运行工程,并尝试配置声音来源,可以看到实时语音或者音乐的频谱。 ![b.Run.jpg](handbook/b.Run.jpg)