分享一个刚毕业的时候写的一个量产测试工具吧,采用的是C语言来编写,刚开始应用在Linux和Android平台上,后面通过移植也用在单片机上,使用起来非常简单,让我们来看看怎么回事。
一、主程序源码分析
int main(void) { s32 i ; //初始化测试系统 INIT_TEST_SYSTEM(); //定义头指针,初始化头节点 INIT_WORK(work_node); for(i = ZERO ; i < NR(work_Register) ; i++) { //实现工作任务的注册 REGISTER_WORK(work_node , create_cwork(work_Register[i].work_num ,work_Register[i].work_name , work_Register[i].work_handler)); } //调度工作任务,编号从小到大排序 SCHEDULING_WORK(work_node,Positive,NR(work_Register)); while(True) { ; } DESTROY_WORK(work_node,work_Register); return SUCCESS ; }
这段程序的核心框架由四部分组成:
- INIT_WORK
- REGISTER_WORK
- SCHEDULING_WORK
- DESTROY_WORK
如果你不去追,你可能以为这是四个定义好的函数,别被它的表面欺骗了,其实它们是宏,宏的下面一级才是函数的实现:
#define __INIT_WORK(_work) \ do{ \ _work =Init_cwork(_work); \ }while(0) #define INIT_WORK(work_node) \ _work work_node = NULL ; \ __INIT_WORK(work_node); #define REGISTER_WORK(__work,new_work) \ Register_work_fuc(__work,new_work); #define SCHEDULING_WORK(work_node,direction,array_size) \ Run_Priority_work(work_node,direction,array_size); #define DESTROY_WORK(work_node,array) \ work_node =Destroy_work(work_node ,array);
各个子函数的实现:
//初始化一个子任务 _work Init_cwork(); //创建一个子任务 _work create_cwork(s32 work_num,pchar work_name ,work_fun work_fuc); //注册子任务 No_returnRegister_work_fuc(_work __work,_work new_work); //查找子任务的编号 s32 Find_Work_Num(_work headler,s32 work_num); //查找子任务的名称 pchar Find_Work_Name(_work headler,pchar work_name); //执行子任务----根据任务名称来执行 s32 Run_work_for_work_name(_work headler,pchar work_name); //销毁一个子任务 s32 Destroy_cwork(_work headler,pchar work_name); //销毁全部任务 _work Destroy_work(_work headler,_work array); //工作优先级调度执行--->工作编号小的优先级高,依次类推 s32 Run_Priority_work(_work handler,s32 direction,const s32 work_array_size);
通过宏调用各个子函数完成任务的初始化,注册、执行、销毁,这个过程是由一个链表来实现的:
typedefstruct __Work { //任务编号 //根据任务编号决定工作任务的优先级 //编号越小,优先级越高 s32 work_num ; //任务名称 pchar work_name ; //根据相应的任务名称,处理相应的任务 void(*work_handler)(int); struct __Work *next; }work; typedef work * _work ;
由于这是一个集成测试工具,所以存在着任务的并行执行,所以当执行一个任务的时候其实就创建了一条线程,这个过程是在Run_Priority_work里实现的。
s32 Run_Priority_work(_work handler,s32 direction,const s32 work_array_size) { s32 count = 0 ; s32 i ; assert(handler != NULL); _work temp = handler->next ; s32 Curent_node_Array[work_array_size]; while(temp != NULL){ Curent_node_Array[count] = temp->work_num ; temp = temp->next ; if(count < work_array_size) count++ ; } Sort_work_num(Curent_node_Array,NR(Curent_node_Array),direction) ; for(i = 0 ; i < NR(Curent_node_Array) ; i++) Run_work_for_work_num(handler,Curent_node_Array[i]); return SUCCESS ; }
核心的部分也就这些了,接下来讲讲怎么用吧。
二、使用MTTEST实现并行测试项
main.c的代码一句都不用动,如果你要添加一个并行的测试项目,只需要在结构体数组里声明好,定义好测试任务函数就可以了,具体使用方法如下:
//按键测试 intTpad_Key_Test(int work_num); //Gsensor测试 intTpad_Gsensor_Test(int work_num); //时钟测试 int RTC_Test(int work_num); //电池电量测试 intBattery_Capacity_Test(int work_num); //电池状态测试 intBattery_Status_Test(int work_num); //内存测试 int DDR_Test(int work_num); //EMMC测试 int EMMC_Test(int work_num); //SD卡测试 int SD_Test(int work_num); //WIFI MAC地址读取测试 int NVRAM_WIFI_MAC_ADDRESS_READ_TEST(int work_num); //WIFI ssid获取测试 int WIFI_SSID_Test(int work_num); //LCD RGB测试 int LCD_Test(int work_num); //初始化测试系统 int INIT_TEST_SYSTEM(); //Camera旋转按键测试 int camera_rotate_test(int work_num); //结构体数组描述: /* ep: {1,"LCD_Test",LCD_Test}, 1表示任务编号,同时也表示在LCD的哪一行进行显示 "LCD_Test"表示任务名称 LCD_Test表示任务执行函数 */ work work_Register[]= { {1,"Tpad_Key_Test",Tpad_Key_Test}, {2,"Tpad_Gsensor_Test",Tpad_Gsensor_Test}, {3,"RTC_Test",RTC_Test}, {4,"Battery_Capacity_Test",Battery_Capacity_Test}, {5,"Battery_Status_Test",Battery_Status_Test}, {6,"DDR_Test",DDR_Test}, {7,"EMMC_Test",EMMC_Test}, {8,"SD_Test",SD_Test}, {9,"NVRAM_WIFI_MAC_ADDRESS_READ_TEST",NVRAM_WIFI_MAC_ADDRESS_READ_TEST}, {10,"WIFI_SSID_Test",WIFI_SSID_Test}, #ifndef __PLAN_A {11,"camera_rotate_test",camera_rotate_test}, #endif {12,"LCD_Test",LCD_Test}, };
预知详情,请详细看看我分享的项目代码,注释很详细。
三、分享链接
链接:https://pan.baidu.com/s/1rPjS2r1-JgmzhF1nFhc0Kg 提取码:dlv3