Hemi
06.07.2023, 09:08
Guten Morgen zusammen,
erstmal sorry für die blöde Überschrift, mir ist keine vernünftige eingefallen...
Zum Problem:
Ich schreibe gerade an einer DLL, die die Verbindung zwischen einer Diagnosesoftware und dem Diagnoseinterface herstellt. Diese DLL implementiert den J2534 Standard, stellt also eine API zur Verfügung.
Es geht um diese Funktion hier:
QUOKAJ2534_API long PassThruIoctl(
unsigned long ChannelID
, unsigned long IoctlID
, void* pInput
, void* pOutput
)
{
LOG(PROTOCOL, "PassThruIoctl called with IoctlID %d", IoctlID);
switch (IoctlID)
{
case GET_CONFIG:
LOG(PROTOCOL, "Get config");
LOG_SBYTE(PROTOCOL, (SBYTE_ARRAY*)pInput);
break;
case SET_CONFIG:
break;
case READ_VBATT:
LOG(PROTOCOL, "Reading battery voltage");
*(unsigned long*)pOutput = 143 * 100;
break;
case FIVE_BAUD_INIT:
{
LOG(PROTOCOL, "Five baud init");
SBYTE_ARRAY* inputMsg = (SBYTE_ARRAY*)pInput;
if (inputMsg->NumOfBytes > 1)
{
LOG(PROTOCOL, "Wake up message length is greater than 1 Byte");
return ERR_INVALID_MSG;
}
LOG(PROTOCOL, "Wake up for ECU with id 0x%02x called", inputMsg->BytePtr[0]);
unsigned char KeyWords[2]{};
SBYTE_ARRAY outputMsg{};
LOG_SBYTE(PROTOCOL, inputMsg);
KeyWords[0] = 0x00;
KeyWords[1] = 0x81;
outputMsg.NumOfBytes = 2;
outputMsg.BytePtr = &KeyWords[0];
LOG_SBYTE(PROTOCOL, &outputMsg);
}
break;
case FAST_INIT:
break;
case CLEAR_TX_BUFFER:
break;
case CLEAR_RX_BUFFER:
break;
case CLEAR_PERIODIC_MSGS:
break;
case CLEAR_MSG_FILTERS:
break;
case CLEAR_FUNCT_MSG_LOOKUP_TABLE:
break;
case ADD_TO_FUNCT_MSG_LOOKUP_TABLE:
break;
case DELETE_FROM_FUNCT_MSG_LOOKUP_TABLE:
break;
case READ_PROG_VOLTAGE:
LOG(PROTOCOL, "Read prog voltage");
*(unsigned long*)pOutput = 10 * 1000;
break;
// J2534-2 SW_CAN
case SW_CAN_HS:
break;
case SW_CAN_NS:
break;
case SET_POLL_RESPONSE:
break;
case BECOME_MASTER:
break;
default:
break;
}
return STATUS_NOERROR;
}
und speziell um den case FIVE_BAUD_INIT.
Beim Aufruf der Funktion PassThruIoctl(...) gibt der Aufrufer (also die Diagnosesoftware) eine IoctlID (in diesem Fall 0x04, was FIVE_BAUD_INIT) und ein pInput, das ein SBYTE_ARRAY ist.
SBYTE_ARRAY sieht wie folgt aus:
typedef struct _SBYTE_ARRAY
{
unsigned long NumOfBytes; // Number of bytes in the array
unsigned char *BytePtr; // Array of bytes
} SBYTE_ARRAY;
Der Aufrufer erwartet als Antwort ebenfalls ein SBYTE_ARRAY, aber mit zwei Bytes drin. Diese zwei Bytes schreibe ich ins KeyWords rein hänge es an den BytePtr vom Array. So weit so gut, das scheint auch zu funktionieren, wenn im Log steht dann folgendes:
Zum pInput:
pInput array
Wake up for ECU with id 0x33 called
pInput array end
Absolut richtig, der Aufrufer hat eine 0x33 runtergegeben.
Und zum pOutput:
pOutput array
Byte: 0, value: 0x00
Byte: 1, value: 0x81
pOutput array end
auch richtig, ich gebe ein 0x00 und ein 0x81 rein. Passt.
Das Problem:
Beim Aufrufer kommt komplett was anderes an... mal kommt ein 0x00 und 0x00 an oder was anderes. Wenn ich es mehrmals probiere, bekomme ich unterschiedliche Werte, also völlig random...
Im Anhang ist das Bild vom Tool, mit dem ich das Ganze teste
ECU Address ist diese besagt 0x33, Keyword 1 und Keyword 2 kommen aus meiner DLL.
Das Testool kommt von einem renomierten Diagnosesoftwarehersteller, die Wahrscheinlichkeit, dass da ein Fehler ist, ist doch sehr geringt... klar, möglich aber geringt.
Andere implementierte CASEs funktionieren fehlerfrei...
Hat jemand eine Idee?
Vielen Dank im Voraus und sorry für den langen Text :)
erstmal sorry für die blöde Überschrift, mir ist keine vernünftige eingefallen...
Zum Problem:
Ich schreibe gerade an einer DLL, die die Verbindung zwischen einer Diagnosesoftware und dem Diagnoseinterface herstellt. Diese DLL implementiert den J2534 Standard, stellt also eine API zur Verfügung.
Es geht um diese Funktion hier:
QUOKAJ2534_API long PassThruIoctl(
unsigned long ChannelID
, unsigned long IoctlID
, void* pInput
, void* pOutput
)
{
LOG(PROTOCOL, "PassThruIoctl called with IoctlID %d", IoctlID);
switch (IoctlID)
{
case GET_CONFIG:
LOG(PROTOCOL, "Get config");
LOG_SBYTE(PROTOCOL, (SBYTE_ARRAY*)pInput);
break;
case SET_CONFIG:
break;
case READ_VBATT:
LOG(PROTOCOL, "Reading battery voltage");
*(unsigned long*)pOutput = 143 * 100;
break;
case FIVE_BAUD_INIT:
{
LOG(PROTOCOL, "Five baud init");
SBYTE_ARRAY* inputMsg = (SBYTE_ARRAY*)pInput;
if (inputMsg->NumOfBytes > 1)
{
LOG(PROTOCOL, "Wake up message length is greater than 1 Byte");
return ERR_INVALID_MSG;
}
LOG(PROTOCOL, "Wake up for ECU with id 0x%02x called", inputMsg->BytePtr[0]);
unsigned char KeyWords[2]{};
SBYTE_ARRAY outputMsg{};
LOG_SBYTE(PROTOCOL, inputMsg);
KeyWords[0] = 0x00;
KeyWords[1] = 0x81;
outputMsg.NumOfBytes = 2;
outputMsg.BytePtr = &KeyWords[0];
LOG_SBYTE(PROTOCOL, &outputMsg);
}
break;
case FAST_INIT:
break;
case CLEAR_TX_BUFFER:
break;
case CLEAR_RX_BUFFER:
break;
case CLEAR_PERIODIC_MSGS:
break;
case CLEAR_MSG_FILTERS:
break;
case CLEAR_FUNCT_MSG_LOOKUP_TABLE:
break;
case ADD_TO_FUNCT_MSG_LOOKUP_TABLE:
break;
case DELETE_FROM_FUNCT_MSG_LOOKUP_TABLE:
break;
case READ_PROG_VOLTAGE:
LOG(PROTOCOL, "Read prog voltage");
*(unsigned long*)pOutput = 10 * 1000;
break;
// J2534-2 SW_CAN
case SW_CAN_HS:
break;
case SW_CAN_NS:
break;
case SET_POLL_RESPONSE:
break;
case BECOME_MASTER:
break;
default:
break;
}
return STATUS_NOERROR;
}
und speziell um den case FIVE_BAUD_INIT.
Beim Aufruf der Funktion PassThruIoctl(...) gibt der Aufrufer (also die Diagnosesoftware) eine IoctlID (in diesem Fall 0x04, was FIVE_BAUD_INIT) und ein pInput, das ein SBYTE_ARRAY ist.
SBYTE_ARRAY sieht wie folgt aus:
typedef struct _SBYTE_ARRAY
{
unsigned long NumOfBytes; // Number of bytes in the array
unsigned char *BytePtr; // Array of bytes
} SBYTE_ARRAY;
Der Aufrufer erwartet als Antwort ebenfalls ein SBYTE_ARRAY, aber mit zwei Bytes drin. Diese zwei Bytes schreibe ich ins KeyWords rein hänge es an den BytePtr vom Array. So weit so gut, das scheint auch zu funktionieren, wenn im Log steht dann folgendes:
Zum pInput:
pInput array
Wake up for ECU with id 0x33 called
pInput array end
Absolut richtig, der Aufrufer hat eine 0x33 runtergegeben.
Und zum pOutput:
pOutput array
Byte: 0, value: 0x00
Byte: 1, value: 0x81
pOutput array end
auch richtig, ich gebe ein 0x00 und ein 0x81 rein. Passt.
Das Problem:
Beim Aufrufer kommt komplett was anderes an... mal kommt ein 0x00 und 0x00 an oder was anderes. Wenn ich es mehrmals probiere, bekomme ich unterschiedliche Werte, also völlig random...
Im Anhang ist das Bild vom Tool, mit dem ich das Ganze teste
ECU Address ist diese besagt 0x33, Keyword 1 und Keyword 2 kommen aus meiner DLL.
Das Testool kommt von einem renomierten Diagnosesoftwarehersteller, die Wahrscheinlichkeit, dass da ein Fehler ist, ist doch sehr geringt... klar, möglich aber geringt.
Andere implementierte CASEs funktionieren fehlerfrei...
Hat jemand eine Idee?
Vielen Dank im Voraus und sorry für den langen Text :)