이벤트는 무엇인가?

우리가 흔히 이벤트라 하면, 뭔가 특별한 것을 생각한다. 일반적으로 이벤트라는 것은 뭔가 어떤 특별한 뭔가를 의미한다.
ST 에서 각 디바이스마다 이벤트가 발생하도록 지원하고 있다.
각 디바이스의 application datasheet 를 보면, 관련 api들을 제공한다. 이런 이벤트 중에서는 정상 동작을 할 때, 발생하는 것이 있는 반면에 에러가 났을 때 발생하는 것이 있다.

이럴 때 이벤트를 봐라?

7020 ATSC 모듈이 A/V play 도중에 멈추는 현상이 있었다. 프로그램을 돌려본 결과, 채널 스캔을 하고 5 초를 넘기지 못했다.
기존의 보드 회로와 거의 같았기 때문에, 하드웨어는 거의 의심하지 않았다.
소프트웨어 쪽에서 알아 볼 수 있는 방법은 어떤 이벤트가 발생하고 멈추는 지 보는 것이 전부였다. 프로그램 역시, 예전 보드때와 동일했기 때문에 특별히 이상하다고 생각하진 않았다. 그렇다고 손 놓고 있을 수는 없으니, 별 수 없지 않는가?

이벤트 동작하게 하기

처음 7020 brick source 의 경우, 많은 이벤트가 동작하도록 세팅되어 있었다. 그래서 실행시킬 때, 화면 가득 이벤트 메세지가 출력되었다. 하지만, DAC5000 으로 옮겨 오면서, 불필요한 이벤트를 주석처리 했다. 이벤트에 대한 설정은 system/event.c 파일에 지정하고 있다.

우선 나는 A/V 와 관련있는 stpti, stvid 의 이벤트 함수를 등록 해제해야 했다.
stvid 에는 아래 표와 같은 이벤트 함수를 제공하고 있다.

이벤트 이름 설명
STVID_DATA_OVERFLOW_EVT Bit buffer level of occupancy reached the upper threshold.
STVID_DATA_UNDERFLOW_EVT Bit buffer level of occupancy reached the lower threshold.
STVID_SPEED_DRIFT_THRESHOLD_EVT The real current speed is drifting compared to the requested speed.
STVID_STOPPED_EVT Driver is now stopped, the last byte of data has been decoded.
STVID_DATA_ERROR_EVT A bad incoming data stream has been detected.
STVID_NEW_PICTURE_DECODED_EVT A new picture has just been decoded.
STVID_PICTURE_DECODING_ERROR_EVT The video driver has detected error(s) when decoding a picture.
STVID_PROVIDED_DATA_TO_BE_INJECTED_EVT Some data is provided by the video driver, which requiresto be injected by the application.
STVID_SEQUENCE_INFO_EVT Next sequence found in bit buffer has new information.
STVID_USER_DATA_EVT User data information are found in the decoded stream.
STVID_DISPLAY_NEW_FRAME_EVT A new picture will be displayed on the next VSYNC.
STVID_NEW_PICTURE_TO_BE_DISPLAYED_EVT A new picture will be displayed on the next VSYNC.
STVID_ASPECT_RATIO_CHANGE_EVT Next picture to be displayed (on next VSYNC) has a new aspect ratio compared to the previous displayed picture.
STVID_FRAME_RATE_CHANGE_EVT Next picture to be displayed (on next VSYNC) has a new frame rate information compared to the previous displayed picture.
STVID_SCAN_TYPE_CHANGE_EVT Next picture to be displayed (on next VSYNC) has a new scan type compared to the previous displayed picture.
STVID_RESOLUTION_CHANGE_EVT Next picture to be displayed (on next VSYNC) has a new resolution compared to the previous displayed picture.
STVID_DIGINPUT_WIN_CHANGE_EVT The digital input driver (stvin) needs to change its windows.
STVID_IMPOSSIBLE_WITH_MEM_PROFILE_EVT An action, with the current memory profile, cannot be performed.
STVID_BACK_TO_SYNC_EVT Video is synchronised again.
STVID_OUT_OF_SYNC_EVT Video lost synchronisation.
STVID_SYNCHRO_EVT The requested action of synchronization has been completed or time out occurred.

많은 이벤트 함수들 중에서, STVID_RESOLUTION_CHANGE_EVT 를 등록해보겠다. event.c 파일에다 특정 이벤트를 등록해두면, 나중에 이벤트가 발생했을 때, 등록할 때 지정해 둔 함수가 실행이 된다. 이 때 거의 대부분 함수는 printf 이다.
우선 event.c 파일을 보자! 등록하는 형식이 다른 이벤트를 등록할 때도 동일하기 때문에 몇 군데만 바꿔주면 된다.

   DevSubscribeParams.NotifyCallback     = (STEVT_DeviceCallbackProc_t)RESOLUTION_CHANGE_EVT;   // 이벤트 발생시 수행될 함수 
 
        ST_ErrorCode = STEVT_SubscribeDeviceEvent(EVT_Handle[0],
           VID_DeviceName,
            (STEVT_EventConstant_t)STVID_RESOLUTION_CHANGE_EVT, &DevSubscribeParams);     // 등록할 이벤트 함수 지정
 
	if (ST_ErrorCode != ST_NO_ERROR)
	{
	    printf("DataErrMessage=%s\n", GetErrorText(ST_ErrorCode) );
	    return( ST_ErrorCode );
	}

다음은 위의 이벤트가 발생할 때 호출되는 함수에 대한 정의이다.

void RESOLUTION_CHANGE_EVT(
    STEVT_CallReason_t Reason,
    const ST_DeviceName_t RegistrantName,
    STEVT_EventConstant_t Event,
    const void *EventData,
    const void *SubscriberData_p)
{
	STVID_PictureParams_t *pictureType;
	pictureType=(STVID_PictureParams_t*)EventData;
 
	printf("STVID_RESOLUTION_CHANGE_EVT!\n");
	printf("Width=%d, height=%d\n",pictureType->Width,pictureType->Height);
}

구조체가 좀 복잡하게 나열되어 있지만, 결국은 printf 문이다.
이번에는 stpti 에 대한 이벤트를 등록해보겠다. stpti 의 경우는 앞의 stvid 와는 약간 다르다.
우선 event.c 에 이벤트를 등록하기전에, stpti_setup() 에서 STPTI_EnableErrorEvent() 함수로 이벤트를 enable 시켜야 한다.
아래는 system/stpti.c 이다.

    ST_ErrorCode = STPTI_EnableErrorEvent(PTI_DeviceName, STPTI_EVENT_BUFFER_OVERFLOW_EVT);  // enable 시킬 이벤트 함수 지정
    if (ST_ErrorCode != ST_ERROR_FEATURE_NOT_SUPPORTED )
    {
  //      printf("PTI_EnableErrorEvent(OVERFLOW)=%s\n", GetErrorText(ST_ErrorCode) );
        if (ST_ErrorCode != ST_NO_ERROR)
            return( ST_ErrorCode );
 
        ST_ErrorCode = STPTI_EnableErrorEvent(PTI_DeviceName, STPTI_EVENT_CC_ERROR_EVT);
 //       printf("PTI_EnableErrorEvent(CC)=%s\n", GetErrorText(ST_ErrorCode) );
        if (ST_ErrorCode != ST_NO_ERROR)
        return( ST_ErrorCode );
 
        ST_ErrorCode = STPTI_EnableErrorEvent(PTI_DeviceName, STPTI_EVENT_INTERRUPT_FAIL_EVT);
  //      printf("PTI_EnableErrorEvent(CC)=%s\n", GetErrorText(ST_ErrorCode) );
        if (ST_ErrorCode != ST_NO_ERROR)
        return( ST_ErrorCode );		

그리고 나서, 이제는 event.c 에 stvid 와 같은 방법으로 등록해주면 된다.

 DevSubscribeParams.NotifyCallback     = (STEVT_DeviceCallbackProc_t)EVENT_PACKET_ERROR_EVT;
 
        ST_ErrorCode = STEVT_SubscribeDeviceEvent(EVT_Handle[0],
           PTI_DeviceName,
            (STEVT_EventConstant_t)STPTI_EVENT_PACKET_ERROR_EVT,
            &DevSubscribeParams);
 
	if (ST_ErrorCode != ST_NO_ERROR)
	{
	    printf("NewPictureDecordErrMessage=%s\n", GetErrorText(ST_ErrorCode) );
	    return( ST_ErrorCode );
	}

아래는 STPTI_EVENT_PACKET_ERROR_EVT 이벤트에 대한 호출 함수이다.

void EVENT_PACKET_ERROR_EVT()
{
	printf("STPTI_EVENT_PACKET_ERROR_EVT!\n");
}

마치면서

현재 DAC5000 의 경우 event.c 를 보면, 대부분의 이벤트가 주석처리 되어 있다. 필요에 따라서 주석을 풀어서 등록이 가능하다.

  • computer/digitalarena/이벤트_사용하기.txt
  • Last modified: 3 years ago
  • by likewind