以下示例程序将展示如何使用gpio的动态链接库编写一个boRecord的驱动程序,并且展示如何使用这个程序,控制一个LED灯的亮灭。
1) 新建这个示例程序的顶层目录,并且用makeBaseApp.pl在新建目录中构建这个IOC程序程序框架:
root@orangepizero2:/usr/local/EPICS/program# mkdir boDriver
root@orangepizero2:/usr/local/EPICS/program# cd boDriver/
root@orangepizero2:/usr/local/EPICS/program/boDriver# makeBaseApp.pl -t ioc boDriver
root@orangepizero2:/usr/local/EPICS/program/boDriver# makeBaseApp.pl -i -t ioc boDriver
Using target architecture linux-aarch64 (only one available)
The following applications are available:
boDriver
What application should the IOC(s) boot?
The default uses the IOC's name, even if not listed above.
Application name?
root@orangepizero2:/usr/local/EPICS/program/boDriver# ls
boDriverApp configure iocBoot Makefile
2) 进入boDriver/boDriverApp/src路径,编写驱动程序和对应的支持文件:
源程序devbo_driver.c:
root@orangepizero2:/usr/local/EPICS/program/boDriver/boDriverApp/src# cat devbo_driver.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <wiringPi.h> // GPIO的头文件
#include "alarm.h"
#include "dbDefs.h"
#include "dbAccess.h"
#include "recGbl.h"
#include "recSup.h"
#include "devSup.h"
#include "boRecord.h"
#include "epicsExport.h"
/* 使用的GPIO管脚 */
#define LED 6
static long init_record(dbCommon *pcommon);
static long write_bo(boRecord *prec);
bodset devBoGPIO = {
{5, NULL, NULL, init_record, NULL},
write_bo
};
static long init_record(dbCommon *pcommon)
{
long status;
// 初始化GPIO
wiringPiSetup();
// 设置LED管脚为输出模式
pinMode(LED, OUTPUT) ;
/*Don't convert*/
status = 2;
return status;
} /* end init_record() */
static long write_bo(boRecord *prec)
{
long status;
// 将输出值写到LED对应的管脚
digitalWrite(LED,prec->val);
return(status);
}
epicsExportAddress(dset,devBoGPIO);
支持文件devbo_driver.dbd:
root@orangepizero2:/usr/local/EPICS/program/boDriver/boDriverApp/src# cat devbo_driver.dbd
device(bo,INST_IO,devBoGPIO, "bo gpio")
编写Makefile文件,添加以下两处内容:
# 添加
boDriver_SRCS += devbo_driver.c
boDriver_DBD += devbo_driver.dbd
# 添加这个IOC所需的支持库
boDriver_LIBS += wiringPi
wiringPi_DIR = /usr/lib
3) 编写数据库实例文件,进入boDriver/boDriverApp/Db目录
编一个名为bo_gpio的数据库实例文件:
record(bo, "$(USER):BO")
{
field(ONAM, "LIGHT ON")
field(ZNAM, "LIGHT OFF")
field(DTYP, "bo gpio")
}
并且把以上文件名添加到同一路径下的Makefile中:
DB += bo_gpio.db
4) 回到顶层目录boDriver执行make命令进行编译:
root@orangepizero2:/usr/local/EPICS/program/boDriver# make
make -C ./configure install
make[1]: Entering directory '/usr/local/EPICS/program/boDriver/configure'
...
make[2]: Nothing to be done for 'install'.
make[2]: Leaving directory '/usr/local/EPICS/program/boDriver/iocBoot/iocboDriver'
make[1]: Leaving directory '/usr/local/EPICS/program/boDriver/iocBoot'
5) 进入启动目录boDriver/iocBoot/iocboDriver中,修改启动文件st.cmd:
#!../../bin/linux-aarch64/boDriver
#- You may have to change boDriver to something else
#- everywhere it appears in this file
< envPaths
cd "${TOP}"
## Register all support components
dbLoadDatabase "dbd/boDriver.dbd"
boDriver_registerRecordDeviceDriver pdbbase
## Load record instances
dbLoadRecords("db/bo_gpio.db","USER=GPIO")
cd "${TOP}/iocBoot/${IOC}"
iocInit
6) 用以下命令启动这个IOC程序:
root@orangepizero2:/usr/local/EPICS/program/boDriver/iocBoot/iocboDriver# ../../bin/linux-aarch64/boDriver st.cmd
#!../../bin/linux-aarch64/boDriver
< envPaths
epicsEnvSet("IOC","iocboDriver")
epicsEnvSet("TOP","/usr/local/EPICS/program/boDriver")
epicsEnvSet("EPICS_BASE","/usr/local/EPICS/base")
cd "/usr/local/EPICS/program/boDriver"
## Register all support components
dbLoadDatabase "dbd/boDriver.dbd"
boDriver_registerRecordDeviceDriver pdbbase
## Load record instances
dbLoadRecords("db/bo_gpio.db","USER=GPIO")
cd "/usr/local/EPICS/program/boDriver/iocBoot/iocboDriver"
iocInit
Starting iocInit
############################################################################
## EPICS R7.0.7
## Rev. 2023-05-26T09:07+0000
## Rev. Date build date/time:
############################################################################
iocRun: All initialization complete
## Start any sequence programs
#seq sncxxx,"user=orangepi"
epics> dbl
GPIO:BO
用dbl命令,查看当前IOC中只加载了一个记录GPIO:BO。
7) 用同一局域网中安装了通道访问工具的另一台计算机对这个IOC进行访问:
用cainfo查看GPIO:BO的信息:
[root@main-machine blctrl]# cainfo GPIO:BO
GPIO:BO
State: connected
Host: orangepizero2:5064
Access: read, write
Native data type: DBF_ENUM
Request type: DBR_ENUM
Element count: 1
在指定的GPIO管脚上点亮LED:
[root@main-machine blctrl]# caput GPIO:BO 1
Old : GPIO:BO LIGHT OFF
New : GPIO:BO LIGHT ON
熄灭指定的GPIO管脚上LED:
[root@main-machine blctrl]# caput GPIO:BO 0
Old : GPIO:BO LIGHT ON
New : GPIO:BO LIGHT OFF
结论:通过在驱动程序源程序中添加GPIO的头文件并且使用GPIO的库函数,并且在Makefile中指定要链接的GPIO库文件名称和对应的路径。在EPICS IOC中能够使用GPIO管脚进行数字量的输入和输出。