属性与状态机
C 没有属性。状态与错误码用自由函数。看状态用静态 pns_*,不必 Connect。写 Q / 读 I:PnSServiceConnectRealtime → PnSServiceStart。主站是否已周期交换看 PnSServiceIsConnected。
属性
不必会话即可查静态项。服务没起来写 pns_last_error。成功路径不清空 sticky 文案。
| 类别 | 属性 | 类型 | 访问 | 说明 |
|---|---|---|---|---|
| 静态 | pns_is_service_ready | bool | 只读 | 本机服务是否就绪 |
pns_last_error | const char * | 只读 | 全应用最近一次失败文案(sticky,成功路径不清空) | |
pns_last_error_code | pns_result_t | 只读 | 全应用最近一次失败的调用错误码。从未失败为 PNS_OK | |
pns_service_connected | bool | 只读 | 主站是否周期交换。服务没起来 = false | |
pns_service_state | pns_device_state_t | 只读 | 运行态。服务没起来 = UNKNOWN | |
pns_service_wait_reason | const char * | 只读 | 等待原因。服务没起来 = 「服务未就绪」 | |
pns_service_status_message | const char * | 只读 | 状态文案。服务没起来 = 「服务未就绪」 | |
| 连接与会话 | PnSServiceIsConnected | bool | 只读 | IO 控制器是否已经建立周期数据交换。true 才表示周期数据在换 |
PnSServiceIsAttached | bool | 只读 | 本 SDK 会话是否已连上本机服务。Stop 不改变 | |
PnSServiceIsStarted | bool | 只读 | IO 设备是否已启用(Start 之后、Stop 之前) | |
| 运行态 | PnSServiceGetState | pns_device_state_t | 只读 | 运行态。读不到真实状态为 UNKNOWN,不要当成 STOPPED |
PnSServiceGetStatus | pns_result_t | 只读 | 一次取回 state / connected / error_code | |
PnSServiceGetWaitReason | const char * | 只读 | 本会话等待原因。主站已连时为空 | |
PnSServiceGetEverConnected | bool | 只读 | 是否曾与 IO 控制器建立过连接。true 且 Connected 为 false = 掉线 | |
| 错误码 | PnSServiceGetErrorCode | int | 只读 | 最近一次运行错误原值(0 = 无错误)。未识别值仍经本函数透传 |
PnSServiceGetErrorMessage | const char * | 只读 | 运行错误中文消息 | |
pns_runtime_error_message | const char * | 只读 | 运行错误原值 → 中文。未识别值带原值 | |
PnSServiceLastError | const char * | 只读 | 本会话最近一次失败文案(sticky,成功路径不清空) | |
| 报警 | PnSServiceGetAlarmCount | int | 只读 | 活动报警总数。与 GetAlarms 同源 |
PnSServiceGetCriticalAlarmCount | int | 只读 | Critical 报警数 | |
PnSServiceGetAlarms | pns_result_t | 只读 | 活动报警。见 [诊断 · 报警](./diagnostics#报警) | |
PnSServiceGetAlarmHistory | pns_result_t | 只读 | 历史报警(最近 500 条)。见 [诊断](./diagnostics#报警) | |
| 诊断与过程数据 | PnSServiceOnConnectedChanged | pns_result_t | 只读 | 本机运行态事件。见 [事件](./events) |
PnSServiceGetDiag | pns_result_t | 只读 | 一次取回链路、帧计数、看门狗、抖动。读不到时 ok 为 0 | |
PnSServiceGetIoStatus | pns_result_t | 只读 | IOPS / IOCS 快照。0x80 = GOOD,0x00 = BAD。掉线如实全 BAD | |
PnSProcessDataInputsMapping / PnSProcessDataOutputsMapping | pns_result_t | 只读 | 0 拷贝:映射一次,取 I / Q 视图 + 长度;只读视图用 PnSProcessDataInputsMappingRO。见 [过程数据](./io) | |
PnSProcessDataWriteStruct / PnSProcessDataReadStruct | pns_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;
}