Description
Application-controlled reset enables a system design where the application is in full control during reset of the time stamp clock. Frame capture can be temporarily stopped or a similar action can be taken by the application as required. Application-controlled reset can also be used when reset limits different from the values predefined by the driver are desired.
Configuration
This ntservice.ini code line configures application-controlled reset:
TimeSyncHardReset = DISABLE
Working principle
In this mode of operation the SmartNIC driver does not reset the time stamp clock except when ntservice is started. It is up to the application to monitor the time skew and reset the time stamp clock when appropriate.
The application can read current time skew using the NT_INFO_CMD_READ_TIMESYNC_V2 command in the information stream. The returned timeSync_v2 structure contains a timeSyncTimeSkew parameter which holds the current clock skew in nanoseconds. If the time stamp clock is free-running, timeSyncTimeSkew is 0.
The application can also monitor alarm event with NT_EVENT_SOURCE_TIMESYNC as source.
Time stamps in received frames are affected in the same way as for driver-controlled reset. The application must be prepared to handle this situation.
Consequences
Time stamps in received frames and transmission timing are affected, in the same way as for driver-controlled reset. The application must be prepared to handle this situation.
Application example
The application can reset the time stamp clock using the NT_ConfigWrite function with the NT_CONFIG_PARM_ADAPTER_TIMESYNC_RESET command ID and the NT_TIMESYNC_RESET_HARD_RESET_TIME_TO_REF value for the timesyncReset.resetCmd parameter:
tsConfig.parm = NT_CONFIG_PARM_ADAPTER_TIMESYNC_RESET; tsConfig.u.timesyncReset.adapter = 0; tsConfig.u.timesyncReset.resetCmd = NT_TIMESYNC_RESET_HARD_RESET_TIME_TO_REF; NT_ConfigWrite(hConfig, &tsConfig))
Sample code for application-controlled time stamp clock monitoring and reset:
#include "./include/nt.h" int main(void) { int status; int hardReset=0; static NtInfoStream_t hInfo=NULL; static NtConfigStream_t hConfig=NULL; NtInfo_t infoRead; NtConfig_t tsConfig; if (NT_Init(NTAPI_VERSION) != NT_SUCCESS) { printf("NT_Init failed. Is ntservice started?\n"); exit(1); } if((status = NT_InfoOpen(&hInfo, "hInfo")) != 0) { printf("NT_InfoOpen failed.\n"); exit(1); } if((status = NT_ConfigOpen(&hConfig, "hConfig")) != 0) { printf("NT_ConfigOpen failed.\n"); exit(1); } while (1) { infoRead.cmd=NT_INFO_CMD_READ_TIMESYNC_V3; infoRead.u.timeSync_v3.adapterNo = 0; if ((status = NT_InfoRead(hInfo, &infoRead)) != NT_SUCCESS) { printf("NT_InfoRead failed\n"); exit(1); } if (!infoRead.u.timeSync_v3.data.timeSyncSupported) { printf("Timesync not supported on this adapter\n"); exit(1); } if (infoRead.u.timeSync_v3.data.timeRef == NT_TIMESYNC_REFERENCE_FREE_RUN || infoRead.u.timeSync_v3.data.timeRef == NT_TIMESYNC_REFERENCE_INVALID) { printf("Free running. No sync mechanism activated yet\n"); sleep(2); continue; } printf("Clock Skew: %li - %s\n", infoRead.u.timeSync_v3.data.timeSyncTimeSkew, infoRead.u.timeSync_v3.data.timeSyncGlobalStatus == NT_TIMESYNC_GLOBAL_STATUS_NOT_IN_SYNC? "Not in Sync":"In Sync"); if (infoRead.u.timeSync_v3.data.timeSyncGlobalStatus == NT_TIMESYNC_GLOBAL_STATUS_NOT_IN_SYNC) { if (!hardReset && infoRead.u.timeSync_v3.data.timeSyncTimeSkew > 100000000) { printf("Skew > 100000000: Hard resetting time to reference\n"); tsConfig.parm = NT_CONFIG_PARM_ADAPTER_TIMESYNC_RESET; tsConfig.u.timesyncReset.adapter = 0; tsConfig.u.timesyncReset.resetCmd = NT_TIMESYNC_RESET_HARD_RESET_TIME_TO_REF; if ((status = NT_ConfigWrite(hConfig, &tsConfig)) != 0) { exit(1); } hardReset=1; } } else { if (hardReset) hardReset=0; } sleep(1); } exit(0); }