TPファームウェアアップグレード、ジェスチャー認識、短絡テストプロセス分析

15468 ワード

一.TPファームウェアアップグレード


 
TPファームウェアのアップグレード方式は自動アップグレード方式を採用し、自動アップグレードは二つに分けられる.
 
1.request_firmware()ユーザースペース取得ファームウェア
2.BINファイルの検索方法、例えば/data/goodix_update_.bin
または/sdcard/goodix_update_.bin.
 

TPファームウェアアップグレードプロセス:


1.駆動初期化はkthread_を呼び出すrun()カーネルでスレッドを作成して起動しgt 1 x_auto_update_proc()メソッド、ここでdata=NULL
static int gt1x_ts_probe(struct i2c_client *client, const struct i2c_device_id *id){

GTP_INFO("GTP Driver Version: %s,slave addr:%02xh",GTP_DRIVER_VERSION,
 client->addr);

#ifdef CONFIG_GTP_AUTO_UPDATE
    do {
        struct task_struct *thread = NULL;
        thread = kthread_run(gt1x_auto_update_proc,
                             (void *)NULL,
                            "gt1x_auto_update");
        if(IS_ERR(thread))
           GTP_ERROR("Failed to create auto-update thread: %d.", ret);
    } while(0);
#endif

}

2.gt 1 x_の実行auto_update_proc()メソッドの場合、data=nullでgt 1 x_を実行しますupdate_firmware(NULL); 0を返します.実行を停止する
int gt1x_auto_update_proc(void *data)
{
    int ret;
    char *filename;
    u8 config[GTP_CONFIG_ORG_LENGTH + GTP_CONFIG_EXT_LENGTH] = { 0 };

    if(data == NULL) {
        GTP_INFO("Start auto update thread from request...");
        gt1x_update_firmware(NULL);
        return 0;
    }
// 
    GTP_INFO("Start auto update thread from file...");
    ret = gt1x_search_update_files();
   if(ret & (FOUND_FW_PATH_1 | FOUND_FW_PATH_2)) {
       if(ret & FOUND_FW_PATH_1) {
            filename = UPDATE_FILE_PATH_1;
        }
        gt1x_update_firmware(filename);

3.//実行gt 1 x_update_firmware(filename)の場合、次の方法gt 1 x_が実行されます.enter_update_mode();ファームウェアアップグレードモードに入る
           gt1x_update_prepare(filename);ファームウェアアップグレード準備gt 1 x_check_firmware();ファームウェアの確認gt 1 x_update_judge();ダウンロードの決定
int gt1x_update_firmware(void *filename)

{
    update_info.status = UPDATE_STATUS_RUNNING;
    update_info.progress = 0;
    gt1x_enter_update_mode();
    ret = gt1x_update_prepare(filename);
    ret = gt1x_check_firmware();
   ............        
    }

request_を呼び出すfirmware(&update_info.fw,GT1X_FW_NAME, >1x_i2c_client->dev)
ユーザースペースからのファームウェアの取得
int gt1x_update_prepare(char *filename)
{
    int ret = 0;
    int retry = 5;

    if(filename == NULL) {
        update_info.fw_name = NULL;
        update_info.fw = NULL;
        ret = request_firmware(&update_info.fw, GT1X_FW_NAME, &gt1x_i2c_client->dev);
        if(ret data;
        update_info.fw_length = update_info.fw->size;
    } else {
        GTP_INFO("Firmware: %s", filename);
        update_info.old_fs = get_fs();
        set_fs(KERNEL_DS); // KERNEL_DS, 
        update_info.fw_name = filename;
        update_info.update_type = UPDATE_TYPE_FILE;

 

二.ジェスチャー認識フロー解析


原理:Gestureモードの下で、ICは指がスクリーンで十分な長さスライドすることを検出して、動作をダブルクリックして、文字をカスタマイズして、中断して発生した後に相応の事件を報告します.
次に、ジェスチャーが定義と方法を起動します.
#ifdef CONFIG_GTP_GESTURE_WAKEUP
extern DOZE_T gesture_doze_status; // 
extern int gesture_enabled; 
extern void gt1x_gesture_debug(int on) ;
// 
extern s32 gesture_event_handler(struct input_dev *dev);
//  
extern s32 gesture_enter_doze(void); 
extern void gesture_clear_wakeup_data(void);
#endif
#define KEY_GES_REGULAR       KEY_F2    // regular gesture-key
#define KEY_GES_CUSTOM        KEY_F3    //customize gesture-key

二.次はジェスチャー起動プロセスです。


 //1.割り込み申請が成功すると割り込み関数gt 1 x_が実行されるts_irq_handler() 
スレッド割り込みコンテキストで呼び出された関数gt 1 x_ts_work_thread()
注意:Linuxでは、割り込みが最も優先されます.いつでも、割り込みイベントが発生すると、カーネルは直ちに対応する割り込み処理プログラムを実行し、すべての保留中の割り込みとソフト割り込み処理が完了するまで正常なタスクを実行できないため、リアルタイムタスクがタイムリーな処理を受けられない可能性があります.割り込みスレッド化後、割り込みはカーネルスレッドとして実行され、異なるリアルタイム優先度が与えられ、リアルタイムタスクは割り込みスレッドよりも高い優先度を有することができる.これにより、最も優先度の高いリアルタイムタスクが優先され、重大な負荷下でもリアルタイム性が保証されます.しかし、すべての割り込みがスレッド化できるわけではありません.例えば、クロック割り込みは、主にシステム時間やタイマを維持するために使用されます.ここで、タイマはオペレーティングシステムの脈拍であり、スレッド化されると、一時停止される可能性があります.このような結果は想像にたえないので、スレッド化されるべきではありません.   
static s32 gt1x_request_irq(void)
{
    s32 ret = -1;
    const u8 irq_table[] = GTP_IRQ_TAB;
    GTP_DEBUG("INT trigger type:%x", gt1x_int_type);
    ret = devm_request_threaded_irq(&gt1x_i2c_client->dev,
                                    gt1x_i2c_client->irq,
                                    gt1x_ts_irq_handler,
                                    gt1x_ts_work_thread,
                                    irq_table[gt1x_int_type],
                                    gt1x_i2c_client->name,
                                    gt1x_i2c_client);
    if(ret) {
        GTP_ERROR("Request IRQ failed!ERRNO:%d.", ret);
        return -1;
    } else {
        gt1x_irq_disable();
        return 0;
    }
}

//2.gt 1 x_の実行ts_work_thread()後にジェスチャー実行関数gesture_が実行されますevent_handler(input_dev);
static irqreturn_t gt1x_ts_work_thread(int irq, void *data)
{
    u8 point_data[11] = { 0 };
    u8 end_cmd = 0;
    u8 finger = 0;
    u8 fod_flag = 0; //add by liuyang3.wt
    s32 ret = 0;

    if(update_info.status) {
        GTP_DEBUG("Ignore interrupts during fw update.");
        return IRQ_HANDLED;
    }

#ifdef CONFIG_GTP_GESTURE_WAKEUP
    ret = gesture_event_handler(input_dev);
    if(ret >= 0)
        goto exit_work_func;
#endif

}

//3.gesture_event_handler(input_dev)関数:ジェスチャーデータ、タイプ、およびエスカレーションイベントの取得
s32 gesture_event_handler(struct input_dev * dev)
{
    u8 doze_buf[4] = { 0 }, ges_type;
    static int err_flag1 = 0, err_flag2 = 0;
    int len, extra_len, need_chk;
    unsigned int key_code = 0;
    s32 ret = 0;

    if(DOZE_ENABLED != gesture_doze_status) {
        return -1;
    }
..........

 


三.短絡テストフローを開く


 

3.1短絡試験方式:


デバイステスト時にすべての信号ピンがテストシステムに対応するチャネルと電気的に接続され、信号ピンが他の信号ピンと接続されていないことを確認します.
電源または地にショートが発生.
 

3.2短絡テストのメリット


 
1.チップの各ピン間に短絡があるかどうかを素早く発見する
2.DUTにピン短絡、bond wire欠損、ピンの静電損傷、製造欠陥などの電気的物理的欠陥があるかどうかを検出する
3.試験時の接触が良好であるか、プローブカードまたは試験台に問題がないかを発見することもできる.
 

3.3短絡テストプロセスを開く


//1.  gt1x_ts_probe()=>駆動初期化後gtp_test_sysfs_init();
static int gt1x_ts_probe(struct i2c_client *client, const struct i2c_device_id *id)
{

//Add for openshort test;
    gtp_test_sysfs_init();
    mz_appid_init();
   mz_gesture_init();
    return 0;

}

//==>2.gtp_test_sysfs_Init()の主な操作:
kobject_create_and_addはkobject構造を動的に作成しsysfsに登録する
たとえば、ディレクトリ・アイテム(/sys/kernel/gt 1 x_test):関数
kobject_create_and_add(「gt 1 x_test」,NULL)は、/sys/kernelの下にhelloworldディレクトリ項目を作成できます.
sysfs_create_fileプロパティファイル(dev_attr_openshort.attr)関数sysfs_create_file(gt 1 x_debug_kobj,&dev_attr_openshort.attr)が確立されます.
これにより、ファイルと操作とのつながりと対応も同時に確立されます.
s32 gtp_test_sysfs_init(void)
{
    gt1x_debug_kobj = kobject_create_and_add("gt1x_test", NULL);
    if(gt1x_debug_kobj == NULL) {
        GTP_ERROR("%s: subsystem_register failed
", __func__);         return -ENOMEM;     }     ret = sysfs_create_file(gt1x_debug_kobj, &dev_attr_openshort.attr);     if(ret) {         GTP_ERROR("%s: sysfs_create_openshort_file failed
", __func__);         return ret;}     }     DEBUG("GT1X debug sysfs create successwtfadd
");     GTP_INFO("GT1X debug sysfs create success!
"); .....

//3. DEVICE_ATTR()関数トリガ条件
DEVICE_の使用ATTRは、sysディレクトリで自動的にファイルを作成する駆動を実現することができ、showとstore関数を実現するだけでよい.その後、アプリケーション層ではcatとechoコマンドによりsysが作成するファイルを読み書き駆動装置としてインタラクションを実現することができる.
注意:
catコマンドを使用すると、関数gtp_が呼び出されます.sysfs_openshort_show();
echoコマンドを使用するとgtp_が呼び出されますsysfs_openshort_store関数
 
static DEVICE_ATTR(openshort, 0664, gtp_sysfs_openshort_show, gtp_sysfs_openshort_store);

//4.catコマンドを使用すると、関数gtp_が呼び出されます.sysfs_openshort_show();=>init_が実行されます.chip_type()とopen_short_test(result)操作
static ssize_t gtp_sysfs_openshort_show(struct device *dev, struct device_attribute *attr,
 char *buff)
{
    unsigned char *result;
ssize_t i, len = 0, ret;

    init_chip_type();
//  malloc(300)  300 ,
    result = (unsigned char *)malloc(300);
    //+Bug436464,liuyang3.wt,ADD,20190402,Coverity Test CID70911
    if(!result)
        return -ENOMEM;
    //-Bug436464,liuyang3.wt,ADD,20190402,Coverity Test CID70911
// 
    ret = open_short_test(result);

    if(ret 

//5.init_chip_type()とopen_short_test(result)操作
int init_chip_type(void)
{
//u8 unsigned char,u16 unsigned short,u32 unsigned long。
u8 *largebuf;
// 2048
    largebuf = (unsigned char *)malloc(2 * 1024);
    if(largebuf == NULL) {
        return MEMORY_ERR;
    }

    sys.reg_rawdata_base = 0xb53c;//           //0xB798;
    sys.key_offest = 83;
    sys.config_length = 239;
    sys.max_sensor_num = 32;
    sys.max_driver_num = 32;
sys.short_head = 4;

// :extern int strcmp(char *str1,char * str2,int n)  str1 str2 n 。
//(!strncmp((const char *)gt1x_version.product_id, "1143", 4)  //gt1x_version.product_id  4 , 1143, sys.chip_type = _GT1143

    if(!strncmp((const char *)gt1x_version.product_id, "1143", 4)) {
        sys.chip_type = _GT1143;
    } else
        if(!strncmp((const char *)gt1x_version.product_id, "1133", 4)) {
            sys.chip_type = _GT1133;
       } else
            if(!strncmp((const char *)gt1x_version.product_id, "1151", 4)) {
                sys.chip_type = _GT1151;
            } else {
                sys.chip_type = _GT9P;
            }
    read_config(largebuf, sys.config_length);
    free(largebuf);
    DEBUG("sen*drv:%d*%d", sys.sensor_num, sys.driver_num);
    return 1;
}

//6.ここで開短絡テストの実行を開始しますopen_short_test(result)  :
そしてopen_short_test()操作が実行されます.
_init_test_paramters(ini_path):テストパラメータを取得_check_short_circuit(test_types, short_result): _check_other_options(test_types):DeviceVersion or ModuleType test結果を含むcheck_rawdata_proc() _save_test_result_data(save_path,test_types,short_result):テスト結果を格納
s32 open_short_test(unsigned char *short_result_data)
{
    int ret = -1, test_types;
    char times = 0, timeouts = 0, check_cfg = 0;
    u16 *rawdata;
    u8 *largebuf, *short_result;
char *ini_path, *save_path;

// 
largebuf = (unsigned char *)malloc(600 + sys.max_sensor_num * sys.max_driver_num * 2);

   //largebuf = (unsigned char *)kmalloc(600 + sys.max_sensor_num * sys.max_driver_num * 2,GFP_KERNEL);

    if(largebuf == NULL) {
        return MEMORY_ERR;
    }
TEST_START:
// 
    memset(largebuf, 0, 600 + sys.max_sensor_num * sys.max_driver_num * 2);
    
ini_path = (char *)(&largebuf[0]);
    short_result = (u8 *)(&largebuf[250]);
    save_path = (char *)(&largebuf[350]);
    rawdata = (u16 *)(&largebuf[600]);
    DEBUG("sen*drv:%d*%d", sys.sensor_num, sys.driver_num);

#if GTP_TEST_PARAMS_FROM_INI

if(auto_find_ini(ini_find_dir1, ini_format, ini_path) < 0) {

        if(auto_find_ini(ini_find_dir2, ini_format, ini_path) < 0) {

            WARNING("Not find the ini file.");

            free(largebuf);
            return INI_FILE_ILLEGAL;
        }
    }


    DEBUG("find ini path:%s len %d", ini_path, strlen(ini_path));
#endif
    test_types = _init_test_paramters(ini_path);
    if(test_types < 0) {
        WARNING("get test params failed.");
        free(largebuf);
        return test_types;
    }
    FORMAT_PATH(save_path, save_result_dir, "test_data");
    DEBUG("save path is %s", save_path);
    memset(save_data_path, 0, sizeof(save_data_path));
    memcpy(save_data_path, save_path, (strlen(save_path) + 1));
    memset(short_result, 0, 100);

    if(test_types & _MODULE_SHORT_CHECK || ((sys.chip_type == _GT1143 || sys.chip_type == _GT1133) && test_types & _ACCORD_CHECK)) {
   
  if(disable_irq_esd() < 0) {
            WARNING("disable irq and esd fail.");
           goto TEST_END;
        }
       usleep(20 * 1000);
        if(sys.chip_type == _GT1143 || sys.chip_type == _GT1133) {
            gt900_drv_gnd_resistor_threshold = gt900_sen_gnd_resistor_threshold;
            gt900_drv_drv_resistor_threshold = gt900_sen_sen_resistor_threshold;
            gt900_drv_sen_resistor_threshold = gt900_sen_sen_resistor_threshold;
        }
        ret = _check_short_circuit(test_types, short_result);
        if(sys.chip_type != _GT1143 && sys.chip_type != _GT1133) {
            reset_guitar();
            usleep(2 * 1000);
            disable_hopping(module_cfg, sys.config_length, 0);
        }
     if(ret < 0) {
            WARNING("Short Test Fail.");
            goto TEST_END;
        }
        DEBUG("cnt %d", short_result[0]);
        if(short_result_data != NULL) {
            memcpy(short_result_data, short_result, short_result[0] * 4 + 1);
        }
        if((sys.chip_type == _GT1143 || sys.chip_type == _GT1133) && test_error_code & _GT_SHORT) {
            goto TEST_COMPLETE;
        }
    }




  ret = _check_other_options(test_types);
    if(ret < 0) {
        WARNING("DeviceVersion or ModuleType test failed.");
        goto TEST_END;
    }
    times = 0;
    timeouts = 0;
  
  if(test_types & (_MAX_CHECK | _MIN_CHECK | _ACCORD_CHECK | _OFFSET_CHECK | _JITTER_CHECK | _KEY_MAX_CHECK | _KEY_MIN_CHECK | _UNIFORMITY_CHECK)) {
   
     while(times < 5) {
            ret = read_raw_data(rawdata, sys.sensor_num * sys.driver_num);
            if(ret < 0) {
                DEBUG("read rawdata timeout %d.", timeouts);
                if(++timeouts > 5) {
                    WARNING("read rawdata timeout.");
                    break;
                }
                be_normal();
                continue;
            }

            ret = _check_rawdata_proc(test_types, rawdata, sys.sensor_num * sys.driver_num, save_path);
            if(ret < 0) {
                WARNING("raw data test proc error.");
                break;
            }
            else
                if(ret == 1) {
                    DEBUG("rawdata check finish.");
                    break;
                }
            times++;
        }
TEST_COMPLETE:
    ret = test_error_code;
#if GTP_SAVE_TEST_DATA
//  if ((check_types & _TEST_RESULT_SAVE) != 0)
    {
        _save_test_result_data(save_path, test_types, short_result);
    }

#endif





 
7.echoコマンドを使用するとgtp_が呼び出されますsysfs_openshort_store関数
static ssize_t gtp_sysfs_openshort_store(struct device *dev, struct device_attribute 
*attr, const char *buff, size_t count)
{
    DEBUG("openshort_store");
    buf = (unsigned char *)malloc(100);
    if(buf == NULL) {
        return -1;
}
//  a+   /sdcard/test.csv
    fp = fopen("/sdcard/test.csv", "a+"); 
    if(fp == NULL) {
        DEBUG("open /sdcard/test.csv fail");
        free(buf);
        return -1;
    }
        bytes += sprintf(&buf[bytes], "%d,", i);
    }

    DEBUG("%s", buf);

    fwrite(buf, bytes, 1, fp);

 
私は間違ったところを書いています.皆さんの指摘を歓迎します.
https://mp.csdn.net/postedit