跳到主要内容

属性与状态机

提示
  • 初始化请参考 初始化 页面。
  • 过程数据(写 Q / 读 I)请参考 过程数据 页面。
  • 诊断功能请参考 诊断 页面。

C 没有属性。状态与错误码用自由函数。看状态用静态 pns_*,不必 Connect。写 Q / 读 I:PnSServiceConnectRealtimePnSServiceStart。主站是否已周期交换看 PnSServiceIsConnected

属性

不必会话即可查静态项。服务没起来写 pns_last_error。成功路径不清空 sticky 文案。

类别属性类型访问说明
静态pns_is_service_readybool只读本机服务是否就绪
pns_last_errorconst char *只读全应用最近一次失败文案(sticky,成功路径不清空)
pns_last_error_codepns_result_t只读全应用最近一次失败的调用错误码。从未失败为 PNS_OK
pns_service_connectedbool只读主站是否周期交换。服务没起来 = false
pns_service_statepns_device_state_t只读运行态。服务没起来 = UNKNOWN
pns_service_wait_reasonconst char *只读等待原因。服务没起来 = 「服务未就绪」
pns_service_status_messageconst char *只读状态文案。服务没起来 = 「服务未就绪」
连接与会话PnSServiceIsConnectedbool只读IO 控制器是否已经建立周期数据交换。true 才表示周期数据在换
PnSServiceIsAttachedbool只读本 SDK 会话是否已连上本机服务。Stop 不改变
PnSServiceIsStartedbool只读IO 设备是否已启用(Start 之后、Stop 之前)
运行态PnSServiceGetStatepns_device_state_t只读运行态。读不到真实状态为 UNKNOWN,不要当成 STOPPED
PnSServiceGetStatuspns_result_t只读一次取回 state / connected / error_code
PnSServiceGetWaitReasonconst char *只读本会话等待原因。主站已连时为空
PnSServiceGetEverConnectedbool只读是否曾与 IO 控制器建立过连接。true 且 Connected 为 false = 掉线
错误码PnSServiceGetErrorCodeint只读最近一次运行错误原值(0 = 无错误)。未识别值仍经本函数透传
PnSServiceGetErrorMessageconst char *只读运行错误中文消息
pns_runtime_error_messageconst char *只读运行错误原值 → 中文。未识别值带原值
PnSServiceLastErrorconst char *只读本会话最近一次失败文案(sticky,成功路径不清空)
报警PnSServiceGetAlarmCountint只读活动报警总数。与 GetAlarms 同源
PnSServiceGetCriticalAlarmCountint只读Critical 报警数
PnSServiceGetAlarmspns_result_t只读活动报警。见 [诊断 · 报警](./diagnostics#报警)
PnSServiceGetAlarmHistorypns_result_t只读历史报警(最近 500 条)。见 [诊断](./diagnostics#报警)
诊断与过程数据PnSServiceOnConnectedChangedpns_result_t只读本机运行态事件。见 [事件](./events)
PnSServiceGetDiagpns_result_t只读一次取回链路、帧计数、看门狗、抖动。读不到时 ok 为 0
PnSServiceGetIoStatuspns_result_t只读IOPS / IOCS 快照。0x80 = GOOD,0x00 = BAD。掉线如实全 BAD
PnSProcessDataInputsMapping / PnSProcessDataOutputsMappingpns_result_t只读0 拷贝:映射一次,取 I / Q 视图 + 长度;只读视图用 PnSProcessDataInputsMappingRO。见 [过程数据](./io)
PnSProcessDataWriteStruct / PnSProcessDataReadStructpns_result_t只读快照:写 Q / 读 I。见 [过程数据](./io)
if (!pns_is_service_ready())
printf("%s (%d)\n", pns_last_error(), (int)pns_last_error_code());

pns_result_t

调用返回码。取值见 枚举参考

pns_device_state_t

设备运行态。取值见 枚举参考

pns_runtime_error_code_t

运行错误码,与 pns_result_t 不要混用。取值见 枚举参考

启停

PnSServiceStart()

pns_result_t PnSServiceStart(pns_service_handle_t session);

使能 IO 设备。已 Start 且尚未 Stop 则幂等返回 PNS_OK。这不是主站已周期交换,主站是否在换数据看 PnSServiceIsConnected

返回值:

  • PNS_OK 成功;句柄非法返回 PNS_ERR_INVALID_PARAM;启动失败返回 PNS_ERR_NATIVE;服务不可达返回 PNS_ERR_NO_CONNECTION

失败写入 PnSServiceLastError

示例:

pns_result_t rc = PnSServiceStart(session);
if (rc != PNS_OK)
printf("%s\n", PnSServiceLastError(session));

PnSServiceStop()

pns_result_t PnSServiceStop(pns_service_handle_t session);

停用 IO 设备。句柄仍在,可再次 Start。未 Start 或已 Stop 则幂等返回。失败写 LastError

不是 PnSServiceClose()Stop 不结束 SDK 会话。

示例:

PnSServiceStop(session);

1ms 高精度时钟(服务侧)

1ms 高精度时钟由服务进程持有,C SDK 不提供本进程开关:经服务 Web API POST /api/high-resolution-timer(body {"highResolutionTimer": true|false})开关,见 Web API。安装包默认不打开。

备注

打开后等待更准,鼠标可能变顿。非 Windows 为空操作。

运行态

PnSServiceGetState()

运行态(只读)。Start / Stop 只管启用 / 停用 IO 设备;本函数始终按现场如实读。读不到真实状态为 UNKNOWN,不要当成 STOPPED

pns_device_state_t PnSServiceGetState(pns_service_handle_t session);

示例:

if (PnSServiceGetState(session) == PNS_DEV_STATE_DATA)
printf("周期数据交换正常\n");

PnSServiceGetStatus()

pns_result_t PnSServiceGetStatus(
pns_service_handle_t session,
pns_device_state_t * p_state,
bool * p_connected,
int * p_error_code);

一次取回状态、是否已交换周期数据、运行错误原值。p_connected / p_error_code 可为 NULL

pns_device_state_t state = PNS_DEV_STATE_UNKNOWN;
bool connected = false;
int err = 0;
PnSServiceGetStatus(session, &state, &connected, &err);
if (!connected)
printf("%s\n", PnSServiceGetWaitReason(session));

PnSServiceGetWaitReason()

const char * PnSServiceGetWaitReason(pns_service_handle_t session);

本会话等待原因。主站已连时为空。循环 if (!PnSServiceIsConnected(session)) 时读本函数或 PnSServiceLastError

示例:

if (!PnSServiceIsConnected(session))
printf("%s\n", PnSServiceGetWaitReason(session));

PnSServiceGetEverConnected()

bool PnSServiceGetEverConnected(pns_service_handle_t session);

是否曾与 IO 控制器建立过连接。false = 从未连过;true 且未连接 = 掉线。掉线后此判别仍保留。

示例:

if (!PnSServiceIsConnected(session) && PnSServiceGetEverConnected(session))
printf("掉线\n");

错误码

PnSServiceGetErrorCode()

int PnSServiceGetErrorCode(pns_service_handle_t session);

最近一次运行错误原值(0 = 无错误)。未识别值仍经本函数透传。中文消息用 PnSServiceGetErrorMessage

示例:

int raw = PnSServiceGetErrorCode(session);
const char * text = PnSServiceGetErrorMessage(session);

PnSServiceGetErrorMessage()

const char * PnSServiceGetErrorMessage(pns_service_handle_t session);

运行错误中文消息。未识别码返回带原值的说明,不丢信息。

示例:

printf("%s\n", PnSServiceGetErrorMessage(session));

PnSServiceLastError()

const char * PnSServiceLastError(pns_service_handle_t session);

本会话最近一次失败文案(sticky)。成功路径不清空。句柄为 NULL 时回落 pns_last_error。循环 if (!IsConnected) 时若本函数为空,读 GetWaitReason

示例:

printf("%s\n", PnSServiceLastError(session));

诊断

PnSServiceGetDiag()

pns_result_t PnSServiceGetDiag(
pns_service_handle_t session,
pns_service_diag_t * p_diag);

一次取回链路、帧计数、看门狗、抖动。读不到时 ok == 0,读 message,不视为异常。字段见 诊断

示例:

pns_service_diag_t snap;
if (PnSServiceGetDiag(session, &snap) == PNS_OK && !snap.ok)
printf("%s\n", snap.message);

PnSServiceGetIoStatus()

pns_result_t PnSServiceGetIoStatus(
pns_service_handle_t session,
pns_service_io_status_t * p_status,
uint16_t * p_input_iops_len, uint8_t * p_input_iops,
uint16_t * p_input_iocs_len, uint8_t * p_input_iocs,
uint16_t * p_output_iops_len, uint8_t * p_output_iops,
uint16_t * p_output_iocs_len, uint8_t * p_output_iocs);

IOPS / IOCS 快照。0x80 = GOOD,0x00 = BAD。掉线如实全 BAD。字段见 诊断

示例:

pns_service_io_status_t st;
if (PnSServiceGetIoStatus(session, &st,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) == PNS_OK
&& !st.all_good)
printf("IOPS BAD %d\n", st.iops_bad_count);

完整示例

#include "pns.h"

int main(void)
{
pns_service_handle_t session = NULL;
bool from_plc = false;
int running = 1;

if (PnSServiceConnectRealtime(&session) != PNS_OK)
return 1;
if (PnSServiceStart(session) != PNS_OK)
return 1;

while (running)
{
if (!PnSServiceIsConnected(session))
{
printf("%d\n", (int)PnSServiceGetState(session));
printf("%s\n", PnSServiceGetWaitReason(session));
printf("%s\n", PnSServiceGetErrorMessage(session));
continue;
}

PnSServiceWriteBool(session, "Q0.0", true);
PnSServiceReadBool(session, "I0.0", &from_plc);
}

PnSServiceStop(session);
PnSServiceClose(session);
return 0;
}