ST work1——印象最深的一个bug DJI 激活时报 SDK_ACTIVE_SDK_VERSION_ERROR

 异步线程激活,应该被异步线程共享的数据却设置成了函数的局部变量

1)  bug     

  激活要用所有数据在官方DEMO中测试都没问题,但是一在自己写的程序里运行就报下面的错

  

  我的代码都是从官方DEMO中粘过来的,唯一更改的就是把ui获得数据改成了我自己的数据,添加了头文件和一些变量的声明。SDK_VERSION的值是官方自己的宏定义,按道理不可能出错才对。

 2) debug 方法,找出函数调用链,逐层对比我的程序和DEMO的输出,找出输出不同的地方和原因

  无奈之下,我查找这个函数的调用链:

  DJI_Pro_Activate_API (&user_act_data,MainWindow_Activate_Callback)

  DJI_Pro_Create_Thread(Activate_API_Thread_Func,p_user_data)

  Activate_API_Thread_Func

  DJI_Pro_App_Send_Data( 2, 0, MY_ACTIVATION_SET, API_USER_ACTIVATION,

                         (unsigned char*)&from_user_account_data,

                          sizeof(from_user_account_data) - sizeof(char *),

                      DJI_Pro_Activate_API_CallBack,1000,1);

  Pro_Send_Interface   (&param)

  Send_Pro_Data        (cmd_session->mmu->pmem)

  DJI_Pro_Activate_API (&user_act_data,MainWindow_Activate_Callback);

  Pro_Hw_Send          (buf,pHeader->length);

  port->write          ((char *)buf + sent,len - sent)

  最后的write是QT的库函数,可见到这里已经是最后了,再往后就没有源代码了。

  write的调用者是port,即某个端口,

  Pro_Hw_Send的调用者是DJI_Pro_Hw,即用于串口通信的官方函数。

  可见,最后两步已经是PC通过串口向无人机的主板发送信息了。

  函数的参数一直在发生变化,但是通过程序可以看出 user_act_data 一致被向后传递着,只是存进了不同的变量里。

  报错的一个很可能的原因就是数据在传递的过程中出错了,为了判断出错是在数据传出去前还是数据传出去后,(因为如果是穿出去前出的错,那就是程序的错误,否则就是线路或无人机的处理出了错)我想在每个函数中输出数据验证一下。

  因为当时对无人机很生疏,所以很怕出错的是程序外(那我很可能就修复不了了),所以选择从最后一个函数的参数开始。

  以十六进制的形式输出write的参数

  在 Pro_Hw_Send 中调用下面的函数

void print(unsigned char *buf, int len){

    for(int i = 0; i < len; i++){

        if(i % 10 == 0) printf(" ");

        printf("%2x ",buf[i]);

    }

}

   结果在我的程序中输出是:

  

  与官方代码输出果然大不相同

3) 最终原因

随着逐层输出,最后发现在Activate_API_Thread_Func中数据就不对了,而在传入该函数前数据还是对的。 

原因就是 DJI_Pro_Create_Thread创建了一个新的线程运行,Activate_API_Thread_Func,并将user_act_data作为参数传入了这个线程,但是我的程序声明的user_act_data是一个函数内的局部变量,同一进程的不同线程能够共享的只有全局变量或者是动态变量,所以在Activate_API_Thread_Func中访问的实际是一个非法的区域。

这个error的本质就是异步线程的变量共享出了问题。

原文地址:https://www.cnblogs.com/CsharpNote/p/5249485.html