tao_z
2022-06-06 20cc603922983f154d10b7d56c6b49e5e02997bd
初步bootloader实现。dbc解析存在解析值不正确问题。
3 files added
3 files deleted
7 files modified
1783 ■■■■■ changed files
.gitignore 4 ●●●● patch | view | raw | blame | history
.qt_for_python/uic/main.py 2 ●●● patch | view | raw | blame | history
DBC/DFLZM.dbc 230 ●●●●● patch | view | raw | blame | history
DBC/SX7H.ini 165 ●●●●● patch | view | raw | blame | history
Pipfile 21 ●●●●● patch | view | raw | blame | history
Pipfile.lock 436 ●●●●● patch | view | raw | blame | history
Shifter.py 28 ●●●●● patch | view | raw | blame | history
USBCAN.py 243 ●●●●● patch | view | raw | blame | history
dbc.py 92 ●●●●● patch | view | raw | blame | history
main.ui 2 ●●● patch | view | raw | blame | history
styleSheet.py 9 ●●●●● patch | view | raw | blame | history
uds/client.py 345 ●●●●● patch | view | raw | blame | history
widgets/ShifterTool.py 206 ●●●●● patch | view | raw | blame | history
.gitignore
@@ -147,3 +147,7 @@
.vscode/*
files/*
.idea/*
log/*
source bin/*
.qt_for_python/*
sx7h_env/*
.qt_for_python/uic/main.py
@@ -1033,7 +1033,7 @@
        self.retranslateUi(MainWindow)
        self.tabWidget.setCurrentIndex(3)
        self.tabWidget.setCurrentIndex(2)
        self.tabWidget_2.setCurrentIndex(2)
DBC/DFLZM.dbc
New file
@@ -0,0 +1,230 @@
VERSION ""
NS_ :
    NS_DESC_
    CM_
    BA_DEF_
    BA_
    VAL_
    CAT_DEF_
    CAT_
    FILTER
    BA_DEF_DEF_
    EV_DATA_
    ENVVAR_DATA_
    SGTYPE_
    SGTYPE_VAL_
    BA_DEF_SGTYPE_
    BA_SGTYPE_
    SIG_TYPE_REF_
    VAL_TABLE_
    SIG_GROUP_
    SIG_VALTYPE_
    SIGTYPE_VALTYPE_
    BO_TX_BU_
    BA_DEF_REL_
    BA_REL_
    BA_DEF_DEF_REL_
    BU_SG_REL_
    BU_EV_REL_
    BU_BO_REL_
    SG_MUL_VAL_
BS_:
BU_: GW_BCM_PT GW_BCM_PEPS_PT ABSESP AGS AMT AT CVT DAS EMS EPS SA SRS TBox TCU GW_Tester BCM
BO_ 329 IC1: 8 GW_BCM_PT
 SG_ odometer_value : 31|24@0+ (1,0) [0|1999999] "km"  ABSESP,AMT,AT,CVT,DAS,EMS,SA,TCU
BO_ 534 CVT1: 8 CVT
 SG_ Shifter_Lever_Signals : 63|8@0+ (1,0) [0|255] ""  GW_BCM_PT,GW_BCM_PEPS_PT,ABSESP,EMS,EPS,SA,TBox
BO_ 530 Engine2: 8 EMS
 SG_ brake_pedal_status : 57|2@0+ (1,0) [0|3] ""  ABSESP,AMT,AT,CVT,DAS,SA,SRS,TBox,TCU
BO_ 1056 SA1: 8 SA
 SG_ SA1_ShifterModeSignal : 1|2@0+ (1,0) [0|3] ""  AT,TCU
 SG_ SA1_IND_ShifterMisUsd : 14|3@0+ (1,0) [0|7] "" Vector__XXX
 SG_ SA1_Status_ShftSensSng_Fault : 15|1@0+ (1,0) [0|1] ""  TCU
 SG_ SA1_Status_EcoShifterModeReq : 16|1@0+ (1,0) [0|1] ""  TCU
 SG_ SA1_Status_UnlockButtonReq : 17|1@0+ (1,0) [0|1] ""  TCU
 SG_ SA1_Status_ParkButtonReq : 19|2@0+ (1,0) [0|3] ""  TCU
 SG_ SA1_ShifterManualSignal : 4|3@0+ (1,0) [0|7] ""  AT,TCU
 SG_ SA1_Status_GearShftPosReq : 23|4@0+ (1,0) [0|15] ""  TCU
 SG_ SA1_Status_RqGearPosInV : 31|4@0+ (1,0) [0|15] ""  TCU
 SG_ SA1_Status_ShiftPosValidFlag : 32|1@0+ (1,0) [0|1] "" Vector__XXX
 SG_ SA1_Status_PRNDL : 7|3@0+ (1,0) [0|7] "" Vector__XXX
 SG_ SA1_Live_counter : 11|4@0+ (1,0) [0|15] ""  AT,TCU
BO_ 16 TCU2: 8 AT
 SG_ ShiftLeverPos : 2|3@0+ (1,0) [0|7] ""  GW_BCM_PT,GW_BCM_PEPS_PT,ABSESP,DAS,EMS,EPS,SA,SRS,TBox
 SG_ ActualGear : 14|4@0+ (1,0) [0|15] ""  ABSESP,DAS,EMS,SA
 SG_ TCUDrivingMode : 10|3@0+ (1,0) [0|7] ""  EMS,SA
BO_ 512 ABS1: 8 ABSESP
 SG_ vehicle_speed : 15|13@0+ (0.05625,0) [0|270] "km/h"  GW_BCM_PT,GW_BCM_PEPS_PT,AGS,AMT,AT,DAS,EMS,EPS,SA,SRS,TBox,TCU
BO_ 1858 BCM_DiagReq_CHINA_VI: 8 GW_Tester
BO_ 1914 BCM_DiagResp_CHINA_VI: 8 BCM
 SG_ EGSM_77A_DiagRep_8 : 63|8@0+ (1,0) [0|0] "" Vector__XXX
 SG_ EGSM_77A_DiagRep_7 : 55|8@0+ (1,0) [0|0] "" Vector__XXX
 SG_ EGSM_77A_DiagRep_6 : 47|8@0+ (1,0) [0|0] "" Vector__XXX
 SG_ EGSM_77A_DiagRep_5 : 39|8@0+ (1,0) [0|0] "" Vector__XXX
 SG_ EGSM_77A_DiagRep_4 : 31|8@0+ (1,0) [0|0] "" Vector__XXX
 SG_ EGSM_77A_DiagRep_3 : 23|8@0+ (1,0) [0|0] "" Vector__XXX
 SG_ EGSM_77A_DiagRep_2 : 15|8@0+ (1,0) [0|0] "" Vector__XXX
 SG_ EGSM_77A_DiagRep_1 : 7|8@0+ (1,0) [0|0] "" Vector__XXX
BO_ 2015 Func_DiagReq: 8 GW_Tester
BO_TX_BU_ 329 : GW_BCM_PT,GW_BCM_PEPS_PT;
BO_TX_BU_ 16 : AT,TCU;
CM_ "Version:V2.5.3 , Date:2016/4/2 , Author:²ÌÆä誠, Review: , Approval: , Description:³õ°æ ;
Version:V2.5.5 , Date:2016.7.7 , Author:²ÌÆä誠, Review: , Approval: , Description:1.SAÔö¼Ó½ÓÊÕÐźÅbrake_pedal_status£¨Engine2£©¡£
2.SAÔö¼Ó½ÓÊÕÐźÅShiftLeverPos£¨AT2£©¡£
3.SAÐÂÔö·¢Ëͱ¨ÎÄSA1,AT½ÓÊÕÆäÐźÅSA1_ShifterModeSignalºÍSA1_ShifterManualSignal ¡£ ;
Version:V2.5.6 , Date:2016.11.09 , Author:²ÌÆä誠, Review: , Approval: , Description:1.¸ü¸ÄÐźÅActualGear£¨AT2£©µÄÐźÅÖµÃèÊö£¬Ôö¼Ó¡°0x7:Current_gear_7¡±¡£ ;
Version:V2.5.8 , Date:2017.12.04 , Author:²ÌÆä誠, Review: , Approval: , Description:1.Ôö¼Ó½ÚµãTCU¡£
2.Ôö¼ÓTCU½ÓÊÕÐźÅSA1_ShifterModeSignal¡¢SA1_ShifterManualSignal¡¢SA1_Live_counter£¨SA1£©¡£
3.ÐÂÔöÐźÅSA1_Status_ShftSensSng_Fault¡¢SA1_Status_EcoShifterModeReq¡¢SA1_Status_UnlockButtonReq¡¢SA1_Status_ParkButtonReq¡¢SA1_Status_GearShftPosReq¡¢SA1_Checksum£¨SA1£©£¬TCU½ÓÊÕ¡£
4.Ôö¼Ó½ÚµãGW_BCM¡¢ABSESP¡£
5.Ôö¼ÓSA½ÓÊÕÐźÅodometer_value£¨IC1£©ºÍvehicle_speed£¨ABS1£©¡£ ;
Version:V2.5.9 , Date:2018.04.10 , Author:²ÌÆ";
CM_ SG_ 329 odometer_value "odometer value";
CM_ SG_ 534 Shifter_Lever_Signals "Actual position measured inside the gearbox from the position sensor";
CM_ SG_ 530 brake_pedal_status "brake pedal switch status
£¨ÓÉEMSÕï¶ÏË«´¥µãÖÆ¶¯µÆ¿ª¹ØµÄÐźÅÓÐЧÐÔ£¬Öƶ¯µÆ¿ª¹Ø½øÈëÁÙ½çÇøÓòµÄÓÐЧʱ¼äÄÚ²»Ó¦½«0x3·¢³ö¡£0x3½ö±íÊ¾ÖÆ¶¯µÆ¿ª¹Ø³öÏÖʧЧ»ò¹ÊÕÏ)
1¡¢While(brake_pedal_BLS_active=0  & brake_pedal_BTS_active=1), brake_pedal_status=0;   While(BLS=1  & BTS=0), brake_pedal_status=1;
2¡¢µ±brake_pedal_parity=0£¬²¢ÇÒ³ÖÐøÊ±¼ä´óÓÚË«Â·ÖÆ¶¯¿ª¹ØÁÙ½çÇøÓòµÄÓÐЧʱ¼ä£¬brake_pedal_status=3;  ÆäÖÐÖÆ¶¯¿ª¹ØÁÙ½çÇøÓòµÄÓÐЧʱ¼äΪ50ms";
CM_ SG_ 1056 SA1_ShifterModeSignal "Shifter Mode signal";
CM_ SG_ 1056 SA1_IND_ShifterMisUsd "Shifter misoperation reminder.
»»µ²Æ÷Îó²Ù×÷ÌáÐÑ¡£";
CM_ SG_ 1056 SA1_Status_ShftSensSng_Fault "Indicate Shift Sensor Single Fault Status
µç×Ó»»µ²Æ÷´«¸ÐÆ÷¹ÊÕÏ״̬";
CM_ SG_ 1056 SA1_Status_EcoShifterModeReq "Eco Shifter Mode Request Status
½ÚÄܼÝʻģʽÇëÇó״̬";
CM_ SG_ 1056 SA1_Status_UnlockButtonReq "Unlock Button Request Status
½âËø¿ª¹ØÇëÇó״̬";
CM_ SG_ 1056 SA1_Status_ParkButtonReq "Parking Button Request Status
פ³µ¿ª¹ØÇëÇó״̬";
CM_ SG_ 1056 SA1_ShifterManualSignal "Shifter Manual Signal";
CM_ SG_ 1056 SA1_Status_GearShftPosReq "Gear Shift Position Request Status
µç×Ó»»µ²Æ÷»»µ²ÇëÇó״̬";
CM_ SG_ 1056 SA1_Status_RqGearPosInV "Driver Requested Gear Shift Position Inverse
µç×Ó»»µ²Æ÷»»µ²ÇëÇ󻥲¹Ð£Ñé";
CM_ SG_ 1056 SA1_Status_ShiftPosValidFlag "Indicate Shift lever Pos valid or invalid Status
»»µ²ÊÖ±úλÖÃÓÐЧÐźÅ
";
CM_ SG_ 1056 SA1_Status_PRNDL "Gear Status
µµÎ»×´Ì¬";
CM_ SG_ 1056 SA1_Live_counter "Message counter";
CM_ SG_ 16 ShiftLeverPos "Gear Selector Display: actual transmission Gear lever position based on the Transmission range selected by driver.";
CM_ SG_ 16 ActualGear "Actual Gear: shows the transmission gear being currently engaged in the gear box.";
CM_ SG_ 16 TCUDrivingMode "Driving program:
Indicates the mode selection of TCU";
CM_ SG_ 512 vehicle_speed "vehicle reference speed";
BA_DEF_ BO_  "NmMessage" ENUM  "No","Yes";
BA_DEF_ BO_  "DiagState" ENUM  "No","Yes";
BA_DEF_ BO_  "DiagRequest" ENUM  "No","Yes";
BA_DEF_ BO_  "DiagResponse" ENUM  "No","Yes";
BA_DEF_ BO_  "GenMsgSendType" ENUM  "Cycle","NoSendType","IfActive";
BA_DEF_ BO_  "GenMsgCycleTime" INT 0 0;
BA_DEF_ SG_  "GenSigSendType" ENUM  "Cycle","OnChange","OnWrite","IfActive","OnChangeWithRepetition","OnWriteWithRepetition","IfActiveWithRepetition";
BA_DEF_ SG_  "GenSigStartValue" INT 0 0;
BA_DEF_ SG_  "GenSigInactiveValue" INT 0 0;
BA_DEF_ BO_  "GenMsgCycleTimeFast" INT 0 0;
BA_DEF_ BO_  "GenMsgNrOfRepetition" INT 0 0;
BA_DEF_ BO_  "GenMsgDelayTime" INT 0 0;
BA_DEF_  "DBName" STRING ;
BA_DEF_ BU_  "NodeLayerModules" STRING ;
BA_DEF_ SG_  "GenSigTimeoutValue" INT 0 1000000000;
BA_DEF_ BO_  "GenMsgCycleTimeActive" INT 0 0;
BA_DEF_ BU_  "ILUsed" ENUM  "No","Yes";
BA_DEF_ BU_  "DiagStationAddress" HEX 0 255;
BA_DEF_ BU_  "NmNode" ENUM  "Not","Yes";
BA_DEF_ BU_  "NmStationAddress" HEX 0 65535;
BA_DEF_ BU_  "NmCAN" INT 0 2;
BA_DEF_  "Manufacturer" STRING ;
BA_DEF_  "NmType" STRING ;
BA_DEF_  "NmBaseAddress" HEX 0 2047;
BA_DEF_  "NmMessageCount" INT 0 255;
BA_DEF_ BO_  "GenMsgILSupport" ENUM  "No","Yes";
BA_DEF_ BO_  "GenMsgStartDelayTime" INT 0 65535;
BA_DEF_  "BusType" STRING ;
BA_DEF_DEF_  "NmMessage" "No";
BA_DEF_DEF_  "DiagState" "No";
BA_DEF_DEF_  "DiagRequest" "No";
BA_DEF_DEF_  "DiagResponse" "No";
BA_DEF_DEF_  "GenMsgSendType" "Cycle";
BA_DEF_DEF_  "GenMsgCycleTime" 0;
BA_DEF_DEF_  "GenSigSendType" "Cycle";
BA_DEF_DEF_  "GenSigStartValue" 0;
BA_DEF_DEF_  "GenSigInactiveValue" 0;
BA_DEF_DEF_  "GenMsgCycleTimeFast" 0;
BA_DEF_DEF_  "GenMsgNrOfRepetition" 0;
BA_DEF_DEF_  "GenMsgDelayTime" 0;
BA_DEF_DEF_  "DBName" "";
BA_DEF_DEF_  "NodeLayerModules" "CANoeILNLVector.dll";
BA_DEF_DEF_  "GenSigTimeoutValue" 0;
BA_DEF_DEF_  "GenMsgCycleTimeActive" 0;
BA_DEF_DEF_  "ILUsed" "No";
BA_DEF_DEF_  "DiagStationAddress" 0;
BA_DEF_DEF_  "NmNode" "Not";
BA_DEF_DEF_  "NmStationAddress" 0;
BA_DEF_DEF_  "NmCAN" 0;
BA_DEF_DEF_  "Manufacturer" "";
BA_DEF_DEF_  "NmType" "";
BA_DEF_DEF_  "NmBaseAddress" 1024;
BA_DEF_DEF_  "NmMessageCount" 128;
BA_DEF_DEF_  "GenMsgILSupport" "No";
BA_DEF_DEF_  "GenMsgStartDelayTime" 0;
BA_DEF_DEF_  "BusType" "CAN";
BA_ "DBName" "PTCAN";
BA_ "GenMsgCycleTime" BO_ 329 10;
BA_ "GenMsgCycleTime" BO_ 534 10;
BA_ "GenMsgCycleTime" BO_ 530 10;
BA_ "GenMsgDelayTime" BO_ 1056 20;
BA_ "GenMsgNrOfRepetition" BO_ 1056 3;
BA_ "GenMsgCycleTimeFast" BO_ 1056 20;
BA_ "GenMsgCycleTime" BO_ 1056 100;
BA_ "GenMsgCycleTime" BO_ 16 10;
BA_ "GenMsgCycleTime" BO_ 512 20;
BA_ "GenMsgSendType" BO_ 1858 8;
BA_ "GenMsgCycleTime" BO_ 1858 0;
BA_ "GenMsgILSupport" BO_ 1914 1;
BA_ "GenMsgSendType" BO_ 1914 1;
BA_ "GenMsgCycleTime" BO_ 1914 0;
BA_ "GenMsgSendType" BO_ 2015 8;
BA_ "GenMsgCycleTime" BO_ 2015 0;
BA_ "GenSigStartValue" SG_ 530 brake_pedal_status 3;
BA_ "GenSigStartValue" SG_ 1056 SA1_Status_GearShftPosReq 15;
BA_ "GenSigSendType" SG_ 1056 SA1_Status_GearShftPosReq 4;
BA_ "GenSigStartValue" SG_ 1056 SA1_Status_PRNDL 7;
BA_ "GenSigStartValue" SG_ 16 ShiftLeverPos 7;
BA_ "GenSigStartValue" SG_ 16 ActualGear 15;
BA_ "GenSigStartValue" SG_ 512 vehicle_speed 8190;
VAL_ 329 odometer_value 16777215 "Invalid" ;
VAL_ 534 Shifter_Lever_Signals 24 "8" 23 "7" 22 "6" 21 "5" 20 "4" 19 "3" 18 "2" 17 "1" 15 "Invalid" 11 "Z4 (Between D and L)" 10 "Z3 (Between N and D)" 9 "Z2 (Between R and N)" 8 "Z1 (Between P and R)" 7 "P (Park)" 6 "R (Reverse)" 5 "N (Neutral)" 4 "D (Drive)" 3 "Sport mode,display PWR on IC." 0 "Unknown" ;
VAL_ 530 brake_pedal_status 3 "Invalid" 2 "Not specified" 1 "Brake actuated" 0 "Brake not actuated" ;
VAL_ 1056 SA1_ShifterModeSignal 3 "Error" 2 "Winter mode" 1 "Sport mode" 0 "Normal mode" ;
VAL_ 1056 SA1_IND_ShifterMisUsd 7 "Reserved" 6 "Please make sure shiftlever in Park position" 5 "Reserved" 4 "Press brake pedal and push unlock button to change gear" 3 "Push unlock button to change gear" 2 "Vehicle speed is too high to change gear" 1 "Press brake pedal  to change gear" 0 "Invalid" ;
VAL_ 1056 SA1_Status_ShftSensSng_Fault 1 "Shift sensor single fault" 0 "Shift sensor single OK" ;
VAL_ 1056 SA1_Status_EcoShifterModeReq 1 "Request" 0 "No request" ;
VAL_ 1056 SA1_Status_UnlockButtonReq 1 "Driver request unlock button" 0 "No request" ;
VAL_ 1056 SA1_Status_ParkButtonReq 3 "Reserved" 2 "Park button fault" 1 "Driver request park button" 0 "No request" ;
VAL_ 1056 SA1_ShifterManualSignal 7 "Error" 6 "Reserved" 5 "Reserved" 4 "Reserved" 3 "M- position" 2 "M+ position" 1 "Manual position" 0 "not manual" ;
VAL_ 1056 SA1_Status_GearShftPosReq 15 "Signal not available / SNA (Double fault shifter sensor)" 14 "M" 13 "M+" 12 "M-" 11 "Reserved" 10 "Reserved" 9 "Reserved" 8 "Shifter not initialized / INIT" 7 "Reserved" 6 "Reserved" 5 "Shifter position five (backwards twice / Y2) / POS_FIVE" 4 "Shifter position four (backwards once / Y1) / POS_FOUR" 3 "Shifter position three (forward once / X1) / POS_THREE" 2 "Shifter position two (forward twice / X2) / POS_TWO" 1 "Reserved" 0 "Shifter position zero (Z) / POS_ZERO" ;
VAL_ 1056 SA1_Status_RqGearPosInV 15 "Shifter position zero (Z) / POS_ZERO" 14 "Reserved" 13 "Shifter position two (forward twice / X2) / POS_TWO" 12 "Shifter position three (forward once / X1) / POS_THREE" 11 "Shifter position four (backwards once / Y1) / POS_FOUR" 9 "Reserved" 8 "Reserved" 7 "Shifter not initialized / INIT" 6 "Reserved" 5 "Reserved" 4 "Reserved" 3 "M-" 2 "M+" 1 "M" 0 "AShifterpositionfive(backwardstwice/Y2)/POS_FIVE" 0 "Signal not available / SNA (Double fault shifter sensor)" ;
VAL_ 1056 SA1_Status_ShiftPosValidFlag 1 "invalid" 0 "valid" ;
VAL_ 1056 SA1_Status_PRNDL 7 "Invalid" 6 "Reserved" 5 "Reserved" 4 "Reserved" 3 "R" 2 "N" 1 "D" 0 "P" ;
VAL_ 16 ShiftLeverPos 7 "Invalid" 6 "M-£¨GJT:Reserved£©" 5 "M+£¨GJT:Reserved£©" 4 "M" 3 "R" 2 "N" 1 "D" 0 "P" ;
VAL_ 16 ActualGear 15 "Invalid" 14 "Reserved" 13 "Current_gear_P" 12 "Reserved" 11 "Current_gear_R" 10 "Reserved" 9 "Reserved" 8 "Reserved" 7 "Current_gear_7" 6 "Current_gear_6" 5 "Current_gear_5" 4 "Current_gear_4" 3 "Current_gear_3" 2 "Current_gear_2" 1 "Current_gear_1" 0 "Current_gear_N" ;
VAL_ 16 TCUDrivingMode 7 "Invalid" 6 "Reserved" 5 "Reserved" 4 "Sport" 3 "Reserved£¨GJT:Normal£©" 2 "Manual" 1 "Snow Mode£¨GJT:Reserved£©" 0 "Standard(Economic)£¨GJT:ECO£©" ;
VAL_ 512 vehicle_speed 8191 "Invalid" ;
DBC/SX7H.ini
New file
@@ -0,0 +1,165 @@
[View_Vehicles]
HIDDEN=
ORDER=0,1,
DEFINITIONS=
COLUMNWIDTHS=250,150,
[View_Vehicle]
HIDDEN=
ORDER=0,1,
DEFINITIONS=
COLUMNWIDTHS=250,250,
[View_VehicleNetworks]
HIDDEN=3,
ORDER=0,1,2,3,4,
DEFINITIONS=1,
COLUMNWIDTHS=250,250,100,100,150,100,
[View_VehicleNetwork]
HIDDEN=
ORDER=0,1,2,3,4,
DEFINITIONS=
COLUMNWIDTHS=250,250,100,250,150,
[View_VehicleNetworkTxMessages]
HIDDEN=
ORDER=0,1,2,3,4,5,6,7,8,
DEFINITIONS=
COLUMNWIDTHS=250,250,55,100,50,100,100,100,150,
[View_VehicleNetworkSignals]
HIDDEN=
ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
DEFINITIONS=
COLUMNWIDTHS=250,250,100,50,100,50,100,100,100,50,50,50,50,100,100,150,
[View_VehicleControlUnit]
HIDDEN=
ORDER=0,1,2,3,4,
DEFINITIONS=
COLUMNWIDTHS=250,250,100,250,150,
[View_VehicleGateways]
HIDDEN=
ORDER=0,1,2,
DEFINITIONS=
COLUMNWIDTHS=250,250,100,
[View_VehicleGatewaySignals]
HIDDEN=
ORDER=0,1,2,3,4,5,6,
DEFINITIONS=
COLUMNWIDTHS=250,250,250,250,250,250,250,
[View_Networks]
HIDDEN=2,
ORDER=0,1,2,3,
DEFINITIONS=1,
COLUMNWIDTHS=250,100,100,150,100,
[View_Network]
HIDDEN=
ORDER=0,1,2,3,
DEFINITIONS=
COLUMNWIDTHS=250,250,100,150,
[View_NetworkTxMessages]
HIDDEN=
ORDER=0,1,2,3,4,5,6,7,8,
DEFINITIONS=
COLUMNWIDTHS=250,250,55,100,50,100,100,100,150,
[View_NetworkTxSignals]
HIDDEN=
ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
DEFINITIONS=
COLUMNWIDTHS=250,250,100,50,100,50,100,100,100,50,50,50,50,100,100,150,-1,
[View_NetworkNodeGroup]
HIDDEN=
ORDER=0,1,2,
DEFINITIONS=
COLUMNWIDTHS=250,100,150,
[View_Ecus]
HIDDEN=
ORDER=0,1,
DEFINITIONS=
COLUMNWIDTHS=250,150,
[View_Ecu]
HIDDEN=
ORDER=0,1,2,3,
DEFINITIONS=
COLUMNWIDTHS=250,250,100,150,
[View_EnvVars]
HIDDEN=
ORDER=0,1,2,3,4,5,6,7,8,9,
DEFINITIONS=
COLUMNWIDTHS=250,100,100,50,50,50,50,100,100,150,
[View_EnvVar]
HIDDEN=
ORDER=0,1,2,3,4,5,6,7,8,9,10,
DEFINITIONS=
COLUMNWIDTHS=250,250,100,100,50,50,50,50,100,100,150,
[View_NodeGroups]
HIDDEN=
ORDER=0,1,
DEFINITIONS=
COLUMNWIDTHS=250,150,
[View_NodeGroup]
HIDDEN=
ORDER=0,1,2,3,
DEFINITIONS=
COLUMNWIDTHS=250,250,55,150,
[View_Nodes]
HIDDEN=
ORDER=0,1,2,
DEFINITIONS=
COLUMNWIDTHS=250,100,150,
[View_Node]
HIDDEN=
ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
DEFINITIONS=
COLUMNWIDTHS=250,250,100,50,50,100,100,100,50,50,50,50,100,100,150,-1,
[View_NodeTxMessages]
HIDDEN=
ORDER=0,1,2,3,4,5,6,7,
DEFINITIONS=
COLUMNWIDTHS=250,250,55,100,50,100,100,150,
[View_NodeTxMsg]
HIDDEN=
ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
DEFINITIONS=
COLUMNWIDTHS=250,250,100,50,50,100,100,100,50,50,50,50,100,100,150,-1,
[View_NodeTxSignals]
HIDDEN=
ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
DEFINITIONS=
COLUMNWIDTHS=250,250,100,50,50,100,100,100,50,50,50,50,100,100,150,-1,
[View_NodeRxSignals]
HIDDEN=
ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
DEFINITIONS=
COLUMNWIDTHS=250,250,100,50,50,100,100,100,50,50,50,50,100,100,150,-1,
[View_NodeTxSigs]
HIDDEN=
ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,
DEFINITIONS=
COLUMNWIDTHS=250,250,50,100,100,100,50,50,50,50,100,100,150,
[View_NodeRxSigs]
HIDDEN=
ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,
DEFINITIONS=
COLUMNWIDTHS=250,250,50,100,100,100,50,50,50,50,100,100,150,
[View_Messages]
HIDDEN=
ORDER=0,1,2,3,4,5,6,7,
DEFINITIONS=
COLUMNWIDTHS=250,55,100,50,100,100,100,150,
[View_Message]
HIDDEN=
ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,
DEFINITIONS=
COLUMNWIDTHS=250,250,100,50,50,100,100,100,50,50,50,50,100,100,150,
[View_Signals]
HIDDEN=
ORDER=0,1,2,3,4,5,6,7,8,9,10,11,12,
DEFINITIONS=
COLUMNWIDTHS=250,50,100,100,100,50,50,50,50,100,100,150,100,
[View_ValueTables]
HIDDEN=
ORDER=0,1,
DEFINITIONS=
COLUMNWIDTHS=250,150,
[View_AttrDefs]
HIDDEN=6,
ORDER=0,1,2,3,4,5,
DEFINITIONS=
COLUMNWIDTHS=250,100,100,50,50,100,150,
Pipfile
File was deleted
Pipfile.lock
File was deleted
Shifter.py
@@ -1,4 +1,3 @@
from ShifterDefine import *
import struct
from udsoncan import DidCodec
@@ -11,8 +10,7 @@
    def __init__(self, string_len=None):
        if string_len is None:
            raise ValueError(
                "You must provide a length to the AsciiCodec")
            raise ValueError("You must provide a length to the AsciiCodec")
        self.string_len = string_len
    def encode(self, string_ascii):
@@ -37,6 +35,7 @@
class PartNumberCodec(DidCodec):
    def __init__(self, byte_len=None):
        if byte_len is None:
            raise ValueError(
@@ -69,6 +68,7 @@
class PartNumberVersionCodec(DidCodec):
    def __init__(self, byte_len=None):
        if byte_len is None:
            raise ValueError(
@@ -132,7 +132,11 @@
        return self.byte_len
UnlockButton_dic = {"Unlock Button No Request": 0, "Unlock Button Request": 1}
class ShifterClass():
    def __init__(self):
        self.position = ShifterPosition(0)
        self.Pbutton = 0
@@ -166,7 +170,6 @@
            0x211B: PartNumberCodec(1),
            0x211c: PartNumberCodec(2),
            0xF197: AsciiCodec(8),
            0xF15a: AsciiCodec(10),
            0xF15B: AsciiCodec(10),
        }
@@ -182,13 +185,14 @@
            self.canid.phy_rxId = 0x742
            self.canid.fun_rxId = 0x7df
            self.canid.normalid = 0x420
        self.dbc = DBC("DBC/SX7H.dbc")
        self.dbc = DBC("DBC/DFLZM.dbc")
    def FramUnpack(self, id=0x420, frame=[]):
        data = []
        data.append(' '.join(['0x' +
                              '{:0<2x}'.format(a).upper() for a in list(frame)]))
        unpackframe = self.dbc.analyzer(msgid=0x420, data=data)
        self.position = ShifterPosition(unpackframe[4]['value']['raw'])
        self.Pbutton = unpackframe[5]['value']['raw']
        self.UnlockButton = unpackframe[6]['value']['raw']
        data = ' '.join(['{:0<2x}'.format(a).upper() for a in list(frame)])
        unpackframe = self.dbc.analyzer(msgid=0x420, data=str(data))
        # print(unpackframe[5]['value']['raw'])
        self.Pbutton = unpackframe[5]['value']['phy']
        # print(unpackframe[6]['value']['raw'])
        self.UnlockButton = unpackframe[4]['value']['phy']
        # print(unpackframe[4]['value']['raw'])
        self.position = unpackframe[7]['value']['phy']
USBCAN.py
@@ -1,3 +1,4 @@
from asyncio.log import logger
from ctypes import *
from curses import raw
# import platform
@@ -50,7 +51,6 @@
SEND_SINGLE = 1
SELF_SEND_RECV = 2
SELF_SEND_RECV_SINGLE = 3
'''
 Interface return status
'''
@@ -62,52 +62,84 @@
class VCI_INIT_CONFIG(Structure):
    _fields_ = [("AccCode", c_ulong),
                ("AccMask", c_ulong),
                ("Reserved", c_ulong),
                ("Filter", c_ubyte),
                ("Timing0", c_ubyte),
                ("Timing1", c_ubyte),
                ("Mode", c_ubyte)
                ]
    _fields_ = [("AccCode", c_ulong), ("AccMask", c_ulong),
                ("Reserved", c_ulong), ("Filter", c_ubyte),
                ("Timing0", c_ubyte), ("Timing1", c_ubyte), ("Mode", c_ubyte)]
class VCI_CAN_OBJ(Structure):
    _fields_ = [("ID", c_uint),
                ("TimeStamp", c_uint),
                ("TimeFlag", c_ubyte),
                ("SendType", c_ubyte),
                ("RemoteFlag", c_ubyte),
                ("ExternFlag", c_ubyte),
                ("DataLen", c_ubyte),
                ("Data", c_ubyte*8),
                ("Reserved", c_ubyte*3)
                ]
    _fields_ = [("ID", c_uint), ("TimeStamp", c_uint), ("TimeFlag", c_ubyte),
                ("SendType", c_ubyte), ("RemoteFlag", c_ubyte),
                ("ExternFlag", c_ubyte), ("DataLen", c_ubyte),
                ("Data", c_ubyte * 8), ("Reserved", c_ubyte * 3)]
class PVCI_ERR_INFO(Structure):
    _fields_ = [("ErrorCode", c_uint),
                ("PassiveErrData", c_ubyte*3),
                ("ArLostErrData", c_ubyte)
                ]
    _fields_ = [("ErrorCode", c_uint), ("PassiveErrData", c_ubyte * 3),
                ("ArLostErrData", c_ubyte)]
baudRateConfig = {
    '5Kbps': {'time0': 0xBF, 'time1': 0xFF},
    '10Kbps': {'time0': 0x31, 'time1': 0x1C},
    '20Kbps': {'time0': 0x18, 'time1': 0x1C},
    '40Kbps': {'time0': 0x87, 'time1': 0xFF},
    '50Kbps': {'time0': 0x09, 'time1': 0x1C},
    '80Kbps': {'time0': 0x83, 'time1': 0xFF},
    '100Kbps': {'time0': 0x04, 'time1': 0x1C},
    '125Kbps': {'time0': 0x03, 'time1': 0x1C},
    '200Kbps': {'time0': 0x81, 'time1': 0xFA},
    '250Kbps': {'time0': 0x01, 'time1': 0x1C},
    '400Kbps': {'time0': 0x80, 'time1': 0xFA},
    '500Kbps': {'time0': 0x00, 'time1': 0x1C},
    '666Kbps': {'time0': 0x80, 'time1': 0xB6},
    '800Kbps': {'time0': 0x00, 'time1': 0x16},
    '1000Kbps': {'time0': 0x00, 'time1': 0x14},
    '5Kbps': {
        'time0': 0xBF,
        'time1': 0xFF
    },
    '10Kbps': {
        'time0': 0x31,
        'time1': 0x1C
    },
    '20Kbps': {
        'time0': 0x18,
        'time1': 0x1C
    },
    '40Kbps': {
        'time0': 0x87,
        'time1': 0xFF
    },
    '50Kbps': {
        'time0': 0x09,
        'time1': 0x1C
    },
    '80Kbps': {
        'time0': 0x83,
        'time1': 0xFF
    },
    '100Kbps': {
        'time0': 0x04,
        'time1': 0x1C
    },
    '125Kbps': {
        'time0': 0x03,
        'time1': 0x1C
    },
    '200Kbps': {
        'time0': 0x81,
        'time1': 0xFA
    },
    '250Kbps': {
        'time0': 0x01,
        'time1': 0x1C
    },
    '400Kbps': {
        'time0': 0x80,
        'time1': 0xFA
    },
    '500Kbps': {
        'time0': 0x00,
        'time1': 0x1C
    },
    '666Kbps': {
        'time0': 0x80,
        'time1': 0xB6
    },
    '800Kbps': {
        'time0': 0x00,
        'time1': 0x16
    },
    '1000Kbps': {
        'time0': 0x00,
        'time1': 0x14
    },
}
TIMING_DICT = {
@@ -136,22 +168,20 @@
class USBCAN_DEVICE_INFO(Structure):
    _fields_ = [("hw_Version", c_ushort),
                ("fw_Version", c_ushort),
                ("dr_Version", c_ushort),
                ("in_Version", c_ushort),
                ("irq_Num", c_ushort),
                ("can_Num", c_ubyte),
    _fields_ = [("hw_Version", c_ushort), ("fw_Version", c_ushort),
                ("dr_Version", c_ushort), ("in_Version", c_ushort),
                ("irq_Num", c_ushort), ("can_Num", c_ubyte),
                ("str_Serial_Num", c_ubyte * 20),
                ("str_hw_Type", c_ubyte * 40),
                ("reserved", c_ushort * 4)]
                ("str_hw_Type", c_ubyte * 40), ("reserved", c_ushort * 4)]
    def __str__(self):
        return "Hardware Version:%s\nFirmware Version:%s\nDriver Interface:%s\nInterface Interface:%s\nInterrupt Number:%d\nCAN Number:%d\nSerial:%s\nHardware Type:%s\n" % (
            self.hw_version, self.fw_version, self.dr_version, self.in_version, self.irq_num, self.can_num, self.serial, self.hw_type)
            self.hw_version, self.fw_version, self.dr_version, self.in_version,
            self.irq_num, self.can_num, self.serial, self.hw_type)
    def _version(self, version):
        return ("V%02x.%02x" if version // 0xFF >= 9 else "V%d.%02x") % (version // 0xFF, version & 0xFF)
        return ("V%02x.%02x" if version // 0xFF >= 9 else
                "V%d.%02x") % (version // 0xFF, version & 0xFF)
    @property
    def hw_version(self):
@@ -199,25 +229,16 @@
class _USBCAN_CHANNEL_CAN_INIT_CONFIG(Structure):
    _fields_ = [("acc_code", c_uint),
                ("acc_mask", c_uint),
                ("reserved", c_uint),
                ("filter",   c_ubyte),
                ("timing0",  c_ubyte),
                ("timing1",  c_ubyte),
                ("mode",     c_ubyte)]
    _fields_ = [("acc_code", c_uint), ("acc_mask", c_uint),
                ("reserved", c_uint), ("filter", c_ubyte),
                ("timing0", c_ubyte), ("timing1", c_ubyte), ("mode", c_ubyte)]
class _USBCAN_CHANNEL_CANFD_INIT_CONFIG(Structure):
    _fields_ = [("acc_code",     c_uint),
                ("acc_mask",     c_uint),
                ("abit_timing",  c_uint),
                ("dbit_timing",  c_uint),
                ("brp",          c_uint),
                ("filter",       c_ubyte),
                ("mode",         c_ubyte),
                ("pad",          c_ushort),
                ("reserved",     c_uint)]
    _fields_ = [("acc_code", c_uint), ("acc_mask", c_uint),
                ("abit_timing", c_uint), ("dbit_timing", c_uint),
                ("brp", c_uint), ("filter", c_ubyte), ("mode", c_ubyte),
                ("pad", c_ushort), ("reserved", c_uint)]
class _USBCAN_CHANNEL_INIT_CONFIG(Union):
@@ -226,25 +247,19 @@
class USBCAN_CHANNEL_INIT_CONFIG(Structure):
    _fields_ = [("can_type", c_uint),
                ("config", _USBCAN_CHANNEL_INIT_CONFIG)]
    _fields_ = [("can_type", c_uint), ("config", _USBCAN_CHANNEL_INIT_CONFIG)]
class USBCAN_CHANNEL_ERR_INFO(Structure):
    _fields_ = [("error_code", c_uint),
                ("passive_ErrData", c_ubyte * 3),
    _fields_ = [("error_code", c_uint), ("passive_ErrData", c_ubyte * 3),
                ("arLost_ErrData", c_ubyte)]
class USBCAN_CHANNEL_STATUS(Structure):
    _fields_ = [("errInterrupt", c_ubyte),
                ("regMode",      c_ubyte),
                ("regStatus",    c_ubyte),
                ("regALCapture", c_ubyte),
                ("regECCapture", c_ubyte),
                ("regEWLimit",   c_ubyte),
                ("regRECounter", c_ubyte),
                ("regTECounter", c_ubyte),
    _fields_ = [("errInterrupt", c_ubyte), ("regMode", c_ubyte),
                ("regStatus", c_ubyte), ("regALCapture", c_ubyte),
                ("regECCapture", c_ubyte), ("regEWLimit", c_ubyte),
                ("regRECounter", c_ubyte), ("regTECounter", c_ubyte),
                ("Reserved",     c_ubyte)]
@@ -257,18 +272,27 @@
class USBCAN():
    def __init__(self, device_type=4, device_index=0, can_index=0, bitrate=None, can_filters=None, **kwargs):
    def __init__(self,
                 device_type=4,
                 device_index=0,
                 can_index=0,
                 bitrate=None,
                 can_filters=None,
                 **kwargs):
        # super(USBCAN, self).__init__(can_index, can_filters, **kwargs)
        self.logger = logging.getLogger()
        self.logger.setLevel(logging.DEBUG)
        # self.logger = logging.getLogger()
        # self.logger.setLevel(logging.DEBUG)
        self.logger = logger
        formatter = logging.Formatter(
            '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        # 终端Handler
        consoleHandler = logging.StreamHandler()
        consoleHandler.setLevel(logging.DEBUG)
        # 文件Handler
        fileHandler = logging.FileHandler(
            './log/USBCAN.log', mode='a', encoding='UTF-8')
        fileHandler = logging.FileHandler('./log/USBCAN.log',
                                          mode='a',
                                          encoding='UTF-8')
        fileHandler.setLevel(logging.NOTSET)
        consoleHandler.setFormatter(formatter)
@@ -286,21 +310,25 @@
        if Timing0 is None or Timing1 is None:
            self.logger.error("Timing registers are not set")
        self.init_config = VCI_INIT_CONFIG(
            0, 0xFFFFFFFF, 0, 1, Timing0, Timing1, 0)
        self.init_config = VCI_INIT_CONFIG(0, 0xFFFFFFFF, 0, 1, Timing0,
                                           Timing1, 0)
    def InitAndStart(self):
        if USBCAN_DLL.VCI_OpenDevice(self.device, self.device_index, 0) == USBCAN_STATUS_ERR:
        if USBCAN_DLL.VCI_OpenDevice(self.device, self.device_index,
                                     0) == USBCAN_STATUS_ERR:
            self.logger.error("VCI_OpenDevice Error")
            return False
            # for can_index in self.channels:
        if USBCAN_DLL.VCI_InitCAN(self.device, self.device_index, self.channel, byref(self.init_config)) == USBCAN_STATUS_ERR:
        if USBCAN_DLL.VCI_InitCAN(self.device, self.device_index, self.channel,
                                  byref(
                                      self.init_config)) == USBCAN_STATUS_ERR:
            self.logger.error("VCI_InitCAN Error")
            self.CloseDevice()
            return False
        if USBCAN_DLL.VCI_StartCAN(self.device, self.device_index, self.channel) == USBCAN_STATUS_ERR:
        if USBCAN_DLL.VCI_StartCAN(self.device, self.device_index,
                                   self.channel) == USBCAN_STATUS_ERR:
            self.logger.error("VCI_StartCAN Error")
            self.CloseDevice()
            return False
@@ -308,7 +336,8 @@
    def OpenDevice(self, device_type, device_index, reserved):
        try:
            return USBCAN_DLL.VCI_OpenDevice(device_type, device_index, reserved)
            return USBCAN_DLL.VCI_OpenDevice(device_type, device_index,
                                             reserved)
        except:
            self.logger.error("Exception on OpenDevice!")
            raise
@@ -323,8 +352,8 @@
    def GetDeviceInf(self):
        try:
            info = USBCAN_DEVICE_INFO()
            ret = USBCAN_DLL.VCI_ReadBoardInfo(
                self.device, self.device_index, byref(info))
            ret = USBCAN_DLL.VCI_ReadBoardInfo(self.device, self.device_index,
                                               byref(info))
            return info if ret == USBCAN_STATUS_OK else None
        except:
            self.logger.error("Exception on USBCAN_GetDeviceInf")
@@ -332,35 +361,40 @@
    def InitCAN(self, device_type,  device_index, can_index, init_config):
        try:
            return USBCAN_DLL.VCI_InitCAN(device_type, device_index, can_index, byref(init_config))
            return USBCAN_DLL.VCI_InitCAN(device_type, device_index, can_index,
                                          byref(init_config))
        except:
            self.logger.error("Exception on USBCAN_InitCAN!")
            raise
    def StartCAN(self, device_type,  device_index, can_index):
        try:
            return USBCAN_DLL.VCI_StartCAN(device_type,  device_index, can_index)
            return USBCAN_DLL.VCI_StartCAN(device_type, device_index,
                                           can_index)
        except:
            self.logger.error("Exception on USBCAN_StartCAN!")
            raise
    def ResetCAN(self, device_type,  device_index, can_index):
        try:
            return USBCAN_DLL.VCI_ResetCAN(device_type,  device_index, can_index)
            return USBCAN_DLL.VCI_ResetCAN(device_type, device_index,
                                           can_index)
        except:
            self.logger.error("Exception on USBCAN_ResetCAN!")
            raise
    def ClearBuffer(self):
        try:
            return USBCAN_DLL.VCI_ClearBuffer(self.device,  self.device_index, self.channel)
            return USBCAN_DLL.VCI_ClearBuffer(self.device, self.device_index,
                                              self.channel)
        except:
            self.logger.error("Exception on USBCAN_ClearBuffer!")
            raise
    def GetReceiveNum(self):
        try:
            return USBCAN_DLL.VCI_GetReceiveNum(self.device, self.device_index, self.channel)
            return USBCAN_DLL.VCI_GetReceiveNum(self.device, self.device_index,
                                                self.channel)
        except:
            self.logger.error("Exception on USBCAN_GetReceiveNum!")
            raise
@@ -381,22 +415,25 @@
        # (msg.arbitration_id, 0, 0, 1, msg.is_remote_frame,
        #                           extern_flag, msg.dlc, (c_ubyte * 8)(*msg.data), (c_ubyte * 3)(*[0, 0, 0]))
        USBCAN_DLL.VCI_Transmit(
            self.device, self.device_index, self.channel, byref(raw_message), 1)
        USBCAN_DLL.VCI_Transmit(self.device, self.device_index, self.channel,
                                byref(raw_message), 1)
    def Receive(self, len=10, timeout=None):
        raw_message = (VCI_CAN_OBJ*len)()
        timeout = -1 if timeout is None else c_int(timeout * 1000)
        msg = list()
        rtn = USBCAN_DLL.VCI_Receive(
            self.device, self.device_index, self.channel, byref(raw_message), len, timeout)
        rtn = USBCAN_DLL.VCI_Receive(self.device,
                                     self.device_index, self.channel,
                                     byref(raw_message), len, timeout)
        if rtn == 0xFFFFFFFF or rtn == 0:
            return None, False
        else:
            for i in range(rtn):
                msg.append(Message(
                    timestamp=raw_message[i].TimeStamp if raw_message[i].TimeFlag else 0.0,
                msg.append(
                    Message(
                        timestamp=raw_message[i].TimeStamp
                        if raw_message[i].TimeFlag else 0.0,
                    arbitration_id=raw_message[i].ID,
                    is_remote_frame=raw_message[i].RemoteFlag,
                    channel=0,
@@ -405,7 +442,8 @@
                ))
            return (msg, rtn)
    def ListeningMsg(self, connectRet, needClose,  msgQueue: Queue, sendQueue: Queue):
    def ListeningMsg(self, connectRet, needClose, msgQueue: Queue,
                     sendQueue: Queue):
        '''call by single process to deal can messages.
        Arguments:
            connectRet {Value} -- return value of connection
@@ -436,5 +474,6 @@
                    for i in range(num):
                        msgQueue.put(revRet[i])
                        self.logger.info(
                            "received can message.it't id is:{}".format(str(revRet[i].arbitration_id)))
                            "received can message.it't id is:{}".format(
                                str(revRet[i].arbitration_id)))
                time.sleep(0.05)
dbc.py
@@ -22,8 +22,10 @@
UNSIGNED = 0
SIGNED = 1
def normalizeValueTable(table):
    return {int(k): v for k, v in table.items()}
@attr.s(cmp=False)
class Frame:
@@ -100,7 +102,8 @@
        for sig in self.signals:
            i += 1
            for bit in range(sig.getStartbit(),  sig.getStartbit() + int(sig.size)):
            for bit in range(sig.getStartbit(),
                             sig.getStartbit() + int(sig.size)):
                if sig.is_little_endian:
                    bitfieldLe[bit] = i
                else:
@@ -114,7 +117,6 @@
            for j in range(0,8):
                if bitfield[i*8+j] == 0:
                    bitfield[i*8+j] = bitfieldBe[i*8+j]
        return bitfield
@@ -156,11 +158,13 @@
    #    offset = attr.ib(converter = float_factory, default = 0.0)
    min  = attr.ib(converter=float_factory)
    @min.default
    def setDefaultMin(self):
        return  self.calcMin()
    max =  attr.ib(converter = float_factory)
    @max.default
    def setDefaultMax(self):
        return  self.calcMax()
@@ -175,7 +179,9 @@
    enumeration = attr.ib(type=str, default = None)
    comments = attr.ib(type=dict, default = attr.Factory(dict))
    attributes = attr.ib(type=dict, default = attr.Factory(dict))
    values = attr.ib(type=dict, converter=normalizeValueTable, default = attr.Factory(dict))
    values = attr.ib(type=dict,
                     converter=normalizeValueTable,
                     default=attr.Factory(dict))
    calc_min_for_none = attr.ib(type=bool, default = True)
    calc_max_for_none = attr.ib(type=bool, default = True)
    muxValMax = attr.ib(default = 0)
@@ -184,7 +190,6 @@
    def __attrs_post_init__(self):
        self.multiplex = self.multiplexSetter(self.multiplex)
    @property
    def spn(self):
@@ -253,7 +258,8 @@
            startBitInternal = startBitInternal + self.size - 1
        # bit numbering not consistent with byte order. reverse
        if bitNumbering is not None and bitNumbering != self.is_little_endian:
            startBitInternal = startBitInternal - (startBitInternal % 8) + 7 - (startBitInternal % 8)
            startBitInternal = startBitInternal - (
                startBitInternal % 8) + 7 - (startBitInternal % 8)
        return int(startBitInternal)
    def calculateRawRange(self):
@@ -304,15 +310,12 @@
                    value = value_key
                    break
            else:
                raise ValueError(
                        "{} is invalid value choice for {}".format(value, self)
                )
                raise ValueError("{} is invalid value choice for {}".format(
                    value, self))
        if not (self.min <= value <= self.max):
            print(
                "Value {} is not valid for {}. Min={} and Max={}".format(
                    value, self, self.min, self.max)
                )
            print("Value {} is not valid for {}. Min={} and Max={}".format(
                value, self, self.min, self.max))
        raw_value = (value - self.offset) / self.factor
        if not self.is_float:
@@ -338,7 +341,9 @@
    def __str__(self):
        return self.name
class DBC:
    def __init__(self, dbcfile=None):
        self.filePath = dbcfile
        self.frames = self.__load()
@@ -349,7 +354,7 @@
        frameList = []
        i = 0
        frame = None
        with open(self.filePath, mode='r', encoding='gb2312') as f:
        with open(self.filePath, mode='r', encoding=dbcImportEncoding) as f:
            for line in f.readlines():
                i = i + 1
                l = line.strip()
@@ -358,11 +363,11 @@
                # logging.info(l)
                if l.startswith('BO_ '):
                    # frames
                    regexp = re.compile("^BO\_ ([^\ ]+) ([^\ ]+) *: ([^\ ]+) ([^\ ]+)")
                    regexp = re.compile(
                        "^BO\_ ([^\ ]+) ([^\ ]+) *: ([^\ ]+) ([^\ ]+)")
                    temp = regexp.match(l)
                    # name, id, dlc, transmitters
                    frame = Frame(
                        temp.group(2),
                    frame = Frame(temp.group(2),
                        id=int(temp.group(1)),
                        size=int(temp.group(3)),
                        transmitters=temp.group(4).split())
@@ -375,12 +380,14 @@
                    temp = regexp.match(l)
                    if temp:
                        extras = {}
                        receiver = list(map(str.strip, temp.group(11).split(',')))
                        tempSig = Signal(
                            temp.group(1),
                        receiver = list(
                            map(str.strip,
                                temp.group(11).split(',')))
                        tempSig = Signal(temp.group(1),
                            startBit=int(temp.group(2)),
                            size=int(temp.group(3)),
                            is_little_endian=(int(temp.group(4)) == 1),
                                         is_little_endian=(int(
                                             temp.group(4)) == 1),
                            is_signed=(temp.group(5) == '-'),
                            factor=temp.group(6),
                            offset=temp.group(7),
@@ -388,17 +395,19 @@
                            max=temp.group(9),
                            unit=temp.group(10),
                            receiver=receiver,
                            **extras
                        )
                                         **extras)
                        if not tempSig.is_little_endian:
                            # startbit of motorola coded signals are MSB in dbc
                            tempSig.setStartbit(int(temp.group(2)), bitNumbering=1)
                            tempSig.setStartbit(int(temp.group(2)),
                                                bitNumbering=1)
                        frame.signals.append(tempSig)
                    else:
                        pattern = "^SG\_ +(\w+) +(\w+) *: *(\d+)\|(\d+)@(\d+)([\+|\-]) +\(([0-9.+\-eE]+),([0-9.+\-eE]+)\) +\[([0-9.+\-eE]+)\|([0-9.+\-eE]+)\] +\"(.*)\" +(.*)"
                        regexp = re.compile(pattern)
                        temp = regexp.match(l)
                        receiver = list(map(str.strip, temp.group(12).split(',')))
                        receiver = list(
                            map(str.strip,
                                temp.group(12).split(',')))
                        multiplex = temp.group(2)
                        is_complex_multiplexed = False
@@ -417,11 +426,11 @@
                        extras = {}
                        tempSig = Signal(
                            temp.group(1),
                        tempSig = Signal(temp.group(1),
                            startBit=int(temp.group(3)),
                            size=int(temp.group(4)),
                            is_little_endian=(int(temp.group(5)) == 1),
                                         is_little_endian=(int(
                                             temp.group(5)) == 1),
                            is_signed=(temp.group(6) == '-'),
                            factor=temp.group(7),
                            offset=temp.group(8),
@@ -430,8 +439,7 @@
                            unit=temp(11),
                            receiver=receiver,
                            multiplex=multiplex,
                            **extras
                        )
                                         **extras)
                        if is_complex_multiplexed:
                            tempSig.is_multiplexer = True
@@ -439,7 +447,8 @@
                        if not tempSig.is_little_endian:
                            # startbit of motorola coded signals are MSB in dbc
                            tempSig.setStartbit(int(temp.group(3)), bitNumbering=1)
                            tempSig.setStartbit(int(temp.group(3)),
                                                bitNumbering=1)
                        frame.addSignal(tempSig)
                        if is_complex_multiplexed:
@@ -468,8 +477,10 @@
                        if testF.id == int(tmpId):
                            for signal in testF.signals:
                                if signal.name == signalName:
                                    for i in range(math.floor(len(tempList) / 2)):
                                        signal.values[tempList[i * 2].strip()] = tempList[i * 2 + 1].strip()
                                    for i in range(
                                            math.floor(len(tempList) / 2)):
                                        signal.values[tempList[i * 2].strip(
                                        )] = tempList[i * 2 + 1].strip()
                                    break
                            break
                elif l.startswith("VAL_TABLE_ "):
@@ -491,7 +502,8 @@
                    regexp = re.compile("^BA\_ +\"[A-Za-z0-9[\-_ .]+\" +(.+)")
                    tempba = regexp.match(l)
                    if tempba.group(1).strip().startswith("BO_ "):
                        regexp = re.compile(r"^BA_ +\"(.*)\" +BO_ +(\w+) +(.+);")
                        regexp = re.compile(
                            r"^BA_ +\"(.*)\" +BO_ +(\w+) +(.+);")
                        temp = regexp.match(l)
                        tempId = temp.group(2)
                        for testF in frameList:
@@ -501,10 +513,12 @@
                            tempCys = temp.group(3)
                            frame.cycle = int(tempCys)
                elif l.startswith("SIG_GROUP_ "):
                    regexp = re.compile("^SIG\_GROUP\_ +(\w+) +(\w+) +(\w+) +\:(.*);")
                    regexp = re.compile(
                        "^SIG\_GROUP\_ +(\w+) +(\w+) +(\w+) +\:(.*);")
                    temp = regexp.match(l)
                elif l.startswith("SIG_VALTYPE_ "):
                    regexp = re.compile("^SIG\_VALTYPE\_ +(\w+) +(\w+)\s*\:(.*);")
                    regexp = re.compile(
                        "^SIG\_VALTYPE\_ +(\w+) +(\w+)\s*\:(.*);")
                    temp = regexp.match(l)
                elif l.startswith("BA_DEF_DEF_ "):
                    pattern = "^BA\_DEF\_DEF\_ +\"([A-Za-z0-9\-_\.]+)\" +(.+)\;"
@@ -527,7 +541,7 @@
        for frame in self.frames:
            # if frame.size == 0:
            frame.calcDLC()
            print(frame.id, frame.size)
            # print(frame.id, frame.size)
            if frame.size > 8:
                frame.is_fd = True
    
@@ -615,7 +629,11 @@
                break
        return ret
if __name__ == '__main__':
    testDbc = DBC("data/SX7H.dbc")
    testDbc = DBC("DBC/DFLZM.dbc")
    abc=testDbc.analyzer(msgid=1056, data='40 01 C8 00 FF 00 00 00')
    print(abc)
    print(abc[5]["name"])
    print(abc[6]["name"])
    print(abc[4]["name"])
main.ui
@@ -194,7 +194,7 @@
           <string notr="true"/>
          </property>
          <property name="currentIndex">
           <number>3</number>
           <number>2</number>
          </property>
          <widget class="QWidget" name="tab">
           <attribute name="title">
styleSheet.py
New file
@@ -0,0 +1,9 @@
FunctionButton_defaultStyle = "background-color: rgb(123, 123, 123);\n" + "color: rgb(255,255,255);  \n" + "border-radius: 30px; \n" + "font: 9pt \"AcadEref\";\n" + "border-style: outset;"
FunctionButton_activeStyle = "background-color: rgb(0, 255, 0);\n" + "color: rgb(255,255,255);  \n" + "border-radius: 30px; \n" + "font: 9pt \"AcadEref\";\n" + "border-style: outset;"
FunctionButton_faultStyle = "background-color: rgb(255,0,  0);\n" + "color: rgb(255,255,255);  \n" + "border-radius: 30px; \n" + "font: 9pt \"AcadEref\";\n" + "border-style: outset;"
Style_dic = {
    0: FunctionButton_defaultStyle,
    1: FunctionButton_activeStyle,
    2: FunctionButton_faultStyle
}
uds/client.py
File was deleted
widgets/ShifterTool.py
@@ -1,6 +1,6 @@
from ast import Not, Pass
from concurrent.futures import thread
from curses import flash
from logging import exception
import threading
from typing import List
@@ -14,17 +14,19 @@
from isotp import CanMessage
import queue
from USBCAN import *
from Shifter import AsciiCodec, ShifterClass
from Shifter import *
from styleSheet import *
from mainwindows import Ui_MainWindow
from PySide2 import QtWidgets, QtCore, QtGui
import struct
import time
import datetime
from ShifterDefine import *
from multiprocessing import Array, Pool, Process, Queue, Value, Pipe
from multiprocessing import Process, Queue, Value, Pipe
MAX_RCV_NUM = 20
APP_ADDR_LOCATION_OFFSET = 8
APP_LENGTH_LOCATION_OFFSET = 12
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
formatter = logging.Formatter(
@@ -33,8 +35,9 @@
consoleHandler = logging.StreamHandler()
consoleHandler.setLevel(logging.DEBUG)
fileHandler = logging.FileHandler(
    './log/ShiftTool.log', mode='a', encoding='UTF-8')
fileHandler = logging.FileHandler('./log/ShiftTool.log',
                                  mode='a',
                                  encoding='UTF-8')
fileHandler.setLevel(logging.NOTSET)
consoleHandler.setFormatter(formatter)
@@ -55,6 +58,7 @@
class HardwreDevice():
    def __init__(self):
        self.device_type = 4
        self.channel = 0  # can_index
@@ -63,6 +67,7 @@
class PeriodSendThread(object):
    def __init__(self, period_func, args=[], kwargs={}):
        self._thread = threading.Thread(target=self._run)
        self._function = period_func
@@ -117,12 +122,13 @@
            self.isotp_layer = isotp_layer
            assert isinstance(
                self.isotp_layer, isotp.TransportLayer), 'isotp_layer must be a valid isotp.TransportLayer '
                self.isotp_layer, isotp.TransportLayer
            ), 'isotp_layer must be a valid isotp.TransportLayer '
        def open(self):
            self.exit_requested = False
            self._read_thread = threading.Thread(
                None, target=self.rxthread_task)
            self._read_thread = threading.Thread(None,
                                                 target=self.rxthread_task)
            self._read_thread.start()
            self.opened = True
            logger.info('Connection opened')
@@ -150,7 +156,8 @@
            if self.mtu is not None:
                if len(payload) > self.mtu:
                    logger.warning(
                        "Truncating payload to be set to a length of %d" % (self.mtu))
                        "Truncating payload to be set to a length of %d" %
                        (self.mtu))
                    payload = payload[0:self.mtu]
            # isotp.protocol.TransportLayer uses byte array. udsoncan is strict on bytes format
@@ -172,12 +179,14 @@
            if timedout:
                raise TimeoutException(
                    "Did not receive frame IsoTP Transport layer in time (timeout=%s sec)" % timeout)
                    "Did not receive frame IsoTP Transport layer in time (timeout=%s sec)"
                    % timeout)
            if self.mtu is not None:
                if frame is not None and len(frame) > self.mtu:
                    logger.warning(
                        "Truncating received payload to a length of %d" % (self.mtu))
                        "Truncating received payload to a length of %d" %
                        (self.mtu))
                    frame = frame[0:self.mtu]
            # isotp.protocol.TransportLayer uses bytearray. udsoncan is strict on bytes format
@@ -204,8 +213,9 @@
                    while self.isotp_layer.available():
                        # isotp_conn.send(self.isotp_layer.recv())
                        self.IsoTPtoUDSQueue.put(self.isotp_layer.recv())
                        self.logger.debug("IsoTPtoUDSQueue queue size is now %d" % (
                            self.IsoTPtoUDSQueue.qsize()))
                        self.logger.debug(
                            "IsoTPtoUDSQueue queue size is now %d" %
                            (self.IsoTPtoUDSQueue.qsize()))
                        # time.sleep(self.isotp_layer.sleep_time())
                    time.sleep(0.001)
@@ -237,8 +247,11 @@
        self.DeviceInit()
        self.WidgetsInit()
        self.ChnInfoUpdate(self._isOpen)
        self.drv_data: bytes = [0x1c, 0x01, 0x06, 0x80,
                                0x1f, 0x01, 0x06, 0x80, 0xfb, 0x0a]
        self.in_programming = False
        self.startfromboot = False
        self.drv_data = [
            0x1c, 0x01, 0x06, 0x80, 0x1f, 0x01, 0x06, 0x80, 0xfb, 0x0a
        ]
        self.app_data: bytes = None
    def DeviceInit(self):
@@ -275,26 +288,33 @@
            'squash_stmin_requirement': False
        }
        self._isotpaddr_PHYS = isotp.Address(
            isotp.AddressingMode.Normal_11bits, txid=self.shifter.canid.phy_rxId, rxid=self.shifter.canid.phy_txId)
            isotp.AddressingMode.Normal_11bits,
            txid=self.shifter.canid.phy_rxId,
            rxid=self.shifter.canid.phy_txId)
        self._isotpaddr_FUNC = isotp.Address(
            isotp.AddressingMode.Normal_11bits, txid=self.shifter.canid.fun_rxId, rxid=self.shifter.canid.phy_txId)
            isotp.AddressingMode.Normal_11bits,
            txid=self.shifter.canid.fun_rxId,
            rxid=self.shifter.canid.phy_txId)
        # self._isotpaddr_EPS = isotp.Address(
        #     isotp.AddressingMode.Normal_11bits, txid=EPS_RX_ID_PHYS, rxid=EPS_TX_ID)
        # self._isotpaddr_EPS4wd = isotp.Address(
        #     isotp.AddressingMode.Normal_11bits, txid=EPS4wd_RX_ID_PHYS, rxid=EPS4wd_TX_ID)
        self.isotp_layer = isotp.TransportLayer(
            rxfn=self.isotp_rcv, txfn=self.isotp_send, address=self._isotpaddr_PHYS, params=self.isotp_params)
        self.isotp_layer = isotp.TransportLayer(rxfn=self.isotp_rcv,
                                                txfn=self.isotp_send,
                                                address=self._isotpaddr_PHYS,
                                                params=self.isotp_params)
        self.conn = ShifterTool.IsoTpConnection(isotp_layer=self.isotp_layer)
        self.udsclient = Client(self.conn, request_timeout=2)
        self.udsclient.config['security_algo'] = self.SecAlgo
        self.udsclient.config['security_algo_params'] = [
            0x11223344, 0x20AA097B, 0x11223344, 0x70237577]
            0x11223344, 0x20AA097B, 0x11223344, 0x70237577
        ]
        self.udsclient.config['data_identifiers'] = self.shifter.did_config
        self.udsclient.config['server_address_format'] = 32
        self.udsclient.config['server_memorysize_format'] = 32
    def SecAlgo(self, level, seed, params):
    def SecAlgo(self, level, seed, params=None):
        """
        Builds the security key to unlock a security level.
@@ -311,8 +331,8 @@
        self.output_key[2] = ((temp_key[1] & 0xFC) >> 2) | (temp_key[0] & 0xC0)
        self.output_key[3] = ((temp_key[0] & 0x0F) << 4) | (temp_key[3] & 0x0F)
        """
        temp_key = (seed[0] << 24) | (
            seed[1] << 16) | (seed[2] << 8) | (seed[3])
        temp_key = (seed[0] << 24) | (seed[1] << 16) | (seed[2] << 8) | (
            seed[3])
        if level == 0x01:
            output_key_temp = 0x20AA097B
            # output_key_temp = ((((temp_key >> 4) ^ temp_key)
@@ -337,8 +357,10 @@
        else:
            output_key_temp = temp_key
        output_key = struct.pack('BBBB', (output_key_temp >> 24) & 0xFF, (
            output_key_temp >> 16) & 0xFF, (output_key_temp >> 8) & 0xFF, output_key_temp & 0xFF)
        output_key = struct.pack('BBBB', (output_key_temp >> 24) & 0xFF,
                                 (output_key_temp >> 16) & 0xFF,
                                 (output_key_temp >> 8) & 0xFF,
                                 output_key_temp & 0xFF)
        return output_key
@@ -430,7 +452,8 @@
        self.UI.radioButton.toggled.connect(self.TestPresentEvent)
        self.UI.pushButton_48.clicked.connect(self.start_programming)
        seff.UI.pushButton_46.clicked.connect(self.loadAppfile)
        self.UI.pushButton_46.clicked.connect(self.loadAppfile)
        self.UI.radioButton_2.toggled.connect(self.SetFromBootFlag)
    def _formatMsgData(self, index, item, received):
        '''msg data to list
@@ -463,8 +486,8 @@
        else:
            data.append('标准帧')
        data.append(' '.join(['0x' +
                              '{:0<2x}'.format(a).upper() for a in list(item.data)]))
        data.append(' '.join(
            ['0x' + '{:0<2x}'.format(a).upper() for a in list(item.data)]))
        return data
    def can_thread_stop(self):
@@ -491,7 +514,6 @@
                                # conn.send(msg[i])  # pipe connection send
                                self.CANtoIsoTPQueue.put(
                                    msg[i])  # send msg to isotp
                                print('收到77A')
                            self.msgQueue.put(msg[i])
                            # logger.info('time:'.format(msg[i].timestamp)+'Rx: ID=0x{:0<3x} '.format(msg[i].arbitration_id) + ' '.join(['0x' +
@@ -522,13 +544,15 @@
        if self._isOpen.value == 0:
            if self._usbcan is None:
                self.update_HardwareDevice()
                can_filters = [
                    {'can_id': 0x420, 'can_mask': 0xFFFFFFFF}]
                can_filters = [{'can_id': 0x420, 'can_mask': 0xFFFFFFFF}]
                bitrate = list(TIMING_DICT.keys())[
                    self.devicedescription.baudrate]
                self._usbcan = USBCAN(device_type=4, device_index=0,
                                      can_index=0, bitrate=bitrate, can_filters=can_filters)
                bitrate = list(
                    TIMING_DICT.keys())[self.devicedescription.baudrate]
                self._usbcan = USBCAN(device_type=4,
                                      device_index=0,
                                      can_index=0,
                                      bitrate=bitrate,
                                      can_filters=can_filters)
                if not self._usbcan.InitAndStart():
                    logger.info("Open usbcan device fail.")
@@ -550,7 +574,8 @@
    def update_HardwareDevice(self):
        self.devicedescription.device_type = self.UI.comboBox_2.currentIndex()+3
        self.devicedescription.device_type = self.UI.comboBox_2.currentIndex(
        ) + 3
        self.devicedescription.channel = self.UI.comboBox_5.currentIndex()
        self.devicedescription.baudrate = self.UI.comboBox_3.currentIndex()
@@ -559,13 +584,14 @@
            self.UI.pushButton.setText("Close CAN")
        elif self.needdisconnect.value == 1:
            self.UI.pushButton.setText("Open CAN")
    # set ui info
    def _StartlistenMsgProcess(self):
        self.msgProcess = Process(
            name='pyUSBCANListener',
        self.msgProcess = Process(name='pyUSBCANListener',
            target=self._usbcan.ListeningMsg,
            args=(self._isOpen, self.needdisconnect, self.msgQueue, self.sendQueue))
                                  args=(self._isOpen, self.needdisconnect,
                                        self.msgQueue, self.sendQueue))
        self.msgProcess.daemon = True
        self.msgProcess.start()
        # 1.5s后检测连接状态,该值可能需要标定
@@ -575,15 +601,19 @@
            time.sleep(0.1)
    def disp_string(self, out_s):
        dt = datetime.now()
        dt = datetime.datetime.now()
        nowtime_str = dt.strftime('%I:%M:%S')  # time
        self.textEdit_2.insertPlainText(nowtime_str + ': ')
        cursor = self.textEdit_2.textCursor()
        self.UI.textEdit_2.insertPlainText(nowtime_str + ': ')
        cursor = self.UI.textEdit_2.textCursor()
        cursor.movePosition(QtGui.QTextCursor.End)
        self.textEdit_2.setTextCursor(cursor)
        self.textEdit_2.insertPlainText(str(out_s+"\t\n"))
        self.UI.textEdit_2.setTextCursor(cursor)
        self.UI.textEdit_2.insertPlainText(str(out_s + "\t\n"))
        # self.statusbar.showMessage(str(out))
    def dispShiftstatus(self):
        self.UI.pushButton_41.setStyleSheet(
            Style_dic[self.shifter.UnlockButton])
        self.UI.pushButton_40.setStyleSheet(Style_dic[self.shifter.Pbutton])
    def _updateRootList(self):
        _dataSize = self.msgQueue.qsize()
@@ -594,9 +624,11 @@
        for i in range(_dataSize):
            receiveNum += 1
            msg = self.msgQueue.get()
            self.shifter.FramUnpack(msg.arbitration_id, msg.data)
            formateddata.append(self._formatMsgData(
                receiveNum, msg, True))  # return a data list
        self._insertDataSmooth(data=formateddata, datasize=_dataSize)
        # self.dispShiftstatus()
    def _insertDataSmooth(self, data, datasize):
        # row = 6-datasize
@@ -628,8 +660,8 @@
    def sessioncontrol_req(self):
        sesson = self.UI.comboBox.currentIndex() + 1
        t = threading.Thread(
            target=self.udsclient.change_session, args=(sesson,))
        t = threading.Thread(target=self.udsclient.change_session,
                             args=(sesson, ))
        t.start()
        t.join()
        # self.udsclient.change_session(sesson)
@@ -682,8 +714,8 @@
    def DID_display(self):
        # print(self.UI.comboBox_6.currentText())
        self.UI.lineEdit.setText("0x{:0<4x}".
                                 format((DID_dic[self.UI.comboBox_6.currentText()])))
        self.UI.lineEdit.setText("0x{:0<4x}".format(
            (DID_dic[self.UI.comboBox_6.currentText()])))
    def ReadDataByID(self):
        tempdid = DID_dic[self.UI.comboBox_6.currentText()]
@@ -701,8 +733,8 @@
            req = 1
        else:
            req = 3
        self.udsclient.communication_control(
            control_type=0, communication_type=req)
        self.udsclient.communication_control(control_type=0,
                                             communication_type=req)
    def StartCalibraiton(self):
        startcmd = bytearray([0x0, 0x0, 0x0, 0x0])
@@ -768,13 +800,20 @@
        resp_1 = self.udsclient.start_routine(routine_id=routine_id, data=data)
        return resp_1.positive
    def pre_programming(self):
    def SetFromBootFlag(self):
        self.startfromboot = self.UI.radioButton_2.isChecked()
    def pre_programming(self):
        if not self.startfromboot:
        self.disp_string('# 预编程步骤')
        # 进入extended session
        self.disp_string('>>> 进入扩展模式')
        response = self.udsclient.change_session(3)
            if response.positive:
                self.disp_string('>>> 解锁安全访问')
                response = self.udsclient.unlock_security_access(9)
        if response.positive:
            # 检查编程条件
            self.disp_string('>>> 检查编程条件')
@@ -795,8 +834,11 @@
        # print(response)
    def main_programming(self):
        self.disp_string('# 主编程步骤')
        if self.startfromboot:
            self.disp_string('>>> 进入扩展模式')
            response = self.udsclient.change_session(3)
        # 进入programming session
        self.disp_string('>>> 进入编程模式')
@@ -807,49 +849,40 @@
            self.disp_string('>>> 安全访问')
            response = self.udsclient.unlock_security_access(9)
        # print(response)
        if response.positive:
            self.disp_string('>>> 请求下载驱动文件')
            address = 0x20004600
            memorysize = 10
            memory_location = MemoryLocation(address, memorysize, 32, 32)
            response = self.udsclient.request_download(memory_location)
        # print(response)
        if response.positive:
            # 发送driver文件
            self.disp_string('>>> 发送driver文件')
            drv_file = self.drv_data
            address = drv_file[16] << 24 | drv_file[17] << 16 | drv_file[
                18] << 8 | drv_file[19] << 0
            memorysize = drv_file[20] << 24 | drv_file[21] << 16 | drv_file[
                22] << 8 | drv_file[23] << 0
            memory_location = MemoryLocation(address, memorysize, 32, 32)
            response = self.udsclient.request_download(memory_location)
        # print(response)
            max_length = response.service_data.max_length
        # 有效数据长度, 去除sid和sequence两个字节
            payload_length = max_length - 2
            count = (len(drv_file) + payload_length - 1) // payload_length
            base = self.get_progressbar_pos()
            for i in range(count):
                start = i * payload_length
                end = start + payload_length
                response = self.udsclient.transfer_data((i + 1) % 256,
                                                        drv_file[start:end])
                self.set_progressbar_pos(base + end)
            response = self.udsclient.transfer_data(1, bytes(drv_file))
            self.set_progressbar_pos(len(drv_file))
            # print(response)
        if response.positive:
            self.disp_string('>>> 发送驱动结束,请求推出')
            response = self.udsclient.request_transfer_exit()
        # print(response)
        if response.positive:
            # driver文件完整性检验
            self.disp_string('>>> driver文件完整性检验')
            response = self.udsclient.start_routine(0xf001, drv_file[0:4])
            drivecrc = bytes([0x9B, 0x39, 0xf2, 0xec])
            response = self.udsclient.start_routine(0xf001, drivecrc)
        # print(response)
        if response.positive:
            app_file = self.app_data
            address = app_file[16] << 24 | app_file[17] << 16 | app_file[
                18] << 8 | app_file[19] << 0
            memorysize = app_file[20] << 24 | app_file[21] << 16 | app_file[
                22] << 8 | app_file[23] << 0
            address = app_file[APP_ADDR_LOCATION_OFFSET] << 24 | app_file[
                APP_ADDR_LOCATION_OFFSET + 1] << 16 | app_file[
                    APP_ADDR_LOCATION_OFFSET +
                    2] << 8 | app_file[APP_ADDR_LOCATION_OFFSET + 3] << 0
            memorysize = app_file[APP_LENGTH_LOCATION_OFFSET] << 24 | app_file[
                APP_LENGTH_LOCATION_OFFSET + 1] << 16 | app_file[
                    APP_LENGTH_LOCATION_OFFSET +
                    2] << 8 | app_file[APP_LENGTH_LOCATION_OFFSET + 3] << 0
            memory_location = MemoryLocation(address, memorysize, 32, 32)
            # 删除app存储空间
@@ -898,12 +931,11 @@
        # 回到default session
        self.disp_string('>>> 回到默认模式')
        self.udsclient.suppress_positive_response.enabled = True
        response = self.udsclient.change_session(1)
        return response.positive
    def start_programming(self):
        self.UI.pushButton_48.setDisabled(True)
        self.set_progressbar_pos(0)
        t1 = time.time()
@@ -915,13 +947,14 @@
            self.post_programming()
        except Exception as e:
            self.disp_string('%s' % e, '#ff0000')
            self.disp_string('%s' % e)
            # self.UI.pushButton_48.setDisabled(False)
        t2 = time.time()
        self.disp_string('finished in %.2f sec' % (t2 - t1))
        self.in_programming = False
        self.UI.pushButton_48.setDisabled(True)
        self.UI.pushButton_48.setDisabled(False)
    def set_progressbar_pos(self, pos):
@@ -944,7 +977,8 @@
            return
        fileName, _ = QtWidgets.QFileDialog.getOpenFileName(
            self, 'comboBox_4', '.', 'All Files (*);;Bin Files (*.bin);;Hex Files (*.hex)')
            None, 'comboBox_4', '.',
            'All Files (*);;Bin Files (*.bin);;Hex Files (*.hex)')
        if fileName != '':
            self.UI.comboBox_4.addItem(fileName)