基于UDS的BOOTLOADER的CANOE脚本

riables
{
    /*Panel*/
    char bootloaderWnd[100] = "BootLoader";
    
    /* Messages */
    message PEPS_Phys_Diag_Rx   msgBootHost;
    message PEPS_Diag_Tx        msgBootClient;

    /* Timers */
    mstimer timDownload;
    mstimer timTransmit;
    mstimer timMonitor;
    mstimer timFCTransmit;
    mstimer timCyclicSend;

    char g_acMsgDisplay[10000000] = "";  
    word g_wMsgDisplayLen = 0;
    const word g_wColumnLettersPerLine = 60;
    char g_acSuffix[g_wColumnLettersPerLine] = "                                                   ";
    
    const int timeslot1ms   = 1;
    const int timeslot10ms  = 10;
    const int timeslot20ms  = 20;
    const int timeslot50ms  = 50;
    const int timeslot100ms = 100;
    const int timeslot200ms = 200;
    const int timeslot500ms = 500;
    const int timeslot1s    = 1000;
    const int timeslot2s    = 2000;
    const int timeslot3s    = 20000;
    const int timeslot5s    = 5000;
    const int timeslot10s   = 10000;
    const int timeslot20s   = 20000;

    const byte TRUE     = 1;
    const byte FALSE    = 0;

    /* global variables */
    char gsBootFilePath[100];

    int g_iDownloadIsActive = FALSE;

    int g_iDownloadStartFlg = FALSE;       //供状态机查询,该标志加载S19完成后置位
    
    const int S19FILE_SCREEN  = 0;
    const int PROCESS_SCREEN = 1;

    //下载状态定义
    enum tDownloadServices{
        DOWNLOAD_IDLE = 0x00,
        DOWNLOAD_S22_TX,
        DOWNLOAD_S22_WAIT_RESP,
        DOWNLOAD_S1003_TX,
        DOWNLOAD_S1003_WAIT_RESP,
        DOWNLOAD_S85_TX,
        DOWNLOAD_S85_WAIT_RESP,
        DOWNLOAD_S28_TX,
        DOWNLOAD_S28_WAIT_RESP,
        DOWNLOAD_S1002_TX,
        DOWNLOAD_S1002_WAIT_RESP,
        DOWNLOAD_S27_SEED_TX,
        DOWNLOAD_S27_SEED_WAIT_RESP,
        DOWNLOAD_S27_KEY_TX,
        DOWNLOAD_S27_KEY_WAIT_RESP,
        DOWNLOAD_S34_TX_DRV,
        DOWNLOAD_S34_WAIT_RESP_DRV,
        DOWNLOAD_S36_TX_DRV,
        DOWNLOAD_S36_WAIT_RESP_DRV,
        DOWNLOAD_S37_TX_DRV,
        DOWNLOAD_S37_WAIT_RESP_DRV,
        DOWNLOAD_S31_START_ERASE_TX,
        DOWNLOAD_S31_START_ERASE_WAIT_RESP,
        //DOWNLOAD_S31_VERIFY_ERASE_TX,
        //DOWNLOAD_S31_VERIFY_ERASE_WAIT_RESP,
        DOWNLOAD_S34_TX,
        DOWNLOAD_S34_WAIT_RESP,
        DOWNLOAD_S36_TX,
        DOWNLOAD_S36_WAIT_RESP,
        DOWNLOAD_S37_TX,
        DOWNLOAD_S37_WAIT_RESP,
        DOWNLOAD_S31_VERIFY_START_TX,
        DOWNLOAD_S31_VERIFY_START_WAIT_RESP,
        //DOWNLOAD_S31_VERIFY_RESULT_TX,
        //DOWNLOAD_S31_VERIFY_RESULT_WAIT_RESP,
        DOWNLOAD_S11_TX,
        DOWNLOAD_S11_WAIT_RESP,
        DOWNLOAD_SID_END
    };

    byte g_ucDownloadEngine = DOWNLOAD_IDLE;
    byte g_ucDownloadErrorNum = DOWNLOAD_IDLE;

    //接收响应状态定义
    const byte UDScub_IN_PROCESS                            = 0x00;
    const byte UDScub_FINISHED                              = 0xFF;

    const byte UDScub_GENERAL_REJECTED                      = 0x10;
    const byte UDScub_SERVICE_NOT_SUPPORTED                 = 0x11;
    const byte UDScub_SUBFUNCTION_NOT_SUPPORTED             = 0x12;
    const byte UDScub_INCORRECT_MSG_LEN                     = 0x13;
    const byte UDScub_BUSY_REPEAT_REQUEST                   = 0x21;
    const byte UDScub_CONDITIONS_NOT_CORRECT                = 0x22;
    const byte UDScub_REQUEST_SEQUENCE_ERROR                = 0x24;
    const byte UDScub_NO_RESPONSE_FROM_SUBNET_COMPONENT     = 0x25;
    const byte UDScub_REQUEST_OUT_OF_RANGE                  = 0x31;
    const byte UDScub_ACCESS_DENIED                         = 0x33;
    const byte UDScub_INVALID_KEY                           = 0x35;
    const byte UDScub_TIME_DELAY_NOT_EXPIRED                = 0x37;
    const byte UDScub_UPLOADDOWNLOAD_NOT_ACCEPTED             = 0x70;    
    const byte UDScub_TRANSFER_DATA_SUSPENDED                = 0x71;    
    const byte UDScub_GENERAL_PROGRAMMING_FAILURE           = 0x72;
    const byte UDScub_WRONG_BLOCK_SEQUENCE_COUNTER             = 0x73;    
    const byte UDScub_REQUEST_RECEIVED_RESPONSE_PENDING     = 0x78;
    const byte UDScub_SFNS_IN_ACTIVE_DIAGNOSTIC_SESSION     = 0x7E;
    const byte UDScub_SNS_IN_ACTIVE_DIAGNOSTIC_SESSION      = 0x7F;
    const byte UDScub_RPM_TOO_HIGH                          = 0x81;
    const byte UDScub_VEHICLE_SPEED_TOO_HIGH                = 0x88;

    byte g_ucRxRespResult = UDScub_IN_PROCESS;

    //解析S19相关结构体和变量
    struct LINE_DATA_S19_ST
    {
        dword udwS19LineAddr;
        byte aucData[16];
        byte ucLineDataLength;
    };
    struct LINE_DATA_S19_ST g_stLineDatas19;

    const word BLOCK_BUFFER_SIZE = 240;//928; 
    struct BLOCK_ST 
    {
        byte ucBlockNum;
        word uwLength;
        byte aucBlockBuf[BLOCK_BUFFER_SIZE];
    };

    const byte MODULE_HAVE_BLOCK_MAX_NUM = 100;//18;
    struct MODULE_ST
    {
        byte ucBlockNumOfModule;
        word uwModuleDataLength;
        dword udwAddress;
        struct BLOCK_ST astBlock[MODULE_HAVE_BLOCK_MAX_NUM];
    };
    
    const byte MAX_MODULE_NUM = 32;
    struct MODULE_ST g_astModule[MAX_MODULE_NUM];

    byte g_ucModuleNumNowDeal = 0;
    byte g_ucBlockNumNowDeal = 0;
    byte g_ucActualModuleNum = 0;

    //TP相关变量
    byte g_ucTpTransmitReqFlag = FALSE;
    byte g_ucTpFCRecvFlag = FALSE;
    
    const byte TPTX_IDEL            = 0x00;
    const byte TPTX_SF              = 0x01;
    const byte TPTX_FF              = 0x02;
    const byte TPTX_WAIT_FC         = 0x03;
    const byte TPTX_CF              = 0x04;
    const byte TPTX_LAST_CF         = 0x05;

    byte g_ucTpTxEngine = TPTX_IDEL;

    const word TP_DATA_BUF_SIZE = 1024;
    struct TPTXINFO_ST
    {
        byte ucTpTxSN;
        word uwTpTxDataLength;
        word uwTpTxDataIndex;
        byte aucTpTxDataBuf[TP_DATA_BUF_SIZE];
    };

    struct TPTXINFO_ST g_stTpTxInfo; 

    struct TPRXINFO_ST
    {
        word uwTpRxDataLength;
        word uwTpRxDataIndex;
        byte aucTpRxDataBuf[TP_DATA_BUF_SIZE];
    };
    
    struct TPRXINFO_ST g_stTpRxInfo; 

    //FT 27认证算法
    const byte s_ucSeedMiddleIndex = 0x00;
    const byte s_ucSeedDB1 = 0x5C;
    const byte s_ucSeedDB2 = 0x1A;
    const byte s_ucSeedDB3 = 0x34;
    const dword s_udwSeedLevel = 0x5fdb9ae2;

    dword s_udwSaSeed = 0;
    byte g_aucSaKey[4] = {0, 0, 0, 0};

    const byte APP_SERVICE_SA_LEVEL1        = 0;
    const byte APP_SERVICE_SA_LEVEL2        = 1;
    const byte APP_SERVICE_SA_LEVEL3        = 2;
    const byte APP_SERVICE_SA_INVALID_LEVEL = 3;

    //31相关变量标志
    const byte ROUTINE_RET_OK                   = 0x00;
    const byte ROUTINE_RET_APP_MISSING          = 0x01;
    const byte ROUTINE_RET_APP_INCOMPATIBLE     = 0x02;
    const byte ROUTINE_RET_APP_INVALID          = 0x03;

    byte g_ucAppDependencyCheckRslt = ROUTINE_RET_OK;
    
    const byte PFLASH_ERASED                    = 0x01;
    const byte PFLASH_NOT_ERASED                = 0x00;

    byte g_ucPFlashStatus = PFLASH_NOT_ERASED;
    

    byte g_ucWaitTimeCounter = 0;

    //CRC_16校验
    word awCRC16Table_CITT[256] = 
    {                        
        0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,                        
        0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,                        
        0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,                        
        0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,                        
        0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,                        
        0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,                        
        0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,                        
        0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,                        
        0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,                        
        0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,                        
        0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,                        
        0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,                        
        0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,                        
        0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,                        
        0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,                        
        0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,                        
        0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,                        
        0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,                        
        0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,                        
        0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,                        
        0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,                        
        0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,                        
        0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,                        
        0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,                        
        0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,                        
        0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,                        
        0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,                        
        0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,                        
        0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,                        
        0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,                        
        0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,                        
        0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0                        
    };

    const dword gc_dwCRC32InitValue = 0xFFFFFFFF;
    const dword gc_dwPolyNomial = 0x04C11DB7;
    dword g_dwRecvVerifyCode = 0;
    dword g_dwActualVerifyCode = gc_dwCRC32InitValue;

    //34相关变量标志
    byte g_uc34RespContentRight = FALSE;

    //提示相关
    char g_acSucceedInfo[DOWNLOAD_SID_END][100] = 
    {
        "",
        "SID22 Transmit Request Succeed.",  
        "SID22 Active Respond.", 
        "SID1003 Transmit Request Succeed.",  
        "SID1003 Active Respond.", 
        "SID85 Transmit Request Succeed.",  
        "SID85 Active Respond.", 
        "SID28 Transmit Request Succeed.",  
        "SID28 Active Respond.", 
        "SID1002 Transmit Request Succeed.",  
        "SID1002 Active Respond.", 
        "SID27 Seed Transmit Request Succeed.",
        "SID27 Seed Active Respond.",
        "SID27 Key Transmit Request Succeed.",
        "SID27 Key Active Respond.",
        "SID34 Driver flash transmit Request Succeed.",
        "SID34 Driver flash active Respond.",
        "SID36 Driver flash transmit Request Succeed.",
        "SID36 Driver flash active Respond.",
        "SID37 Driver flash transmit Request Succeed.",
        "SID37 Driver flash active Respond.",
        "SID31 start erasing request succeed.",
        "SID31 start erasing respond.",
        //"SID31 verify erasing request succeed.",
        //"SID31 verify erasing respond.",
        "SID34 Transmit Request Succeed.",
        "SID34 Active Respond.",
        "SID36 Transmit Request Succeed.",
        "SID36 Active Respond.",
        "SID37 Transmit Request Succeed.",
        "SID37 Active Respond.",
        "SID31 Verify Start Transmit Request Succeed.",
        "SID31 Verify Start Active Respond.",
        //"SID31 Verify Result Transmit Request Succeed.",
        //"SID31 Verify Result Active Respond.",
        "SID11 Transmit Request Succeed.",
        "SID11 Active Respond."
    };

    char g_acFailInfo[DOWNLOAD_SID_END][100] = 
    {
        "",
        "SID22 Transmit Request Failed.",  
        "SID22 Negative Respond.", 
        "SID1003 Transmit Request Failed.",  
        "SID1003 Negative Respond.", 
        "SID85 Transmit Request Failed.",  
        "SID85 Negative Respond.", 
        "SID28 Transmit Request Failed.",  
        "SID28 Negative Respond.", 
        "SID1002 Transmit Request Failed.",  
        "SID1002 Negative Respond.", 
        "SID27 Seed Transmit Request Failed.",
        "SID27 Seed Negative Respond.",
        "SID27 Key Transmit Request Failed.",
        "SID27 Key Negative Respond.",
        "SID34 Driver flash transmit Request Failed.",
        "SID34 Driver flash negative Respond.",
        "SID36 Driver flash transmit Request Failed.",
        "SID36 Driver flash negative Respond.",
        "SID37 Driver flash transmit Request Failed.",
        "SID37 Driver flash negative Respond.",
        "SID31 start erasing request failed.",
        "SID31 negative respond.",
        //"SID31 verify erasing request failed.",
        //"SID31 negative respond.",
        "SID34 Transmit Request Failed.",
        "SID34 Negative Respond.",
        "SID36 Transmit Request Failed.",
        "SID36 Negative Respond.",
        "SID37 Transmit Request Failed.",
        "SID37 Negative Respond.",
        "SID31 Verify Start Transmit Request Failed.",
        "SID31 Verify Start Negative Respond.",
        //"SID31 Verify Result Transmit Request Failed.",
        //"SID31 Verify Result Negative Respond.",
        "SID11 Transmit Request Failed.",
        "SID11 Negative Respond."
    };

    char g_acErrorCode[20] = "Error Code: 0xXX.";


    const word DID_F183 = 0xF183;
    const word DID_F184 = 0xF184;
    const word DID_F18E = 0xF18E;
    const word DID_F18A = 0xF18A;
    const word DID_F190 = 0xF190;
    const word DID_F191 = 0xF191;

    enum ReadDID
    {
        READ_DID_F183,
        READ_DID_F184,
        READ_DID_F18E,
        READ_DID_F18A,
        READ_DID_F190,
        READ_DID_F191,
        READ_DID_END
    }readDidSequence = READ_DID_F183;

    enum SimSel
    {
        SIM_SEL_LOADER_ONLY,
        SIM_SEL_BOOTLOADER
    };

    const dword dwBootloaderMask = 0x17354870;

    const byte saLevelSubFunction = 0x11;   /* Seed request = 0x11, key send = 0x12 */
 
    const dword BLOCK0_START_ADDR      = 0x4020;
    const dword BLOCK0_END_ADDR     = 0x8000;
    const dword BLOCK0_DATA_LEN     = 0x3FE0;
    
    const dword BLOCK1_START_ADDR      = 0x48000;
    const dword BLOCK1_END_ADDR     = 0x4C000;
    const dword BLOCK1_DATA_LEN     = 0x4000;
    
    const dword BLOCK2_START_ADDR      = 0x58000;
    const dword BLOCK2_END_ADDR     = 0x5C000;
    const dword BLOCK2_DATA_LEN     = 0x4000;
    
    const dword BLOCK3_START_ADDR      = 0x68000;
    const dword BLOCK3_END_ADDR     = 0x6C000;
    const dword BLOCK3_DATA_LEN     = 0x4000;
    
    const dword BLOCK4_START_ADDR      = 0x78000;
    const dword BLOCK4_END_ADDR     = 0x7C000;
    const dword BLOCK4_DATA_LEN     = 0x4000;
    
    const dword BLOCK5_START_ADDR      = 0x88000;
    const dword BLOCK5_END_ADDR     = 0x8C000;
    const dword BLOCK5_DATA_LEN     = 0x4000;
    
    const dword BLOCK6_START_ADDR      = 0x98000;
    const dword BLOCK6_END_ADDR     = 0x9C000;
    const dword BLOCK6_DATA_LEN     = 0x4000;
    
    const dword BLOCK7_START_ADDR      = 0xA8000;
    const dword BLOCK7_END_ADDR     = 0xAC000;
    const dword BLOCK7_DATA_LEN     = 0x4000;
    
    const dword BLOCK8_START_ADDR      = 0xB8000;
    const dword BLOCK8_END_ADDR     = 0xBC000;
    const dword BLOCK8_DATA_LEN     = 0x4000;
    
    const dword BLOCK9_START_ADDR      = 0xC8000;
    const dword BLOCK9_END_ADDR     = 0xCC000;
    const dword BLOCK9_DATA_LEN     = 0x4000;
    
    const dword BLOCK10_START_ADDR      = 0xE8000;
    const dword BLOCK10_END_ADDR     = 0xEC000;
    const dword BLOCK10_DATA_LEN     = 0x4000;
    
    const int BLOCK_START_ADDR_INDEX = 0;
    const int BLOCK_END_ADDR_INDEX   = 1;
    const int BLOCK_DATA_LEN_INDEX   = 2;
    
    dword flashAddrTbl[11][3] = 
    {
        {BLOCK0_START_ADDR, BLOCK0_END_ADDR, BLOCK0_DATA_LEN},
        {BLOCK1_START_ADDR, BLOCK1_END_ADDR, BLOCK1_DATA_LEN},
        {BLOCK2_START_ADDR, BLOCK2_END_ADDR, BLOCK2_DATA_LEN},
        {BLOCK3_START_ADDR, BLOCK3_END_ADDR, BLOCK3_DATA_LEN},
        {BLOCK4_START_ADDR, BLOCK4_END_ADDR, BLOCK4_DATA_LEN},
        {BLOCK5_START_ADDR, BLOCK5_END_ADDR, BLOCK5_DATA_LEN},
        {BLOCK6_START_ADDR, BLOCK6_END_ADDR, BLOCK6_DATA_LEN},
        {BLOCK7_START_ADDR, BLOCK7_END_ADDR, BLOCK7_DATA_LEN},
        {BLOCK8_START_ADDR, BLOCK8_END_ADDR, BLOCK7_DATA_LEN},
        {BLOCK9_START_ADDR, BLOCK9_END_ADDR, BLOCK7_DATA_LEN},
        {BLOCK10_START_ADDR, BLOCK10_END_ADDR, BLOCK7_DATA_LEN}
    };
    
    dword TableCRC32[256] = 
    {
        0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F,0xE963A535,
        0x9E6495A3,0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988,0x09B64C2B,0x7EB17CBD,
        0xE7B82D07,0x90BF1D91,0x1DB71064,0x6AB020F2,0xF3B97148,0x84BE41DE,0x1ADAD47D,
        0x6DDDE4EB,0xF4D4B551,0x83D385C7,0x136C9856,0x646BA8C0,0xFD62F97A,0x8A65C9EC,
        0x14015C4F,0x63066CD9,0xFA0F3D63,0x8D080DF5,0x3B6E20C8,0x4C69105E,0xD56041E4,
        0xA2677172,0x3C03E4D1,0x4B04D447,0xD20D85FD,0xA50AB56B,0x35B5A8FA,0x42B2986C,
        0xDBBBC9D6,0xACBCF940,0x32D86CE3,0x45DF5C75,0xDCD60DCF,0xABD13D59,0x26D930AC,
        0x51DE003A,0xC8D75180,0xBFD06116,0x21B4F4B5,0x56B3C423,0xCFBA9599,0xB8BDA50F,
        0x2802B89E,0x5F058808,0xC60CD9B2,0xB10BE924,0x2F6F7C87,0x58684C11,0xC1611DAB,
        0xB6662D3D,0x76DC4190,0x01DB7106,0x98D220BC,0xEFD5102A,0x71B18589,0x06B6B51F,
        0x9FBFE4A5,0xE8B8D433,0x7807C9A2,0x0F00F934,0x9609A88E,0xE10E9818,0x7F6A0DBB,
        0x086D3D2D,0x91646C97,0xE6635C01,0x6B6B51F4,0x1C6C6162,0x856530D8,0xF262004E,
        0x6C0695ED,0x1B01A57B,0x8208F4C1,0xF50FC457,0x65B0D9C6,0x12B7E950,0x8BBEB8EA,
        0xFCB9887C,0x62DD1DDF,0x15DA2D49,0x8CD37CF3,0xFBD44C65,0x4DB26158,0x3AB551CE,
        0xA3BC0074,0xD4BB30E2,0x4ADFA541,0x3DD895D7,0xA4D1C46D,0xD3D6F4FB,0x4369E96A,
        0x346ED9FC,0xAD678846,0xDA60B8D0,0x44042D73,0x33031DE5,0xAA0A4C5F,0xDD0D7CC9,
        0x5005713C,0x270241AA,0xBE0B1010,0xC90C2086,0x5768B525,0x206F85B3,0xB966D409,
        0xCE61E49F,0x5EDEF90E,0x29D9C998,0xB0D09822,0xC7D7A8B4,0x59B33D17,0x2EB40D81,
        0xB7BD5C3B,0xC0BA6CAD,0xEDB88320,0x9ABFB3B6,0x03B6E20C,0x74B1D29A,0xEAD54739,
        0x9DD277AF,0x04DB2615,0x73DC1683,0xE3630B12,0x94643B84,0x0D6D6A3E,0x7A6A5AA8,
        0xE40ECF0B,0x9309FF9D,0x0A00AE27,0x7D079EB1,0xF00F9344,0x8708A3D2,0x1E01F268,
        0x6906C2FE,0xF762575D,0x806567CB,0x196C3671,0x6E6B06E7,0xFED41B76,0x89D32BE0,
        0x10DA7A5A,0x67DD4ACC,0xF9B9DF6F,0x8EBEEFF9,0x17B7BE43,0x60B08ED5,0xD6D6A3E8,
        0xA1D1937E,0x38D8C2C4,0x4FDFF252,0xD1BB67F1,0xA6BC5767,0x3FB506DD,0x48B2364B,
        0xD80D2BDA,0xAF0A1B4C,0x36034AF6,0x41047A60,0xDF60EFC3,0xA867DF55,0x316E8EEF,
        0x4669BE79,0xCB61B38C,0xBC66831A,0x256FD2A0,0x5268E236,0xCC0C7795,0xBB0B4703,
        0x220216B9,0x5505262F,0xC5BA3BBE,0xB2BD0B28,0x2BB45A92,0x5CB36A04,0xC2D7FFA7,
        0xB5D0CF31,0x2CD99E8B,0x5BDEAE1D,0x9B64C2B0,0xEC63F226,0x756AA39C,0x026D930A,
        0x9C0906A9,0xEB0E363F,0x72076785,0x05005713,0x95BF4A82,0xE2B87A14,0x7BB12BAE,
        0x0CB61B38,0x92D28E9B,0xE5D5BE0D,0x7CDCEFB7,0x0BDBDF21,0x86D3D2D4,0xF1D4E242,
        0x68DDB3F8,0x1FDA836E,0x81BE16CD,0xF6B9265B,0x6FB077E1,0x18B74777,0x88085AE6,
        0xFF0F6A70,0x66063BCA,0x11010B5C,0x8F659EFF,0xF862AE69,0x616BFFD3,0x166CCF45,
        0xA00AE278,0xD70DD2EE,0x4E048354,0x3903B3C2,0xA7672661,0xD06016F7,0x4969474D,
        0x3E6E77DB,0xAED16A4A,0xD9D65ADC,0x40DF0B66,0x37D83BF0,0xA9BCAE53,0xDEBB9EC5,
        0x47B2CF7F,0x30B5FFE9,0xBDBDF21C,0xCABAC28A,0x53B39330,0x24B4A3A6,0xBAD03605,
        0xCDD70693,0x54DE5729,0x23D967BF,0xB3667A2E,0xC4614AB8,0x5D681B02,0x2A6F2B94,
        0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D  
    };
}
/*@@end*/

/*@@startStart:Start:*/
on start
{
    BootInit();
    //openpanel("BootLoader");

    DisplayMsgOnScreen(PROCESS_SCREEN, "Boot loader starts :-) ...");
   

//    settimercyclic(timCyclicSend, 100);
}
/*@@end*/

/*@@caplFunc:Name:*/
void BootInit (void)
{
    putvalue(S19FileDisplay, "");
    putvalue(BootProgress, 0);
}
/*@@end*/

/*@@envVar:Name:*/
on envVar BootStart
{
    if ((getvalue(this)) && (FALSE == g_iDownloadIsActive))
    { 
        if (0 == strlen(gsBootFilePath))
        {
            DisplayMsgOnScreen(PROCESS_SCREEN, "Please load BIN file first. ");
        }
        else 
        {
            if (0 == CheckFileSuffix(gsBootFilePath))
            {
                DisplayMsgOnScreen(PROCESS_SCREEN, "BIN file is invalid. Please load a new correct file. ");
            }  
            else
            {
                clearMsgDisplay();
                
                putvalue(BootProgress, 0);
                
                putvalue(bnSimSelOk, 1);
                //openpanel("SimSel");
                
                write("Download is in process....................................");
                
                /* Send message to wake up PEPS */
                msgBootClient.byte(0) = 2;
                msgBootClient.byte(1) = 0x3E;
                msgBootClient.byte(2) = 0x00;
                output(msgBootClient);
            } 
        }
    }
}
/*@@end*/

/*@@caplFunc:Name:*/
int CheckFileSuffix (char filePath[])
{
    int result;
    int fileLen;
  
    result = 0;
    fileLen = strlen(filePath);
    
    if (fileLen < 5) return 0;

    fileLen--;

    if (((filePath[fileLen] == 'N')) || (filePath[fileLen] == 'n'))
    {
        fileLen--;

        if (((filePath[fileLen] == 'I')) || (filePath[fileLen] == 'i'))
        {
            fileLen--;

            if ((filePath[fileLen] == 'b') || (filePath[fileLen] == 'B'))
            {
                fileLen--;

                if (filePath[fileLen] == '.')
                {
                    result = 1;
                }
            }
        }
    }
    
    return result;
}
/*@@end*/

/*@@envVar:Name:*/
on envVar BootFilePath
{
    getvalue(BootFilePath, gsBootFilePath);
}
/*@@end*/

/*@@timer:Name:*/
on timer timDownload
{
    settimer(timDownload, timeslot20ms);

    if (TRUE == g_iDownloadStartFlg)
    {
        if(getvalue(env_SimLoaderOnly) == SIM_SEL_LOADER_ONLY)  /* Simulate LOADER only */
        {
            if (DOWNLOAD_IDLE == g_ucDownloadEngine)
            {
                //g_ucDownloadEngine = DOWNLOAD_S27_SEED_TX;
              g_ucDownloadEngine = DOWNLOAD_S1003_TX;
            }
        }
        else                                                    /* Simulate BOOTLOADER (the whole process) */
        {
            if (DOWNLOAD_IDLE == g_ucDownloadEngine)
            {
                //g_ucDownloadEngine = DOWNLOAD_S22_TX;
                g_ucDownloadEngine = DOWNLOAD_S1003_TX;
            }
        }

        if (1 == g_ucDownloadEngine % 2)
        {
            TransmitDataSet(g_ucDownloadEngine);    //设置发送内容

            if (TRUE == TpTransmitReq())   //transmit succeed
            {
                DisplayMsgOnScreen(PROCESS_SCREEN, g_acSucceedInfo[g_ucDownloadEngine]);    //show succeed prompt
                
                settimer(timMonitor, timeslot3s);

                g_ucDownloadEngine += 1;
            }
            else
            {
                g_ucDownloadErrorNum = g_ucDownloadEngine;
                g_ucDownloadEngine = DOWNLOAD_IDLE;
            }
        }
        else
        {
            if (UDScub_FINISHED == g_ucRxRespResult)   
            {
                canceltimer(timMonitor);
                DisplayMsgOnScreen(PROCESS_SCREEN, g_acSucceedInfo[g_ucDownloadEngine]);    //show succeed prompt

                if (DOWNLOAD_S11_WAIT_RESP == g_ucDownloadEngine)
                {
                    DisplayMsgOnScreen(PROCESS_SCREEN, "DownLoad Succeed.");
                    ReinitPanel();
                    canceltimer(timDownload);
                }
                else if (DOWNLOAD_S22_WAIT_RESP == g_ucDownloadEngine)
                {
                    if (readDidSequence < READ_DID_END)
                    {
                        g_ucDownloadEngine = DOWNLOAD_S22_TX;
                    }
                    else
                    {
                        g_ucDownloadEngine += 1; 

                        readDidSequence = READ_DID_F183;
                    }
                }
                else if (DOWNLOAD_S34_WAIT_RESP == g_ucDownloadEngine)
                {
                    if (TRUE == g_uc34RespContentRight)
                    {
                        g_uc34RespContentRight = FALSE;
                        g_ucDownloadEngine += 1;
                    }
                    else
                    {
                        DisplayMsgOnScreen(PROCESS_SCREEN, "SID34 Respond Content Wrong.");
                        ReinitPanel();
                        canceltimer(timDownload);
                    }
                }
                else if (DOWNLOAD_S36_WAIT_RESP == g_ucDownloadEngine)
                {
                    if ((g_astModule[g_ucModuleNumNowDeal].ucBlockNumOfModule - 1) == g_ucBlockNumNowDeal)
                    {
                        g_ucBlockNumNowDeal = 0;
                        g_ucDownloadEngine += 1;
                    }
                    else
                    {
                        g_ucBlockNumNowDeal++;
                        g_ucDownloadEngine = DOWNLOAD_S36_TX;
                    }
                }
                else if (DOWNLOAD_S37_WAIT_RESP == g_ucDownloadEngine)
                {
                    if ((g_ucActualModuleNum  - 1) == g_ucModuleNumNowDeal)
                        {
                            g_ucModuleNumNowDeal = 0;
                            g_ucDownloadEngine += 1;
                        }
                        else
                        {
                            g_ucModuleNumNowDeal++;
                            g_ucDownloadEngine = DOWNLOAD_S34_TX;
                        }
                        write("g_udwRecvVerifyCode = 0x%4x", g_dwRecvVerifyCode);
                        write("g_dwActualVerifyCode = 0x%4x", g_dwActualVerifyCode);
                        
                        
                    g_dwActualVerifyCode = gc_dwCRC32InitValue;
                    
                    if (0 != g_ucActualModuleNum)
                    {
                        if (0 != g_ucModuleNumNowDeal)
                        {
                            putvalue(BootProgress, (int)(g_ucModuleNumNowDeal * 100 / g_ucActualModuleNum));
                        }
                        else
                        {
                            putvalue(BootProgress, 100);
                        }
                    }
                }
//                else if (DOWNLOAD_S31_VERIFY_RESULT_WAIT_RESP == g_ucDownloadEngine)
//                {
//                    if (ROUTINE_RET_OK == g_ucAppDependencyCheckRslt)
//                    {
//                        g_ucDownloadEngine = DOWNLOAD_S11_TX;
//                    }
//                    else
//                    {
//                        DisplayMsgOnScreen(PROCESS_SCREEN, "Verify Code Fault.");
//                        ReinitPanel();
//                        canceltimer(timDownload);
//                    }
//                }
//                else if (DOWNLOAD_S31_VERIFY_ERASE_WAIT_RESP == g_ucDownloadEngine)
//                {
//                    if (PFLASH_ERASED == g_ucPFlashStatus)
//                    {
//                        DisplayMsgOnScreen(PROCESS_SCREEN, "PFlash erasing complete.");
//                        g_ucDownloadEngine += 1;
//                    }
//                    else
//                    {
//                        DisplayMsgOnScreen(PROCESS_SCREEN, "PFlash erasing failed. Downloading is terminated :-(");
//                        ReinitPanel();
//                        canceltimer(timDownload);
//                    }
//                }
                else
                {
                    if (DOWNLOAD_S1002_WAIT_RESP == g_ucDownloadEngine)
                    {
                        settimer(timDownload, 400);
                    }
                    g_ucDownloadEngine += 1;
                }
            }
            else if (UDScub_REQUEST_RECEIVED_RESPONSE_PENDING == g_ucRxRespResult || UDScub_IN_PROCESS == g_ucRxRespResult)
            {
                if (UDScub_REQUEST_RECEIVED_RESPONSE_PENDING == g_ucRxRespResult)
                {
                    settimer(timMonitor, timeslot3s);      //超时时间处理
                }
            }
            else
            {
                canceltimer(timMonitor);
                g_ucDownloadErrorNum = g_ucDownloadEngine;
                g_ucDownloadEngine = DOWNLOAD_IDLE;
            }

            g_ucRxRespResult = UDScub_IN_PROCESS;
        }

        if (DOWNLOAD_IDLE == g_ucDownloadEngine && DOWNLOAD_IDLE != g_ucDownloadErrorNum)
        {
            DisplayMsgOnScreen(PROCESS_SCREEN, g_acFailInfo[g_ucDownloadEngine]);    //show error prompt
            DisplayMsgOnScreen(PROCESS_SCREEN, "Download Error, Please try again.");    //show error prompt
            ReinitPanel();
            canceltimer(timDownload);
        }
    }
    else
    {
        g_ucDownloadEngine = DOWNLOAD_IDLE; 
    }
}
/*@@end*/

/*@@msg:Name:*/
on message PEPS_Diag_Tx
{
    byte i = 0;
    byte ucRxFinishedFlag = FALSE;
    ucRxFinishedFlag = FALSE;
    /* Boot client message received, copy this message */
    msgBootClient = this;
    
    if (!getvalue(Env_EnableBootloader))
    {
        return;
    }

    switch (msgBootClient.byte(0) & 0xF0)
    {
        case 0x00:
            g_stTpRxInfo.uwTpRxDataLength = msgBootClient.byte(0) & 0x0F;

            for (i = 1; i < 8; i++)
            {
                if (i < g_stTpRxInfo.uwTpRxDataLength + 1)
                {
                    g_stTpRxInfo.aucTpRxDataBuf[i - 1] = msgBootClient.byte(i);
                }
                else
                {
                    g_stTpRxInfo.aucTpRxDataBuf[i - 1] = 0x55;
                }
            } 

            ucRxFinishedFlag = TRUE;
            break;
        case 0x10:
            g_stTpRxInfo.uwTpRxDataLength = msgBootClient.byte(0) & 0x0F;
            g_stTpRxInfo.uwTpRxDataLength = (g_stTpRxInfo.uwTpRxDataLength << 8) + msgBootClient.byte(1);

            for (i = 2; i < 8; i++)
            {
                g_stTpRxInfo.aucTpRxDataBuf[i - 2] = msgBootClient.byte(i);
            } 
            
            settimer(timFCTransmit, timeslot10ms);            

            g_stTpRxInfo.uwTpRxDataIndex = 6;
            break;
        case 0x20:
            //SN检测
            for (i = 1; i < 8; i++)
            {
                g_stTpRxInfo.aucTpRxDataBuf[g_stTpRxInfo.uwTpRxDataIndex + i - 1] = msgBootClient.byte(i);
            } 

            g_stTpRxInfo.uwTpRxDataIndex += 7;

            if (g_stTpRxInfo.uwTpRxDataIndex >= g_stTpRxInfo.uwTpRxDataLength)
            {
                ucRxFinishedFlag = TRUE;
            }
            break;
        case 0x30:
            g_ucTpFCRecvFlag = TRUE;
            break;
        default:
            break;
    }

    if (TRUE == ucRxFinishedFlag)
    {
        g_ucRxRespResult = UDScub_FINISHED;

        switch (g_stTpRxInfo.aucTpRxDataBuf[0])
        {
            case 0x62:
            case 0x50:
            case 0xC5:
            case 0x68:
            case 0x51:
            case 0x76:
            case 0x77:
                break;
            case 0x67:
                if (saLevelSubFunction == g_stTpRxInfo.aucTpRxDataBuf[1])
                {
                    s_udwSaSeed = (((dword)g_stTpRxInfo.aucTpRxDataBuf[2]) << 24) + 
                                  (((dword)g_stTpRxInfo.aucTpRxDataBuf[3]) << 16) + 
                                  (((dword)g_stTpRxInfo.aucTpRxDataBuf[4]) << 8) + 
                                  ((dword)g_stTpRxInfo.aucTpRxDataBuf[5]);
                }
                break;
            case 0x71:
                if (0x03 == g_stTpRxInfo.aucTpRxDataBuf[1])
                {
                    if (0xFF == g_stTpRxInfo.aucTpRxDataBuf[2] && 0x01 == g_stTpRxInfo.aucTpRxDataBuf[3])
                    {
                        g_ucAppDependencyCheckRslt = g_stTpRxInfo.aucTpRxDataBuf[4];
                    }
                    else if (0xFF == g_stTpRxInfo.aucTpRxDataBuf[2] && 0x00 == g_stTpRxInfo.aucTpRxDataBuf[3])
                    {
                        g_ucPFlashStatus = g_stTpRxInfo.aucTpRxDataBuf[4];
                    }
                    else
                    {}
                }
                break;
            case 0x74:
                if (0x20 == g_stTpRxInfo.aucTpRxDataBuf[1] /*&&
                    0x03 == g_stTpRxInfo.aucTpRxDataBuf[2] && 
                    0xA2 == g_stTpRxInfo.aucTpRxDataBuf[3]*/)
                {
                    g_uc34RespContentRight = TRUE;
                }
                break;
            case 0x7F:
                if (0x78 != g_stTpRxInfo.aucTpRxDataBuf[2])
                {
                    g_acErrorCode[14] = ((g_stTpRxInfo.aucTpRxDataBuf[2] & 0xF0) >> 4) + 0x30; 
                    g_acErrorCode[15] = (g_stTpRxInfo.aucTpRxDataBuf[2] & 0x0F) + 0x30; 
                    DisplayMsgOnScreen(PROCESS_SCREEN, g_acErrorCode);     //show error prompt
                }
                g_ucRxRespResult = g_stTpRxInfo.aucTpRxDataBuf[2];
                break;
            default:
            //    write("g_stTpRxInfo.aucTpRxDataBuf[0] = 0x%x", g_stTpRxInfo.aucTpRxDataBuf[0]);
                DisplayMsgOnScreen(PROCESS_SCREEN, "SID Not Define ");     //show error prompt
                
                g_ucRxRespResult = UDScub_IN_PROCESS;
                break;
        }

        TpRxInit();
    }
}
/*@@end*/

/*@@msg:Name:*/
on message PEPS_Phys_Diag_Rx
{
    /* Boot host message received. No handling is needed */
}
/*@@end*/

/*@@caplFunc:Name:*/
void DisplayMsgOnScreen (int screenNum, char msg[])
{
    if (0 == screenNum)
    {
        //putvaluetocontrol("BootLoader", "S19FileStore", msg);
        //putvaluetocontrol("BootLoader", "S19FileStore", "\n");
        g_wMsgDisplayLen += strlen(msg) + 1;

        strncat( g_acMsgDisplay, msg, g_wMsgDisplayLen );  
        
        g_wMsgDisplayLen += g_wColumnLettersPerLine - (g_wMsgDisplayLen % g_wColumnLettersPerLine) + 1;
                                    
        strncat( g_acMsgDisplay, g_acSuffix, g_wMsgDisplayLen ); 

        putvalue(Env_BootLoaderDisplay, g_acMsgDisplay);
    }
    else if (1 == screenNum)
    {
        //putvaluetocontrol("BootLoader", "BootProcessDisplay", msg);
        //putvaluetocontrol("BootLoader", "BootProcessDisplay", "\n");
        g_wMsgDisplayLen += strlen(msg) + 1;

        strncat( g_acMsgDisplay, msg, g_wMsgDisplayLen );  
        
        g_wMsgDisplayLen += g_wColumnLettersPerLine - (g_wMsgDisplayLen % g_wColumnLettersPerLine) + 1;
                                    
        strncat( g_acMsgDisplay, g_acSuffix, g_wMsgDisplayLen ); 

        putvalue(Env_BootLoaderDisplay, g_acMsgDisplay);
        //putvalue(Env_BootLoaderDisplay, "\n"); //DB
    }
    else
    {
    }
}
/*@@end*/

/*@@timer:Name:*/
on timer timMonitor
{
    canceltimer(timMonitor);
    
    setcontrolforecolor("BootLoader", "tbCanStatusDisplay", MakeRGB(255, 0, 0));
    putvalue(CanStatus, "Client missing");

    DisplayMsgOnScreen(PROCESS_SCREEN, "Timeout Error: No response from client within specific time.");
    
    /* Exit the bootloader by calling 11 01 service */
    TransmitDataSet(DOWNLOAD_S11_TX);
    
    if (TRUE == TpTransmitReq())
    {
        DisplayMsgOnScreen(PROCESS_SCREEN, "Exit the bootloader mode by reset service.");
    }

    ReinitPanel();
}
/*@@end*/

/*@@envVar:Name:*/
on envVar BootStop
{
    putvalue(bnSimSelOk, 0);
    
    ReinitPanel();

    /* stop timers */
    canceltimer(timDownload);
    
    write("Download is terminated!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
    msgbeep(400);
}
/*@@end*/

/*@@timer:Name:*/
on timer timFCTransmit
{
    canceltimer(timFCTransmit);

    msgBootHost.byte(0) = 0x30;
    msgBootHost.byte(1) = 0x02;
    msgBootHost.byte(2) = 0x14;
    msgBootHost.byte(3) = 0x00;
    msgBootHost.byte(4) = 0x00;
    msgBootHost.byte(5) = 0x00;
    msgBootHost.byte(6) = 0x00;
    msgBootHost.byte(7) = 0x00;

    output(msgBootHost);
}
/*@@end*/

/*@@caplFunc:Name:*/
void ReinitPanel ( void )
{
    g_iDownloadIsActive = FALSE;
    g_iDownloadStartFlg = FALSE;

    g_ucDownloadEngine = DOWNLOAD_IDLE;
    g_ucDownloadErrorNum = DOWNLOAD_IDLE;

    g_ucRxRespResult = UDScub_IN_PROCESS;

    g_ucModuleNumNowDeal = 0;
    g_ucBlockNumNowDeal = 0;
    g_ucActualModuleNum = 0;

    g_ucTpTransmitReqFlag = FALSE;
    g_ucTpFCRecvFlag = FALSE;

    g_ucWaitTimeCounter = 0;

    g_dwRecvVerifyCode = 0;
    g_dwActualVerifyCode = gc_dwCRC32InitValue;

    g_uc34RespContentRight = FALSE;

    FileResolverInit();

    TpTxInit();

    TpRxInit();

    SaBufInit();

    readDidSequence = READ_DID_F183;

    //putvalue(BootProgress, 0);
}
/*@@end*/

/*@@envVar:Name:*/
on envVar AboutOk
{
    //closepanel("");
}
/*@@end*/

/*@@caplFunc:Name:*/
void FileResolverInit (void)
{
    byte i = 0;
    byte j = 0;
    word k = 0;
    
    for (i = 0; i < MAX_MODULE_NUM; i++)
    {
        g_astModule[i].ucBlockNumOfModule = 0;
        g_astModule[i].uwModuleDataLength = 0;
        g_astModule[i].udwAddress = 0;

        for (j = 0; j < MODULE_HAVE_BLOCK_MAX_NUM; j++)
        {
            g_astModule[i].astBlock[j].ucBlockNum = 0;
            g_astModule[i].astBlock[j].uwLength = 0;

            for (k = 0; k < BLOCK_BUFFER_SIZE; k++)
            {
                g_astModule[i].astBlock[j].aucBlockBuf[k] = 0;
            }
        } 
    }
}
/*@@end*/

/*@@caplFunc:Name:*/
byte ResolveS19File (char filePath[])
{
    byte cBuffer[0x80000];
    word uwFileReadErr = 0;
    dword udwFileHandle = 0;
    byte ucTemp = 0;
    byte ucRetVal = 0;
    byte i = 0;
    dword fileWrite = 0;

    DisplayMsgOnScreen(PROCESS_SCREEN, "Loading BIN file is ongoing ... ");
    putvalue(CanStatus, "Loading BIN File ...");

    udwFileHandle = openfileread(filePath, 1);
    
    setWritePath("C:\\");
    fileWrite  = openfileWrite("test.bin", 1);
    
    if (0 == fileWrite)
    {
        write("Open file to write failed.");
    }
    
    if (0 != udwFileHandle)
    {    
        g_dwActualVerifyCode = gc_dwCRC32InitValue;

        /* discard the data from address 00000000 to 00004010 in total 1026 * 16 bytes */
        uwFileReadErr = fileGetBinaryBlock(cBuffer, 0x4020, udwFileHandle);
        
        /* Read address from 4020 ~ 8000*/
        uwFileReadErr = fileGetBinaryBlock(cBuffer, 0x3FE0, udwFileHandle);
        fileWriteBinaryBlock(cBuffer, 0x3FE0, fileWrite);
        S19LineDataAddStart();
        S19LineDataAdd(cBuffer, 0);
        
        /* Discard data from 8000~48000 */
        uwFileReadErr = fileGetBinaryBlock(cBuffer, 0x40000, udwFileHandle);
        
        /* Read data from 48000~4C000 */
        uwFileReadErr = fileGetBinaryBlock(cBuffer, 0x4000, udwFileHandle);
        fileWriteBinaryBlock(cBuffer, 0x4000, fileWrite);
        S19LineDataAddStart();
        S19LineDataAdd(cBuffer, 1);
        
        /* Discard data from 4C000~58000 */
        uwFileReadErr = fileGetBinaryBlock(cBuffer, 0xC000, udwFileHandle);
        
        /* Read data from 58000~5C000 */
        uwFileReadErr = fileGetBinaryBlock(cBuffer, 0x4000, udwFileHandle);
        fileWriteBinaryBlock(cBuffer, 0x4000, fileWrite);
        S19LineDataAddStart();
        S19LineDataAdd(cBuffer, 2);
        
        /* Discard data from 5C000~68000*/
        uwFileReadErr = fileGetBinaryBlock(cBuffer, 0xC000, udwFileHandle);
        
        /* Read data from 68000~6C000 */
        uwFileReadErr = fileGetBinaryBlock(cBuffer, 0x4000, udwFileHandle);
        fileWriteBinaryBlock(cBuffer, 0x4000, fileWrite);
        S19LineDataAddStart();
        S19LineDataAdd(cBuffer, 3);

        /* Discard data from 6C000~78000 */
        uwFileReadErr = fileGetBinaryBlock(cBuffer, 0xC000, udwFileHandle);
        
        /* Read data from 78000~7C000 */
        uwFileReadErr = fileGetBinaryBlock(cBuffer, 0x4000, udwFileHandle);
        fileWriteBinaryBlock(cBuffer, 0x4000, fileWrite);
        S19LineDataAddStart();
        S19LineDataAdd(cBuffer, 4);
        
        /* Discard data from 7C000~88000 */
        uwFileReadErr = fileGetBinaryBlock(cBuffer, 0xC000, udwFileHandle);
        
        /* Read data from 88000~8C000 */
        uwFileReadErr = fileGetBinaryBlock(cBuffer, 0x4000, udwFileHandle);
        fileWriteBinaryBlock(cBuffer, 0x4000, fileWrite);
        S19LineDataAddStart();
        S19LineDataAdd(cBuffer, 5);

        /* Discard data from 8C000~98000 */
        uwFileReadErr = fileGetBinaryBlock(cBuffer, 0xC000, udwFileHandle);
        
        /* Read data from 98000~9C000 */
        uwFileReadErr = fileGetBinaryBlock(cBuffer, 0x4000, udwFileHandle);
        fileWriteBinaryBlock(cBuffer, 0x4000, fileWrite);
        S19LineDataAddStart();
        S19LineDataAdd(cBuffer, 6);
        
        
        /* Discard data from 9C000~A8000 */
        uwFileReadErr = fileGetBinaryBlock(cBuffer, 0xC000, udwFileHandle);
        
        /* Read data from A8000~AC000 */
        uwFileReadErr = fileGetBinaryBlock(cBuffer, 0x4000, udwFileHandle);
        fileWriteBinaryBlock(cBuffer, 0x4000, fileWrite);
        S19LineDataAddStart();
        S19LineDataAdd(cBuffer, 7);
        
        /* Discard data from AC000~B8000 */
        uwFileReadErr = fileGetBinaryBlock(cBuffer, 0xC000, udwFileHandle);
        
        /* Read data from B8000~BC000 */
        uwFileReadErr = fileGetBinaryBlock(cBuffer, 0x4000, udwFileHandle);
        fileWriteBinaryBlock(cBuffer, 0x4000, fileWrite);
        S19LineDataAddStart();
        S19LineDataAdd(cBuffer, 8);
        
        /* Discard data from BC000~C8000 */
        uwFileReadErr = fileGetBinaryBlock(cBuffer, 0xC000, udwFileHandle);
        
        /* Read data from C8000~CC000 */
        uwFileReadErr = fileGetBinaryBlock(cBuffer, 0x4000, udwFileHandle);
        fileWriteBinaryBlock(cBuffer, 0x4000, fileWrite);
        S19LineDataAddStart();
        S19LineDataAdd(cBuffer, 9);
        
        /* Discard data from CC000~DC000 (because it's data stored in 4020~8000') */
        uwFileReadErr = fileGetBinaryBlock(cBuffer, 0x10000, udwFileHandle);
        
        /* Discard data from DC000~E8000 */
        uwFileReadErr = fileGetBinaryBlock(cBuffer, 0xC000, udwFileHandle);
        
        /* Read data from E8000~EC000*/
        uwFileReadErr = fileGetBinaryBlock(cBuffer, 0x4000, udwFileHandle);
        fileWriteBinaryBlock(cBuffer, 0x4000, fileWrite);
        S19LineDataAddStart();
        S19LineDataAdd(cBuffer, 10);
        
        /* Read complete!!! */

        g_ucActualModuleNum = g_ucModuleNumNowDeal;

        g_ucModuleNumNowDeal = 0;
        g_ucBlockNumNowDeal = 0;

        ucRetVal = 1;
    }
    else
    {
        DisplayMsgOnScreen(PROCESS_SCREEN, "S19 file was not opened for read access. Boot loading process is termianted!");
    }

    fileclose(udwFileHandle);
    fileclose(fileWrite);
    
    return ucRetVal;
}
/*@@end*/

/*@@caplFunc:Name:*/
/************************************************************
 * BIN 文件说明:
 * 1) BIN 文件每行"h:"前为数据起始地址,长度为4
 * 2) BIN 文件每行末尾没有Checksum校验
 * 3) BIN文件每行(除地址外)只有16个字节
 */
byte GetS19LineData(byte cBuffer[], int block)
{
    byte ucRetVal = 0;
    byte i = 0;

    /* cBuffer[] contains one line of bin-file */
    //获得长度
    g_stLineDatas19.ucLineDataLength = 16;  /* BIN is fixed */

    //获得地址
    g_stLineDatas19.udwS19LineAddr = 0x4020 + block * 0x10;
    
    //获得数据
    for (i = 0; i < (g_stLineDatas19.ucLineDataLength); i++)
    {
        /* first get data */
        g_stLineDatas19.aucData[i] = cBuffer[i];
    }
    
    ucRetVal = 1;
    return ucRetVal;
}
/*@@end*/

/*@@caplFunc:Name:*/
void getSubStr(char subStr[], char src[], int src_offset, int subStrLen)
{
    int i;
    
    for (i = 0; i < subStrLen; i++)
    {
        subStr[i] = src[src_offset + i];
    }
}
/*@@end*/

/*@@caplFunc:Name:*/
byte Str2Byte( char str[], int len )
{
    if (len != 2)
    {
        write("String length is in correct!!!");
    }
    
    return (byte)((byte)Char2Hex(str[0]) << 4 + (byte)Char2Hex(str[1]));
}
/*@@end*/

/*@@caplFunc:Name:*/
word Str2Word( char str[], int len )
{
    if (len != 4)
    {
        write("String length is in correct!!!");
    }
    
    return (word)((word)Char2Hex(str[0]) << 12 + (word)Char2Hex(str[1]) << 8 + (word)(Char2Hex(str[2])) << 4 + (word)(Char2Hex(str[3])));
}
/*@@end*/

/*@@caplFunc:Name:*/
dword Str2Dword( char str[], int len )
{
    if (len != 8)
    {
        write("String length is in correct!!!");
    }
    
    return (dword)((dword)Char2Hex(str[0]) << 28 + (dword)Char2Hex(str[1]) << 24 + (dword)(Char2Hex(str[2])) << 20 
            + (dword)(Char2Hex(str[3])) << 16 + (dword)(Char2Hex(str[4])) << 12 + (dword)(Char2Hex(str[5])) << 8
            + (dword)(Char2Hex(str[6])) << 4 + (dword)(Char2Hex(str[7])));
}
/*@@end*/

/*@@caplFunc:Name:*/
void memcpy_off_override( byte dest[], dword destOffset, byte source[], dword sourceOffset, dword length)
{
    dword iter;

    for(iter = 0;iter < length; iter++)
    {
       dest[destOffset+iter] = source[sourceOffset+iter];
    }
}
/*@@end*/

/*@@caplFunc:Name:*/
void S19LineDataAdd (byte buff[], int block)
{
    int copyComplete;
    dword index;
    dword dataLen;
    
    copyComplete = 0;
    index = 0;
    
    dataLen = flashAddrTbl[block][BLOCK_DATA_LEN_INDEX];
    
    g_astModule[g_ucModuleNumNowDeal].uwModuleDataLength = dataLen;
    
    g_astModule[g_ucModuleNumNowDeal].udwAddress = flashAddrTbl[block][BLOCK_START_ADDR_INDEX];
        
    do{
        if ((index + BLOCK_BUFFER_SIZE) < dataLen)
        {
            copyComplete = 0;
            
            memcpy_off(g_astModule[g_ucModuleNumNowDeal].astBlock[g_ucBlockNumNowDeal].aucBlockBuf, 
                       0, 
                       buff, 
                       index,
                       BLOCK_BUFFER_SIZE);

            g_astModule[g_ucModuleNumNowDeal].astBlock[g_ucBlockNumNowDeal].uwLength = BLOCK_BUFFER_SIZE;     
                        
            index += BLOCK_BUFFER_SIZE;

            if (index < dataLen)
            {
                /* Start the next module */
                g_ucBlockNumNowDeal++;

                g_astModule[g_ucModuleNumNowDeal].astBlock[g_ucBlockNumNowDeal].ucBlockNum = g_ucBlockNumNowDeal + 1;

                g_astModule[g_ucModuleNumNowDeal].ucBlockNumOfModule++;
            }
            else
            {
                /* Copy complete */
                copyComplete = 1;
            }
        }
        else
        {
            copyComplete = 1;
            
            g_astModule[g_ucModuleNumNowDeal].astBlock[g_ucBlockNumNowDeal].uwLength = dataLen - index;
            
            memcpy_off(g_astModule[g_ucModuleNumNowDeal].astBlock[g_ucBlockNumNowDeal].aucBlockBuf, 
                       0, 
                       buff, 
                       index,
                       dataLen - index);

            g_ucModuleNumNowDeal++;
        }
    }while(copyComplete != 1);
}
/*@@end*/

/*@@caplFunc:Name:*/
void S19LineDataAddStart (void)
{
    g_ucBlockNumNowDeal = 0;

    g_astModule[g_ucModuleNumNowDeal].ucBlockNumOfModule = 1;
        
    g_astModule[g_ucModuleNumNowDeal].astBlock[g_ucBlockNumNowDeal].ucBlockNum = 1;

    g_astModule[g_ucModuleNumNowDeal].astBlock[g_ucBlockNumNowDeal].uwLength = 0;
}
/*@@end*/

/*@@caplFunc:Name:*/
byte Char2Hex (byte ucChar)
{
    byte ucHex = 0;
 
    if (ucChar >= 0x30 && ucChar < 0x3A)
    {
        ucHex = ucChar - 0x30;
    }
    else if (ucChar >= 65 && ucChar < 71)
    {
        ucHex = ucChar - 55;
    }
    else if (ucChar >= 97 && ucChar < 103)
    {
        ucHex = ucChar - 87;
    }

    return ucHex;
}
/*@@end*/

/*@@caplFunc:Name:*/
void TransmitDataSet (byte ucDownloadEngine)
{
    switch(ucDownloadEngine)
    {
        case DOWNLOAD_S22_TX:
            if (READ_DID_F183 == readDidSequence)
            {
                g_stTpTxInfo.aucTpTxDataBuf[0] = 0x22;
                g_stTpTxInfo.aucTpTxDataBuf[1] = 0xF1;
                g_stTpTxInfo.aucTpTxDataBuf[2] = 0x83;
                g_stTpTxInfo.uwTpTxDataLength = 3;
            }
            else if (READ_DID_F184 == readDidSequence)
            {
                g_stTpTxInfo.aucTpTxDataBuf[0] = 0x22;
                g_stTpTxInfo.aucTpTxDataBuf[1] = 0xF1;
                g_stTpTxInfo.aucTpTxDataBuf[2] = 0x84;
                g_stTpTxInfo.uwTpTxDataLength = 3;
            }
            else if (READ_DID_F18E == readDidSequence)
            {
                g_stTpTxInfo.aucTpTxDataBuf[0] = 0x22;
                g_stTpTxInfo.aucTpTxDataBuf[1] = 0xF1;
                g_stTpTxInfo.aucTpTxDataBuf[2] = 0x8E;
                g_stTpTxInfo.uwTpTxDataLength = 3;
            }
            else if (READ_DID_F18A == readDidSequence)
            {
                g_stTpTxInfo.aucTpTxDataBuf[0] = 0x22;
                g_stTpTxInfo.aucTpTxDataBuf[1] = 0xF1;
                g_stTpTxInfo.aucTpTxDataBuf[2] = 0x8A;
                g_stTpTxInfo.uwTpTxDataLength = 3;
            }
            else if (READ_DID_F190 == readDidSequence)
            {
                g_stTpTxInfo.aucTpTxDataBuf[0] = 0x22;
                g_stTpTxInfo.aucTpTxDataBuf[1] = 0xF1;
                g_stTpTxInfo.aucTpTxDataBuf[2] = 0x90;
                g_stTpTxInfo.uwTpTxDataLength = 3;
            }
            else if (READ_DID_F191 == readDidSequence)
            {
                g_stTpTxInfo.aucTpTxDataBuf[0] = 0x22;
                g_stTpTxInfo.aucTpTxDataBuf[1] = 0xF1;
                g_stTpTxInfo.aucTpTxDataBuf[2] = 0x91;
                g_stTpTxInfo.uwTpTxDataLength = 3;
            }
            else
            {}

            readDidSequence++;

            break;
        case DOWNLOAD_S1003_TX:
            g_stTpTxInfo.aucTpTxDataBuf[0] = 0x10;
            g_stTpTxInfo.aucTpTxDataBuf[1] = 0x03;
            g_stTpTxInfo.uwTpTxDataLength = 2;
            break;
        case DOWNLOAD_S85_TX:
            g_stTpTxInfo.aucTpTxDataBuf[0] = 0x85;
            g_stTpTxInfo.aucTpTxDataBuf[1] = 0x02;
            g_stTpTxInfo.aucTpTxDataBuf[2] = 0xFF;
            g_stTpTxInfo.aucTpTxDataBuf[3] = 0xFF;
            g_stTpTxInfo.aucTpTxDataBuf[4] = 0xFF;
            g_stTpTxInfo.uwTpTxDataLength = 2;
            break;
        case DOWNLOAD_S28_TX:
            g_stTpTxInfo.aucTpTxDataBuf[0] = 0x28;
            g_stTpTxInfo.aucTpTxDataBuf[1] = 0x03;
            g_stTpTxInfo.aucTpTxDataBuf[2] = 0x03;
            g_stTpTxInfo.uwTpTxDataLength = 3;
            break;
        case DOWNLOAD_S1002_TX:
            g_stTpTxInfo.aucTpTxDataBuf[0] = 0x10;
            g_stTpTxInfo.aucTpTxDataBuf[1] = 0x02;
            g_stTpTxInfo.uwTpTxDataLength = 2;
            break;
        case DOWNLOAD_S27_SEED_TX:
            g_stTpTxInfo.aucTpTxDataBuf[0] = 0x27;
            g_stTpTxInfo.aucTpTxDataBuf[1] = 0x11;
            g_stTpTxInfo.uwTpTxDataLength = 2;
            break;
        case DOWNLOAD_S27_KEY_TX:
            g_stTpTxInfo.aucTpTxDataBuf[0] = 0x27;
            g_stTpTxInfo.aucTpTxDataBuf[1] = 0x12;

            SaKeyGenerate();

            g_stTpTxInfo.aucTpTxDataBuf[2] = g_aucSaKey[0];
            g_stTpTxInfo.aucTpTxDataBuf[3] = g_aucSaKey[1];
            g_stTpTxInfo.aucTpTxDataBuf[4] = g_aucSaKey[2];
            g_stTpTxInfo.aucTpTxDataBuf[5] = g_aucSaKey[3];

            g_stTpTxInfo.uwTpTxDataLength = 6;
            break;
        case DOWNLOAD_S34_TX_DRV:
            g_stTpTxInfo.aucTpTxDataBuf[0] = 0x34;
            g_stTpTxInfo.aucTpTxDataBuf[1] = 0x00;
            g_stTpTxInfo.aucTpTxDataBuf[2] = 0x44;
            
            g_stTpTxInfo.aucTpTxDataBuf[3] = 0x00;
            g_stTpTxInfo.aucTpTxDataBuf[4] = 0x00;
            g_stTpTxInfo.aucTpTxDataBuf[5] = 0x20;
            g_stTpTxInfo.aucTpTxDataBuf[6] = 0x00;
            g_stTpTxInfo.aucTpTxDataBuf[7] = 0x00;
            g_stTpTxInfo.aucTpTxDataBuf[8] = 0x00;
            g_stTpTxInfo.aucTpTxDataBuf[9] = 0x00;
            g_stTpTxInfo.aucTpTxDataBuf[10] = 0x10;
            
            g_stTpTxInfo.uwTpTxDataLength = 11;
            break;
        case DOWNLOAD_S36_TX_DRV:
            g_stTpTxInfo.aucTpTxDataBuf[0] = 0x36;
            g_stTpTxInfo.aucTpTxDataBuf[1] = 0x01;
            
            g_stTpTxInfo.aucTpTxDataBuf[2] = 0xA4;
            g_stTpTxInfo.aucTpTxDataBuf[3] = 0x78;
            g_stTpTxInfo.aucTpTxDataBuf[4] = 0x00;
            g_stTpTxInfo.aucTpTxDataBuf[5] = 0x00;
            g_stTpTxInfo.aucTpTxDataBuf[6] = 0x00;
            g_stTpTxInfo.aucTpTxDataBuf[7] = 0x00;
            g_stTpTxInfo.aucTpTxDataBuf[8] = 0x00;
            g_stTpTxInfo.aucTpTxDataBuf[9] = 0x00;
            g_stTpTxInfo.aucTpTxDataBuf[10] = 0x00;
            g_stTpTxInfo.aucTpTxDataBuf[11] = 0x00;
            g_stTpTxInfo.aucTpTxDataBuf[12] = 0x00;
            g_stTpTxInfo.aucTpTxDataBuf[13] = 0x00;
            g_stTpTxInfo.aucTpTxDataBuf[14] = 0x00;
            g_stTpTxInfo.aucTpTxDataBuf[15] = 0x00;
            g_stTpTxInfo.aucTpTxDataBuf[16] = 0x00;
            g_stTpTxInfo.aucTpTxDataBuf[17] = 0x00;
            
            g_stTpTxInfo.uwTpTxDataLength = 18;

            break;
        case DOWNLOAD_S37_TX_DRV:
            g_stTpTxInfo.aucTpTxDataBuf[0] = 0x37;
            g_stTpTxInfo.uwTpTxDataLength = 1;
            break;
        case DOWNLOAD_S31_START_ERASE_TX:
            g_stTpTxInfo.aucTpTxDataBuf[0] = 0x31;
            g_stTpTxInfo.aucTpTxDataBuf[1] = 0x01;
            g_stTpTxInfo.aucTpTxDataBuf[2] = 0xFF;
            g_stTpTxInfo.aucTpTxDataBuf[3] = 0x00;
            g_stTpTxInfo.uwTpTxDataLength = 4;
            break;
//        case DOWNLOAD_S31_VERIFY_ERASE_TX:
//            g_stTpTxInfo.aucTpTxDataBuf[0] = 0x31;
//            g_stTpTxInfo.aucTpTxDataBuf[1] = 0x03;
//            g_stTpTxInfo.aucTpTxDataBuf[2] = 0xFF;
//            g_stTpTxInfo.aucTpTxDataBuf[3] = 0x00;
//            g_stTpTxInfo.uwTpTxDataLength = 4;
//            break;
        case DOWNLOAD_S34_TX:
            g_stTpTxInfo.aucTpTxDataBuf[0] = 0x34;
            g_stTpTxInfo.aucTpTxDataBuf[1] = 0x00;
            g_stTpTxInfo.aucTpTxDataBuf[2] = 0x44;
            
            g_stTpTxInfo.aucTpTxDataBuf[3] = 0x00;
            g_stTpTxInfo.aucTpTxDataBuf[4] = (byte)(g_astModule[g_ucModuleNumNowDeal].udwAddress >> 16);
            g_stTpTxInfo.aucTpTxDataBuf[5] = (byte)(g_astModule[g_ucModuleNumNowDeal].udwAddress >> 8);
            g_stTpTxInfo.aucTpTxDataBuf[6] = (byte)g_astModule[g_ucModuleNumNowDeal].udwAddress;
            g_stTpTxInfo.aucTpTxDataBuf[7] = 0x00;
            g_stTpTxInfo.aucTpTxDataBuf[8] = 0x00;
            g_stTpTxInfo.aucTpTxDataBuf[9] = (byte)(g_astModule[g_ucModuleNumNowDeal].uwModuleDataLength >> 8);
            g_stTpTxInfo.aucTpTxDataBuf[10] = (byte)g_astModule[g_ucModuleNumNowDeal].uwModuleDataLength;
 //           write("g_astModule[%d].uwModuleDataLength = %d", g_ucModuleNumNowDeal, g_astModule[g_ucModuleNumNowDeal].uwModuleDataLength);

            g_stTpTxInfo.uwTpTxDataLength = 11;
            break;
        case DOWNLOAD_S36_TX:
            g_stTpTxInfo.aucTpTxDataBuf[0] = 0x36;

            g_stTpTxInfo.aucTpTxDataBuf[1] = g_astModule[g_ucModuleNumNowDeal].astBlock[g_ucBlockNumNowDeal].ucBlockNum;

            memcpy_off(g_stTpTxInfo.aucTpTxDataBuf,
                       2,
                       g_astModule[g_ucModuleNumNowDeal].astBlock[g_ucBlockNumNowDeal].aucBlockBuf,
                       0,
                       g_astModule[g_ucModuleNumNowDeal].astBlock[g_ucBlockNumNowDeal].uwLength);

            g_stTpTxInfo.uwTpTxDataLength = 2 + g_astModule[g_ucModuleNumNowDeal].astBlock[g_ucBlockNumNowDeal].uwLength;

            _Checksum_CheckAreaCRC32(g_astModule[g_ucModuleNumNowDeal].astBlock[g_ucBlockNumNowDeal].aucBlockBuf, 
                               g_astModule[g_ucModuleNumNowDeal].astBlock[g_ucBlockNumNowDeal].uwLength);

//            write("g_stTpTxInfo.uwTpTxDataLength = %d", g_stTpTxInfo.uwTpTxDataLength);
            break;
        case DOWNLOAD_S37_TX:
            g_stTpTxInfo.aucTpTxDataBuf[0] = 0x37;
            g_stTpTxInfo.uwTpTxDataLength = 1;
            break;
        case DOWNLOAD_S31_VERIFY_START_TX:
            g_stTpTxInfo.aucTpTxDataBuf[0] = 0x31;
            g_stTpTxInfo.aucTpTxDataBuf[1] = 0x01;
            g_stTpTxInfo.aucTpTxDataBuf[2] = 0xFF;
            g_stTpTxInfo.aucTpTxDataBuf[3] = 0x01;
            g_stTpTxInfo.uwTpTxDataLength = 4;
            break;
//        case DOWNLOAD_S31_VERIFY_RESULT_TX:
//            g_stTpTxInfo.aucTpTxDataBuf[0] = 0x31;
//            g_stTpTxInfo.aucTpTxDataBuf[1] = 0x03;
//            g_stTpTxInfo.aucTpTxDataBuf[2] = 0xFF;
//            g_stTpTxInfo.aucTpTxDataBuf[3] = 0x01;
//            g_stTpTxInfo.uwTpTxDataLength = 4;
//            break;
        case DOWNLOAD_S11_TX:
            g_stTpTxInfo.aucTpTxDataBuf[0] = 0x11;
            g_stTpTxInfo.aucTpTxDataBuf[1] = 0x01;
            g_stTpTxInfo.uwTpTxDataLength = 2;
            break;
        default:
            break;
    }
}
/*@@end*/

/*@@caplFunc:Name:*/
void TpTxInit (void)
{
    word i = 0;

    g_stTpTxInfo.ucTpTxSN = 0;
    g_stTpTxInfo.uwTpTxDataLength = 0;
    g_stTpTxInfo.uwTpTxDataIndex = 0;

    for (i = 0; i < TP_DATA_BUF_SIZE; i++)
    {
        g_stTpTxInfo.aucTpTxDataBuf[i] = 0;
    }
}
/*@@end*/

/*@@caplFunc:Name:*/
byte TpTransmitReq (void)
{
    byte ucRetVal = FALSE;
    
    if (FALSE == g_ucTpTransmitReqFlag)
    {
        settimer(timTransmit, timeslot10ms);
        g_ucTpTransmitReqFlag = TRUE;
        ucRetVal = TRUE;
    }

    return ucRetVal;
}
/*@@end*/

/*@@timer:Name:*/
on timer timTransmit
{
    byte i = 0;

    settimer(timTransmit, timeslot1ms);

    if (TPTX_IDEL == g_ucTpTxEngine)
    {
        if (g_stTpTxInfo.uwTpTxDataLength < 8)
        {
            g_ucTpTxEngine = TPTX_SF;
        }
        else
        {
            g_ucTpTxEngine = TPTX_FF;
        }
    }

    switch (g_ucTpTxEngine)
    {
        case TPTX_SF:
            msgBootHost.byte(0) = (byte)g_stTpTxInfo.uwTpTxDataLength & 0x0F;

            for (i = 1; i < 8; i++)
            {
                if (i < g_stTpTxInfo.uwTpTxDataLength + 1)
                {
                    msgBootHost.byte(i) = g_stTpTxInfo.aucTpTxDataBuf[i - 1];
                }
                else
                {
                    msgBootHost.byte(i) = 0xAA;
                }
            }
 
            output(msgBootHost);
            
            canceltimer(timTransmit);
            g_ucTpTransmitReqFlag = FALSE;
            g_ucTpTxEngine = TPTX_IDEL;
            break;
        case TPTX_FF:
            msgBootHost.byte(0) = 0x10 | ((byte)(g_stTpTxInfo.uwTpTxDataLength >> 8) & 0x0F);
            msgBootHost.byte(1) = (byte)g_stTpTxInfo.uwTpTxDataLength;

            for (i = 2; i < 8; i++)
            {
                msgBootHost.byte(i) = g_stTpTxInfo.aucTpTxDataBuf[i - 2];
            }

            output(msgBootHost);

            g_stTpTxInfo.ucTpTxSN = 1;
            g_stTpTxInfo.uwTpTxDataIndex = 6;
            g_ucTpTxEngine = TPTX_WAIT_FC;
            break;
        case TPTX_WAIT_FC:
            if (TRUE == g_ucTpFCRecvFlag)
            {
                g_ucTpFCRecvFlag = FALSE; 

                if (g_stTpTxInfo.uwTpTxDataLength < 14)
                {
                    g_ucTpTxEngine = TPTX_LAST_CF;
                }
                else
                {
                    g_ucTpTxEngine = TPTX_CF;
                }
            }
            break;
        case TPTX_CF:
            msgBootHost.byte(0) = 0x20 | (g_stTpTxInfo.ucTpTxSN & 0x0F);

            for (i = 1; i < 8; i++)
            {
                msgBootHost.byte(i) = g_stTpTxInfo.aucTpTxDataBuf[g_stTpTxInfo.uwTpTxDataIndex + i - 1];
            }

            output(msgBootHost);
            
            if (15 == g_stTpTxInfo.ucTpTxSN)
            {
                g_stTpTxInfo.ucTpTxSN = 0;
            }
            else
            {
                g_stTpTxInfo.ucTpTxSN++;
            }

            g_stTpTxInfo.uwTpTxDataIndex += 7;

            if (g_stTpTxInfo.uwTpTxDataLength < (g_stTpTxInfo.uwTpTxDataIndex + 8))
            {
                g_ucTpTxEngine = TPTX_LAST_CF;
            }
            break;
        case TPTX_LAST_CF:
            msgBootHost.byte(0) = 0x20 | (g_stTpTxInfo.ucTpTxSN & 0x0F);

            for (i = 1; i < 8; i++)
            {
                if (i > g_stTpTxInfo.uwTpTxDataLength - g_stTpTxInfo.uwTpTxDataIndex)
                {
                    msgBootHost.byte(i) = 0xAA;
                }
                else
                {
                    msgBootHost.byte(i) = g_stTpTxInfo.aucTpTxDataBuf[g_stTpTxInfo.uwTpTxDataIndex + i - 1];
                }
            }

            output(msgBootHost);
            
            canceltimer(timTransmit);

            TpTxInit();

            g_ucTpTransmitReqFlag = FALSE;
            g_ucTpTxEngine = TPTX_IDEL;
            break;
        default:
            g_ucTpTxEngine = TPTX_IDEL;
            break;
    }
}
/*@@end*/

/*@@caplFunc:Name:*/
void SaKeyGenerate(void)
{
    byte    i = 0;
    dword    udwKey;
    byte   tmpSeed[4];

    udwKey = dwBootloaderMask;
    tmpSeed[0] = (byte)(s_udwSaSeed >> 24);
    tmpSeed[1] = (byte)(s_udwSaSeed >> 16);
    tmpSeed[2] = (byte)(s_udwSaSeed >> 8);
    tmpSeed[3] = (byte)(s_udwSaSeed);

    /* Calculate key */
    for (i = 0; i < 4; i++)
    {
        udwKey ^= (dword)((udwKey << 5 ) + tmpSeed[i]+ (udwKey >> 4 )); 
    }
    
    for (i = 0; i < 4; i++)
    {
        g_aucSaKey[i] = (udwKey >> (i*8))&0xFF;
    }
}     
/*@@end*/

/*@@caplFunc:Name:*/
void SaBufInit (void)
{
    byte i = 0;

    for (i = 0; i < 4; i++)
    {
        g_aucSaKey[i] = 0;
    }

    s_udwSaSeed = 0;
}
/*@@end*/

/*@@caplFunc:Name:*/
void TpRxInit (void)
{
    word i = 0;

    g_stTpRxInfo.uwTpRxDataLength = 0;
    g_stTpRxInfo.uwTpRxDataIndex = 0;

    for (i = 0; i < TP_DATA_BUF_SIZE; i++) 
    {
        g_stTpRxInfo.aucTpRxDataBuf[i] = 0;
    }
}
/*@@end*/

/*@@timer:Name:*/
on timer timCyclicSend
{
 //   output(msgBcmStatus);
}
/*@@end*/

/*@@envVar:Name:*/
on envVar bnSimSelOk
{
    if (getvalue(this) == 1)
    {
        g_iDownloadIsActive = TRUE;

        if (ResolveS19File(gsBootFilePath))
        {
            DisplayMsgOnScreen(PROCESS_SCREEN, "Loading complete. Now start downloading ");
            setcontrolforecolor("BootLoader", "tbCanStatusDisplay", MakeRGB(0, 255, 0));
            putvalue(CanStatus, "Downloading ...");

            g_iDownloadStartFlg = TRUE;

            settimer(timDownload, timeslot100ms);

            //closepanel("SimSel");
        }
    }
    else
    {}
}
/*@@end*/

/*@@caplFunc:Name:*/
dword CheckSumByteCRC32(dword crc, byte val, dword poly) {
//  byte index;
//  byte temp;
//    
//  for (index= 8; index != 0; index--) {
//    if ((crc & 0x80000000) != 0) { temp= (val & 0x80) == 0; } else { temp= (val & 0x80) != 0; }
//    crc <<= 1;
//    val <<= 1;
//    if (temp) {
//      crc ^=  poly;
//    }
//  }
//  return crc;

    dword oldcrc;

    oldcrc = TableCRC32[(byte)(crc>>24) & 0xFF];
    crc = (crc << 8)|val;
    crc = crc ^ oldcrc;

    return crc;
}
/*@@end*/

/*@@caplFunc:Name:*/
void _Checksum_CheckAreaCRC32(byte pucData[], word len) 
{
  word index;

  index = 0;

  while (len-- > 0) {
    g_dwActualVerifyCode = CheckSumByteCRC32(g_dwActualVerifyCode, pucData[index], gc_dwPolyNomial);

    index++;
  }
}
/*@@end*/

/*@@envVar:Name:*/
/*void memcpy_off( byte dest[], dword destOffset, byte source[], dword sourceOffset, dword length)
{
    dword i;

    for (i = 0; i < length; i++)
    {
        dest[destOffset + i] = source[sourceOffset + i];
    
    }
}*/

on envVar Env_EnableBootloader
{
    if (1 == getvalue(this))
    {
        openpanel(bootloaderWnd);
        write("openpanel(bootloaderWnd);");
    }
    else
    {
        closepanel(bootloaderWnd);
    }
}
/*@@end*/

/*@@caplFunc:Name:*/
void clearMsgDisplay(void)
{
    g_wMsgDisplayLen = 0;
        
    g_acMsgDisplay[0] = '\0';

    putvalue(Env_BootLoaderDisplay, g_acMsgDisplay);
}
/*@@end*/

  • 4
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_34309267

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值