factory.cpp的main函数下
            #if 1
                                if(is_pc_control(usb_com_port))
                                {
                                        pthread_create(&read_thread, NULL, read_data_thread_callback, NULL);
                                        LOGD(TAG "after create pthread");
                                        ata_status = 1;
                                        pc_control_mode(usb_com_port);
                                        LOGD(TAG "pc control stops in if()!\n");
                                        ata_status = 0;
                                }
        #else
        //end add at order teset current
        //for ata test
        at_command_processor();
        //add at order teset current
        #endif

此处是田大师修改,ATA测试判定条件 is_pc_control,然后调用的查询函数,仅仅 用到如下一个数组,
故若是增加一个ATA测试项,仅需要在如下数组增加即可,相应逻辑请在   read_data_thread_callback下增加。

item_t pc_control_items[] =
{
    item(ITEM_FM,      "AT+FM"),
    item(ITEM_MEMCARD,      "AT+MEMCARD"),
    item(ITEM_SIM,      "AT+SIM"),
    item(ITEM_GPS,      "AT+GPS"),
    item(ITEM_EMMC,      "AT+EMMC"),
    item(ITEM_WIFI,        "AT+WIFI"),
    item(ITEM_WAVEPLAYBACK,      "AT+RINGTONE"),
    item(ITEM_SIGNALTEST,      "AT+SIGNALTEST"),
    item(ITEM_RTC,      "AT+RTC"),
    item(ITEM_CHARGER,      "AT+CHARGER"),
    item(ITEM_BT,      "AT+BT"),
………………………………………………………………………………………………
#ifdef FEATURE_FTM_HDMI
    item(ITEM_HDMI, "AT+HDMI"),
#endif
        item(ITEM_MAX_IDS, NULL),
        #if defined(MTK_SPEAKER_MONITOR_SUPPORT)
    item(ITEM_SPEAKER_MONITOR_SET_TMP,      "AT+SPKSETTMP"),
    item(ITEM_SPEAKER_MONITOR,      "AT+SPKMNTR"),
#endif
};

大师注释掉的at_command_processor->read_data_thread->at_command_parser->get_at_cmd_index
内比较的是
    ftm_cmd_hdlr *at_cmd_hdlr = cmd_hdlr;
    ftm_cmd_hdlr *other_at_cmd_hdlr = other_cmd_hdlr;

这两个数组分别如下:

static ftm_cmd_hdlr other_cmd_hdlr[]={
        {0, ITEM_CUSTOM_START, "AT+START", (hdlr)dispatch_data_to_pc_cb},
        {1, ITEM_CUSTOM_STOP, "AT+STOP", (hdlr)dispatch_data_to_pc_cb},
        {2, ITEM_CUSTOM_REQUESTDATA, "AT+REQUESTDATA", (hdlr)ftm_request_data_cb},
        {3, ITEM_CUSTOM_VERSION, "AT+VERSION", (hdlr)display_version},
        {4, ITEM_CUSTOM_READBARCODE, "AT+READBARCODE", (hdlr)ftm_read_barcode},
        {5, ITEM_CUSTOM_WRITEBARCODE, "AT+BARCODE", (hdlr)ftm_write_barcode},
        {6, ITEM_CUSTOM_CAMERADATA, "AT+CAMERADATA", (hdlr)ftm_camera_data},
        {7, ITEM_CUSTOM_PROPERTY, "AT+PROPERTY", (hdlr)ftm_set_property},
        {8, ITEM_WIFI,  "AT+READBTADDR", (hdlr)ftm_read_bt_addr},
        {9, ITEM_WIFI,  "AT+WRITEBTADDR", (hdlr)ftm_write_bt_addr},
        {10,ITEM_BT,    "AT+READWIFIMAC", (hdlr)ftm_read_wifi_mac_addr},
        {11,ITEM_BT,    "AT+WRITEWIFIMAC", (hdlr)ftm_write_wifi_mac_addr},
        {ITEM_MAX_IDS, ITEM_MAX_IDS, NULL, NULL},
};
static ftm_cmd_hdlr cmd_hdlr[]={
    #ifdef MTK_FM_SUPPORT
    #ifdef FEATURE_FTM_FM
    #ifdef MTK_FM_RX_SUPPORT
        {1, ITEM_FM, "AT+FM", (hdlr)ftm_item_entry_cb},
    #endif
    #endif
    #endif

#ifndef FEATURE_FTM_WIFI_ONLY
    #ifdef FEATURE_FTM_MEMCARD
        {2, ITEM_MEMCARD, "AT+MEMCARD", (hdlr)ftm_item_entry_cb},
    #endif
………………………………

#ifdef FEATURE_FTM_SUB_STROBE
        {37, ITEM_SUB_STROBE, "AT+SUBSTROBE", (hdlr)ftm_item_add_cb},
#endif

#ifdef FEATURE_FTM_OTG
            {38, ITEM_OTG, "AT+OTG", (hdlr)ftm_item_entry_cb},
    #endif

#ifdef FEATURE_FTM_RF
                {39, ITEM_RF_TEST, "AT+RFTEST", (hdlr)ftm_item_entry_cb},
        #endif

{ITEM_MAX_IDS, ITEM_MAX_IDS, NULL, NULL},

};

这里注释掉了,所以逻辑没有用到

较早期的一些工厂工具AT+READBARCODE可以读到SN号,也是这里没有注释掉才有的响应

目前的ATA代码逻辑已经注释掉了原有的MTK的ATA实现方式,是仿着这个方式去增加的逻辑

说回正题ATMODE下的AT+VIBRATOR震动不振问题

看工厂截图才明白

static ftm_cmd_hdlr at_mode_cmd_hdlr[]={
        {0, ITEM_ATMODE_PMICRECV, "AT+PMICRECV", (hdlr)at_mode_audio_test},
        {1, ITEM_ATMODE_HMICRECV, "AT+HMICRECV", (hdlr)at_mode_audio_test},
        {2, ITEM_ATMODE_HMICEAR, "AT+HMICEAR", (hdlr)at_mode_audio_test},
        {3, ITEM_ATMODE_HMICSPK, "AT+HMICSPK", (hdlr)at_mode_audio_test},
        {4, ITEM_ATMODE_PMICEAR, "AT+PMICEAR", (hdlr)at_mode_audio_test},
        {5, ITEM_ATMODE_PREFMICEAR, "AT+PREFMICEAR", (hdlr)at_mode_audio_test},
        {6, ITEM_ATMODE_VIBRATOR, "AT+VIBRATOR=1,2", (hdlr)at_mode_audio_test},
        {7, ITEM_ATMODE_READBARCODE, "AT+READBARCODE", (hdlr)at_mode_read_barcode},
        {8, ITEM_ATMODE_DMICEAR, "AT+DMICEAR", (hdlr)at_mode_audio_test},
        {9, ITEM_ATMODE_POWEROFF, "AT+POWEROFF", (hdlr)at_mode_audio_test},
        {ITEM_MAX_IDS, ITEM_MAX_IDS, NULL, NULL},
};

这个数组的用处在哪儿

ATMODE的ITEM选中情况下进入如下逻辑

at_mode_init->at_mode_entry->at_mode_read_data_thread->at_mode_command_parser->get_at_cmd_index(at_cmd_struct, at_cmd_hdlr);

测试项目数组如下:
ftm_cmd_hdlr *at_cmd_hdlr = at_mode_cmd_hdlr;

核心问题点:
at_mode_command_parser
参数解释
at_cmd_struct->string_ptr为电脑端传给手机端参数

///如下为循环赋值at_cmd_struct->string_ptr给at_cmd_struct->at_cmd_string知道碰到'=''\r''\n'为止
    while((at_cmd_struct->cmd_index < strlen((const char *)at_cmd_struct->string_ptr)) 
           && (at_cmd_struct->string_ptr[at_cmd_struct->cmd_index] != '=')
           && (at_cmd_struct->string_ptr[at_cmd_struct->cmd_index] != '\r')
           && (at_cmd_struct->string_ptr[at_cmd_struct->cmd_index] != '\n'))
    {
        LOGD(TAG "at_command_parser--%c\n", at_cmd_struct->string_ptr[at_cmd_struct->cmd_index]);
        at_cmd_struct->at_cmd_string[k] = at_cmd_struct->string_ptr[at_cmd_struct->cmd_index];
        at_cmd_struct->cmd_index++;
        k++;
        skip_spaces(at_cmd_struct);
    }

///获取测试项目的id的index输入给at_cmd_struct->index,若未找到at_cmd_struct->index为-1
    get_at_cmd_index(at_cmd_struct, at_cmd_hdlr);

if(at_cmd_struct->index == -1)
    {
        at_cmd_struct->cmd_type = -1; // it is not at mode cmd
        return 2;
    }
    else
    {
        at_cmd_struct->cmd_type = 1;  // It is a factory mode test item
    }
    LOGD(TAG "at_cmd_struct->cmd_index = %d, strlen(at_cmd_struct->at_cmd_string) = %d, at_cmd_struct->cmd_type=%d\n",
        at_cmd_struct->cmd_index, strlen((const char *)at_cmd_struct->string_ptr),
        at_cmd_struct->cmd_type);

///解析下一个字符为结束符的命令处理,即at+****同at+****=1同样的返回值处理

if((at_cmd_struct->string_ptr[at_cmd_struct->cmd_index] == '\r')|| (at_cmd_struct->string_ptr[at_cmd_struct->cmd_index] == '\n' )|| 
        (at_cmd_struct->cmd_index == strlen((const char *)at_cmd_struct->string_ptr)))
    {
        // There is no '='
        LOGD(TAG "at_cmd_struct->cmd_index == strlen(at_cmd_struct->at_cmd_string)\n");
         // test audio or other open
                at_cmd_struct->test_type = 2;
                return 0;
    }
///解析下一个字符为等号的命令处理
    else if(at_cmd_struct->string_ptr[at_cmd_struct->cmd_index] == '=')
    {
        LOGD(TAG "at_cmd_struct->cmd_index != strlen(at_cmd_struct->at_cmd_string)\n");
        at_cmd_struct->cmd_index++; // The char after '='
        skip_spaces(at_cmd_struct);

///at_cmd_struct->cmd_index+1总字数比电脑端读取的命令长度长,即异常情况

if(at_cmd_struct->cmd_index >= strlen((const char *)at_cmd_struct->string_ptr))
        {
            return 1;
        }

/// at_cmd_struct->cmd_index+1为等号且下一个字符为0,再下一个为结束符'\r'或者'\n'时会返回相应的属性值给到上面处理,
       /// 即at+****=1打开at+***=0关闭

LOGD(TAG "at_cmd_struct->test_type = %d, %c\n", at_cmd_struct->test_type, at_cmd_struct->string_ptr[at_cmd_struct->cmd_index]);
        if((at_cmd_struct->string_ptr[at_cmd_struct->cmd_index] == '0') 
            &&((at_cmd_struct->string_ptr[at_cmd_struct->cmd_index+1] == '\r')||(at_cmd_struct->string_ptr[at_cmd_struct->cmd_index+1] == '\n')))
            {
                // close
                at_cmd_struct->test_type = 0;
                return 0;
            }
       else if((at_cmd_struct->string_ptr[at_cmd_struct->cmd_index] == '1') 
        &&((at_cmd_struct->string_ptr[at_cmd_struct->cmd_index+1] == '\r')||(at_cmd_struct->string_ptr[at_cmd_struct->cmd_index+1] == '\n')))
        {
                // open use test_type as 2
                at_cmd_struct->test_type = 2;
                return 0;
        }
    ///其他情况的返回值为2
        else
        {
                return 2;
        }

来看看上面的函数返回后的处理逻辑

parse_result = at_mode_command_parser(&at_cmd_struct, USB_read_buffer, &at_command_type, &index);

///at_cmd_struct->cmd_index+1总字数比电脑端读取的命令长度长,即异常情况
          if(parse_result == 1)
          {
              LOGD(TAG "The format of at command is illegal!\n");
          }
          else if(parse_result == 2)///其他情况的返回值为2,写入找不到module给工具pc端
          {
              LOGD(TAG "Cannot find the module!\n");
              strcpy(result, "Cannot find the module!\r\n");
              write_data_to_pc(result, strlen(result));
          }
       /// at_cmd_struct->cmd_index+1为等号且下一个字符为0,再下一个为结束符'\r'或者'\n'时会返回相应的属性值给到上面处理,
       /// 即at+****=1打开at+***=0关闭,正常情况启动相应item
           else if(parse_result == 0)
          {
                LOGD(TAG "cmd index =%d, cmd_type = %d, test_type =%d\n", at_cmd_struct.index, at_cmd_struct.cmd_type, at_cmd_struct.test_type);
                at_mode_cmd_hdlr[at_cmd_struct.index].fun(&at_cmd_struct, result);
                LOGD(TAG "After callback");
          }

看看item启动后的处理,截取一段,可以看到item是根据test_type来判断相应的打开关闭处理流程的

static char* at_mode_audio_test(at_cmd *test_item_struct, char* result)
{
    if(test_item_struct->cmd_type == 1)
    {
        strcpy(result, "receive CMD OK!\r\n");
        write_data_to_pc(result, strlen(result));

LOGD(TAG "at_mode_cmd_hdlr[%d].item_id = %d\n", test_item_struct->index, at_mode_cmd_hdlr[test_item_struct->index].item_id);
       switch(at_mode_cmd_hdlr[test_item_struct->index].item_id)
            {

case ITEM_ATMODE_VIBRATOR:
                if(test_item_struct->test_type == 0)
                {        
                    LOGD(TAG "VIBRATOR OFF \n");

at_mode_vibrator(0);
                    strcpy(result, "VIBRATOR OFF\r\n");
                    write_data_to_pc(result, strlen(result));
                }
                else
                {
                    LOGD(TAG "VIBRATOR ON \n");
                    at_mode_vibrator(1);
                    strcpy(result, "VIBRATOR ON\r\n");
                    write_data_to_pc(result, strlen(result));
               }
                break;

}

}

}

故ATA命令的修改还是仅改pc_item一个就可以了,不要改动到其他的数组

各有各的处理流程,再没有明晰其做何用时,还是慎重修改

工厂端的每个工具基本都会有AT命令的处理

代码逻辑都是出于关机工模下的,此处AT命令的修改是比较牵一发而动全身的

修改方案:

其他两个数组的AT+VIBRATOR=1,2还是改回AT+VIBRATOR维持原有逻辑即可
以上为我目前暂时的逻辑分析,如有错之处,还望大家帮忙纠错,共同进步
个人经验建议:
针对工具升级的命令修改,还是增加一项item不要修改旧的item命令,做到兼容旧版工具
以备工厂测试工具命令未更新导致的问题

ATA工厂测试AT_MODE下震动不振问题分析相关推荐

  1. mtk平台at_mode模式下震动不振原因分析

    factory.cpp的main函数下             #if 1                                 if(is_pc_control(usb_com_port) ...

  2. 单片机晶振异常分析于测试

    单片机晶振异常分析于测试 最近在一个项目当中使用的是STM32F407的芯片,晶振是使用的25M,当单板拿回来后简单的测量了电源参数,正常后给到软件工程师烧录程序,在烧录的过程中出现了关于晶振的问题, ...

  3. Linux下gcov和lcov代码覆盖率分析(C/C++覆盖率在NGINX测试中的应用)

    Linux下gcov和lcov代码覆盖率分析方法 gcov是Linux下GCC自带的一个C/C++代码覆盖率分析工具 使用方法:在gcc或者g++后面添加参数 -fprofile-arcs -ftes ...

  4. 测试环境下将centos6.8升级到centos7的操作记录(转)

    在测试环境下安装openstack,由于在centos6下安装openstack,针对源的问题有很多,安装起来很不顺利! 但是在centos7下安装却很顺利,所以考虑将服务器由centos6升级到ce ...

  5. 测试Cgroup下的FROZEN(冻住)/THAWED(解冻)对wait_event_interruptible()的影响

    测试Cgroup下的FROZEN/THAWED对wait_event_interruptible的影响 一.带有等待队列的字符设备驱动(testdrv.c) 二.应用程序(test.c) 三.FROZ ...

  6. 叶罗丽颜值测试软件齐娜多少分,叶罗丽:颜值测试考验下的男仙子,颜爵颜值爆表,水王子才90分...

    导语:精彩新番不用急,最新消息说给你,欢迎来到好看好玩的动漫世界,这里有最新的动漫资讯,最好看的漫画新番,让你一次看个够,经典怀旧<七龙珠>孙悟空最强状态到底如何?各个版本你最喜欢那一块的 ...

  7. 单片机不起振原因分析(转)

    1.单片机晶振不起振原因分析 遇到单片机晶振不起振是常见现象,那么引起晶振不起振的原因有哪些呢? (1) PCB板布线错误: (2) 单片机质量有问题: (3) 晶振质量有问题: (4) 负载电容或匹 ...

  8. Windows2000下Api函数的拦截分析

    Windows2000下Api函数的拦截分析 来源:网络 作者: 查看:[大字体 中字体 小字体] 编辑:napl 简介: Api拦截并不是一个新的技术,很多商业软件都采用这种技术.对windows的 ...

  9. 测试工程师必会能力之缺陷分析入门

    缺陷分析也是测试工程师需要掌握的一个能力,但是很多时候大家只记得要提交缺陷.统计缺陷情况,而忽视了缺陷分析. 其实每个项目的缺陷记录都是有很大价值的: 在测试阶段分析当前缺陷情况,及时发现存在的问题并 ...

最新文章

  1. 怎么从华为nova4导入计算机,手机知识:华为nova4怎么导出联系人
  2. 通俗易懂地解释遗传算法?有什么例子?
  3. Lunar New Year and a Wander
  4. 随机样本一致性:一种用于图像分析和自动制图的模型拟合模型(3)--(P3P的迭代解)
  5. 如何快速验证电子邮件地址?
  6. Tomcat 映射虚拟目录
  7. 2021年SWPUACM暑假集训day3最小生成树算法
  8. 使用tcpdump找出PP用户
  9. 杰理之RX传导杂散【篇】
  10. unzip unbuntu 中文乱码
  11. Mac电脑打开app,提示无法验证此App不包含恶意软件解决方法
  12. 【渲染管线】关于透明度混合blend
  13. group by 和where可以一起使用吗
  14. 基于STM32F103单片机的智能温室大棚RS485通信温湿度监测
  15. QT字符文字转换语音播放
  16. phpstudy_pro启动mysql后循环停止又重启
  17. Hadoop自定义排序实现topN
  18. 全国天气查询、空气质量查询数据接口
  19. PHP基础之一揽子方案
  20. linux自动拨号脚本,arm中实现pppd连接GPRS上网的相关笔记,含GPRS自动拨号脚本(真正的实时监控,断线自动重拨)...

热门文章

  1. UI组件介绍(for设计师)
  2. 【计算机图形学】期末大作业_虚拟场景建模
  3. sql数据库包含关系查询
  4. OS性能监控及优化——osw工具详解
  5. 机器学习和人工智能的关系
  6. 《大明王朝》赵贞吉的拉扯
  7. 一个自动生成评论的小工具
  8. CSV文件乱码问题解决
  9. 大型语言模型的推理演算
  10. labelImg打标签教程