个人常用软件分享
音乐 Listen1 音乐播放器 [Windows/Linux/MacOS/Android] YesPlayMusic 高颜值的第三方网易云播放器 [Windows/Linux/MacOS] AIMP [Windows/Android] Dopamine [Windows] 视频 PotPlayer [Windows] MPC-BE [Windows] QQ影音 [Window/MacOS/Android/iOS] MX Player [Android] 美图下载 Pixiviz pixivFANBOX SauceNAO PixEz [Android/iOS] 下载 Flud 种子下载器 [Android] Internet Download Manager [Windows] Free Download Manager [Windows/MacOS/Linux/Android] Motrix [Windows/MacOS/Linux] 截图、录屏 PixPin [Windows/MacOS] Snipaste [Windows/MacOS] GifCam [Windows] VeryCapture [Windows] ...
EPICS IOC 访问安全
原文:IOC Access Security 功能 访问安全功能用于保护IOC数据库,限制来自未经授权的CA或pvAccess客户端访问。访问安全性基于以下几点: Who 客户端的用户ID(Channel Access/pvAccess)。 Where 用户登录的主机 ID。客户端运行的主机,但不会分辨用户是本地用户或远程登录到主机的用户。 What 记录的各个字段都受到保护。每条记录都有一个字段包含记录的访问安全组(ASG)。每个字段都有一个访问安全级别(ASL0或ASL1)。安全级别在记录定义文件(.dbd)中定义。 When 访问规则可以包含类似于CALC Record的输入计算。 定义 ASL 访问安全级别 ASG 访问安全组 UAG 用户访问组 HAG 主机访问组 快速上手 为了启用特定 IOC 的访问安全性,需要完成以下操作: 创建访问安全文件(.acf) 可能需要修改IOC数据库 记录实例可能需要设置访问安全组ASG字段。如果ASG为空,记录将会使用“DEFAULT”访问安全组。 访问安全文件可以在iocInit之后通过asSubInit和asSubProcess作为关联的子程序重新加载。将值1写入此记录将导致重新加载。 必须启动脚本在的iocInit之前包含以下命令: 1 2 3 4 asSetFilename("/full/path/to/accessSecurityFile") /* 下面是一个可选命令 */ /* 使用宏替换 */ asSetSubstitutions("var1=sub1,var2=sub2,...") 如果在iocInit之前未执行asSetFilename,就不会启用访问安全限制。 如果给定asSetFilename,但在首次初始化访问安全性时发生错误,则对该IOC的所有访问都会被拒绝。 成功启动访问安全性后,尝试重新启动时出现错误,将会保持上次的访问安全配置。 启动IOC并启用访问安全后,可以通过asSetFilename、asSetSubstitutions和asInit来更改访问安全规则。也可以使用函数asInitialize、asInitFile和asInitFP。 在启动IOC之后重新初始化访问安全配置操作是“非常昂贵”的操作,尽量不要这样做。 访问安全配置文件 本节介绍包含用户访问组(UAG)、主机访问组(HAG)和访问安全组(ASG)。IOC会读取访问配置文件(建议使用扩展名.acf)然后创建访问配置数据库。首先给出一个简单的例子,然后是完整的语法描述。 简单示例 1 2 3 4 5 6 7 8 9 UAG(uag) {user1,user2} HAG(hag) {host1,host2} ASG(DEFAULT) { RULE(1,READ) RULE(1,WRITE) { UAG(uag) HAG(hag) } } 上面的规则提供了无限制的读权限(READ),而位于主机host1和host2上的用户user1和user2则拥有写权限(WRITE)。 ...
龙芯开发板移植 IgH EtherCAT Master
前言 IgH EtherCAT Master 是一个开源的EtherCAT主站驱动程序,用于管理EtherCAT从站设备,支持Linux操作系统,工控上使用的比较多。 dls ethercat是由英国钻石光源开发的用于 EPICS 控制系统 EtherCAT 设备的支持程序,基于 IgH Master 主站程序开发,实现对 EtherCAT 总线设备的读写。 交叉编译环境:Ubuntu 运行开发板:龙芯2K0500金龙开发板 内核版本:Linux LS-GD 5.10.0-rt17.lsgd #1 PREEMPT_RT 相关软件包下载地址 epics-base - (launchpad.net) / epics-base/epics-base / EPICS Base (anl.gov) epics-modules/asyn: EPICS module for driver and device support epics-modules/busy: APS BCDA synApps module: busy epics-modules/autosave: APS BCDA synApps module: autosave dls-controls/ethercat: EPICS support to read/write to ethercat based hardware IgH EtherCAT Master for Linux PREEMPT RT patch 配置交叉编译环境 关于这一节,之前的文章已经详细讲过,参考配置交叉编译环境。 ...
EPICS的MODBUS模块的编译和使用
前言 MODBUS是一种应用层消息传递协议,通常用于 I/O 系统通信和可编程逻辑控制器(PLC)通信。 链接类型 描述 MODBUS TCP TCP/IP 使用502端口 MODBUS RTU RTU通常通过串行通信链路运行,即RS-232、 RS-422 或 RS-485。RTU 使用额外的 CRC 进行数据包检查。协议直接将每个字节作为 8 个数据位传输,因此使用“二进制” 而不是 ASCII 编码。使用串行链路开始和结束时,消息帧是按时间而不是按特定字符检测的。 MODBUS ASCII 串行协议,通常在串行通信链路上运行,即 RS-232、RS-422 或 RS-485。串行 ASCII 使用额外的 LRC 数据包检查。该协议将每个字节编码为 2 个 ASCII 字符。消息帧的开始和结束由特定字符检测 (“:” 开始消息,CR/LF 结束消息)。该协议效率低于 Modbus RTU,但在某些环境中可能更可靠。 Modbus 提供对以下 4 种类型的数据的访问: 主表 对象类型 访问 说明 离散输入 1bit 只读 这种类型的数据可以由 I/O 系统提供。 线圈 1bit 读写 此类数据可由应用程序更改。 输入寄存器 16位字(2字节) 只读 这种类型的数据可以由 I/O 系统提供。 保持寄存器 16位字(2字节) 读写 此类数据可由应用程序更改。 Modbus 通信由从 Modbus 客户端发送到 Modbus 服务器的请求消息组成。服务器使用响应消息进行回复。Modbus 请求消息包含: ...
交叉编译EPICS和IOC
前言 之前已经讲过在龙芯3A5000(loongarch64)上编译运行EPICS,不过这种情况只适用于有完整开发环境的情况下进行编译。一些时候,我们只有编译器,而缺少make,perl等工具,比如一些开发板厂商提供的开发套件。这种情况下,就需要通过交叉编译(cross-compiling)的方式来编译EPICS。 这里以龙芯金龙2K500先锋开发板为例,我们使用Ubuntu-20.04作为构建系统,详细讲解如何构建出可以在开发板上运行的EPICS工具包,并部署在开发板上。 由于开发板上没有开发环境,即使编译出目标平台的EPICS Base,我们依然不能直接在开发板上创建和编译IOC。所以,我们还是使用Ubuntu-20.04作为构建系统,创建并编译IOC,最后在开发板上运行。 配置交叉编译环境 关于这一节,之前的文章已经详细讲过,参考配置交叉编译环境。 如果你使用的是其他开发套件,请按照开发手册安装配置好环境。 编译 EPICS Base 首先,下载、解压Base,参考以前的文章。 在龙芯3A5000(loongarch64)上编译运行EPICS中我已经详细讲解了如何在龙架构上编译EPICS,这次,需要在原来对源码修改的基础上,再增加对交叉编译的支持。 添加configure/os/CONFIG.linux-x86_64.linux-loong64 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 # CONFIG.linux-x86_64.linux-loong64 # # Definitions for linux-x86_64 host - linux-loong64 target builds # Sites may override these in CONFIG_SITE.linux-x86_64.linux-loong64 #------------------------------------------------------- VALID_BUILDS = Ioc Command GNU_TARGET = loongarch64-linux-gnu # prefix of compiler tools CMPLR_SUFFIX = CMPLR_PREFIX = $(addsuffix -,$(GNU_TARGET)) # Provide a link-time path for readline if needed OP_SYS_INCLUDES += $(READLINE_DIR:%=-I%/include) READLINE_LDFLAGS = $(READLINE_DIR:%=-L%/lib) RUNTIME_LDFLAGS_READLINE_YES_NO = $(READLINE_DIR:%=-Wl,-rpath,%/lib) RUNTIME_LDFLAGS += \ $(RUNTIME_LDFLAGS_READLINE_$(LINKER_USE_RPATH)_$(STATIC_BUILD)) SHRLIBDIR_LDFLAGS += $(READLINE_LDFLAGS) PRODDIR_LDFLAGS += $(READLINE_LDFLAGS) # Library flags STATIC_LDFLAGS_YES= -Wl,-Bstatic STATIC_LDFLAGS_NO= STATIC_LDLIBS_YES= -Wl,-Bdynamic STATIC_LDLIBS_NO= 添加configure/os/CONFIG_SITE.linux-x86_64.linux-loong64 ...
Linux LED子系统
前言 Linux 内核提供了丰富的设备驱动接口,其中GPIO和LED属于是最基本的一类了。之前就已经讲过用户空间下的GPIO读写操作,LED设备的操作也基本相同。其实完全可以使用GPIO驱动去控制LED,但LED的驱动针对LED提供了更多的功能,一起来看一下吧。 配置设备树 设备树中的LED节点配置,例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 /* kernel/arch/arm/boot/dts/imx6ul-14x14-evk-c-emmc.dts */ leds { compatible = "gpio-leds"; pinctrl-names = "default"; status = "okay"; led1{ label = "led1"; gpios = <&gpio5 9 GPIO_ACTIVE_LOW>; default-state = "off"; }; led2{ label = "led2"; gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; default-state = "off"; }; led3{ label = "heartbeat"; gpios = <&gpio5 5 GPIO_ACTIVE_LOW>; linux,default-trigger = "heartbeat"; }; }; 节点属性说明: label:LED设备的名字,名字必须是唯一的。如果没有设置,则会使用节点的名字。 gpios:GPIO的编号,以及高低电平设置,GPIO_ACTIVE_LOW低电平点亮,GPIO_ACTIVE_HIGH高电平点亮。 default-state:默认状态,on/off。 linux,default-trigger:设置LED的触发器。backlight-背光灯,heartbeat-心跳灯,timer-定时,default-on-默认开状态,disk-activity-硬盘状态,gpio,none。 用户空间下的LED操作 注意:以下操作都需要root权限! 用户空间下的GPIO文件系统接口在/sys/class/leds/{label}目录下。 LED节点有以下属性可以配置: ...
EPICS Qt安装
前言 本文主要记录了EPICS Qt在Linux上的安装步骤。这里以loongnix操作系统为例,Ubuntu系统上编译安装步骤类似。 EPICS Qt是一个基于Qt的分层框架,使用Channel Access (CA) and PV Access(PVA)访问EPICS数据。它是为快速开发控制系统图形界面而设计的,最初是在澳大利亚同步加速器开发的。 安装EPICS 这里不再写具体步骤了,总之就是非常简单,下载、解压、编译即可。具体步骤可以参考以前的文章。 安装Qt 直接使用终端安装Qt 1 2 3 4 5 sudo apt update sudo apt install qtbase5-dev qt5-qmake qtcreator sudo apt install qtdeclarative5-dev qttools5-dev # 安装Qt Svg库,编译QWT时需要用到 sudo apt install libqt5svg5-dev 安装QWT Qt EPICS推荐使用Qwt 6.1.4,如果在Ubuntu 20.04上直接通过终端安装也是这个版本。我使用Qwt 6.2.0编译,也是没有问题的,这里以Qwt 6.2.0为例。 最新测试:Qwt 6.3.0也可以用 ~ 先下载Qwt的源码 下载Qwt-6.2.0。 下载完成后解压 1 2 3 4 # 解压tar.bz2 tar -jxvf qwt-6.2.0.tar.bz2 # 解压zip unzip qwt-6.2.0.zip 解压完成后编译Qwt,使用QtCreator或者在终端使用qmake都可以。 然后手动将编译生成的文件复制到以下位置,例: 1 2 3 4 5 6 7 # 复制编译生成的qwt sudo cp -r build-qwt-unknown-Release/lib/* /usr/lib/loongarch64-linux-gnu/ # 复制编译生成的designer插件 sudo cp build-qwt-unknown-Release/designer/plugins/designer/libqwt_designer_plugin.so /usr/lib/loongarch64-linux-gnu/qt5/plugins/designer/ # 复制qwt头文件 sudo mkdir /usr/include/qwt sudo cp qwt-6.2.0/src/*.h /usr/include/qwt 安装ACAI ACAI Channel Access Interface ...
龙芯2K500开发板上实现的呼吸灯效果
前言 本来这篇文章应该在上周就写完的,不过突然被安排出差,一直忙到了现在,终于可以静下心来做些其它事情。 之前和龙芯3A5000主机一起送过来的还有一块龙芯2K500的迷你开发板,整个板子不到巴掌大小。之前只是简单做了上电启动,这次拿到了比较完整的开发资料,可以尝试为开发板编写一些程序了。 由于暂时没有屏幕,只能先试着做一些其它的事情,如通信和IO控制,其中最简单,最基础的就是LED灯的控制。然后我就发现,这个板子居然有一颗可以调节亮度的LED灯!没错,之前做的LED控制都只能进行开关操作,而可以调节亮度,意味着可以做出更多的显示效果,这次我就做了一个呼吸灯的效果。 然后,我也简单了解了一下这种亮度调节的原理,实际上就是通过调节PWM输出的占空比,改变一个周期内输出的高低电平所占的比例,实现控制LED灯亮度的效果。由于引脚输出的电压是固定的,所以不能通过改变电平来控制亮度,而改变高低电平的占空比则是另一种思路,嵌入式设备的屏幕背光亮度调节也是基于同样的原理。 开发板上电启动、连接串口终端 由于暂时没有屏幕,想要和开发板进行交互就只能通过终端的方式,通常开发板都会有调试串口,我们先通过串口终端登录设备,配置好网口IP地址后,再通过网络连接登录设备。 串口的连接方式如下图: 将绿、白、黑三色线以图中方式接好(红线不用接),USB端插入到电脑,应该不需要装驱动,电脑可以直接识别出串口设备。 打开串口终端工具,比如Windows MobaXterm,linux minicom等,我比较喜欢用putty。 配置好端口,设置 波特率:115200 数据位:8位 停止位:1位 校验:无 硬件流控:无 然后给开发板接通电源,就可以看到调试输出信息了。 查看系统信息,可以看到运行的是安装了PREEMPT_RT补丁的实时操作系统。 1 2 3 [root@LS-GD ~]# uname -a Linux LS-GD 5.10.0.lsgd-g434b00a6badf #1 PREEMPT Wed Sep 14 12:57:58 CST 2022 loongarch64 GNU/Linux [root@LS-GD ~]# 配置交叉编译环境 2K500开发板是loongarch64架构的嵌入式板卡。下载好对应的交叉编译工具链后,解压到系统/opt/目录下。按手册来就好~ 1 $ sudo tar -xf toolchain-loongarch64-linux-gnu-gcc8-host-x86_64-2022-07-18.tar.xz -C /opt/ 然后我们需要将交叉编译器添加到系统路径,方便我们接下来使用。 这里我直接将配置写成脚本,方便下次使用。 1 2 3 4 5 6 7 8 $ cd /opt/toolchain-loongarch64-linux-gnu-gcc8-host-x86_64-2022-07-18 # 创建脚本 $ sudo touch environment-setup-loongarch64-linux-gnu # 添加可执行权限 $ sudo chmod +x environment-setup-loongarch64-linux-gnu # 修改脚本内容 $ sudo vi environment-setup-loongarch64-linux-gnu # 内容如下~ 1 2 3 4 5 6 7 8 # environment-setup-loongarch64-linux-gnu CC_PREFIX=/opt/toolchain-loongarch64-linux-gnu-gcc8-host-x86_64-2022-07-18 export PATH=$CC_PREFIX/bin:$PATH export LD_LIBRARY_PATH=$CC_PREFIX/lib:$LD_LIBRARY_PATH export LD_LIBRARY_PATH=$CC_PREFIX/loongarch64-linux-gnu/lib64:$LD_LIBRARY_PATH export ARCH=loongarch export CROSS_COMPILE=loongarch64-linux-gnu- 接下来测试一下交叉编译环境 ...
龙芯3A5000(LoongArch64)上编译运行EPICS
前言 之前尝试过在龙芯3A4000上编译运行EPICS,由于3A4000还是mips64指令集,而3A5000则是龙芯的自主指令集loongarch64,适配起来步骤也会有所不同。 这次使用的是龙博特龙芯3A5000电脑主机。 虽然EPICS官方并没有适配loongarch和mips64,无法做到开箱即用,但只要有gcc、g++、make、perl这些工具,理论上就能编译运行EPICS,在开始编译前,确保你的设备上已经装好了这些工具。 关于如何称呼「龙架构」,龙芯社区也有一些讨论。最初我直接使用loongarch64,后来也使用过la64作为简写,直到我看到如何称呼龙架构?,我觉得有必要和社区保持一致,后续统一使用 loong64 作为架构标识。 下载 base 这里我们就以目前最新版本7.0.7为例,其它版本的Base也类似。 1 2 3 $ cd ~/下载/ $ wget https://epics.anl.gov/download/base/base-7.0.7.tar.gz $ tar -xzvf base-7.0.7.tar.gz 你可以在你觉得合适的位置编译安装Base,这里按我们的习惯,放在/usr/local/epics目录下。 1 2 $ mkdir /usr/local/epics $ mv base-7.0.7 /usr/local/epics/ 编译 按照一般步骤,现在就可以开始编译了,我们可以先尝试一下,看看是什么结果。 1 2 3 $ cd /usr/local/epics/base-7.0.7/ # 执行 `make` 命令 $ make 不出所料,果然失败了,输出的错误和在3A4000上编译时的错误也有一些不同。 下面是在3A4000上编译时输出的错误: 下面一行报错是差不多的,在loongarch64上编译却多了上面一行报错,意思就是没有识别出loongarch64架构。 但是先不要慌,这里同时也给出了报错的位置,让我们看看EpicsHostArch.pl里写了些什么。 1 $ vi ./src/tools/EpicsHostArch.pl 它其实就是一个perl脚本,用来判断当前的系统和cpu架构,而loongarch64显然没有做适配,所以就出现了上面错误。 “Architecture ’loongarch64-linux-gnu-thread-multi’ not recognized” 既然识别不了loongarch64,那我们就手动添加一行,让它可以识别就行了,即使看不太懂上面的脚本也没关系,看个半懂就行了。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 sub HostArch { my $arch = $Config{archname}; for ($arch) { return 'linux-x86_64' if m/^x86_64-linux/; return 'linux-x86' if m/^i[3-6]86-linux/; return 'linux-arm' if m/^arm-linux/; return 'linux-aarch64' if m/^aarch64-linux/; return 'linux-ppc64' if m/^powerpc64-linux/; return 'linux-loong64' if m/^loongarch64-linux/; return 'windows-x64' if m/^MSWin32-x64/; return 'win32-x86' if m/^MSWin32-x86/; return "cygwin-x86_64" if m/^x86_64-cygwin/; return "cygwin-x86" if m/^i[3-6]86-cygwin/; return 'solaris-sparc' if m/^sun4-solaris/; return 'solaris-x86' if m/^i86pc-solaris/; my ($kernel, $hostname, $release, $version, $cpu) = uname; if (m/^darwin/) { for ($cpu) { return 'darwin-x86' if m/^x86_64/; return 'darwin-aarch64' if m/^arm64/; } die "$0: macOS CPU type '$cpu' not recognized\n"; } die "$0: Architecture '$arch' not recognized\n"; } } 我们在上面位置添加一行内容,来让它可以识别loongarch64架构。 ...
Linux GPIO 操作其一
前言 由于换了新的工作,我的工作方向也有了很大的变化,之前基本上是单纯的写代码,现在则经常需要和硬件设备交互,开发平台也转到了Linux+Qt。硬件设备的控制,其中最基本的就是LED灯以及一些开关继电器的操作,其本质就是GPIO的操作。考虑到系统的精简和成本控制,最好是可以直接通过Linux系统去控制,当然也有其它替代方案,比如使用支持Modbus协议的IO模块。关于Modbus的使用,后面有空再讲,这里就记录一下最简单的Linux系统下的GPIO控制,用户空间下的GPIO文件系统接口。 在此之前,有必要再了解一下GPIO的概念。 “通用输入/输出”(GPIO)是一种灵活的软件控制数字信号。它们由多种芯片提供,对于使用嵌入式和定制硬件的Linux开发人员来说很熟悉。每个GPIO代表一个连接到特定引脚的位,即球栅阵列(BGA)封装上的“球”。电路板示意图显示了哪些外部硬件连接到哪些GPIO。驱动程序可以通用地编写,以便板设置代码将这样的引脚配置数据传递给驱动程序。 A “General Purpose Input/Output” (GPIO) is a flexible software-controlled digital signal. They are provided from many kinds of chip, and are familiar to Linux developers working with embedded and custom hardware. Each GPIO represents a bit connected to a particular pin, or “ball” on Ball Grid Array (BGA) packages. Board schematics show which external hardware connects to which GPIOs. Drivers can be written generically, so that board setup code passes such pin configuration data to drivers. ...