前言

之前讲过Linux的GPIO操作,主要是使用程序访问Linux系统提供的用户空间接口。这次是介绍如何使用EPICS IOC控制GPIO的输入或输出。EPICS有许多设备支持程序,其中就包括Linux GPIO驱动,对于某些需要使用EPICS控制设备GPIO的情况十分有用。

编译GPIO设备支持模块

使用到的软件模块

需要先安装好EPICS Base.

编译 devgpio

注意:gpio设备支持用到了Linux 5.x 内核提供的gpio应用程序接口。

Version 2 of this device support uses the new V2 ABI for GPIO character device (c.f. /usr/include/linux/gpio.h) which was introduced in Kernel 5.x.

如果你使用的是旧版的linxu内核,可能需要使用R1-0-6

交叉编译时gpio.h的路径:${SDKTARGETSYSROOT}/usr/include/linux/gpio.h

编译步骤:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
cd epics-devgpio
touch configure/RELEASE.local
vi configure/RELEASE.local

# 修改成和EPICS Base一样的架构
# EPICS_HOST_ARCH=linux-loong64
# EPICS Base路径(示例)
EPICS_BASE=/home/ubuntu/epics/base-7.0.8.1

# 直接编译
# make
# 交叉编译(示例)
# make LD=loongarch64-linux-gnu-ld CC=loongarch64-linux-gnu-gcc CCC=loongarch64-linux-gnu-g++
make

使用GPIO的设备支持库

IOC程序添加GPIO设备支持,和其他设备支持程序使用方法一样。

示例:

  1. 修改configure/RELEASE

添加devgpio的模块位置

1
2
SUPPORT=/home/ubuntu/epics/epics-modules
DEVGPIO=$(SUPPORT)/epics-devgpio
  1. 修改程序的Makefile

例:修改exampleApp/src/Makefile

1
2
3
4
5
# 添加以下内容
ifneq ($(DEVGPIO),)
example_DBD += devgpio.dbd
example_LIBS += devgpio
endif
  1. 编写db

例:添加exampleApp/Db/gpio.db

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
record(bo, "${IOC}:GPIO:IO39:OUT" {
  field(DESC, "GPIO 39 output")
  field(DTYP, "devgpio")
  field(OUT, "@39")
  field(ZNAM, "OFF")
  field(ONAM, "ON")
}

record(bi, "${IOC}:GPIO:IO38:IN" {
  field(DESC, "GPIO 38 input")
  field(DTYP, "devgpio")
  field(INP, "@38 both")
  field(SCAN, "I/O Intr")
  field(ZNAM, "OFF")
  field(ONAM, "ON")
}

修改exampleApp/Db/Makefile

1
2
# 添加编写的db
DB += gpio.db
  1. 修改启动脚本st.cmd

例:修改iocBoot/iocexample/st.cmd

1
2
3
4
# 设置gpio设备,示例:
GpioChip "/dev/gpiochip0"
# 加载db
dbLoadRecords "db/gpio.db", "IOC=${IOC}"
  1. 编译IOC
1
2
cd example
make

至此,所有步骤都完成了,现在可以运行测试。

  1. 测试运行
1
2
cd iocBoot/iocexample
./st.cmd

输入模式:

1
2
3
4
5
6
> camonitor iocsysStats:GPIO:IO38:IN
iocsysStats:GPIO:IO38:IN       <undefined> OFF UDF INVALID
iocsysStats:GPIO:IO38:IN       2024-12-02 11:21:05.738442 ON
iocsysStats:GPIO:IO38:IN       2024-12-02 11:21:13.115063 OFF
iocsysStats:GPIO:IO38:IN       2024-12-02 11:21:48.090581 ON
iocsysStats:GPIO:IO38:IN       2024-12-02 11:21:51.567303 OFF

输出模式:

1
2
3
4
5
6
> caput iocsysStats:GPIO:IO39:OUT 1
Old : iocsysStats:GPIO:IO39:OUT      OFF
New : iocsysStats:GPIO:IO39:OUT      ON
> caput iocsysStats:GPIO:IO39:OUT 0
Old : iocsysStats:GPIO:IO39:OUT      ON
New : iocsysStats:GPIO:IO39:OUT      OFF

关于record的编写

以下说明中 <> 为必填内容,[] 为可选内容。

  • devgpio支持bibombbi/ombbi/oDirect类型的记录。
  • recordDTYP字段必须为devgpio
  • recordINP字段语法为:@<GPIO1> [GPIO2] [LOW] [FALLING/RISING/BOTH] GPIOx为GPIO的编号,具体可以查阅相应开发板的手册。对于bi类型的记录,只支持一个GPIO。
    LOW标志可以将GPIO切换到低电平模式,对应的选项为low或者lFALLING/RISING/BOTH表示GPIO输入的中断方式。falling/f表示下降沿触发中断,rising/r表示上升沿触发中断,both/b表示两侧均可以触发中断。只有启用了此选项,才可以将SCAN字段设置为I/O Intr
  • recordOUT字段语法为:@<GPIO1> [GPIO2] [LOW] GPIOx为GPIO的编号,具体可以查阅相应开发板的手册。对于bo类型的记录,只支持一个GPIO。
    LOW标志可以将GPIO切换到低电平模式,对应的选项为low或者l