From b03213ea7ae77b746fd09043d0dad0ec50ea1e37 Mon Sep 17 00:00:00 2001 From: Sang Woo Kim Date: Fri, 17 Jul 2026 00:12:32 +0900 Subject: [PATCH] seqRecord: fix upper display limit of the DLYn fields get_graphic_double() assigns lower_disp_limit twice and never writes upper_disp_limit, so a DBR_GR_DOUBLE read of any DLYn field reports the inverted range lower=10, upper=0. The second assignment was evidently meant for the upper limit; the 0 in the upper slot is the zeroed buffer dbAccess.c hands to the RSET, not a chosen value. Both assignments date from commit 27e80be2e5 which introduced the DLYn limits, so every release since 3.14.11 reports the inverted range over both CA (DBR_GR/CTRL) and PVA (display.limitLow/High). Extend seqTest with a DBR_GR_DOUBLE read of DLY0; the new cases fail with lower=10, upper=0 before this fix. --- modules/database/src/std/rec/seqRecord.c | 2 +- modules/database/test/std/rec/seqTest.c | 24 +++++++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/modules/database/src/std/rec/seqRecord.c b/modules/database/src/std/rec/seqRecord.c index 44d8599c4..d0160677e 100644 --- a/modules/database/src/std/rec/seqRecord.c +++ b/modules/database/src/std/rec/seqRecord.c @@ -327,7 +327,7 @@ static long get_graphic_double(DBADDR *paddr, struct dbr_grDouble *pgd) switch (fieldOffset & 3) { case 0: /* DLYn */ pgd->lower_disp_limit = 0.0; - pgd->lower_disp_limit = 10.0; + pgd->upper_disp_limit = 10.0; return 0; case 2: /* DOn */ dbGetGraphicLimits(get_dol(prec, fieldOffset), diff --git a/modules/database/test/std/rec/seqTest.c b/modules/database/test/std/rec/seqTest.c index 1febda78a..5c0dfa994 100644 --- a/modules/database/test/std/rec/seqTest.c +++ b/modules/database/test/std/rec/seqTest.c @@ -13,6 +13,27 @@ void recTestIoc_registerRecordDeviceDriver(struct dbBase *); +/* + * The DLYn fields advertise a display range of 0 to 10 seconds + * */ +static +void testSeqDlyLimits(void){ + DBADDR addr; + struct { + DBRgrDouble + epicsFloat64 value; + } buf; + long options = DBR_GR_DOUBLE; + long nRequest = 1; + + testOk1(!dbNameToAddr("seq0.DLY0", &addr)); + testOk1(!dbGetField(&addr, DBR_DOUBLE, &buf, &options, &nRequest, NULL)); + testOk(buf.lower_disp_limit == 0.0, + "DLY0 lower_disp_limit (%g) == 0", buf.lower_disp_limit); + testOk(buf.upper_disp_limit == 10.0, + "DLY0 upper_disp_limit (%g) == 10", buf.upper_disp_limit); +} + /* * This test verifies the behavior of seq using Specified for SELM * The behavior should be the same for all the DOLx @@ -34,7 +55,7 @@ void testSeqSpecified(void){ MAIN(eventTest) { - testPlan(4*16); + testPlan(4*16 + 4); testdbPrepare(); @@ -47,6 +68,7 @@ MAIN(eventTest) { testIocInitOk(); eltc(1); + testSeqDlyLimits(); testSeqSpecified(); testIocShutdownOk();