ST work1——印象最深的一个bug DJI 激活时报 SDK_ACTIVE_SDK_VERSION_ERROR
2016-03-07 09:42 yinglang 阅读(765) 评论(0) 编辑 收藏 举报异步线程激活,应该被异步线程共享的数据却设置成了函数的局部变量
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 (¶m)
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("\n"); 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的本质就是异步线程的变量共享出了问题。