Chinaunix首页 | 论坛 | 博客
  • 博客访问: 178864
  • 博文数量: 27
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 618
  • 用 户 组: 普通用户
  • 注册时间: 2013-11-15 09:12
文章分类
文章存档

2014年(17)

2013年(10)

我的朋友

分类: Android平台

2014-04-02 17:45:25

我设计的工厂测试工具是CS结构的,在设备端会有一个Server,再PC端会有一个Client,两者进行交互完成测试。

通讯方式选择:
1.Stocket:优点是不基于ADB,可以自己定义接口,相对稳定,在Android2.3以前似乎多数的测试工具都是使用这个方式,需要在设备端跑起来一个S程序,等待接收命令。
2.ADB:优点方便,直接移植过来Android的ADBD的程序即可,加一些传输的信息的D-CODE以及P-CODE即可,在Android2.3以后ADB逐渐稳定,我觉得使用这种方式更加方便。

PC端:窗口设计需要简明,简单,按钮大,方便工厂测试工人的操作;与工厂产线的接口需要开放,扩展性好。(推荐使用VC开发)

设备端:设计需要扩展性强,稳定,(使用C开发)

我主要做的设备端,就说说设备端的设计吧:

先确定你需要测试的模块,在确定你需要测试模块的相关功能,这样把每个模块分开,可以尽量的模块之间的干扰。

main.h

点击(此处)折叠或打开

  1. #define CMD(cmd) extern int cmd##_main(char**, int, char*);
  2. #include<DefineCommand.h>
  3. #undef CMD

  4. typedef int (*mode_main_func)(char** argv, int argc, char* send_buff);

  5. typedef struct _MODE
  6. {
  7.         char* name;
  8.         mode_main_func main_func;
  9. } MODE;

  10. MODE g_ModeTable[] = {
  11. #define CMD(cmd) { #cmd, cmd##_main },
  12. #include<DefineCommand.h>
  13. #undef CMD
  14. };
DefineCommand.h

点击(此处)折叠或打开

  1. CMD(bt)
  2. CMD(wifi)
  3. CMD(nfc)
  4. CMD(fm)
  5. CMD(audio)
  6. CMD(headset)
  7. CMD(mic)
  8. CMD(speaker)
  9. CMD(camera)
  10. CMD(gps)
  11. CMD(touch)
  12. CMD(rtc)
  13. CMD(vibrator)
  14. CMD(imei)
  15. CMD(battery)
  16. CMD(charging)
  17. CMD(g_sensors)
  18. CMD(p_sensors)
  19. CMD(l_sensors)
  20. CMD(led)
  21. CMD(lcd)
  22. CMD(keypad)
  23. CMD(modem)
  24. CMD(sd)
  25. CMD(hdmi)
  26. CMD(small_camera)
  27. CMD(lcd_back_light)
  28. CMD(camera_flash)
main.c

点击(此处)折叠或打开

  1. MODE* getMode(char* mode);

  2. int main(int argc, char **argv)
  3. {
  4.         int ret = 0;
  5.         MODE* tMode = NULL;
  6.         char* mode_name = (char *)malloc(MODE_SIZE);      //模块名称
  7.         char* func_name = (char *)malloc(FUNC_SIZE);      //模块测试功能名称
  8.         char* send_buff = (char *)malloc(MAXBUFF);
  9.         int func_val = -1, func_argc= 0;

  10.         if (argc < ARGC_NUM) {
  11.                 //TCMD_LOGE(mode_name, func_name, COMMAND_ARGC_ERROR);
  12.                 return COMMAND_ARGC_ERROR;
  13.         }

  14.         stpcpy(mode_name, argv[1]);
  15.         stpcpy(func_name, argv[2]);
  16.         func_argc = argc - 3;

  17.         tMode = getMode(mode_name);

  18.         if (tMode) {

  19.                 func_val = tMode->main_func(argv, func_argc, send_buff);

  20.                 switch (func_val)
  21.                 {
  22.                         case COMMAND_UNDEFINE_FUNC:
  23.                                 //TCMD_LOGE(mode_name, func_name, COMMAND_UNDEFINE_FUNC);
  24.                                 ret = COMMAND_UNDEFINE_FUNC;
  25.                                 break;
  26.                         case COMMAND_ARGC_ERROR:
  27.                                 //TCMD_LOGE(mode_name, func_name, COMMAND_ARGC_ERROR);
  28.                                 ret = COMMAND_ARGC_ERROR;
  29.                                 break;
  30.                         case COMMAND_EXEC_FAILE:
  31.                                 //TCMD_LOGE(mode_name, func_name, COMMAND_EXEC_FAILE);
  32.                                 ret = COMMAND_EXEC_FAILE;
  33.                         case COMMAND_EXEC_SUCCESSFUL:
  34.                                 //TCMD_LOGI(mode_name, func_name, "Successful.\n");
  35.                                 ret = COMMAND_EXEC_SUCCESSFUL;
  36.                                 break;
  37.                         default:
  38.                                 //TCMD_LOGE(mode_name, func_name, COMMAND_UNKNOWN_ERROR);
  39.                                 ret = COMMAND_UNKNOWN_ERROR;
  40.                                 break;
  41.                 }

  42.         } else {
  43.                 //TCMD_LOGE(mode_name, func_name,COMMAND_UNDEFINE_MODE);
  44.                 ret = COMMAND_UNDEFINE_MODE;
  45.         }

  46.         return ret;
  47. }
  48. MODE* getMode(char* name)
  49. {
  50.         MODE* tMode = NULL;
  51.         int i = 0;
  52.         int mode_num = sizeof(g_ModeTable) / sizeof(MODE);

  53.         for (; i < mode_num; ++i) {
  54.                 if(!strcmp(name, g_ModeTable[i].name)) {
  55.                         tMode = &g_ModeTable[i];
  56.                         TCMD_LOGD("Mode_table.name = %s", tMode->name);
  57.                         break;
  58.                 }

  59.         }
  60.         return tMode == NULL ? NULL : tMode;
  61. }
然后就进入到各个模块的的main中执行了,例子battery.c

点击(此处)折叠或打开

  1. int battery_main(char** argv, int argc, char* send_buff)
  2. {
  3.         int ret = 0;
  4.         char* func_name = (char *)malloc(FUNC_SIZE);

  5.         stpcpy(func_name, argv[2]);

  6.         if(!strcmp(func_name, "--info"))
  7.                 ret = battery_read_info(argv, argc, send_buff);
  8.         else
  9.                 ret = COMMAND_UNDEFINE_FUNC;
  10.         
  11.         return ret;
  12. }
分两种的测试方式,一种是直接操作kernel提供的sys测试节点,比如Touch Sensor Battery Rtc都可以这样搞,但是像Audio Camera BT/WIFI/GPS Modem这样的大型模块就不太好这样测试了,需要调用相关的测试模块,这样就需要进程之间的通信,我使用的recovery中recovery与updater之间的方式,pipefd。

举例子,测试modem的时候:

点击(此处)折叠或打开

  1. int modem_read_imsi(char** argv, int argc, char* send_buff)
  2. {
  3.         int ret = 1;
  4.         const char* binary = MODEM_ADAPTER;

  5.         TCMD_LOGI(argv[1], argv[2], "Test to start...\n");
  6.         
  7.         if ( argc != MODEM_READ_IMSI_ARGC)
  8.                 ret = COMMAND_ARGC_ERROR;
  9.         else {
  10.                 int pipefd[2];
  11.                 pipe(pipefd);

  12.                 const char** args = (const char**)malloc(sizeof(char*) * 4);
  13.                 args[0] = binary;
  14.                 args[1] = IMSI;
  15.                 char* temp = (char*)malloc(10);
  16.                 sprintf(temp, "%d", pipefd[1]);
  17.                 args[2] = temp;
  18.                 args[3] = NULL;
  19.                 
  20.                 ret = exec_binary(binary, args, pipefd[0], pipefd[1], send_buff);
  21.         }
  22.         return ret;
  23. }
  24. int modem_main(char** argv, int argc, char* send_buff)
  25. {
  26.         int ret = 0;
  27.         char* func_name = (char *)malloc(FUNC_SIZE);

  28.         stpcpy(func_name, argv[2]);

  29.         if(!strcmp(func_name, "--imei"))
  30.                 ret = modem_read_imei(argv, argc, send_buff);
  31.         else if(!strcmp(func_name, "--ue_version"))
  32.                 ret = modem_read_uversion(argv, argc, send_buff);
  33.         else if(!strcmp(func_name, "--imsi"))
  34.                 ret = modem_read_imsi(argv, argc, send_buff);
  35.         else if(!strcmp(func_name, "--echo"))
  36.                 ret = modem_get_status(argv, argc, send_buff);
  37.         else
  38.                 ret = COMMAND_UNDEFINE_FUNC;
  39.         
  40.         return ret;
  41. }

点击(此处)折叠或打开

  1. int exec_binary(const char* binary, const char** cmd, int fb_p, int fb_c, char* send_buff)
  2. {
  3.         pid_t pid = fork();

  4.         if (pid == 0) {
  5.                 close(fb_p);
  6.                 execv(binary, (char* const*)cmd);
  7.                 _exit(-1);
  8.         }
  9.         close(fb_c);

  10.         FILE* from_child = fdopen(fb_p, "r");
  11.         int size = fread(send_buff, 1, MAXBUFF, from_child);
  12.         if ( size <= 0)
  13.                 return COMMAND_EXEC_FAILE;

  14.         int status;
  15.         waitpid(pid, &status, 0);
  16.         if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
  17.                 return COMMAND_EXEC_FAILE;

  18.         return COMMAND_EXEC_SUCCESSFUL;
  19. }
这样设计的好处就是如果测试相关模块出现问题,不用修改测试工具,直接更新模块的binary即可。
这就是我设计的工厂测试工具,设计与开发大概不到2星期,相关模块的集成在一个月做完,但是由于公司项目黄了,没有用到,但是我还是从中学习到了好多知识,感谢指导我思路的老宋,大牛!

阅读(3522) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

c语言达人2014-11-29 18:30:50

yimibuluo:可不可以加您的求求,有问题咨询您?

wangxiaoxu_198416@hotmail.com 咨询谈不上 不是大牛 大家一起讨论下可以

回复 | 举报

yimibuluo2014-11-04 10:21:27

可不可以加您的求求,有问题咨询您?