• EPICS asynPortDriver中数组用法示例


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

    1)源代码如下:

    arraydriver.h:

    1. #include "epicsEvent.h"
    2. #include "asynPortDriver.h"
    3. #define P_Int32ArrayValueString "INT32_ARRAY_VALUE" /* asynInt32Array */
    4. #define P_Float32ArrayValueString "FLOAT32_ARRAY_VALUE" /* asynFloat32Array */
    5. #define P_RunThreadString "Run_Thread" /* asynInt32Digital */
    6. class ArrayDriver:public asynPortDriver{
    7. public:
    8. ArrayDriver(const char * portName, size_t intsize, size_t floatsize);
    9. virtual asynStatus readInt32Array(asynUser *pasynUser, epicsInt32 * value,size_t nElements,size_t *nIn);
    10. virtual asynStatus readFloat32Array (asynUser *pasynUser, epicsFloat32 *value, size_t nElements, size_t *nIn);
    11. virtual asynStatus writeUInt32Digital (asynUser *pasynUser, epicsUInt32 value, epicsUInt32 mask);
    12. void startThread(void);
    13. protected:
    14. int P_Int32ArrayValue;
    15. int P_Float32ArrayValue;
    16. int P_RunThread;
    17. private:
    18. size_t intsize_;
    19. epicsInt32 * pInt32_;
    20. size_t floatsize_;
    21. float * pFloat32_;
    22. epicsEventId startevent_;
    23. epicsUInt32 run_;
    24. };

    arraydriver.cpp:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include "epicsEvent.h"
    6. #include "asynPortDriver.h"
    7. #include "arraydriver.h"
    8. #include "epicsTypes.h"
    9. #include "iocsh.h"
    10. #include "epicsExport.h"
    11. static const char * driverName = "ArrayDriver";
    12. static void startThreadC(void * pvt);
    13. ArrayDriver::ArrayDriver(const char * portName, size_t intsize, size_t floatsize)
    14. :asynPortDriver(portName,
    15. 1,
    16. asynInt32ArrayMask | asynFloat32ArrayMask | asynUInt32DigitalMask | asynDrvUserMask,
    17. asynInt32ArrayMask | asynFloat32ArrayMask | asynUInt32DigitalMask,
    18. 0,
    19. 1,
    20. 0,0), intsize_(intsize), floatsize_(floatsize),run_(0)
    21. {
    22. srand(time(NULL));
    23. pInt32_ = (epicsInt32 *)malloc(sizeof(epicsInt32) * intsize_);
    24. pFloat32_ = (float *)malloc(sizeof(float) * floatsize);
    25. createParam(P_Int32ArrayValueString, asynParamInt32Array, &P_Int32ArrayValue);
    26. createParam(P_Float32ArrayValueString, asynParamFloat32Array, &P_Float32ArrayValue);
    27. createParam(P_RunThreadString, asynParamUInt32Digital, &P_RunThread);
    28. for (size_t i = 0; i < intsize_; i++){
    29. pInt32_[i] = i;
    30. }
    31. for (size_t i = 0; i < floatsize_; i++){
    32. pFloat32_[i] = i * 0.2;
    33. }
    34. setUIntDigitalParam(P_RunThread, run_, 0x1, 0x1);
    35. startevent_ = epicsEventMustCreate(epicsEventEmpty);
    36. int status = (epicsThreadCreate("startThreadC", epicsThreadPriorityMedium, epicsThreadGetStackSize(epicsThreadStackMedium),
    37. (EPICSTHREADFUNC)::startThreadC, (void *)this) == NULL);
    38. if (status ){
    39. printf("%s: %s epicsThreadCreate failed\n", "ArraryDriver", "startThreadC");
    40. return;
    41. }
    42. }
    43. asynStatus ArrayDriver::readInt32Array(asynUser *pasynUser, epicsInt32 * value,size_t nElements,size_t *nIn)
    44. {
    45. int function = pasynUser->reason;
    46. size_t copysize;
    47. if (function == P_Int32ArrayValue){
    48. if (intsize_ >= nElements)
    49. copysize = nElements;
    50. else
    51. copysize = intsize_;
    52. *nIn = copysize;
    53. memcpy(value, pInt32_, sizeof(epicsInt32) * copysize);
    54. }
    55. return asynSuccess;
    56. }
    57. asynStatus ArrayDriver::readFloat32Array (asynUser *pasynUser, epicsFloat32 *value, size_t nElements, size_t *nIn)
    58. {
    59. int function = pasynUser->reason;
    60. size_t copysize;
    61. if (function == P_Float32ArrayValue){
    62. if (floatsize_ >= nElements)
    63. copysize = nElements;
    64. else
    65. copysize = floatsize_;
    66. *nIn = copysize;
    67. memcpy(value, pFloat32_, sizeof(float) * copysize);
    68. }
    69. return asynSuccess;
    70. }
    71. asynStatus ArrayDriver::writeUInt32Digital (asynUser *pasynUser, epicsUInt32 value, epicsUInt32 mask)
    72. {
    73. int function = pasynUser->reason;
    74. epicsUInt32 run;
    75. if (function == P_RunThread){
    76. run = value & mask;
    77. setUIntDigitalParam(P_RunThread, run, 0x1, 0x1);
    78. if (run){
    79. epicsEventSignal(startevent_);
    80. }
    81. callParamCallbacks();
    82. return asynSuccess;
    83. }
    84. else{
    85. return asynPortDriver::writeUInt32Digital(pasynUser, value, mask);
    86. }
    87. }
    88. //用单独一个线程运行这个方法,为数组产生随机数,用于测试
    89. void ArrayDriver::startThread()
    90. {
    91. epicsUInt32 run;
    92. lock();
    93. while(1){
    94. unlock();
    95. epicsEventMustWait(startevent_);
    96. lock();
    97. getUIntDigitalParam(P_RunThread, &run, 0x01);
    98. while (run){
    99. for (size_t i = 0; i < intsize_; i++){
    100. pInt32_[i] = rand() % 100 + 1;
    101. }
    102. for (size_t i = 0; i < floatsize_; i++){
    103. pFloat32_[i] = (rand() % 100 + 1) * 0.01;
    104. }
    105. unlock();
    106. epicsThreadSleep(1.0);
    107. lock();
    108. getUIntDigitalParam(P_RunThread, &run, 0x01);
    109. }
    110. }
    111. }
    112. static void startThreadC(void * pvt)
    113. {
    114. ArrayDriver * parrayDriver = (ArrayDriver *)pvt;
    115. parrayDriver->startThread();
    116. }
    117. extern "C"{
    118. int ArrayDriverConfigure(const char * portName, size_t intsize, size_t floatsize)
    119. {
    120. new ArrayDriver(portName, intsize,floatsize);
    121. return asynSuccess;
    122. }
    123. /* EPICS iocsh shell command */
    124. static const iocshArg initArg0 = {"portName", iocshArgString};
    125. static const iocshArg initArg1 = {"intsize", iocshArgInt};
    126. static const iocshArg initArg2 = {"floatsize", iocshArgInt};
    127. static const iocshArg * const initArgs[] = {&initArg0, &initArg1, &initArg2};
    128. static iocshFuncDef initFuncDef = {"ArrayDriverConfigure", 3, initArgs};
    129. static void initCallFunc(const iocshArgBuf * args)
    130. {
    131. ArrayDriverConfigure(args[0].sval, args[1].ival, args[2].ival);
    132. }
    133. void ArrayDriverRegister(void)
    134. {
    135. iocshRegister(&initFuncDef, initCallFunc);
    136. }

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

    1. # 用于读取整型数组
    2. record(waveform, "$(P)wfInt32")
    3. {
    4. field(NELM,"$(NUMS1)")
    5. field(FTVL, "LONG")
    6. field(SCAN, "$(SCAN)")
    7. field(DTYP, "asynInt32ArrayIn")
    8. field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))INT32_ARRAY_VALUE")
    9. }
    10. # 用于读取浮点数数组
    11. record(waveform, "$(P)wfFloat32")
    12. {
    13. field(NELM, "$(NUMS2)")
    14. field(FTVL, "FLOAT")
    15. field(SCAN, "$(SCAN)")
    16. field(DTYP, "asynFloat32ArrayIn")
    17. field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))FLOAT32_ARRAY_VALUE")
    18. }
    19. # 控制随机数线程的运行
    20. record(bo, "$(P)StartThread")
    21. {
    22. field(PINI, "$(PINI)")
    23. field(DTYP, "asynUInt32Digital")
    24. field(OUT, "@asynMask($(PORT),$(ADDR),0x1, $(TIMEOUT))RUN_THREAD")
    25. field(ZNAM, "Stop")
    26. field(ONAM, "Start")
    27. }

    3) 启动脚本:

    1. ...
    2. # 启动驱动程序
    3. ArrayDriverConfigure("MYPORT", 10, 5)
    4. ## 装载记录实例
    5. dbLoadRecords("db/arrays.db","P=TEST:,PORT=MYPORT, ADDR=0, TIMEOUT=1.0, SCAN=I/O Intr, NUMS1=10, NUMS2=5,PINI=NO")
    6. ...

    4)测试界面:

    5) 进行测试:

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

  • 相关阅读:
    技术与产品:工业革命与时代进步的缩影
    数据结构复盘——第一章:绪论
    Spring修炼之旅(4)静态/动态代理模式与AOP
    华清远见11.2
    SCS【4】单细胞转录组数据可视化分析 (Seurat 4.0)
    MySQL-触发器
    pkl文件与打开(使用numpy和pickle)
    blender怎么导入stl格式文件?
    一文搞定接口幂等性架构设计方案
    【JQuery】扩展BootStrap入门——知识点讲解(一)
  • 原文地址:https://blog.csdn.net/yuyuyuliang00/article/details/132804678