hwLowcal - LowCAL Hardware Record

Author:

Benjamin Franksen

Introduction

The normal use of this record is to read or write data over the CAN bus, using a protocol called LowCAL. The record transports only raw integral values as defined by the LowCAL specification.

If conversion to engineering units is desired, the 8 input (RDx) and 8 output (WRx) fields of the hwLowcal record can be targeted by the INP or OUT field of a standard record (ai, ao, bi, bo, etc.). In this way the hwLowcal record acts as a kind of server record, and the records of standard type as client records. The client records may use a special device support called ‘HwClient’ to enable asynchronous link processing and to obtain information about raw value data, such as minimum and maximum value or number of significant bits. For details see the document ‘HwClient - Device Support for Clients of Hardware Records’.

LowCAL Variables

The hwLowcal record represents one entity of the LowCAL protocol, a so called LowCAL variable. In general, LowCAL variables are arrays of up to 8 elements of one of the simple types signed or unsigned char (8 bits), short (16 bits) or long (32 bits). The array elements of the variable can be accessed for reading through the 8 fields RD1…RD8, or for writing through the fields RD1…RD8. Like any other variable, LowCAL variables have a unique location on the bus, that is, there is exactly one CAN node in which they ‘exist’. This node is called the Server node; all other nodes are called Clients with respect to this variable.

A LowCAL variable is defined by the following data which can be (statically) configured by setting the appropriate fields of the hwLowcal record:

  • User type: Either Client or Server. A Server variable ‘exists’ on the same CAN node (the IOC), whereas a Client variable ‘exists’ on some other node.

  • Access type: There are three choices: ‘RO’ (read-only), ‘WO’ (write-only) and ‘RW’ (read-write). As the names suggest, only RO and RW variables can be read and only WO and RW variables can be written. Note that ‘read’ and ‘write’ only refers to the direction of the data flow over the CAN bus if the variable has user type Client. A Server variable never initiates actual I/O - it only answers to Client requests. E.g. a write to a Server variable will only update the local copy; Server-WO variables are read by Clients and Server-RO variables are written to by Clients.

  • Class: This must be either ‘Basic’ or ‘Multiplexed’. Basic variables use all 8 data bytes for ‘real’ data. Multiplexed variables use one of the 8 bytes as a sort of channel identifier, so that only 7 bytes may be ‘real’ data.

  • Multiplexer: An integral number between 0 and 127 (inclusive). If the variable’s class is Multiplexed, then this is the identifier of the ‘channel’.

  • Base type: This can be either ‘NIL’ (meaning zero data length) or any standard integral data type, i.e. one, two or four byte, signed or unsigned integers. They are named after the standard EPICS data types, i.e. ‘CHAR’, ‘UCHAR, ‘SHORT’, ‘USHORT’, ‘LONG’, and ‘ULONG’.

  • Array size: The number of elements of the data array. Scalar data is equivalent to an array with one element.

  • Data size: This is the size of the data area in bytes, including Multiplexer (if variable is Multiplexed).

  • CAN Port: A hardware (resp. driver) dependent value that identifies the CAN port.

  • CAN object ids: These are the COBs of at most two CAN objects that are used for incoming and outgoing messages. Not all variable types need two COBs: Variables of type Basic-RO and all WO types need only one.

  • Inhibit time: This can be used to slow down the sending of certain CAN messages, for example if receiving nodes are single tasked and can process new messages only after previous data has been digested.

  • Timeout: This value determines how long to wait for confirmation, if the variable’s type is a confirmed one. Confirmed variables are those of type RW and RO. Timeouts make sense only if the variable is configured as Server, because otherwise read and write operations are purely local.

For further details concerning the LowCAL protocol definition, please refer to the document ‘MultiCAN - EPICS goes CAN with Multiple Protocol Support’.

Field Summary

Field Summary

Field

Type

DCT

Initial

Access

Modify

Monitor

PP

VAL

NOACCESS

No

0

No

No

No

No

ATYP

GBLCHOICE

Yes

RO

Yes

No

No

No

UTYP

GBLCHOICE

Yes

Client

Yes

No

No

No

CLAS

GBLCHOICE

Yes

Basic

Yes

No

No

No

BTYP

GBLCHOICE

Yes

NIL

Yes

No

No

No

NELM

UCHAR

Yes

1

Yes

No

No

No

DLEN

UCHAR

Yes

0

Yes

No

No

No

MUX

UCHAR

Yes

0

Yes

No

No

No

PORT

UCHAR

Yes

0

Yes

No

No

No

NOBT

UCHAR

Yes

0

Yes

No

No

No

OBJI

USHORT

Yes

0

Yes

No

No

No

OBJO

USHORT

Yes

0

Yes

No

No

No

INHB

ULONG

Yes

0

Yes

No

No

No

TMO

ULONG

Yes

0

Yes

No

No

No

RD1..8

CHAR

No

0

Yes

Yes

Yes

Yes

WR1..8

CHAR

No

0

Yes

Yes

Yes

Yes

ORD

STRING

No

0

Yes

No

Yes

No

OWR

STRING

No

0

Yes

No

Yes

No

RMIN

LONG

No

0

Yes

No

No

No

RMAX

LONG

No

0

Yes

No

No

No

ASYN

UCHAR

No

0

Yes

No

No

No

BMPL

UCHAR

No

0

Yes

No

No

No

WNPM

UCHAR

Yes

0

Yes

Yes

No

No

WNPF

UCHAR

No

0

Yes

No

No

No

WNPL

INLINK

Yes

0

Yes

Yes

No

No

NLIS

NOACCESS

No

0

No

No

No

No

IOSC

NOACCESS

No

0

No

No

No

No

Field Descriptions

Field Descriptions

Field

Summary

Description

VAL

Current Value

Dummy field, only present because every record needs a VAL field.

ATYP

Access Type

‘RO’ (readonly) or ‘WO’ (writeonly) or ‘RW’ (read-write)

UTYP

User Type

‘Client’ or ‘Server’

CLAS

Class

‘Basic’ or ‘Multiplexed’

BTYP

Base Type

‘NIL’, ‘CHAR’, ‘UCHAR’, ‘SHORT’, ‘USHORT’, ‘LONG’, ‘ULONG’

NELM

Number of Elements

Size of the data array in elements.

DLEN

Data Length

Size of data in bytes. This includes the ‘’MUX’’ byte, if appropriate.

MUX

Multiplexor

A number between 0 and 127 for multiplexed data.

PORT

CAN Port on card

Port number on the CAN bus interface device.

NOBT

Number of significant Bits

Higher order bits are ignored. This value must be set correctly!

OBJI

CAN id of Incoming Object

Every LowCAL variable needs at most two COBs for incoming and outgoing messages.

OBJO

CAN id of Outgoing Object

INHB

Inhibit time

CAN messages for this variable are sent only every ‘’INHB * 100’’ microseconds. This feature is currently not supported by the driver.

TMO

Timeout

After this number of milliseconds, the device support assumes a timeout. This is valid only for confirmed services, i.e. only for user type Client and access type RO and WR.

RD1…8

Read Input Values 1..8

These are the fields from which data can be read.

WR1…8

Desired Output Values 1..8

These are the fields to which data can be written.

ORD

Old Read Values

The old ‘’RDx’’ fields.

OWR

Old Write Values

The old ‘’WRx’’ fields.

RMIN

Minimum Raw Value

These fields are used for communication with HwClient device support. They are used to save device support specific information. ‘’RMIN’’ and ‘’RMAX’’ are used to enable the device supports of analog records to determine linear conversion parameters. They are calculated from ‘’BTYP’’ and ‘’NOBT’’. ‘’ASYN’’ and ‘’BMPL’’ are for all record types and enable client device supports to adapt their asynchronous and warm reboot facilities. They are either 1 (yes) or 0 (no).

RMAX

Maximum Raw Value

ASYN

Is processing Asynchronous?

BMPL

Do we Bumpless Reboot?

WNPM

Write on Next Process Mask

For WO and RW variables. This fields contains an 8 bit mask. If bit x of the mask is set, then a write to the corresponding ‘’WR(x+1)’’ field will cause the record to assemble and send the current data as soon as the record is processed the next time.

WNPF

Write on Next Process Flags

Internals flags.

WNPL

Write on Next Process mask Location

If not constant, then each time the record is processed, ‘’WNPL’’ is read to determine a new ‘’WNPM’’ value. If constant, this is done only at iocInit.

NLIS

Notify List

These fields are for internal use only.

IOSC

I/O Scan private for clients

Record Support Routines

init_record

long init_record(hwLowcalRecord *prec, int pass)

This routine does all work in the first call to init_record. It initializes the notify list (NLIS) and the ioscanpvt (IOSC) of the record. Afterwards, existence of a device support is checked and the init_record of the device support is called.

process

long process(hwLowcalRecord *prec)

This routine initiates and completes the actual I/O.

  1. If PACT is set, then

  2. Determine the kind of action. This depends on the access type (ATYP) and user type (UTYP) of the record, as well as the state of the WNPF field.

    Process Actions

    ATYP

    UTYP

    Action

    RO

    Client

    Always read.

    WO

    Server

    RO

    Server

    Always write.

    WO

    Client

    RW

    Server

    If one of the WRx fields that have the corresponding bit in WNPM set has been written to, then write, else read.

    RW

    Client

  3. If WNPL is not a constant link, get WNPM from WNPL.

  4. If BMPL is set, override action to read’ and reset ``BMPL`.

  5. Clear action flag (read or write) in WNPF.

  6. Call device support read or write function depending on action.

  7. If device support set PACT, remember action (read or write) in WNPF for process completion and return.

  8. If PACT is not set, then complete processing by calling device support’s read or write function, depending on remembered action.

  9. Set PACT.

  10. If status is ok, clear UDF.

  11. Get timestamp.

  12. Reset alarms and post events for VAL and for the RDx and WRx fields.

  13. Complete processing of the records in the notify list.

  14. Process forward link.

  15. Reset PACT and return status (i.e. result from device support call).

special

long special(struct dbAddr *paddr, int after)

After a write to one of the WRx fields, set write action bit in WNPF.

cvt_dbaddr

long cvt_dbaddr(struct dbAddr *paddr)

This routine is called whenever one of the RDx or RDx fields is accessed. It converts the addresses of the fields according to the size (in bytes) of the base type (BTYP) and the index in the array. For example, if the base type has two bytes (SHORT’ or `USHORT’), then ``WR2` is relocated to WR3, WR3 to WR5, and WR4 to WR7. Thus, the index x’ in ``WRx` or RDx always refers to the array index, not the position in bytes.

Warning: This may cause confusion if the a record instance is viewed with the dbpr command line tool, because dbpr does not relocate fields, i.e. does not call cvt_dbaddr.

The number of elements in the array must not exceed 8 bytes divided by the base type size. For example, if the base type is LONG’, the only ``RDx` and WRx fields that may be accessed are RD1, RD2, WR1, and WR2. Access to other fields is an error and will cause processing to fail.

Note that this routine not only relocates the field address, but also adapts the field size according to the base type.

get_hw_info

long get_hw_info(hwLowcalRecord *prec, HW_INFO *pinfo)

This is a non-standard additional record support function. It is meant to be called by client records during the initialization phase to receive information for conversion, bumpless reboot and asynchronous processing, and to register themselves with the hwLowcalRecord for process callbacks.

For details see the document ‘HwClient - Device Support for Clients of Hardware Records’.

Device Support

The only admissible device support (DTYP) is lowcal. In principle, this record wouldn’t need device support, because it is by design limited to exactly one sort of device, whose access methods could be integrated into the record support directly. Nevertheless, in order to use this record together with standard record types that use the same CAN bus protocol, the actual device I/O was factored out into the (already existing) mCANSupport module.