From bd7f4e806147fbf89f6fe2f9eb84d8568698fb80 Mon Sep 17 00:00:00 2001 From: KruFFT Date: Sat, 15 Jun 2024 18:25:04 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=20=D0=BE=D1=82=D0=BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B8=D0=BD=D1=82=D0=B5=D1=80=D0=B2=D0=B0?= =?UTF-8?q?=D0=BB=D0=B0=20=D0=B2=D1=80=D0=B5=D0=BC=D0=B5=D0=BD=D0=B8=20?= =?UTF-8?q?=D0=BC=D0=B5=D0=B6=D0=B4=D1=83=20=D0=BF=D0=B0=D0=BA=D0=B5=D1=82?= =?UTF-8?q?=D0=B0=D0=BC=D0=B8.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- wxCAN Sniffer/CANParser.cpp | 12 ++- wxCAN Sniffer/Common.h | 25 +++-- wxCAN Sniffer/FormMain.cpp | 134 ++++++++++++++------------- wxCAN Sniffer/FormMain.h | 3 - wxCAN Sniffer/FramesContainer.cpp | 24 ++--- wxCAN Sniffer/ThreadedSerialPort.cpp | 6 +- 6 files changed, 105 insertions(+), 99 deletions(-) diff --git a/wxCAN Sniffer/CANParser.cpp b/wxCAN Sniffer/CANParser.cpp index 94b2abd..4b76603 100644 --- a/wxCAN Sniffer/CANParser.cpp +++ b/wxCAN Sniffer/CANParser.cpp @@ -8,13 +8,15 @@ bool CANParser::Parse(uint8_t** bufferHead, CANFrame& frame) { *bufferHead += 4; // сборка пакета - frame.ID = *(uint32_t*)*bufferHead; + frame.id = *(uint32_t*)*bufferHead; *bufferHead += 4; - frame.Length = *(*bufferHead)++; - if (frame.Length <= 8) + frame.interval = *(uint16_t*)*bufferHead; + *bufferHead += 2; + frame.length = *(*bufferHead)++; + if (frame.length <= 8) { - for (size_t iData = 0; iData < frame.Length; iData++) - frame.Data[iData] = *(*bufferHead)++; + for (size_t iData = 0; iData < frame.length; iData++) + frame.data[iData] = *(*bufferHead)++; return true; } diff --git a/wxCAN Sniffer/Common.h b/wxCAN Sniffer/Common.h index b012117..7024c69 100644 --- a/wxCAN Sniffer/Common.h +++ b/wxCAN Sniffer/Common.h @@ -16,7 +16,7 @@ using namespace std; -#define CAPTION wxT("CAN Sniffer 2.0.0") +#define CAPTION wxT("CAN Sniffer 2.1.0") #define SIG_BYTE_0 0xAA #define SIG_BYTE_1 0x55 @@ -24,14 +24,19 @@ using namespace std; #define SIG_BYTE_3 0x55 #define SIG_DWORD (uint32_t)(SIG_BYTE_3 << 24 | SIG_BYTE_2 << 16 | SIG_BYTE_1 << 8 | SIG_BYTE_0) +#define COM_NAME wxT("COM6") // последовательный порт по умолчанию +#define UDP_PORT 0xAA55 // UDP порт +#define UDP_BUFFER_SIZE 1000 // размер буфера приёма пакетов + // CAN-пакет для отправки данных #pragma pack (push, 1) struct CANFrame { public: - uint32_t ID; // идентификатор пакета - uint8_t Length; // длина пакета - uint8_t Data[8]; // массив данных пакета, до 8 байт + uint32_t id; // идентификатор пакета + uint16_t interval; // интервал между пакетами (мс) + uint8_t length; // длина пакета + uint8_t data[8]; // массив данных пакета, до 8 байт }; #pragma pack(pop) @@ -40,13 +45,13 @@ struct CANFrame struct VisualCANFrame { public: - CANFrame Frame; // пакет с данными - wxColour Color[8]; // цвет фона ячейки + CANFrame frame; // пакет с данными + wxColour color[8]; // цвет фона ячейки // оператор сравнения CAN-пакета необходим для сортировки - bool operator < (const VisualCANFrame& frame) const + bool operator < (const VisualCANFrame& anotherFrame) const { - return (Frame.ID < frame.Frame.ID); + return (frame.id < anotherFrame.frame.id); } }; #pragma pack(pop) @@ -65,6 +70,6 @@ struct SendCANFrame struct LogFile { public: - uint32_t ID; // идентификатор пакета - wxFFile* File; // хэндл ассоциированного файла + uint32_t id; // идентификатор пакета + wxFFile* file; // хэндл ассоциированного файла }; diff --git a/wxCAN Sniffer/FormMain.cpp b/wxCAN Sniffer/FormMain.cpp index 2719c5f..83a45ce 100644 --- a/wxCAN Sniffer/FormMain.cpp +++ b/wxCAN Sniffer/FormMain.cpp @@ -32,7 +32,7 @@ FormMain::FormMain() : wxFrame(nullptr, ID_MAIN_FORM, CAPTION, wxDefaultPosition { // иконка this->SetIcon(wxICON(wxicon)); - this->SetSizeHints(wxSize(940, 600)); + this->SetSizeHints(wxSize(1110, 600)); // главный сайзер окна wxBoxSizer* sizerMain = new wxBoxSizer(wxHORIZONTAL); @@ -47,7 +47,7 @@ FormMain::FormMain() : wxFrame(nullptr, ID_MAIN_FORM, CAPTION, wxDefaultPosition { gridCANView = new wxGrid(panelLeftTop, ID_GRID_CAN_VIEW); // параметры сетки - gridCANView->CreateGrid(0, 10); + gridCANView->CreateGrid(0, 11); gridCANView->EnableEditing(false); gridCANView->EnableGridLines(true); gridCANView->EnableDragGridSize(false); @@ -64,19 +64,20 @@ FormMain::FormMain() : wxFrame(nullptr, ID_MAIN_FORM, CAPTION, wxDefaultPosition gridCANView->SetDefaultCellAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE); // заполнение таблицы gridCANView->SetColLabelValue(0, wxT("CAN ID")); - gridCANView->SetColLabelValue(1, wxT("Длина")); - gridCANView->SetColLabelValue(2, wxT("Байт 0")); - gridCANView->SetColLabelValue(3, wxT("Байт 1")); - gridCANView->SetColLabelValue(4, wxT("Байт 2")); - gridCANView->SetColLabelValue(5, wxT("Байт 3")); - gridCANView->SetColLabelValue(6, wxT("Байт 4")); - gridCANView->SetColLabelValue(7, wxT("Байт 5")); - gridCANView->SetColLabelValue(8, wxT("Байт 6")); - gridCANView->SetColLabelValue(9, wxT("Байт 7")); + gridCANView->SetColLabelValue(1, wxT("Интервал")); + gridCANView->SetColLabelValue(2, wxT("Длина")); + gridCANView->SetColLabelValue(3, wxT("Байт 0")); + gridCANView->SetColLabelValue(4, wxT("Байт 1")); + gridCANView->SetColLabelValue(5, wxT("Байт 2")); + gridCANView->SetColLabelValue(6, wxT("Байт 3")); + gridCANView->SetColLabelValue(7, wxT("Байт 4")); + gridCANView->SetColLabelValue(8, wxT("Байт 5")); + gridCANView->SetColLabelValue(9, wxT("Байт 6")); + gridCANView->SetColLabelValue(10, wxT("Байт 7")); // установка ширины столбцов - for (size_t iCol = 0; iCol < 10; iCol++) + for (size_t iCol = 0; iCol < 11; iCol++) { - gridCANView->SetColSize(iCol, 50); + gridCANView->SetColSize(iCol, 60); } sizerLeftTop->Add(gridCANView, 1, wxEXPAND, 0); @@ -543,11 +544,11 @@ void FormMain::ProcessCANFrame(CANFrame& frame) bool found = false; // если это пакет с адресом 000 - это статистика и её надо вывести отдельно - if (frame.ID == 0 && frame.Length >= 4) + if (frame.id == 0 && frame.length >= 4) { - uint16_t fps = ((uint16_t)frame.Data[0] << 8) + (uint16_t)frame.Data[1]; + uint16_t fps = ((uint16_t)frame.data[0] << 8) + (uint16_t)frame.data[1]; textFPS->SetValue(wxString::Format(wxT("%i"), fps)); // кадров в секунду - uint16_t bps = ((uint16_t)frame.Data[2] << 8) + (uint16_t)frame.Data[3]; + uint16_t bps = ((uint16_t)frame.data[2] << 8) + (uint16_t)frame.data[3]; textBPS->SetValue(wxString::Format(wxT("%i"), bps)); // байтов в секунду } else @@ -568,7 +569,7 @@ void FormMain::ProcessCANFrame(CANFrame& frame) { for (size_t iLog = 0; iLog < logFilterIDs.size(); iLog++) { - if (frame.ID == logFilterIDs[iLog]) + if (frame.id == logFilterIDs[iLog]) { SaveToLog(frame); } @@ -576,21 +577,21 @@ void FormMain::ProcessCANFrame(CANFrame& frame) } // если ожидается ответ от этого ID - добавить его в список ответов - if (frame.ID == answerID) + if (frame.id == answerID) { int32_t lastRow = gridCANLog->GetNumberRows(); gridCANLog->InsertRows(lastRow); - gridCANLog->SetCellValue(lastRow, 0, wxString::Format(wxT("%03X"), frame.ID)); - gridCANLog->SetCellValue(lastRow, 1, wxString::Format(wxT("%i"), frame.Length)); + gridCANLog->SetCellValue(lastRow, 0, wxString::Format(wxT("%03X"), frame.id)); + gridCANLog->SetCellValue(lastRow, 1, wxString::Format(wxT("%i"), frame.length)); // заполнение столбцов параметров for (size_t iData = 0; iData < 8; iData++) { - if (iData < frame.Length) + if (iData < frame.length) { // вывод данных - gridCANLog->SetCellValue(lastRow, iData + 2, wxString::Format(wxT("%02X"), frame.Data[iData])); + gridCANLog->SetCellValue(lastRow, iData + 2, wxString::Format(wxT("%02X"), frame.data[iData])); } else { @@ -616,8 +617,8 @@ void FormMain::ShowNumbers() } VisualCANFrame vFrame = frames.GetFrame(rowToView); - uint8_t firstByte = vFrame.Frame.Data[colToView]; - uint8_t secondByte = colToView < 7 ? vFrame.Frame.Data[colToView + 1] : 0; + uint8_t firstByte = vFrame.frame.data[colToView]; + uint8_t secondByte = colToView < 7 ? vFrame.frame.data[colToView + 1] : 0; // выбор между big endian и little endian uint32_t value = bigEndian ? (firstByte << 8) + secondByte : (secondByte << 8) + firstByte; @@ -670,14 +671,14 @@ void FormMain::ButtonAdd_OnClick(wxCommandEvent& event) bool found = false; for (size_t iID = 0; iID < logFilterIDs.size(); iID++) { - if (frames.GetFrame(rowToLog).Frame.ID == logFilterIDs[iID]) + if (frames.GetFrame(rowToLog).frame.id == logFilterIDs[iID]) { found = true; break; } } if (!found) - logFilterIDs.push_back(frames.GetFrame(rowToLog).Frame.ID); + logFilterIDs.push_back(frames.GetFrame(rowToLog).frame.id); } RefreshListLog(); @@ -789,10 +790,10 @@ void FormMain::SaveToLog(CANFrame& frame) for (size_t iFile = 0; iFile < logFiles.size(); iFile++) { // проверка существования потока - if (logFiles[iFile].ID == frame.ID) + if (logFiles[iFile].id == frame.id) { // если файл для этого кадра уже существует - просто дописать в него данные - LogWriteLine(logFiles[iFile].File, frame); + LogWriteLine(logFiles[iFile].file, frame); found = true; break; @@ -804,16 +805,16 @@ void FormMain::SaveToLog(CANFrame& frame) { try { - wxString logPath = wxGetCwd() + wxT("\\CAN ID ") + wxString::Format(wxT("%03X"), frame.ID) + logExt; + wxString logPath = wxGetCwd() + wxT("\\CAN ID ") + wxString::Format(wxT("%03X"), frame.id) + logExt; LogFile newLogFile = { 0 }; - newLogFile.File = new wxFFile(); - if (newLogFile.File->Open(logPath, wxT("a"))) + newLogFile.file = new wxFFile(); + if (newLogFile.file->Open(logPath, wxT("a"))) { - newLogFile.File->SeekEnd(); - newLogFile.ID = frame.ID; + newLogFile.file->SeekEnd(); + newLogFile.id = frame.id; logFiles.push_back(newLogFile); - LogWriteLine(logFiles[logFiles.size() - 1].File, frame); + LogWriteLine(logFiles[logFiles.size() - 1].file, frame); } } catch (...) {} @@ -833,20 +834,20 @@ void FormMain::LogWriteLine(wxFFile* file, CANFrame& frame) try { // идентификатор пакета и его длина - newLine += wxString::Format(wxT("%03X"), frame.ID) + logSeparator; - newLine += wxString::Format(wxT("%i"), frame.Length) + logSeparator; + newLine += wxString::Format(wxT("%03X"), frame.id) + logSeparator; + newLine += wxString::Format(wxT("%i"), frame.length) + logSeparator; // данные пакета - for (size_t iData = 0; iData < frame.Length; iData++) + for (size_t iData = 0; iData < frame.length; iData++) { if (logDecimal) { // десятичный вывод - newLine += wxString::Format(wxT("%0i"), frame.Data[iData]) + logSeparator; + newLine += wxString::Format(wxT("%0i"), frame.data[iData]) + logSeparator; } else { // шестнадцатиричный вывод - newLine += wxString::Format(wxT("%02X"), frame.Data[iData]) + logSeparator; + newLine += wxString::Format(wxT("%02X"), frame.data[iData]) + logSeparator; } } @@ -855,7 +856,7 @@ void FormMain::LogWriteLine(wxFFile* file, CANFrame& frame) if (logASCII) { // дополнить строку разделителями для выравнивания - for (size_t iData = frame.Length; iData < 8; iData++) + for (size_t iData = frame.length; iData < 8; iData++) { newLine += logSeparator; } @@ -863,11 +864,11 @@ void FormMain::LogWriteLine(wxFFile* file, CANFrame& frame) // добавить ASCII данные из пакета buf = newLine.ToStdString(); - for (size_t iData = 0; iData < frame.Length; iData++) + for (size_t iData = 0; iData < frame.length; iData++) { - if (frame.Data[iData] > 0x1F) + if (frame.data[iData] > 0x1F) { - buf += frame.Data[iData]; + buf += frame.data[iData]; } else { @@ -894,10 +895,10 @@ void FormMain::FlushLogs() // сбросить данные на диск для массива логов for (size_t iFile = 0; iFile < logFiles.size(); iFile++) { - logFiles[iFile].File->Flush(); - logFiles[iFile].File->Close(); - delete logFiles[iFile].File; - logFiles[iFile].File = nullptr; + logFiles[iFile].file->Flush(); + logFiles[iFile].file->Close(); + delete logFiles[iFile].file; + logFiles[iFile].file = nullptr; } // сохранить всё, если лог один @@ -984,27 +985,28 @@ void FormMain::RefreshGridCANView() for (size_t iFrame = 0; iFrame < framesCount; iFrame++) { - // вывод ID и длины пакета + // вывод ID, интервала и длины пакета VisualCANFrame vFrame = frames.GetFrame(iFrame); - gridCANView->SetCellValue(iFrame, 0, wxString::Format(wxT("%03X"), vFrame.Frame.ID)); - gridCANView->SetCellValue(iFrame, 1, wxString::Format(wxT("%i"), vFrame.Frame.Length)); + gridCANView->SetCellValue(iFrame, 0, wxString::Format(wxT("%03X"), vFrame.frame.id)); + gridCANView->SetCellValue(iFrame, 1, wxString::Format(wxT("%i"), vFrame.frame.interval)); + gridCANView->SetCellValue(iFrame, 2, wxString::Format(wxT("%i"), vFrame.frame.length)); // заполнение столбцов данных for (size_t iData = 0; iData < 8; iData++) { - if (iData < vFrame.Frame.Length) + if (iData < vFrame.frame.length) { // вывод данных - gridCANView->SetCellValue(iFrame, iData + 2, wxString::Format(wxT("%02X"), vFrame.Frame.Data[iData])); - gridCANView->SetCellBackgroundColour(iFrame, iData + 2, vFrame.Color[iData]); + gridCANView->SetCellValue(iFrame, iData + 3, wxString::Format(wxT("%02X"), vFrame.frame.data[iData])); + gridCANView->SetCellBackgroundColour(iFrame, iData + 3, vFrame.color[iData]); } else { // вывод пустых ячеек - gridCANView->SetCellValue(iFrame, iData + 2, wxT(" ")); - gridCANView->SetCellBackgroundColour(iFrame, iData + 2, wxColor(DEFAULT_COLOR)); + gridCANView->SetCellValue(iFrame, iData + 3, wxT(" ")); + gridCANView->SetCellBackgroundColour(iFrame, iData + 3, wxColor(DEFAULT_COLOR)); } - gridCANView->RefreshBlock(iFrame, 2, iFrame, 9); + gridCANView->RefreshBlock(iFrame, 3, iFrame, 9); } } } @@ -1079,61 +1081,61 @@ void FormMain::ButtonSend_OnClick(wxCommandEvent& event) // ID пакета textCANID->GetValue().ToLong(&tempValue, 16); if (tempValue >= 0 && tempValue <= 0x7FFF) - frame.ID = (uint32_t)tempValue; + frame.id = (uint32_t)tempValue; else return; // длина данных пакета textCANLength->GetValue().ToLong(&tempValue, 10); if (tempValue >= 0 && tempValue <= 8) - frame.Length = (uint8_t)tempValue; + frame.length = (uint8_t)tempValue; else return; // байт 1 textCANByte1->GetValue().ToLong(&tempValue, 16); if (tempValue >= 0 && tempValue <= 0xFF) - frame.Data[0] = (uint8_t)tempValue; + frame.data[0] = (uint8_t)tempValue; else return; // байт 2 textCANByte2->GetValue().ToLong(&tempValue, 16); if (tempValue >= 0 && tempValue <= 0xFF) - frame.Data[1] = (uint8_t)tempValue; + frame.data[1] = (uint8_t)tempValue; else return; // байт 3 textCANByte3->GetValue().ToLong(&tempValue, 16); if (tempValue >= 0 && tempValue <= 0xFF) - frame.Data[2] = (uint8_t)tempValue; + frame.data[2] = (uint8_t)tempValue; else return; // байт 4 textCANByte4->GetValue().ToLong(&tempValue, 16); if (tempValue >= 0 && tempValue <= 0xFF) - frame.Data[3] = (uint8_t)tempValue; + frame.data[3] = (uint8_t)tempValue; else return; // байт 5 textCANByte5->GetValue().ToLong(&tempValue, 16); if (tempValue >= 0 && tempValue <= 0xFF) - frame.Data[4] = (uint8_t)tempValue; + frame.data[4] = (uint8_t)tempValue; else return; // байт 6 textCANByte6->GetValue().ToLong(&tempValue, 16); if (tempValue >= 0 && tempValue <= 0xFF) - frame.Data[5] = (uint8_t)tempValue; + frame.data[5] = (uint8_t)tempValue; else return; // байт 7 textCANByte7->GetValue().ToLong(&tempValue, 16); if (tempValue >= 0 && tempValue <= 0xFF) - frame.Data[6] = (uint8_t)tempValue; + frame.data[6] = (uint8_t)tempValue; else return; // байт 8 textCANByte8->GetValue().ToLong(&tempValue, 16); if (tempValue >= 0 && tempValue <= 0xFF) - frame.Data[7] = (uint8_t)tempValue; + frame.data[7] = (uint8_t)tempValue; else return; // запомнить ID пакета, от которого ожидается ответ diff --git a/wxCAN Sniffer/FormMain.h b/wxCAN Sniffer/FormMain.h index 04857a4..6a70524 100644 --- a/wxCAN Sniffer/FormMain.h +++ b/wxCAN Sniffer/FormMain.h @@ -7,9 +7,6 @@ #define DRAW_COLOR 0x0000FF // red (BGR) #define TIMER_INTERVAL 40 // интервал срабатывания таймера обновления данных на экране (около 25 кадров/с) -#define COM_NAME wxT("COM3") // последовательный порт по умолчанию -#define UDP_PORT 0xAA55 // UDP порт -#define UDP_BUFFER_SIZE 1000 // размер буфера приёма пакетов // Идентификаторы необходимых объектов enum IDs diff --git a/wxCAN Sniffer/FramesContainer.cpp b/wxCAN Sniffer/FramesContainer.cpp index 66496ac..12f5b52 100644 --- a/wxCAN Sniffer/FramesContainer.cpp +++ b/wxCAN Sniffer/FramesContainer.cpp @@ -19,7 +19,7 @@ void FramesContainer::Clear() frames.clear(); } -// Добавить новый CAN-пакет с раскраской его данных +// Добавить данные нового CAN-пакет с раскраской его данных в таблицу void FramesContainer::AddFrame(CANFrame& frame) { // поиск ID в таблице @@ -27,44 +27,44 @@ void FramesContainer::AddFrame(CANFrame& frame) for (size_t iID = 0; iID < idCount; iID++) { // если найден - выделить яркостью цета изменяющиеся данные и заменить CAN-пакет - if (frames[iID].Frame.ID == frame.ID) + if (frames[iID].frame.id == frame.id) { // обновить данные раскраски элементов - for (size_t iData = 0; iData < frames[iID].Frame.Length; iData++) + for (size_t iData = 0; iData < frames[iID].frame.length; iData++) { // если новые данные такие же, что были ранее - необходимо плавно осветлять фоновую заливку - if (frames[iID].Frame.Data[iData] == frame.Data[iData]) + if (frames[iID].frame.data[iData] == frame.data[iData]) { - if (frames[iID].Color[iData] == NEW_COLOR) + if (frames[iID].color[iData] == NEW_COLOR) { - frames[iID].Color[iData] = CHANGE_COLOR; + frames[iID].color[iData] = CHANGE_COLOR; } else { // постепенно добавить цвет до белого в каналах G и B - uint32_t curentColorValue = frames[iID].Color[iData].GetRGBA(); + uint32_t curentColorValue = frames[iID].color[iData].GetRGBA(); if (curentColorValue < DEFAULT_COLOR) { curentColorValue += 0x00010100; - frames[iID].Color[iData] = curentColorValue; + frames[iID].color[iData] = curentColorValue; } } } else { - frames[iID].Color[iData] = CHANGE_COLOR; + frames[iID].color[iData] = CHANGE_COLOR; } } // обновить данные пакета - frames[iID].Frame = frame; + frames[iID].frame = frame; return; } } // если ID не найден - добавить новый с зелёным цветом VisualCANFrame vFrame; - vFrame.Frame = frame; - fill_n(vFrame.Color, 8, NEW_COLOR); + vFrame.frame = frame; + fill_n(vFrame.color, 8, NEW_COLOR); frames.push_back(vFrame); sort(frames.begin(), frames.end()); diff --git a/wxCAN Sniffer/ThreadedSerialPort.cpp b/wxCAN Sniffer/ThreadedSerialPort.cpp index 70f79b2..2fce611 100644 --- a/wxCAN Sniffer/ThreadedSerialPort.cpp +++ b/wxCAN Sniffer/ThreadedSerialPort.cpp @@ -148,14 +148,14 @@ wxThread::ExitCode ThreadedSerialPort::Entry() } // если есть данные на отправку - отправить - if (frameToSend.Frame.ID != 0) + if (frameToSend.Frame.id != 0) { syncCANSend.Lock(); // 4 байта сигнатуры + 4 байта ID-пакета + 1 байт длина данных + сами данные - bytesToSend = 9 + frameToSend.Frame.Length; + bytesToSend = 9 + frameToSend.Frame.length; WriteFile(hSerial, &frameToSend, bytesToSend, &bytesSent, NULL); // после отправки - сбросить флаг наличия данных - frameToSend.Frame.ID = 0; + frameToSend.Frame.id = 0; syncCANSend.Unlock(); } /*else