Search code examples
c++vxworksrtos

How can I simulate Health-Monitor Events in VxWorks 653 2.5.0.2?


I'm new to RTOS as a whole, and to WindRiver's VxWorks particulary.

I come from a Java background, and making my first steps into enterprise RTOS embedded systems. Currently, I'm working on VxWorks 653 2.5.0.2.

My first task, is to configure the Module.xml file (see attached image) with the relevant Health-Monitoring tables (system, partition and module - see section 5 in this document). After configuring it, I noticed I don't really know how to test it.

Sure, I can probably "simulate" an HME_NUMERIC_ERROR by diving by zero, but I'm trying to find some better way to simulate these tests.

A best approach, in my POV, will be to have some shell command in the VxWorks shell, that injects Health Monitor Events by demand. Something like these commands.

Any thoughts about shell commands or best-practices to approach this, would be great.

Hope you guys can help me, Thanks!

Module.xml file example (taken from here):

module.xml

Health Monitor Table example (Scavenged from here - what language is that?!):

<PartitionHMTable Name="partition1Hm">
 <SystemState>
  <ErrorIDAction Error Identifier="HME_UNKNOWN" ErrorAction="hmDefaultHandler"/>
  <ErrorIDAction Error Identifier="HME_NUMERIC_ERROR" ErrorAction=""/>
  <ErrorIDAction Error Identifier="HME_POWER_FAIL" ErrorAction="hmDH_HME_POWER_FAIL"/>
  <ErrorIDAction Error Identifier="HME_KERNEL" ErrorAction="hmDH_HME_KERNEL"/>
  <ErrorIDAction Error Identifier="HME_CONFIG_ERROR" ErrorAction="hmDH_EventLog"/>
  <ErrorIDAction Error Identifier="HME_INIT_ERROR" ErrorAction="hmDH_HME_INIT_ERROR"/>
  <ErrorIDAction Error Identifier="HME_PARTITION_OVERFLOW" ErrorAction="hmDefaultHandler"/>
  <ErrorIDAction Error Identifier="HME_PARTITION_MODE_SET" ErrorAction="hmDH_HME_PARTITION_MODE_SET"/>
  <ErrorIDAction Error Identifier="HME_APEX_INTERNAL_ERROR" ErrorAction="hmDefaultHandler"/>
  <ErrorIDAction Error Identifier="HME_HM_INTERNAL_ERROR" ErrorAction="hmDefaultHandler"/>
  <ErrorIDAction Error Identifier="HME_PORT_INTERNAL_ERROR" ErrorAction="hmDefaultHandler"/>
  <ErrorIDAction Error Identifier="HME_LOST_TICKS" ErrorAction="hmDM_LOST_TICKS"/>
  <ErrorIDAction Error Identifier="HME_HM_ERROR" ErrorAction="hmDefaultHandler"/>
  <ErrorIDAction Error Identifier="HME_HMQ_OVERFLOW" ErrorAction="hmDefaultHandler"/>
  <ErrorIDAction Error Identifier="HME_DATA_LOSS" ErrorAction=""/>
   <ErrorIDAction Error Identifier="HME_HM_DEADLINE_MISSED" ErrorAction="hmDefaultHandler"/>
  <ErrorIDAction Error Identifier="HM_MSG" ErrorAction="hmDH_EventLog"/>
  <ErrorIDAction Error Identifier="HME_DEFAULT" ErrorAction=""/>
 <Settings maxQueueDepth="34" queueThresHold="32" stackSize="16384" maxLogEntries="100" logEntriesThreshold="98" attributesMask="0x00000001" notificationHandler ="" notificationMaxQueueDepth="0" eventFilterMask="0xFFFFFFFF" maxErrorHandlerQueueDepth="128" errorHandlerQueueThreshold="126"
  </Settings>
  </SystemState>
</PartitionHMTable>

Solution

  • Turns out VxWorks have a designated function for this: HM_EVENT_INJECT which can be used if you include the hmLib.h file in your application code.

    Here is a small sample of the code I wrote, simplified for clarity:

    void HMEInject(int strLength, char* errorString) {
        switch (choice) {
        case 1:
            //HME_DEADLINE_MISSED
            HM_EVENT_INJECT(HME_DEADLINE_MISSED, HM_SUB_CODE_STRING, 0, strLength,
                    (char * ) errorString);
            break;
        case 2:
            //HME_APPLICATION_ERROR
            HM_EVENT_INJECT(HME_APPLICATION_ERROR, HM_SUB_CODE_STRING, 0, strLength,
                    (char * ) errorString);
            break;
        case 3:
            //HME_NUMERIC_ERROR
            HM_EVENT_INJECT(HME_NUMERIC_ERROR, HM_SUB_CODE_STRING, 0, strLength,
                    (char * ) errorString);
            break;
        case 4:
            //HME_ILLEGAL_REQUEST
            HM_EVENT_INJECT(HME_ILLEGAL_REQUEST, HM_SUB_CODE_STRING, 0, strLength,
                    (char * ) errorString);
            break;
    
            ...
        }
     }
    

    Note that all of the HM_CODEs can be used after including the hmTypes.h file.

    Snippet from hmTypes.h:

    enum HM_CODE
        {  
    
        /* ARINC 653 defined codes */
    
        HME_DEADLINE_MISSED = 0,    /* first ARINC code must be 0 */
        HME_APPLICATION_ERROR,
        HME_NUMERIC_ERROR,
        HME_ILLEGAL_REQUEST,
        HME_STACK_OVERFLOW,
        HME_MEMORY_VIOLATION,
        HME_HARDWARE_FAULT,
        HME_POWER_FAIL,
    
        ...
    
        }
    

    Clarification:

    1. Did not test this code on our target OS yet.
    2. These injections will work on Process Level via the Partition Health-Monitoring table only. For Kernel Level (via the Module Health-Monitoring table), please use the same command on the VxWorks Terminal.