22 Haziran 2014 Pazar

VxWorks 653 Process Seviyesi Health Monitor

Process Seviyesi Health Monitor Ayarları

XML haricinde uygulamamız için Health Monitoring işlevini yerine getiren kod yazmak ta mümkün.
There is potential for a process health monitor for each partition. The application must create the process health monitor by calling hmCreateErrorHandler (bu native API) or for ARINC 653 applications by issuing CREATE_ERROR_HANDLER. The routines create a highest priority task in the partition OS with which to run the process health monitor handler.

Uygulamamız için hata raise edilirse, SystemState uygulamayı belirteceği için kendi kodumuz çalışır.
Aşağıdaki cümleler önemli.
 * The HM will not violate partitioning when handling process level errors.
 * The error handler process is active in NORMAL mode only.

Error Handler Yaratmak

Eğer uygulamamız için de health monitor eklemek istiyorsak CREATE_ERROR_HANDLER metodunu kullanarak kod yazmamız gerekir. Buradaki açıklama önemli
The error handler task is invoked when the RTOS 653 health monitor detects a process level error
Aşağıda error handler yaratmak için örnek kod var:

STACK_SIZE_TYPE stackSize = 1024 // 1 KB
RETURN_CODE_TYPE returnCode;
//Shall create a special process with the highest priority, ENTRY_POINT and STACK_SIZE attributes.for the current partition,
CREATE_ERROR_HANDLER ((SYSTEM_ADDRESS_TYPE)ErrorHandler, stackSize, returnCode);

CREATE_ERROR_HANDLER Metodunun İçi

Metod içeride yeni bir task yaratıp bu task ile haberleşmek için msgQueue oluşturuyor.

CREATE_ERROR_HANDLER (SYSTEM_ADDRESS_TYPE ENTRY_POINT,
                                                       STACK_SIZE_TYPE STACK_SIZE,
                                                       RETURNCODE_TYPE* RETURNCODE) {
      //... do some stuff
   if (hmErrorHandlerCreate ((FUNCPTR)ENTRY_POINT,STACK_SIZE,1) {...}
}

hmErrorHandlerCreate Metodunun İçi

Aşağıdaki kod parçasında msgQCreate metodunun çağırıldığı görülebilir.

STATUS hmErrorHandlerCreate (...) {
   //... do some stuff
   hmCtxId->ehQueueId = msgQCreate (hmCtxId->ehMaxQueueDepth,
                                                                sizeof(HM_EVENT),
                                                                MSG_Q_FIFIO);

  hmCtxId->ehTaskId = taskCreat ("tHmErrorHandler"// task name
                                                        hmCtxId->ehTaskPrio, // 0. priority
                                                        options,
                                                        stackSize,
                                                        errorHandler,
                                                        param,
                                                        0,0,0,0,0,0,0,0,0);
}

Error Handler Metodunda Kullanılabilecek Çağrılar

VxWorks'ün sunduğu kütüphaneler kullanılabildiği gibi ARINC 653 portlarına da erişmek mümkün. Çünkü portlar partition seviyesinde açılıyor.

Error Handler Metoduna Gelen Hata Kodları
Error Handler metodunda yakalamamız gereken hata kodlarını açıklayan şu cümle önemli.
The following are process-level APEX error codes:
  • APPLICATION_ERROR
  • DEADLINE_MISSED
  • HARDWARE_FAULT
  • ILLEGAL_REQUEST
  • MEMORY_VIOLATION
  • NUMERIC_ERROR : Floating point işleminde overflow, sıfıra bölme vb. olursa bu hata gönderilir. 
  • POWER_FAIL
  • STACK_OVERFLOW
Örnek Error Handler Metodu

#include "taskLib.h"
//Hata alan uygulamayı durdurma örneği
void ApplErrorHandler (){
    ERROR_STATUS_TYPE errorStatus;
    RETURN_CODE_TYPE returnCode;

    while (true){
        GET_ERROR_STATUS  (&errorStatus,&returnCode);
        if (returnCode == NO_ERROR){
            switch (errorStatus.ERROR_CODE){
                case APPLICATION_ERROR:{
                    //Log error
                    printf ("Error code : %d %s \n",errorStatus.ERROR_CODE,errorStatus.MESSAGE);
             
                    //veya istenirse loglama amacıyla port'a yazılabilir
                    SEND_QUEUING_MESSAGE (portNo,
                                                                        errorStatus.MESSAGE,
                                                                        strlen(errorStatus.MESSAGE),
                                                                        0 , //timeout
                                                                        &returnCode);

                    //Suspend task for debugging

                    int taskId = taskIdFromProcIdGet (errorStatus.FAILED_PROCESS_ID);
                    taskSuspend (taskId);//tasklib icinde
                    break;
                }//case
            }//switch
        }//if
        STOP_SELF();
    }//while
}

Klasik Bir Error Handler
Klasik bir error handler içinde call stack yazdırılır ve hata veren partition durdurulur. Hata adresini almak için taskInfo kütüphanesindeki taskRegsGet() kullanılabilir.

int taskId = taskIdFromProcIdGet (errorStatus.FAILED_PROCESS_ID);
REG_SET regs;
//Get CPU registers with VxWorks native api
if (taskRegsGet (taskId,&reg) ==  OK){
  printf ("0x%.8x",regs.gpr [1]);//General Purpose Register error address

}

Bir başka örnekte traceLib içindeki trcStack() metodu kullanılmış.

REG_SET regs;
taskRegsGet(taskId, &regs);
trcStack(&regs, (FUNCPTR) wpiCleanTracePrint, taskId);

Hiç yorum yok:

Yorum Gönder