EPICS Home

Experimental Physics and Industrial Control System


 
1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  <20242025  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  <20242025 
<== Date ==> <== Thread ==>

Subject: Re: [EXTERNAL] lso record
From: Heinz Junkes via Tech-talk <tech-talk at aps.anl.gov>
To: "Johnson, Andrew N." <anj at anl.gov>
Cc: EPICS Tech Talk <tech-talk at aps.anl.gov>
Date: Mon, 9 Sep 2024 21:46:22 +0200
Hi Andrew,
thanks for the explanation.
It works with that:

epics@ares:~/FHI/IOCs/sampleIOC$ cat sampleIOCApp/Db/tempLinuxExample.db

record(lso, "$(user):zone0")
{
   field(SIZV, "64")
   field(DOL, {const:"/sys/devices/virtual/thermal/thermal_zone0/temp"})
   field(PINI, "YES")
   field(OUT,"$(user):tempLinuxExample.A")
}

record(lso, "$(user):zone1")
{
   field(SIZV, "64")
   field(DOL, {const:"/sys/devices/virtual/thermal/thermal_zone1/temp"})
   field(PINI, "YES")
   field(OUT,"$(user):tempLinuxExample.B")
}

record(lso, "$(user):zone2")
{
   field(SIZV, "64")
   field(DOL, {const:"/sys/devices/virtual/thermal/thermal_zone2/temp"})
   field(PINI, "YES")
   field(OUT,"$(user):tempLinuxExample.C")
}

record(aSub,"$(user):tempLinuxExample")
{
   field(INAM,"tempLinuxInit")
   field(SNAM,"tempLinuxProcess")
   field(FTA, "CHAR")
   field(FTB, "CHAR")
   field(FTC, "CHAR")

   field(NOA, "64")
   field(NOB, "64")
   field(NOC, "64")
}


/* SPDX-License-Identifier: EPICS */
/* tempLinuxExample.c, adaption of dbSubEmxample.c */

#include <stdio.h>

#include <dbDefs.h>
#include <registryFunction.h>
#include <aSubRecord.h>
#include <epicsExport.h>
#include <errlog.h>
#include <menuFtype.h>

int tempLinuxDebug;

#define MAX_TEMP_INPUT 3

static long tempLinuxInit(aSubRecord *precord)
{
    if (tempLinuxDebug)
        printf("Record %s called tempLinuxInit(%p)\n",
               precord->name, (void*) precord);

    /* read sensor filename, first stupid versio form a/b/c */

    for(int i=0; i<MAX_TEMP_INPUT; i++) {
        if ((&precord->fta)[i] != menuFtypeCHAR) {
            errlogPrintf("%s [%d] incorrect input type - must be CHAR. ", precord->name, i);
	 return -1;
        }
    }

    return 0;
}

static long tempLinuxProcess(aSubRecord *precord)
{
    if (tempLinuxDebug)
        printf("Record %s called tempLinuxProcess(%p)\n",
               precord->name, (void*) precord);

    for(int i=0; i<MAX_TEMP_INPUT; i++) {
        printf("Temp Input %d: %s\n", i, (char *)(&precord->a)[i]);
    }
    return 0;
}

/* Register these symbols for use by IOC code: */

epicsExportAddress(int, tempLinuxDebug);
epicsRegisterFunction(tempLinuxInit);
epicsRegisterFunction(tempLinuxProcess);

This shows on processing:

epics> Record ares:tempLinuxExample called tempLinuxProcess(0x56404aaba940)
Temp Input 0: /sys/devices/virtual/thermal/thermal_zone0/temp
Temp Input 1: /sys/devices/virtual/thermal/thermal_zone1/temp
Temp Input 2: /sys/devices/virtual/thermal/thermal_zone2/temp

Gruss Heinz


> On 9. Sep 2024, at 21:33, Johnson, Andrew N. <anj at anl.gov> wrote:
>
> Hello Heinz,
>  I agree that EPICS strings are messy, they have evolved over many years while keeping as much compatibility between clients and IOCs that we were able to do. The approach we came up with allowed older CA clients to access long string fields without any modifications since many of them could already display a char waveform as a string. The alternative approaches to adding long strings would have broken CA interoperability and required changes to all CA clients, and we didn't want to do that.
>  If you had used double-quotes in your first .db file this should have worked:
>     field(VAL, "blabberblabberblub")
> You don't need to  The Long String field modifier '$' is documented here, but it probably should be explained elsewhere as well. The catools (caget/caput/camonitor) support long strings using the '-S' flag, and AFAIK all current display managers do as well, but their widgets have to be configured to display the value as a string instead of an array (that's their equivalent to the '-S' flag to the catools).
>  Unfortunately the pvget/pvput tools don't currently have an equivalent of the '-S' flag although if they did that would work with a $ field modifier. If your IOC runs QSRV-2 from PVXS that can transport long strings over PVA, and with that you don't have to use the $ field modifier at all. I'm not sure if PVXS can support treating a waveform containing a char array as a string, it may be possible if you set an info field.
>  An aSub INPA link can fetch a long string from an lsi/lsi/printf record. The FTA field should be set to CHAR, NOA set to the maximum string size (probably 64 for your examples) and the INPA link should point to the .VAL$ field of the source lsi/lso record. If you're outputting long strings from the aSub record (say the VALA field) after writing the string to VALA you also have to set NEVA:
>     prec->neva = strlen(prec->vala) + 1;
>  HTH,
>  - Andrew
>   On 9/9/24, 12:56 PM, "Tech-talk" <tech-talk-bounces at aps.anl.gov> wrote:
> Thanks Steve,
> Yes, that works. However, in my opinion, none of this is well explained in our documentation. Examples are also missing.
> I'll try to write something about this in the next few days, including the DCT field.
>  Unfortunately, we make it infinitely difficult for beginners to get to grips with Epics. And even I couldn't figure it out today :-(
>  And if I set the Epics record as described by you
>   record(lso, "$(user):zone0")
> {
>     field(SIZV, "64")
>     field(DOL, {const:"/sys/devices/virtual/thermal/thermal_zone0/temp”})
>     field(PINI, "YES")
> }
>  the result with caget/pvget looks like this (truncated):
>  pvget ares:zone0
> ares:zone0 <undefined>              /sys/devices/virtual/thermal/thermal_zo INVALID DRIVER UDF
>  epics@ares:~$ pvget ares:zone0
> ares:zone0 2024-09-09 19:52:41.690  /sys/devices/virtual/thermal/thermal_zo
>  epics@ares:~$ caget ares:zone0
> ares:zone0                     /sys/devices/virtual/thermal/thermal_zo
>  I know about VAL$ (is this documented anywhere?):
>  epics@ares:~$ pvget ares:zone0.VAL$
> ares:zone0.VAL$ 2024-09-09 19:52:41.690  [47,115,121,115,47,100,101,118,105,99,101,115,47,118,105,114,116,117,97,108,47,116,104,101,114,109,97,108,47,116,104,101,114,109,97,108,95,122,111,110,101,48,47,116,101,109,112,0]
>  epics@ares:~$ caget ares:zone0.VAL$
> ares:zone0.VAL$ 64 47 115 121 115 47 100 101 118 105 99 101 115 47 118 105 114 116 117 97 108 47 116 104 101 114 109 97 108 47 116 104 101 114 109 97 108 95 122 111 110 101 48 47 116 101 109 112 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
>  Now I'm curious if I want to use this PV as the INPA of an aSubRecord. I'm already worried about ‘cutting it off’ …
>  Heinz
>   ------------------------------------------------------------------------------
> Fritz-Haber-Institut    | Phone:         (+49 30) 8413-4270
> Heinz Junkes             | Fax (G3+G4):   (+49 30) 8413-5900
> Faradayweg 4-6        | VC: https://zoom.fhi.berlin/junkes
> D - 14195 Berlin        | E-Mail:        junkes at fhi-berlin.mpg.de
> ------------------------------------------------------------------------------
>  > On 9. Sep 2024, at 18:27, Hartman, Steven <hartmansm at ornl.gov> wrote:
> > > This works . . .
> > > record(lso, "myLSO")
> > {
> >    field(DOL, {const:"foo"})
> > }
> > > > -- > Steven Hartman
> > hartmansm at ornl.gov
> > > > >> On Sep 9, 2024, at 11:44 AM, Heinz Junkes via Tech-talk <tech-talk at aps.anl.gov> wrote:
> >> >> Good evening,
> >> >> I have a problem with the lso (long string out) record.
> >> >> When I use it as a replacement for stringout (limited to 41 char),
> >> >> according to the Record reference Manual : "To initialize a string output record it is simplest to set the VAL field directly"
> >> >> record(lso, "$(user):zone0")
> >> {
> >>    field(VAL, 'blabberblabberblub')
> >> }
> >> >> >> I get the following message:
> >> >> >> dbLoadRecords "db/tempLinuxExample.db", "user=ares"
> >> Can't set "ares:zone0.VAL" to "blabberblabberblub"  : Bad Field value
> >> ERROR:  at or before ')' in file "db/tempLinuxExample.db" line 7
> >> >> 7 |     field(VAL, 'blabberblabberblub')
> >> >> ERROR failed to load 'db/tempLinuxExample.db’
> >> >> We then tried the contradictory definitions of the description:
> >> "DOL can also be a constant instead of a link, in which case VAL is initialized to the constant value.”
> >> >> record(lso, "$(user):zone0")
> >> {
> >>    field(DOL, 'blabberblabberblub')
> >> }
> >> >> >> epics@ares:~$ caget -s ares:zone0.VAL$
> >> ares:zone0.VAL$ 41 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
> >> >> But I don't quite understand this:
> >> >> "The first field that determines where the desired output originates is the output mode select (OMSL) field, which can have two possible values: closed_loop or supervisory. If closed_loop is specified, the VAL field's value is fetched from the address specified in the Desired Output Link field (DOL) which can be either a database link or a channel access link. If supervisory is specified, DOL is ignored, “
> >> >> record(lso, "$(user):zone0")
> >> {
> >>    field(OMSL, "closed_loop")
> >>    field(DOL, 'blabberblabberblub')
> >> }
> >> >> The same output :
> >> >> epics@ares:~$ caget -s ares:zone0.VAL$
> >> ares:zone0.VAL$ 41 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
> >> >> >> >> Danke Heinz
> >> >

Attachment: smime.p7s
Description: S/MIME cryptographic signature


References:
lso record Heinz Junkes via Tech-talk
Re: [EXTERNAL] lso record Hartman, Steven via Tech-talk
Re: [EXTERNAL] lso record Heinz Junkes via Tech-talk
Re: [EXTERNAL] lso record Johnson, Andrew N. via Tech-talk

Navigate by Date:
Prev: Re: [EXTERNAL] lso record Johnson, Andrew N. via Tech-talk
Next: Re: [EXTERNAL] Another question regarding record stringout, lso and Record reference manual in general Timo Korhonen via Tech-talk
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  <20242025 
Navigate by Thread:
Prev: Re: [EXTERNAL] lso record Johnson, Andrew N. via Tech-talk
Next: Re: [EXTERNAL] lso record Ralph Lange via Tech-talk
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  <20242025