Skip to content
Start free evaluation

SECS-II messages

SECS-II (SEMI E5) defines the structure and meaning of the messages that equipment and hosts exchange. It doesn’t care how the bytes travel: the same SECS-II message can go over HSMS (TCP/IP) or over SECS-I (RS-232).

A SECS-II message has a header and an optional body. The header carries:

Header field Meaning
Device ID Identifies the equipment the message is for. HSMS calls it the session ID.
Stream The message category, from 1 to 127.
Function The message within the category, from 0 to 255.
W-bit Set when the sender waits for a reply.
System bytes A 4-byte transaction number that pairs a reply with its request.

Messages are named by stream and function, as in S1F3. When a message expects a reply, it’s often written S1F3 W.

A stream groups related messages. These are the streams you’ll meet most often with this SDK:

Stream Area
S1 Equipment status: are-you-there, status variables, establishing communication, on-line and off-line
S2 Equipment control and diagnostics: equipment constants, report definitions, remote commands
S5 Exception handling: alarms
S6 Data collection: event reports, spooled data
S7 Process program management
S9 System errors: notices about an unknown device ID, stream, function and so on
S10 Terminal services: operator display messages

Function numbers follow a few rules:

  • An odd function is a primary message. It starts a conversation.
  • An even function is a secondary message: the reply. Its function number is the request’s plus one, so S1F3 is answered by S1F4.
  • Function 0 (F0) aborts the transaction. If you can’t give a normal reply to a request, answer with F0 in the same stream.
  • If a primary message has the W-bit set, the receiver must reply.
  • If the W-bit is clear, the receiver doesn’t reply. Some messages may be sent without the W-bit.
  • A reply never sets the W-bit.
  • A reply reuses the request’s system bytes, which is how the sender matches it to the request.
  • If no reply arrives in time, the request fails with a reply timeout (T3). See HSMS and SECS-I for the timers.

A sender uses distinct system bytes for every open transaction. A PDComm HSMS endpoint numbers its requests from initial_system_bytes and tracks up to 32 requests that wait for a reply (PDCOMM_TCP_MAX_TRANSACTIONS). When the reply arrives, its event carries the same token you got when you sent the request.

The body is a single item. An item is either a list or a primitive item that holds values. Lists contain other items, so a body can be a tree.

Every item is encoded the same way (SEMI E5, data structures and item formats):

+-------------+----------------------+------------------------+
| format byte | length bytes (1..3) | data |
+-------------+----------------------+------------------------+
bits 7..2: format code
bits 1..0: number of length bytes (1, 2 or 3)
  • The upper six bits of the format byte hold the format code; the lower two bits say how many length bytes follow.
  • For a primitive item, the length counts data bytes. For a list, it counts elements.
  • Three length bytes can express up to 16,777,215.
  • Numbers are big-endian. One primitive item can hold several values of its format, which makes it an array.

The standard writes format codes in octal. The PDComm constants hold the same 6-bit format code as a decimal number.

Symbol Format Octal code Element size C constant .NET SecsFormat
L List 00 element count PDCOMM_SECS_LIST (0) List
B Binary 10 1 PDCOMM_SECS_BINARY (8) Binary
BOOLEAN Boolean 11 1 PDCOMM_SECS_BOOLEAN (9) Boolean
A ASCII string 20 1 PDCOMM_SECS_ASCII (16) Ascii
J JIS-8 string 21 1 PDCOMM_SECS_JIS8 (17) Jis8
I8 8-byte signed integer 30 8 PDCOMM_SECS_I8 (24) I8
I1 1-byte signed integer 31 1 PDCOMM_SECS_I1 (25) I1
I2 2-byte signed integer 32 2 PDCOMM_SECS_I2 (26) I2
I4 4-byte signed integer 34 4 PDCOMM_SECS_I4 (28) I4
F8 8-byte floating point 40 8 PDCOMM_SECS_F8 (32) F8
F4 4-byte floating point 44 4 PDCOMM_SECS_F4 (36) F4
U8 8-byte unsigned integer 50 8 PDCOMM_SECS_U8 (40) U8
U1 1-byte unsigned integer 51 1 PDCOMM_SECS_U1 (41) U1
U2 2-byte unsigned integer 52 2 PDCOMM_SECS_U2 (42) U2
U4 4-byte unsigned integer 54 4 PDCOMM_SECS_U4 (44) U4

PDComm supports these 15 formats.

Values of different formats are different values even when they look alike: U4 0 and the ASCII string "0" encode to different bytes, and the receiver compares the format too.

Value Encoding (hex)
<A "IDLE"> 41 04 49 44 4C 45
<U4 0> B1 04 00 00 00 00
<F4 21.5> 91 04 41 AC 00 00
<L [2] ...> list header 01 02, followed by the two encoded elements

41 combines format code 20 (octal, ASCII) with one length byte. B1 is U4 and 91 is F4.

Logs and documents often use SML (SECS Message Language), a text notation for messages. SML isn’t a SEMI standard, but it’s the common convention. Here the host asks for status variables 1 and 2, and the equipment answers:

S1F3 W
<L [2]
<U4 1>
<U4 2>
>
.
S1F4
<L [2]
<F4 21.5>
<A "LOT-001">
>
.

On the wire, the S1F4 body is 01 02 91 04 41 AC 00 00 41 07 4C 4F 54 2D 30 30 31. The PDComm tutorial example prints received bodies in this hexadecimal form. The values come back in the order of the requested IDs.

The table lists the messages GEM uses most and what PDComm does with them. “Built in” means the PDComm GEM API builds and parses the message for you. In the direction column, H is the host and E is the equipment.

Message Name Direction PDComm
S1F1/F2 Are You There / On Line Data H↔E Built in. The equipment answers with its model name and software revision.
S1F3/F4 Selected Equipment Status H→E Built in
S1F11/F12 Status Variable Namelist H→E Built in
S1F13/F14 Establish Communications H↔E Built in
S1F15/F16 Request OFF-LINE H→E Built in
S1F17/F18 Request ON-LINE H→E Built in
S1F21/F22 Data Variable Namelist H→E Built in
S1F23/F24 Collection Event Namelist H→E Built in
S2F13/F14 Equipment Constant Request H→E Built in
S2F15/F16 New Equipment Constant Send H→E Built in; your application decides whether to accept.
S2F29/F30 Equipment Constant Namelist H→E Built in
S2F33/F34 Define Report H→E Built in
S2F35/F36 Link Event Report H→E Built in
S2F37/F38 Enable/Disable Event Report H→E Built in
S2F41/F42 Host Command Send H→E Built in; your application decides whether to accept.
S2F43/F44 Reset Spooling Streams and Functions H→E Built in
S2F49/F50 Enhanced Remote Command H→E Built in; your application decides whether to accept.
S5F1/F2 Alarm Report Send E→H Built in
S5F3/F4 Enable/Disable Alarm Send H→E Built in
S5F5/F6 List Alarms Request H→E Built in
S5F7/F8 List Enabled Alarm Request H→E Built in
S6F11/F12 Event Report Send E→H Built in
S6F15/F16, S6F19/F20, S6F21/F22 Event and report requests H→E Built in
S6F23/F24 Request Spooled Data H→E Built in
S7F1/F2, S7F3/F4, S7F5/F6 Process Program Load Inquire, Send, Request H↔E Built in
S7F17/F18 Delete Process Program Send H→E Built in
S7F19/F20 Current Process Program Directory H→E Built in
S7F21–S7F32 Formatted process programs and verification H↔E Built in
S9F1–S9F13 Error notices E→H The SDK never sends them automatically. The simulator sends S9F3, S9F5 and S9F7 for messages it doesn’t handle.
S2F17/F18, S2F23, S6F1, S10 Clock, trace, terminal services Various Exchanged through the general send and reply functions.

A primary message that the GEM API doesn’t handle produces a result of kind Unhandled. Your application then replies with the original event or aborts the transaction with F0. The PDComm SDK never sends S9 error messages, and it sends F0 on its own only when every incoming slot is taken. Status codes explains how the PDComm simulator answers such messages. You exchange any other SECS-II message through the HSMS endpoint with pdcomm_tcp_request and pdcomm_tcp_reply. Both return PDCOMM_LIMIT_EXCEEDED when a body exceeds the item limits or doesn’t fit in one frame. GEM capabilities explains what each capability does.

PDComm treats items as immutable objects. When you create one, you pass size limits (PdcommSecsLimits) that cap the message bytes, item bytes, item count and nesting depth. These limits are your application’s policy. Nesting can never exceed 64, whatever the limits say.

Task C C++ .NET
Create a primitive item pdcomm_secs_primitive SecsItem::primitive SecsItem.FromAscii, FromF4, FromU4
Create a list pdcomm_secs_list SecsItem::list SecsItem.CreateList
Encode to bytes pdcomm_secs_encode SecsItem::bytes SecsItem.Encode
Decode from bytes pdcomm_secs_decode SecsItem::decode SecsItem.Decode

The tutorial example, for instance, builds <F4 21.5> in C# with SecsItem.FromF4([21.5f], ...) and <A "LOT-001"> in C++ with pdcomm::SecsItem::primitive(PDCOMM_SECS_ASCII, ...). For the full types, see SecsItem and SecsItem.