This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TDA4VM: Accidental initialization exception on csitx node

Part Number: TDA4VM

Hi Ti's experts,

     We found that Csitx node may experience initialization exceptions when we repeatedly run our apps. This phenomenon has occurred on both SDK 7.03 and SDK 8.05 in QNX. 

     

     In order to reproduce the problem, I attempted to write a demo code and found this issue during repeated testing.

     Please find the attachment for the source code cc_csitx.tar.gz

     Could you please checkout the source code and And help us locate the problem? Thanks  a lot!

     

  • Hi,

    Is it possible to recreate this on EVM? Also if possible, can you also share the complete log, even the output of previous run? I am suspecting something failed in the previous run and so driver is not closed properly and so in the next run, open itself is failing.. 

    Regards,

    Brijesh

  • i Brijesh,

        I did not reproduce this issue during testing on the EVM board,But it's easy to replicate on our board.

       Please find the attachment for the complete log

      198.18.36.94_2023-06-01_12_41_11.zip 

      I did not find the log of the previous run error,Could this be a problem caused by different peripheral circuits of the board? 

      Is there any way to locate the problem? Or force a reset of the CSITx node when we release resources?

  • Hi zheng,

    The shared log seems to be completely empty. Can you please capture and share it again?

    Regards,

    Brijesh

  • Hi zheng,

    ok, by looking into the shared code, i see couple of things.

    1, Looking like you are killing the csitx process using the script. could you please confirm? 

    2, After the main loop gets over ie loops that calls MonitorProcess API, it seems you are not calling vxWaitGraph, can you please call it? 

    3, Also in the signal handler, you are just setting a flag to stop the main loop. Instead i would suggest to set this flag, call vxWaitGraph and then release all resources in the handler itself.. 

    Can you please try with the above changes? 

    Regards,

    Brijesh

  • HI Brijesh,

           

       1, Looking like you are killing the csitx process using the script. could you please confirm? 

       We used to send signals to terminate the program : slay -s SIGINT cc_csitx.out

       2, After the main loop gets over ie loops that calls MonitorProcess API, it seems you are not calling vxWaitGraph, can you please call it? 

      We called it in the function monitor_delete_graph (line:267 ./csitx/monitor_utils.c)

        

    static void monitor_delete_graph(MonitorObj *obj) {
      vxWaitGraph(obj->csitx_graph);
    
      CsitxObjectDeinit(&obj->csitxObj);
      printf("Csitx delete done!\n");
    
      vxReleaseGraph(&obj->csitx_graph);
      printf("Csitx Graph delete done!\n");
    }

       3. Also in the signal handler, you are just setting a flag to stop the main loop. Instead i would suggest to set this flag, call vxWaitGraph and then release all resources in the handler itself.. 

       I guess we have done as your suggestion, am i right?

       

    static void signal_process(int sig)
    {
        gAppObj.stop_task = 1;
    }
    
    static void catch_signal()
    {
      signal(SIGHUP, signal_process);
      signal(SIGINT, signal_process);
      signal(SIGILL, signal_process);
      signal(SIGTRAP, signal_process);
      signal(SIGABRT, signal_process);
      signal(SIGBUS, signal_process);
      signal(SIGFPE, signal_process);
    }
    
    static vx_status app_run_graph(AppObj *obj)
    {
        vx_status status = VX_SUCCESS;
        vx_int32 idx = 0;
        for(obj->frame_id = 0; obj->frame_id < obj->num_frames_to_run; obj->frame_id++)
        {   
            idx = obj->frame_id % MAX_INPUT_DEPTH;
            MonitorProcess(&obj->monitor_obj, obj->in_img[idx]);        
            usleep(5000);
            if(obj->stop_task == 1)
            {
                break;
            }  
        }
        return status;
    }

  •  I guess we have done as your suggestion, am i right?

    It does not look like, can you please try calling below from system call handlers also?

    app_delete_graph(obj);
    printf("App Delete Graph Done! \n");

    app_deinit(obj);
    printf("App De-init Done! \n");

    Regards,

    Brijesh

  • Hi Brijesh,

        I have modified the code as your suggestion,

      

    #include <utils/perf_stats/include/app_perf_stats.h>
    #include <utils/console_io/include/app_get.h>
    #include <utils/grpx/include/app_grpx.h>
    #include <VX/vx_khr_pipelining.h>
    #include <ti/osal/SemaphoreP.h>
    #include "app_common.h"
    
    #include "csitx/monitor_utils.h"
    #include <stdio.h>
    #include <string.h>
    #include <time.h>
    
    #define DVR_BUFFER_Q_DEPTH      (2)
    #define DVR_PIPELINE_DEPTH      (2)
    #define APP_MAX_IMAGE_PLANE_MAX (4U)
    #define MAX_INPUT_DEPTH         (10)
    
    typedef struct {
        vx_context                  context;
        vx_image                    in_img[MAX_INPUT_DEPTH];
        vx_uint32                   num_frames_to_run;
        vx_int32                    frame_id;
        vx_uint32                   stop_task;
        MonitorObj                  monitor_obj;
    } AppObj;
    AppObj gAppObj;
    
    static vx_status app_init(AppObj *obj);
    static void      app_deinit(AppObj *obj);
    static vx_status app_create_graph(AppObj *obj);
    static vx_status app_run_graph(AppObj *obj);
    static void      app_delete_graph(AppObj *obj);
    static void      app_default_param_set(AppObj *obj);
    
    static char menu[] = {
        "\n"
        "\n ========================="
        "\n Demo: CSITX Test Demo"
        "\n ========================="
        "\n"
        "\n p: Print performance statistics"
        "\n"
        "\n x: Exit"
        "\n"
        "\n Enter Choice: "
    };
    
    static void signal_process(int sig)
    {
        gAppObj.stop_task = 1;
        app_delete_graph(&gAppObj);
        printf("App Delete Graph Done! \n");
    
        app_deinit(&gAppObj);
        printf("App De-init Done! \n");
    }
    
    static void catch_signal()
    {
      signal(SIGHUP, signal_process);
      signal(SIGINT, signal_process);
      signal(SIGILL, signal_process);
      signal(SIGTRAP, signal_process);
      signal(SIGABRT, signal_process);
      signal(SIGBUS, signal_process);
      signal(SIGFPE, signal_process);
    }
    
    vx_int32 app_multi_cam_main(vx_int32 argc, vx_char* argv[])
    {
        vx_status status = VX_SUCCESS;
        AppObj *obj      = &gAppObj;
        catch_signal();
        /*Optional parameter setting*/
        app_default_param_set(obj);
        if (status == VX_SUCCESS)
        {
            status = app_init(obj);
        }
    
        if(status == VX_SUCCESS)
        {
            printf("App Init Done! \n");
            status = app_create_graph(obj);
            if(status == VX_SUCCESS)
            {
                if(status == VX_SUCCESS)
                {
                    printf("App Verify Graph Done! \n");
                    status = app_run_graph(obj);
                }
            }
            printf("App Run Graph Done! \n");
        }
        return status;
    }
    
    static vx_status app_init(AppObj *obj)
    {
        vx_status status = VX_SUCCESS;
    
        /* Create OpenVx Context */
        obj->context = vxCreateContext();
        status = vxGetStatus((vx_reference)obj->context);
        printf("Creating context done!\n");
        if (status == VX_SUCCESS)
        {
            tivxHwaLoadKernels(obj->context);
            printf("Kernel loading done!\n");
        }
        return status;
    }
    
    static void app_deinit(AppObj *obj)
    {
        tivxHwaUnLoadKernels(obj->context);
        printf("Kernels unload done!\n");
        vxReleaseContext(&obj->context);
        printf("Release context done!\n");
    }
    
    static void app_delete_graph(AppObj *obj)
    {
        tivx_utils_graph_perf_print(obj->monitor_obj.csitx_graph);
        ccMonitorDeinit(&obj->monitor_obj);
        for(int i =0; i < MAX_INPUT_DEPTH; i++) {
            vxReleaseImage(&obj->in_img[i]);
        }
    }
    
    static vx_status app_create_graph(AppObj *obj)
    {
        vx_status status = VX_SUCCESS;
        vx_graph_parameter_queue_params_t graph_parameters_queue_params_list[5];
        vx_int32 graph_parameter_index;
    
        if (status == VX_SUCCESS) 
        {  
            for(int i = 0; i < MAX_INPUT_DEPTH; i++) {
                obj->in_img[i] = vxCreateImage(obj->context,
                                    5120,
                                    1285,
                                    VX_DF_IMAGE_UYVY);
    
                vx_imagepatch_addressing_t image_addr_out;
                vx_rectangle_t rect_out;
                vx_map_id id_out;
                void *data_ptr_out;
                rect_out.start_x = 0;
                rect_out.start_y = 0;
                rect_out.end_x   = AVM_WIDTH;
                rect_out.end_y   = AVM_HEIGHT;
    
                vxMapImagePatch(obj->in_img[i],
                            &rect_out,
                            0,
                            &id_out,
                            &image_addr_out,
                            &data_ptr_out,
                            VX_READ_ONLY,
                            VX_MEMORY_TYPE_HOST,
                            VX_NOGAP_X);
    
                memset(data_ptr_out, (25 * (i + 1)) & 0xFF, (sizeof(unsigned char) * 5120 * 1285 * 2));
                vxUnmapImagePatch(obj->in_img[i] , id_out);             
            }
            status = ccMonitorInit(&obj->monitor_obj);
        }
        printf("graph create done! %d\n", status);
        return status;
    }
    
    static vx_status app_run_graph(AppObj *obj)
    {
        vx_status status = VX_SUCCESS;
        vx_int32 idx = 0;
        for(obj->frame_id = 0; obj->frame_id < obj->num_frames_to_run; obj->frame_id++)
        {   
            idx = obj->frame_id % MAX_INPUT_DEPTH;
            MonitorProcess(&obj->monitor_obj, obj->in_img[idx]);        
            usleep(5000);
            if(obj->stop_task == 1)
            {
                break;
            }  
        }
        return status;
    }
    
    static void app_default_param_set(AppObj *obj)
    {
        obj->frame_id          = 0;
        obj->num_frames_to_run = 0xffffffff;
        obj->stop_task         = 0;
    }
    

      There may still be issues with CSITX initialization failure, And occasional CoreDump when program is releasing.

      198.18.36.94_2023-06-02_9_56_18.log

     Shall we have a method to forcibly reset the CSITX node at the application layer?

     Best wishes.

  • Hi zheng,

    Can you please share your test_app.sh script? I want to check how application is getting killed and try to recreate this on EVM. 

    Also can you provide more information about this usecase. Why do you want to forcefully kill a running application?

    Regards,

    Brijesh

  • Hi Brijesh,

        Please find the attachment for the  test_app.sh

    test_app.zip

      Due to memory size limitations, we will release some resources to ensure the operation of other functions. So we need to kill the running application, then rerun the application when other functions are completed.

  • Hi zheng,

    I think i am also seeing the similar issue on EVM after around 26 iterations.. I am debugging it and will get back to you.

    Regards,

    Brijesh

  • Hi Brijesh,

        Looking forward to good results from you, thanks.

       

       Best Wishes

  • Hi zheng,

    I think i know why this is not working. This requires two changes in the CSITx driver. Can you please make these two changes and try it out? 

    1, In the API CsitxDrv_delete, in the file ti-processor-sdk-rtos-j721e-evm-08_06_00_12\pdk_jacinto_08_06_00_31\packages\ti\drv\csitx\src\csitx_drv.c, can you please replace loop from

                    for (eventIdx = 0U ;
                         eventIdx < instObj->createParams.instCfg.eventParams[eventIdx].eventGroup;
                         eventIdx++)
                    {
                        /* Initialize event configuration parameters */
                        retVal = CsitxDrv_eventGroupUnRegister(instObj,
                                instObj->createParams.instCfg.eventParams[eventIdx].eventGroup);
                    }
    

    to

                    for (eventIdx = 0U ;
                         eventIdx < CSITX_EVENT_GROUP_MAX;
                         eventIdx++)
                    {
                        /* Initialize event configuration parameters */
                        retVal = CsitxDrv_eventGroupUnRegister(instObj,
                                instObj->createParams.instCfg.eventParams[eventIdx].eventGroup);
                    }
    

    2, Also in the API CsitxDrv_eventGroupUnRegister, in the file ti-processor-sdk-rtos-j721e-evm-08_06_00_12\pdk_jacinto_08_06_00_31\packages\ti\drv\csitx\src\csitx_event.c, can you please comment out call to semaphore_pend and post, like below?

        //if (instObj->lockSem != NULL)
        //{
        //    /* Pend on the instance semaphore */
        //    (void)SemaphoreP_pend(instObj->lockSem, SemaphoreP_WAIT_FOREVER);
        //}
    

        //if (instObj->lockSem != NULL)
        //{
        //    /* Post the instance semaphore */
        //    (void)SemaphoreP_post(instObj->lockSem);
        //}
    

    With these changes, you should be able to run this graph multiple times. I am able to run it for 100 iterations.. 

    Regards,

    Brijesh