//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // typedefs //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ typedef enum { SOFTWAREWATCHDOG__HEARTBEATMISSEDACTION__TERMINATESELF, SOFTWAREWATCHDOG__HEARTBEATMISSEDACTION__KEEPSELFRUNNING } SoftwareWatchdog_HeartbeatMissedAction_t; //------------------------------------------------------------------------------ // function: SoftwareWatchdog_AttachToHAM // description: create connection with the QNX HAM and attach process as entity // parameters: EntityName - symbolic name for this entity // HeartbeatFrequency - frequency in nanoseconds // returns: 0 if successfully attached, 1 else //------------------------------------------------------------------------------ int SoftwareWatchdog_AttachToHAM( const char * EntityName, const u64 HeartbeatFrequency ) { int rc; // connect with the ham rc = ham_connect(0); if (rc != 0) { return 1; } ehdl = ham_attach_self( EntityName, // name HeartbeatFrequency, // heartbeat frequency in ns 1, // number of allowed missed heartbeats - triggers CONDHBEATMISSEDLOW 1, // number of allowed missed heartbeats - triggers CONDHBEATMISSEDHIGH 0 // flags ); if (ehdl == NULL) { return 1; } return 0; } //------------------------------------------------------------------------------ // function: SoftwareWatchdog_HeartbeatMissedAction // description: set up the action triggered if heartbeat is missed // parameters: Action - terminate self or keep running // BinaryName - name (including path) of binary that'll be started // returns: 0 if successfully executed, 1 else //------------------------------------------------------------------------------ int SoftwareWatchdog_HeartbeatMissedAction( SoftwareWatchdog_HeartbeatMissedAction_t Action, const char * BinaryName ) { ham_condition_t *chdl; // condition handle ham_action_t *ahdl; // action handle char command[37]; // build kill command (with kill binary out of image) sprintf( command, "on -d -p35 \"/proc/boot/kill %d\"", getpid() ); // now we get a condition handle for DEATH chdl = ham_condition( ehdl, CONDHBEATMISSEDHIGH, "HeartbeatMissedHigh", 0 ); if (chdl == NULL) { return 1; } switch (Action) { case SOFTWAREWATCHDOG__HEARTBEATMISSEDACTION__TERMINATESELF: ahdl = ham_action_execute( chdl, "HeartbeatMissedHigh_TerminateAction", command, 0 ); if (ahdl == NULL) { return 1; } // release action handle ham_action_handle_free(ahdl); break; case SOFTWAREWATCHDOG__HEARTBEATMISSEDACTION__KEEPSELFRUNNING: // nothing to do break; } if (BinaryName != NULL) { // add an execute action to condition CONDHBEATMISSEDHIGH ahdl = ham_action_execute( chdl, "HeartbeatMissedHigh_StartAction", BinaryName, 0 ); if (ahdl == NULL) { return 1; } } return 0; } //------------------------------------------------------------------------------ // function: SoftwareWatchdog_SendHeartBeat // description: send a heartbeat to the HAM // parameters: none // returns: nothing //------------------------------------------------------------------------------ void SoftwareWatchdog_SendHeartBeat( void ) { (void) ham_heartbeat(); } /------------------------------------------------------------------------------ // function: main // description: main routine // parameters: none //------------------------------------------------------------------------------ int main( void ) { (void) SoftwareWatchdog_AttachToHAM( "EntityName", 1000000000ULL // 1 second ); (void) SoftwareWatchdog_HeartbeatMissedAction( SOFTWAREWATCHDOG__HEARTBEATMISSEDACTION__TERMINATESELF, "ProcessName" ); for (;;) { SoftwareWatchdog_SendHeartBeat(); } }