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维持原有逻辑即可

以上为我目前暂时的逻辑分析,如有错之处,还望大家帮忙纠错,共同进步

mtk平台at_mode模式下震动不振原因分析相关推荐

  1. 【Ethercat CSP控制模式下电机卡顿原因分析及解决方法】

    Ethercat CSP控制模式下电机卡顿原因分析及解决方法 ethercat总线经过近十年的发展,逐渐成为国际上最广泛应用的实时以太网总线之一.国外商业化的ethercat主站价格昂贵,国内尚未有全 ...

  2. ATA工厂测试AT_MODE下震动不振问题分析

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

  3. 微信三方开发平台开发模式下被动回复用户消息

    微信三方开发平台开发模式下被动回复用户消息视频

  4. java上传ddi_Android平台dalvik模式下java Hook框架ddi的分析(2)--dex文件的注入和调用...

    前面的博客<Android平台dalvik模式下java Hook框架 ddi 的分析(1)>中,已经分析了dalvik模式下 ddi 框架Hook java方法的原理和流程,这里来学习一 ...

  5. Android平台dalvik模式下java Hook框架ddi的分析(2)--dex文件的注入和调用

    本文博客地址:http://blog.csdn.net/qq1084283172/article/details/77942585 前面的博客<Android平台dalvik模式下java Ho ...

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

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

  7. Android平台dalvik模式下java Hook框架ddi的分析(1)

    本文博客地址:http://blog.csdn.net/qq1084283172/article/details/75710411 一.前 言 在前面的博客中已经学习了作者crmulliner编写的, ...

  8. 高通平台user模式下串口输入及使用QFIL在线烧录的问题解决

    一般产品发布都是使用的user版本,但是在user版本的时候,我们有时候又需要通过串口敲一些命令查看一些状态.默认情况下在user模式串口是有输出没有输入的,那怎么打开这个输入呢?可以通过下面的方法: ...

  9. 【电力电子】【2014】三相电压型逆变器在独立和并网模式下的动态建模与分析

    本文为美国堪萨斯州立大学(作者:FALEH A ALSKRAN)的硕士论文,共118页. 不断增长的能源需求.不断上涨的油价和对环境的担忧,迫使人们关注环境友好.独立于化石燃料的替代能源.可再生能源( ...

最新文章

  1. IOS版添加phonegap-视频播放插件教程
  2. 页面中的多选框的非空判断
  3. 关于Windows 2019 antimalware 进程占用CPU 过多的处理方法 关闭windows 病毒防护的方法...
  4. 奇异的Pinvoke调用
  5. svg绘图工具raphael.js的使用
  6. Redis 6.0 源码阅读笔记(1) -- Redis 服务端启动及命令执行
  7. 随机生成一串字符串(java)
  8. 大话数据结构PDF/word
  9. 在window10中怎样连接扫描仪,扫描证件
  10. DL-31/6电流继电器
  11. 暴力破解Windows密码(二、三):使用getpass内存提取windows用户密码、使用quarkpwdump导出windows用户密码hash值
  12. winsxs目录清理工具
  13. 手把手教您用虹科MatrikonOPC UA数据平台掌握您所有的UA服务器
  14. terraform 腾讯云_使用Terraform优化云成本的权威指南
  15. python课程论文_python结课论文_python论文_工程伦理结课论文文库
  16. php pdo的用法,php pdo函数库用法详解
  17. 9.1总结前日(数学+图论)
  18. 松下小型plc程序案例,plc型号为fp-xh c60t,案例中有两个plc
  19. QTableWidget自动调整列宽和行高
  20. 【传智播客】Libevent学习笔记(四):事件event

热门文章

  1. html 图片遮盖,html实现图片遮盖
  2. 德勤oracle团队,【焦点】德勤管理咨询荣膺甲骨文中国FY19年度最佳PeopleSoft实施伙伴...
  3. 中移动内部 无线信号测试软件,- 移动网无线信号质量监测系统[图]
  4. 基于神经网络的蒙文手写字母识别的一些研究(综述)
  5. C语言程序设计(一)计算机思维导论
  6. 笔记整理nodeJS
  7. 遥感影像叠加在谷歌地球(Google earth)上
  8. 短视频运营创作方案教程
  9. 数据工厂---DataFactory+MySQL数据构造
  10. 有信用就有明天!区块链+供应链金融助力企业融资的5种方式