ATA工厂测试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维持原有逻辑即可
以上为我目前暂时的逻辑分析,如有错之处,还望大家帮忙纠错,共同进步
个人经验建议:
针对工具升级的命令修改,还是增加一项item不要修改旧的item命令,做到兼容旧版工具
以备工厂测试工具命令未更新导致的问题
ATA工厂测试AT_MODE下震动不振问题分析相关推荐
- mtk平台at_mode模式下震动不振原因分析
factory.cpp的main函数下 #if 1 if(is_pc_control(usb_com_port) ...
- 单片机晶振异常分析于测试
单片机晶振异常分析于测试 最近在一个项目当中使用的是STM32F407的芯片,晶振是使用的25M,当单板拿回来后简单的测量了电源参数,正常后给到软件工程师烧录程序,在烧录的过程中出现了关于晶振的问题, ...
- Linux下gcov和lcov代码覆盖率分析(C/C++覆盖率在NGINX测试中的应用)
Linux下gcov和lcov代码覆盖率分析方法 gcov是Linux下GCC自带的一个C/C++代码覆盖率分析工具 使用方法:在gcc或者g++后面添加参数 -fprofile-arcs -ftes ...
- 测试环境下将centos6.8升级到centos7的操作记录(转)
在测试环境下安装openstack,由于在centos6下安装openstack,针对源的问题有很多,安装起来很不顺利! 但是在centos7下安装却很顺利,所以考虑将服务器由centos6升级到ce ...
- 测试Cgroup下的FROZEN(冻住)/THAWED(解冻)对wait_event_interruptible()的影响
测试Cgroup下的FROZEN/THAWED对wait_event_interruptible的影响 一.带有等待队列的字符设备驱动(testdrv.c) 二.应用程序(test.c) 三.FROZ ...
- 叶罗丽颜值测试软件齐娜多少分,叶罗丽:颜值测试考验下的男仙子,颜爵颜值爆表,水王子才90分...
导语:精彩新番不用急,最新消息说给你,欢迎来到好看好玩的动漫世界,这里有最新的动漫资讯,最好看的漫画新番,让你一次看个够,经典怀旧<七龙珠>孙悟空最强状态到底如何?各个版本你最喜欢那一块的 ...
- 单片机不起振原因分析(转)
1.单片机晶振不起振原因分析 遇到单片机晶振不起振是常见现象,那么引起晶振不起振的原因有哪些呢? (1) PCB板布线错误: (2) 单片机质量有问题: (3) 晶振质量有问题: (4) 负载电容或匹 ...
- Windows2000下Api函数的拦截分析
Windows2000下Api函数的拦截分析 来源:网络 作者: 查看:[大字体 中字体 小字体] 编辑:napl 简介: Api拦截并不是一个新的技术,很多商业软件都采用这种技术.对windows的 ...
- 测试工程师必会能力之缺陷分析入门
缺陷分析也是测试工程师需要掌握的一个能力,但是很多时候大家只记得要提交缺陷.统计缺陷情况,而忽视了缺陷分析. 其实每个项目的缺陷记录都是有很大价值的: 在测试阶段分析当前缺陷情况,及时发现存在的问题并 ...
最新文章
- 怎么从华为nova4导入计算机,手机知识:华为nova4怎么导出联系人
- 通俗易懂地解释遗传算法?有什么例子?
- Lunar New Year and a Wander
- 随机样本一致性:一种用于图像分析和自动制图的模型拟合模型(3)--(P3P的迭代解)
- 如何快速验证电子邮件地址?
- Tomcat 映射虚拟目录
- 2021年SWPUACM暑假集训day3最小生成树算法
- 使用tcpdump找出PP用户
- 杰理之RX传导杂散【篇】
- unzip unbuntu 中文乱码
- Mac电脑打开app,提示无法验证此App不包含恶意软件解决方法
- 【渲染管线】关于透明度混合blend
- group by 和where可以一起使用吗
- 基于STM32F103单片机的智能温室大棚RS485通信温湿度监测
- QT字符文字转换语音播放
- phpstudy_pro启动mysql后循环停止又重启
- Hadoop自定义排序实现topN
- 全国天气查询、空气质量查询数据接口
- PHP基础之一揽子方案
- linux自动拨号脚本,arm中实现pppd连接GPRS上网的相关笔记,含GPRS自动拨号脚本(真正的实时监控,断线自动重拨)...