• EPICS记录参考--sub-Array记录(subArray)


    subArray记录类型的一般用法是从waveform记录获取子数组。设置元素数目(NELM)或索引(INDX)字段使得这个记录再被运行依次,因此使用标准EPICS操作接口工具能够实现这样的应用程序,在这个应用程序中在一个waveform记录中一个子数组的长度和位置动态变化。

     

    subArray记录的第一个元素(在被引用的waveform记录中INDX位置)可以以标量被显示,或者用与waveform记录相同的方式显示整个subarray(NELM长度)。如果被引用waveform记录在INDX后的元素少于NELM个元素,返回实际可以获取的元素数目,并且被读取元素数目字段(NORD)被设置来反映这个。这个记录类型不支持写新值到waveform记录。

    参数字段

    记录专用字段在下面描述,按功能分组:

    用于扫描的参数

    subArray记录有用于指定在什么情况下将运行这个记录的标准字段。这些字段在Scan Fields中列出。

    用于读取的参数

    subArray输入链接(INP)应该被配置成引用Waveform记录。它应该指定一个waveform记录的VAL字段。INP字段可以是通道访问链接和数据库链接。

    这些参数确定了数组元素的数目(数组长度)和那些元素的数据类型。字段值的类型(FTVL)字段确定了这个数组的数据类型。

    用户在MALM字段中指定了要被读入到这个subarray的数目最大数目。这通常应该等于Waveform数组中元素数目(在Waveform的NELM字段中找到)。MALM字段用于分配内存。subArray的元素数目字段是用户指定subArray将提取的实际元素数目的地方。它当然不应该大于MALM;如果它是,记录运行的process例程设置其等于MALM。

     INDX字段确定了subArray记录的数组相对于Waveform数组的偏移。例如,如果INDX是2,则subArray将读取NELM元素从Waveform的数组的第三个元素开始读取NELM个元素。因而,它等于Waveform的数组的索引号。

    实际的子数组是被VAL字段引用。

    这些参数用于向操作者显示有意义的数据。它们以文本或图形显示这个subArray记录的值和其它参数。EGU是一个最长16个字符的字符串,描述这个subArray记录保存值的工程单位。通过get_units()记录支持例程获取它。

    HOPR和LOPR字段为这个sub-array元素设置上下显示限制。get_graphic_double()和get_control_double()记录支持例程都获取这些字段。

    PREC字段确定了用什么浮点精度显示VAL。当调用get_precision()记录支持例程时使用它。

    有关记录名(NAME)和描述(DESC)字段的更多信息见Fields Common to All Record Type。

    用于警报的参数

     subArray记录有所有记录类型共有的警报参数。Alarm Fields列出了与所有记录类型共有警报相关联的字段。

    运行时参数

    这些字段不是由用户配置的。它们用于记录内部运行或者代表这个记录的当前状态。

    NORD字段保存了实际被读入这个数组的元素数目。当NELM和INDX字段之和超过了在源数组中找到的已有元素数目时,它将少于NELM。

    BPTR包含了一个指向这个记录的数组的指针。

    记录支持

    记录支持例程

     1) init_record

     long (*init_record)(struct dbCommon *precord, int pass)

     使用MALM和FTVL,为数组分配空间。数组地址存储在BPTR。这个例程检查设备支持是否可用以及设备支持读取例程是否被定义。如果二者中有一个不存在,发出一条错误消息,并且终结运行的process。如果设备支持包含init_record(),它被调用。

    2) process

      long (*process)(struct dbCommon *precord)

    3) cvt_dbaddr

     long (*cvt_dbaddr)(struct dbAddr *paddr)

    这被dbNameToAddr()调用。它使得dbAddr结构体指向保存这个结果的实际缓存。

    4) get_array_info

     long (*get_array_info)(struct dbAddr *paddr, long *no_elements, long *offset)

    获取NORD。

    5) put_array_info

     long (*put_array_info)(struct dbAddr *paddr, long nNew)

    设置NORD。

    6) get_graphic_double

      long (*get_graphic_double)(struct dbAddr *paddr, struct dbr_grDouble *p)

    对于数组中元素,这个例程设置HOPR和LOPR。对于INDX字段,这个例程返回MALM-1和0。对于MALM,返回MALM和1。对于其它字段,它调用recGblGetGraphicDouble。

    7) get_control_double

    long (*get_control_double)(struct dbAddr *paddr, struct dbr_ctrlDouble *p)

    对于数组元素,这个例程获取HOPR和LOPR。否则,调用recGblControlDouble()。

    8) get_units

    long (*get_units)(struct dbAddr *paddr, char *units)

    获取EGU。

    9) get_precision

     long (*get_precision)(const struct dbAddr *paddr, long *precision)

    记录运行

    记录运行实现以下算法:

    1) 检查合适的设备支持模块是否存在。如果它不存在,则发出一条错误消息并且用PACT字段仍设置为TRUE终止正在运行的process。这确保了不再为这个记录调用processes。因而不会发生错误风暴。

    2) 检查NELM和INDX。如果NELM大于MALM,它被设置成MALM。如果INDX大于或等于MALM,它被设置成MALM-1。

    3) 调用设备支持的read_sa()例程。预计这个例程从缓存起始放置所需的子数组,并且设置NORD为被读取的子数组的元素数目。

    4) 如果PACT已经被更改为TRUE,设备支持读取操作已经开始,但还未结束写新值。

    5)  检查是否应该调用monitors。

    • 如果警报状态或者严重性发生变化,调用警报监视器
    • 总是调用archive和值变化监视器
    • NSEV和NSTA被重置为0

    6) 如果需要,扫描forward链接,设置PACT为FALSE,并且返回。

    设备支持

    设备支持有关字段

    设备支持例程主要使用以下字段:

    设备支持例程(devSASoft.c)

     设备支持由以下例程组成:

    1) long report(int level)

    这个可选的例程被IOC命令dbior调用,并且被传递用户请求的报告等级。它应该打印一个有关设备支持的报告到stdout。level参数可以用于用更改等级输出更加详细的信息,或者选择用不同级别的不同信息类型。级别0应该输出一小段概述。

    2) long init(int after)

    这个可选的例程在IOC初始化时被调用两次。第一次调用用整数参数after设置为0在进行任何init_record()调用前发生。第二次调用用after设置为1在已经进行了所有init_record()调用后发生。

    3) init_record

     long init_record(subArrayRecord *prec)

    这个例程被记录支持init_record()例程调用。

    4) read_sa

    long read_sa(subArrayRecord *prec)

    从源waveform开始读取源waveform足够到BPTR,去包含请求的子数组。接着数组被复制到这个缓存的起始。NORD被设置成被采集的子数组的元素数目。

    软记录的设备支持

    当前只提供设备支持模块Soft Channel。

    Soft Channel

    预计INP指向一个waveform记录或者类似的一个数组字段。

    示例:数据库实例文件

    这个数据库实例文件有三个记录实例组成:

    1) $(USER):arrayIn记录实例是waveform类型记录实例,它驱动$(USER):subArray记录实例运行并且为其提供数据源。

    2) $(USER):subArray记录实例是subArray类型记录实例,它用其INDX和ELEM字段从其源waveform记录实例数组中提取子数组,放入本记录数组中,并且驱动$(USER):arrayOut记录实例运行并且为其提供数据源。

    3) $(USER):arrayOut记录实例是waveform类型记录实例,它从$(USER):subArray记录实例的数组中获取数组,存入本记录的数组中。

    1. record(waveform, "$(USER):arrayIn")
    2. {
    3. field(SCAN, "Passive")
    4. field(DTYP, "Soft Channel")
    5. field(NELM, "10")
    6. field(FTVL, "LONG")
    7. field(FLNK, "$(USER):subArray")
    8. }
    9. record(subArray, "$(USER):subArray")
    10. {
    11. field(SCAN, "Passive")
    12. field(DTYP, "Soft Channel")
    13. field(FTVL,"LONG")
    14. field(MALM, "10")
    15. field(NELM, "5")
    16. field(INDX, "2")
    17. field(INP, "$(USER):arrayIn.VAL")
    18. field(FLNK, "$(USER):arrayOut")
    19. }
    20. record(waveform, "$(USER):arrayOut")
    21. {
    22. field(SCAN, "Passive")
    23. field(DTYP, "Soft Channel")
    24. field(FTVL, "LONG")
    25. field(NELM, "10")
    26. field(INP, "$(USER):subArray.VAL")
    27. }

    将上述记录数据库文件加载到IOC中,用dbl观察一共加载的记录实例:

    1. epics> dbl
    2. blctrl:arrayIn
    3. blctrl:arrayOut
    4. blctrl:subArray

    另开一个命令窗口,用通道访问命令对以上记录实例的数据传递进行测试:

    1. # IOC初始化时,三个记录各自初始的值
    2. [root@bjAli ~]# caget blctrl:arrayIn blctrl:subArray blctrl:arrayOut
    3. blctrl:arrayIn 10 3 0 0 0 0 0 0 0 0 0
    4. blctrl:subArray 10 327690 0 0 0 0 0 0 0 0 0
    5. blctrl:arrayOut 10 0 0 0 0 0 0 0 0 0 0
    6. # 向blctrl:arrayIn记录中写入一个长度为10的数组,数组元素从1~10
    7. # 观察blctrl:subArray和blctrl:arrayOut记录实例中数组元素以及这两个记录实例实际获取的元素数目
    8. # INDX=2,ELEM=5,subArray记录获取的数组元素是从blctrl:arrayIn数组中第三个元素开始,取5个元素
    9. [root@bjAli ~]# caput -a blctrl:arrayIn 10 1 2 3 4 5 6 7 8 9 10
    10. Old : blctrl:arrayIn 10 3 0 0 0 0 0 0 0 0 0
    11. New : blctrl:arrayIn 10 1 2 3 4 5 6 7 8 9 10
    12. [root@bjAli ~]# caget blctrl:arrayIn blctrl:subArray blctrl:arrayOut
    13. blctrl:arrayIn 10 1 2 3 4 5 6 7 8 9 10
    14. blctrl:subArray 10 3 4 5 6 7 0 0 0 0 0
    15. blctrl:arrayOut 10 3 4 5 6 7 0 0 0 0 0
    16. [root@bjAli ~]# caget blctrl:arrayIn.NORD blctrl:subArray.NORD blctrl:arrayOut.NORD
    17. blctrl:arrayIn.NORD 10
    18. blctrl:subArray.NORD 5
    19. blctrl:arrayOut.NORD 5
    20. # 更改subArray记录实例的取值索引起始值
    21. [root@bjAli ~]# caput blctrl:arrayIn.INDX 4
    22. Channel connect timed out: 'blctrl:arrayIn.INDX' not found.
    23. [root@bjAli ~]# caput blctrl:subArray.INDX 4
    24. Old : blctrl:subArray.INDX 2
    25. New : blctrl:subArray.INDX 4
    26. [root@bjAli ~]# caget blctrl:arrayIn blctrl:subArray blctrl:arrayOut
    27. blctrl:arrayIn 10 1 2 3 4 5 6 7 8 9 10
    28. blctrl:subArray 10 5 6 7 8 9 0 0 0 0 0
    29. blctrl:arrayOut 10 5 6 7 8 9 0 0 0 0 0
    30. [root@bjAli ~]# caget blctrl:arrayIn.NORD blctrl:subArray.NORD blctrl:arrayOut.NORD
    31. blctrl:arrayIn.NORD 10
    32. blctrl:subArray.NORD 5
    33. blctrl:arrayOut.NORD 5
    34. # 更改subArray记录实例的取值数目值
    35. [root@bjAli ~]# caget blctrl:subArray.NELM 2
    36. Channel connect timed out: some PV(s) not found.
    37. [root@bjAli ~]# caput blctrl:subArray.NELM 2
    38. Old : blctrl:subArray.NELM 5
    39. New : blctrl:subArray.NELM 2
    40. [root@bjAli ~]# caget blctrl:arrayIn blctrl:subArray blctrl:arrayOut
    41. blctrl:arrayIn 10 1 2 3 4 5 6 7 8 9 10
    42. blctrl:subArray 10 5 6 0 0 0 0 0 0 0 0
    43. blctrl:arrayOut 10 5 6 0 0 0 0 0 0 0 0
    44. [root@bjAli ~]# caget blctrl:arrayIn.NORD blctrl:subArray.NORD blctrl:arrayOut.NORD
    45. blctrl:arrayIn.NORD 10
    46. blctrl:subArray.NORD 2
    47. blctrl:arrayOut.NORD 2
  • 相关阅读:
    如何用好Nginx的gzip指令
    react源码分析:实现react时间分片
    Pytorch——查找、替换module相关操作
    从零开始的力扣刷题记录-第八十九天
    Dubbo 面试题(三)
    设计原则之显式依赖关系
    JAVA线程池
    QT状态机使用笔记1
    三个线程依次顺序执行
    计算机系统中的大端模式和小端模式
  • 原文地址:https://blog.csdn.net/yuyuyuliang00/article/details/127406003