mtk平台at_mode模式下震动不振原因分析
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模式下震动不振原因分析相关推荐
- 【Ethercat CSP控制模式下电机卡顿原因分析及解决方法】
Ethercat CSP控制模式下电机卡顿原因分析及解决方法 ethercat总线经过近十年的发展,逐渐成为国际上最广泛应用的实时以太网总线之一.国外商业化的ethercat主站价格昂贵,国内尚未有全 ...
- ATA工厂测试AT_MODE下震动不振问题分析
factory.cpp的main函数下 #if 1 if(is_pc_control(usb_com_port) ...
- 微信三方开发平台开发模式下被动回复用户消息
微信三方开发平台开发模式下被动回复用户消息视频
- java上传ddi_Android平台dalvik模式下java Hook框架ddi的分析(2)--dex文件的注入和调用...
前面的博客<Android平台dalvik模式下java Hook框架 ddi 的分析(1)>中,已经分析了dalvik模式下 ddi 框架Hook java方法的原理和流程,这里来学习一 ...
- Android平台dalvik模式下java Hook框架ddi的分析(2)--dex文件的注入和调用
本文博客地址:http://blog.csdn.net/qq1084283172/article/details/77942585 前面的博客<Android平台dalvik模式下java Ho ...
- 单片机不起振原因分析(转)
1.单片机晶振不起振原因分析 遇到单片机晶振不起振是常见现象,那么引起晶振不起振的原因有哪些呢? (1) PCB板布线错误: (2) 单片机质量有问题: (3) 晶振质量有问题: (4) 负载电容或匹 ...
- Android平台dalvik模式下java Hook框架ddi的分析(1)
本文博客地址:http://blog.csdn.net/qq1084283172/article/details/75710411 一.前 言 在前面的博客中已经学习了作者crmulliner编写的, ...
- 高通平台user模式下串口输入及使用QFIL在线烧录的问题解决
一般产品发布都是使用的user版本,但是在user版本的时候,我们有时候又需要通过串口敲一些命令查看一些状态.默认情况下在user模式串口是有输出没有输入的,那怎么打开这个输入呢?可以通过下面的方法: ...
- 【电力电子】【2014】三相电压型逆变器在独立和并网模式下的动态建模与分析
本文为美国堪萨斯州立大学(作者:FALEH A ALSKRAN)的硕士论文,共118页. 不断增长的能源需求.不断上涨的油价和对环境的担忧,迫使人们关注环境友好.独立于化石燃料的替代能源.可再生能源( ...
最新文章
- IOS版添加phonegap-视频播放插件教程
- 页面中的多选框的非空判断
- 关于Windows 2019 antimalware 进程占用CPU 过多的处理方法 关闭windows 病毒防护的方法...
- 奇异的Pinvoke调用
- svg绘图工具raphael.js的使用
- Redis 6.0 源码阅读笔记(1) -- Redis 服务端启动及命令执行
- 随机生成一串字符串(java)
- 大话数据结构PDF/word
- 在window10中怎样连接扫描仪,扫描证件
- DL-31/6电流继电器
- 暴力破解Windows密码(二、三):使用getpass内存提取windows用户密码、使用quarkpwdump导出windows用户密码hash值
- winsxs目录清理工具
- 手把手教您用虹科MatrikonOPC UA数据平台掌握您所有的UA服务器
- terraform 腾讯云_使用Terraform优化云成本的权威指南
- python课程论文_python结课论文_python论文_工程伦理结课论文文库
- php pdo的用法,php pdo函数库用法详解
- 9.1总结前日(数学+图论)
- 松下小型plc程序案例,plc型号为fp-xh c60t,案例中有两个plc
- QTableWidget自动调整列宽和行高
- 【传智播客】Libevent学习笔记(四):事件event
热门文章
- html 图片遮盖,html实现图片遮盖
- 德勤oracle团队,【焦点】德勤管理咨询荣膺甲骨文中国FY19年度最佳PeopleSoft实施伙伴...
- 中移动内部 无线信号测试软件,- 移动网无线信号质量监测系统[图]
- 基于神经网络的蒙文手写字母识别的一些研究(综述)
- C语言程序设计(一)计算机思维导论
- 笔记整理nodeJS
- 遥感影像叠加在谷歌地球(Google earth)上
- 短视频运营创作方案教程
- 数据工厂---DataFactory+MySQL数据构造
- 有信用就有明天!区块链+供应链金融助力企业融资的5种方式