• 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的本质就是异步线程的变量共享出了问题。

  • 相关阅读:
    url中的特殊字符问题
    Gridview中几个Button的应用
    Asp.net中static变量和viewstate的使用方法(谨慎)
    my97DatePicker选择年、季度、月、周、日
    Server.MapPath()
    asp.net(C#)读取文件夹和子文件夹下所有文件,绑定到GRIDVIEW并排序 .
    sql union和union all的用法及效率
    asp.net 字符串替换、截取和从字符串中最后某个字符 开始截取
    ASP.NET
    sql中查询中的when...then 语句
  • 原文地址:https://www.cnblogs.com/CsharpNote/p/5249485.html
Copyright © 2020-2023  润新知