EPICS asynPortDriver中数组用法示例

2023-11-03

本驱动程序是继承自asynPortDriver,分别重写了用于读取32位整型数组和32位浮点型数组的 readInt32Array和readFloat32Array。

1)源代码如下:

arraydriver.h:

#include "epicsEvent.h"
#include "asynPortDriver.h"

#define P_Int32ArrayValueString         "INT32_ARRAY_VALUE"     /* asynInt32Array */
#define P_Float32ArrayValueString       "FLOAT32_ARRAY_VALUE"   /* asynFloat32Array */
#define P_RunThreadString               "Run_Thread"            /* asynInt32Digital */

class ArrayDriver:public asynPortDriver{
public:
        ArrayDriver(const char * portName, size_t intsize, size_t floatsize);
        virtual asynStatus readInt32Array(asynUser *pasynUser, epicsInt32 * value,size_t nElements,size_t *nIn);
        virtual asynStatus readFloat32Array (asynUser *pasynUser, epicsFloat32 *value, size_t nElements, size_t *nIn);
        virtual asynStatus writeUInt32Digital (asynUser *pasynUser, epicsUInt32 value, epicsUInt32 mask);
        void    startThread(void);

protected:
        int P_Int32ArrayValue;
        int P_Float32ArrayValue;
        int P_RunThread;

private:
        size_t          intsize_;
        epicsInt32      * pInt32_;
        size_t          floatsize_;
        float           * pFloat32_;
        epicsEventId    startevent_;
        epicsUInt32     run_;
};

arraydriver.cpp:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

#include "epicsEvent.h"
#include "asynPortDriver.h"
#include "arraydriver.h"
#include "epicsTypes.h"
#include "iocsh.h"
#include "epicsExport.h"

static const char * driverName = "ArrayDriver";

static void startThreadC(void * pvt);

ArrayDriver::ArrayDriver(const char * portName, size_t intsize, size_t floatsize)
        :asynPortDriver(portName,
                    1,
                    asynInt32ArrayMask | asynFloat32ArrayMask | asynUInt32DigitalMask | asynDrvUserMask,
                    asynInt32ArrayMask | asynFloat32ArrayMask | asynUInt32DigitalMask,
                    0,
                    1,
                    0,0), intsize_(intsize), floatsize_(floatsize),run_(0)
{
        srand(time(NULL));

        pInt32_ = (epicsInt32 *)malloc(sizeof(epicsInt32) * intsize_);
        pFloat32_ = (float *)malloc(sizeof(float) * floatsize);

        createParam(P_Int32ArrayValueString,             asynParamInt32Array,                   &P_Int32ArrayValue);
        createParam(P_Float32ArrayValueString,           asynParamFloat32Array,                 &P_Float32ArrayValue);
        createParam(P_RunThreadString,                   asynParamUInt32Digital,                &P_RunThread);

        for (size_t i = 0; i < intsize_; i++){
                pInt32_[i] = i;
        }

        for (size_t i = 0; i < floatsize_; i++){
                pFloat32_[i] = i * 0.2;
        }

        setUIntDigitalParam(P_RunThread,        run_,   0x1, 0x1);

        startevent_ = epicsEventMustCreate(epicsEventEmpty);

        int status = (epicsThreadCreate("startThreadC",  epicsThreadPriorityMedium, epicsThreadGetStackSize(epicsThreadStackMedium),
                    (EPICSTHREADFUNC)::startThreadC, (void *)this) == NULL);

        if (status ){
                printf("%s: %s  epicsThreadCreate failed\n", "ArraryDriver", "startThreadC");
                return;
        }

}

asynStatus ArrayDriver::readInt32Array(asynUser *pasynUser, epicsInt32 * value,size_t nElements,size_t *nIn)
{
        int function = pasynUser->reason;
        size_t copysize;

        if (function == P_Int32ArrayValue){
                if (intsize_ >= nElements)
                        copysize = nElements;
                else
                        copysize = intsize_;

                *nIn = copysize;

                memcpy(value, pInt32_, sizeof(epicsInt32) * copysize);
        }

        return asynSuccess;
}


asynStatus ArrayDriver::readFloat32Array (asynUser *pasynUser, epicsFloat32 *value, size_t nElements, size_t *nIn)
{
        int function = pasynUser->reason;
        size_t copysize;

        if (function == P_Float32ArrayValue){
                if (floatsize_ >= nElements)
                        copysize = nElements;
                else
                        copysize = floatsize_;

                *nIn = copysize;

                memcpy(value, pFloat32_, sizeof(float) * copysize);
        }
        return asynSuccess;
}

asynStatus ArrayDriver::writeUInt32Digital (asynUser *pasynUser, epicsUInt32 value, epicsUInt32 mask)
{
        int function = pasynUser->reason;
        epicsUInt32 run;

        if (function == P_RunThread){
                run = value & mask;
                setUIntDigitalParam(P_RunThread,        run,   0x1, 0x1);

                if (run){
                        epicsEventSignal(startevent_);
                }

                callParamCallbacks();
                return asynSuccess;
        }
        else{
                return asynPortDriver::writeUInt32Digital(pasynUser, value, mask);
        }

}

//用单独一个线程运行这个方法,为数组产生随机数,用于测试
void ArrayDriver::startThread()
{
        epicsUInt32 run;
        lock();

        while(1){
                unlock();
                epicsEventMustWait(startevent_);
                lock();
                getUIntDigitalParam(P_RunThread, &run, 0x01);
                while (run){
                        for (size_t i = 0; i < intsize_; i++){
                                pInt32_[i] = rand() % 100 + 1;
                        }
                        for (size_t i = 0; i < floatsize_; i++){
                                pFloat32_[i] = (rand() % 100 + 1) * 0.01;
                        }
                        unlock();
                        epicsThreadSleep(1.0);
                        lock();
                        getUIntDigitalParam(P_RunThread, &run, 0x01);
                }
        }
}

static void startThreadC(void * pvt)
{
        ArrayDriver * parrayDriver = (ArrayDriver *)pvt;

        parrayDriver->startThread();
}

extern "C"{
int ArrayDriverConfigure(const char * portName, size_t intsize, size_t floatsize)
{
        new ArrayDriver(portName, intsize,floatsize);
        return asynSuccess;
}

/* EPICS iocsh shell command */
static const iocshArg initArg0 = {"portName", iocshArgString};
static const iocshArg initArg1 = {"intsize", iocshArgInt};
static const iocshArg initArg2 = {"floatsize", iocshArgInt};
static const iocshArg * const initArgs[] = {&initArg0, &initArg1, &initArg2};
static iocshFuncDef initFuncDef = {"ArrayDriverConfigure", 3, initArgs};

static void initCallFunc(const iocshArgBuf * args)
{
    ArrayDriverConfigure(args[0].sval, args[1].ival, args[2].ival);
}

void ArrayDriverRegister(void)
{
    iocshRegister(&initFuncDef, initCallFunc);
}

2) 数据库实例文件arrays.db:

# 用于读取整型数组
record(waveform, "$(P)wfInt32")
{
        field(NELM,"$(NUMS1)")
        field(FTVL, "LONG")
        field(SCAN, "$(SCAN)")
        field(DTYP, "asynInt32ArrayIn")
        field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))INT32_ARRAY_VALUE")
}

# 用于读取浮点数数组
record(waveform, "$(P)wfFloat32")
{
        field(NELM, "$(NUMS2)")
        field(FTVL, "FLOAT")
        field(SCAN, "$(SCAN)")
        field(DTYP, "asynFloat32ArrayIn")
        field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))FLOAT32_ARRAY_VALUE")
}

# 控制随机数线程的运行
record(bo, "$(P)StartThread")
{
   field(PINI, "$(PINI)")
   field(DTYP, "asynUInt32Digital")
   field(OUT,  "@asynMask($(PORT),$(ADDR),0x1, $(TIMEOUT))RUN_THREAD")
   field(ZNAM, "Stop")
   field(ONAM, "Start")
}

3) 启动脚本:

...
# 启动驱动程序
ArrayDriverConfigure("MYPORT", 10, 5)

## 装载记录实例
dbLoadRecords("db/arrays.db","P=TEST:,PORT=MYPORT, ADDR=0, TIMEOUT=1.0, SCAN=I/O Intr, NUMS1=10, NUMS2=5,PINI=NO")
...

4)测试界面:

5) 进行测试:

启动IOC后,点击按钮,每一秒钟会产生一个随机整数数组和一个随机浮点数组:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

EPICS asynPortDriver中数组用法示例 的相关文章

  • SQL Server 数据库——第三章课后题

    习题 3 SQL表达式 4 SQL语句建立第2章习题6中4个表 5 针对习题4中的4个表试用SQL完成以下各项操作 9 请为三建工程项目建立一个供应情况的视图 心得 3 SQL表达式 SELECT FROM S WHERE A 10 SEL
  • IPv6 vs IPv4使用差异说明

    1 IPv6 vs IPv4使用差异说明 1 1 约束限制 chrony支持全局地址 global address 不支持链路本地地址 link local address Firefox支持通过http https协议访问全局地址 glo
  • 微信分享链接出现config:invalid signature错误的解决方法

    当开发微信时需要做特定的页面做分享时 根据官方提供的jssdk php文件创建的签名数据包调试时 大家碰到的最多的错误而且解决最麻烦的大概就是signature错误了 如下图 分享时提示错误 errMsg config invalid si

随机推荐

  • JSP中的内置对象pageContext的作用

    1 当作当前页面域对象使用 2 可以获取到jsp中其他8个内置对象 jsp中其实可以直接用其他内置对象 但再el表达式中可以尝试使用 因为request response session servletContext servletConf
  • 小程序-报错 xxx is not defined (已解决)

    小程序 报错 xxx is not defined 已解决 问题情境 这样一段代码 微信的小程序报错 is not defined 我 wxml 想这样调用 wxml 代码
  • 力扣每日一题【用户分组】

    题目链接 用户分组 视频连接 用户分组 C 代码 class Solution public vector
  • CTO六大能力模型

    一个公司的CTO面临着许多难题和尴尬处境 他们整天忙得焦头烂额 跟CEO肩并肩共同应对各种困难 他们跟其它高管紧密配合 提供强大的技术后盾 他们不断学习新技术 制定符合企业的技术战略 想要成为一名优秀的CTO 究竟要具备哪些方面的能力素质
  • 如何评估大型语言模型(LLM)?

    编者按 近期几乎每隔一段时间 就有新的大语言模型发布 但是当下仍然没有一个通用的标准来评估这些大型语言模型的质量 我们急需一个可靠的 综合的LLM评估框架 本文说明了为什么我们需要一个全面的大模型评估框架 并介绍了市面上这些现有的评估框架
  • 地址解析协议 (ARP)

    地址解析协议 ARP 是互联网协议 IP 套件的关键第 2 层协议 可将 IP 地址转换为媒体访问控制 MAC 地址 IP MAC ARP 在实现网络连接方面发挥着不可或缺的作用 能够发现本地网络上设备的硬件地址并将其映射到其 IP 地址
  • STM32F429 不断重复复位

    之前做过一块STM32F429的板子 板子搭载SDRAM和NAND flash 刚开始板子还是好好的 用了一段时间之后 板子变得很奇怪 开机后SDRAM和NAND初始化之后 运行SDRAM的测试代码 大概运行10S左右就会出现一次复位 我在
  • html设置一段文字颜色,用span css设置div内部分字体颜色

    用span标签设置div内放一段文字中的一小部分文字字体色采方式 一段笔墨放在DIV内或P内 当咱们配置div或p设置字体色彩 内里全体笔墨的字体色调就会变成咱们所配置字体色彩 通常会结构一段翰墨中个中几个字或一小块字的字体色采不同 此时就
  • Hibernate学习(2)- hibernate.cfg.xml详解

    1 主配置文件主要分为三部分 注意 通常情况下 一个session factory节点代表一个数据库 1 1 第一部分 数据库连接部分 注意 hibernate connection driver class 中间的 1 2 第二部分 其他
  • LintCode 202. Segment Tree Query (线段树经典题!)

    Segment Tree Query 中文English For an integer array index from 0 to n 1 where n is the size of this array in the correspon
  • 玩转ChatGPT:视频制作

    一 写在前面 最近 在码深度学习图像识别的相关知识和代码 这一part 看看能否用小Chat搞一个介绍视频 简单问小Chat 咒语 我怎么使用你做一个视频 需要配合什么软件生成 大意就是 惊呆了 这不是我想要的 还是先半自动 后全自动吧 二
  • flink启动报错Failed to construct kafka producer

    flink local模式下启动 sink2kafka报错 具体报错如下 apache kafka common KafkaException Failed to construct kafka producer at org apache
  • python谁是卧底、猜词语

    python谁是卧底 谁是卧底也是深受很多人喜欢的游戏 起码要三人以上才能玩 大致分为几个阶段 1 分配平民词语和卧底词语 gt 2 玩家依次发言 gt 3 根据发言投票认为谁是卧底 gt 4 得到票数最多的玩家出局 gt 5 出局玩家刚好
  • 网络安全—攻防

    招聘需求 尝试通过收集招聘平台的相关职业岗位描述DJ 进行相关方面能力学习 攻防安全 认证 TCSP证书 CISM证书 CISP证书 CISSP证书 CISP PTE证书 CISP DSG证书 CISP A证书 CISD证书 CCSRP证书
  • 2020-10-14 KIBANA7 配置(搜索、可视化组件和仪表板)导出导入

    需求描述 线上Kibana的可视化图表跟仪表盘配置意外丢失了 还好测试环境有相同的配置 根据Kibana的功能进行配置的导出 gt 导入 避免手工一个一个重新配置的繁琐跟配置错误疏漏等情况 也同时进行下配置文件的导出备份工作 参考资料 官方
  • 好分数阅卷3.0_自考阅卷老师是怎么打分的?

    距离十月自考还有一个月 又到了全国考生转发考神的时间 但还有一招更有用 解密阅卷老师 往年很多同学查分后 都会有这么几个疑问 在答题的时候 感觉每道题都答得不错 为什么分数只有这么点 56 57这种分数 搞不懂老师为什么就不能多给我几分 俗
  • Matlab如何打包成jar并给java使用(混合编程)

    Matlab如何打包成jar并给java使用 由于期末数字图像课程设计需求 使用matlab码好了函数可是没有界面 所以打算用jsp随便搞一搞 可是这样就要跨语言编程了 说得很高大上其实就是打成jar然后丢到项目lib包里面去 这时就需要打
  • H5——连连看小游戏实现思路及源码

    部门要求推广新产品用连连看小游戏的方式 设计那边UI还没有排期 先撸个功能demo 正好记录一下 连连看都玩过 程序的关键在于判断连续点击的两张图片是否能够消除 两个图片消除的条件有两个 图片相同 两张图之间连线的转角数不超过2 第一个条件
  • 高级纹理映射技术(6)

    高级纹理映射技术 6 对一些特殊的应用需要对纹理坐标进行处理 主要包括纹理坐标自动生成和纹理坐标变换 下图显示了纹理坐标的来源 处理过程以及到达光栅处理器的过程 纹理坐标自动生成 在Direct3D程序中 不仅可以在模型载入阶段或渲染阶段指
  • EPICS asynPortDriver中数组用法示例

    本驱动程序是继承自asynPortDriver 分别重写了用于读取32位整型数组和32位浮点型数组的 readInt32Array和readFloat32Array 1 源代码如下 arraydriver h include epicsEv