Помощь в написании студенческих работ
Антистрессовый сервис

Требования к ПО стенда РПДП

РефератПомощь в написанииУзнать стоимостьмоей работы

Функции WriteUSB () и ReadUSB () работают предельно просто. Вся их суть заключается в вызове функций WriteFile (hWrite, tmp_buf1, kol, &dwBytesWritten, NULL) и ReadFile (hRead, InFile, kol, &dwBytesRead, NULL). Обеим функциям в качестве параметров передаются созданные ранее дескрипторы чтения и записи, указатель на буфер, куда записывать прочитанную информацию или откуда считывать передаваемую… Читать ещё >

Требования к ПО стенда РПДП (реферат, курсовая, диплом, контрольная)

Для проверки блока РПДП требуется произвести запись эталонной регистрации средствамиKCAN-G и KCAN-P контролеров. ПО подключается к KCAN-G и KCAN-P по каналу USB. ПО открывает эталонный файл регистрации, и, в соответствии с CAN — идентификаторами (KCAN-G 0×600), по USB каналу записывает информацию в KCAN-G и KCAN-P контролеры. В свою очередь KCAN-G и KCAN-P контролеры записываютинформацию в блок РПДП по CAN каналу.

Подключив ПЭВМ, кабелем Ethernet, к блоку РПДП, требуется произвести считывание зарегистрированной блоком РПДП регистрации и сравнение ее с отправленной эталонной регистрацией.

РПДП Рисунок 4.2.2 Стенд РПДП.
Рисунок 4.2.1 РПДП Рисунок 4.2.2 Стенд РПДП.

Рисунок 4.2.1 РПДП Рисунок 4.2.2 Стенд РПДП.

CAN-G, CAN-P-контроллер.

Рисунок 4.2.3 CAN-G, CAN-P-контроллер.

Установление USB соединения

После запуска программы необходимо выбрать эталонную регистрацию для ее дальнейшей отправки на РПДП. Эталонная регистрация представляет собой бинарный файл расширения .rpdp, содержащий набор зарегистрированных РПДП строк.

Окно открытия эталонной регистрации.

Рисунок 4.3.1 Окно открытия эталонной регистрации.

После открытия эталонной регистрации, необходимо произвести ее отправку нажатием на кнопку «Отправить» BtnSendToCan. В первую очередь необходимо произвести установление соединения с CAN-контроллером по USB. Данную задачу выполняет функция InitUSB (), приведенная ниже. При вызове этой функции происходит процесс инициализации устройства.

Так как используемый CAN-контроллер соответствует спецификациям USB HID, его можно отнести к классу HID-устройств. Поэтому он может работать с написанным программным обеспечением, тоже поддерживающим эти спецификации, без необходимости разработки дополнительных драйверов.

Общий смысл работы с девайсами класса HID сводится к открытию девайса самой обычной функцией CreateFile () и последующему чтению из него функцией ReadFile (). Всё точно так же, как при работе с обычными файлами. Но до этого нужно получить путь к девайсу (device path)[9]. Для получения пути к устройству, необходимо проделать несколько следующих шагов [10]:

  • 1. Получить GUID (Globally Unique Identifier) класса HID. GUID— статистический уникальный 128-битный идентификатор. Этот идентификатор указан в протоколе CAN-контроллера, поэтому в программе он задается явным образом.
  • 2. Далее необходимо получить набор с описанием всех девайсов этого класса. Для этого надо вызвать функцию SetupDiGetClassDevs (), передав ей в качестве параметра GUID. Функция вернет дескриптор этого набора. Вторым параметром передается ноль, так как для выбора устройства не используется счетчик. Третий параметр — дескриптор окна для ассоциирования с устройством, также можно задать NULL. Последним параметр указывает на то, что в набор необходимо включать только устройства, присутствующие в системе (DIGCF_PRESENT).
  • 3. Если дескриптор создан успешно, нужно открыть цикл по 127 устройствам (максимальное число возможных подключений по USB). Пройтись по ранее созданному набору устройств вызовом функции SetupDiEnumDeviceInterfaces (). Пройтись — значит вызывать её в цикле для каждого элемента набора до тех пор, пока она не вернёт false. Каждый элемент, для которого функция вернёт true, соответствует одному подключённому девайсу класса HID. Функция SetupDiEnumDeviceInterfaces () получает в качестве параметра дескриптор набора устройств, GUID интересующего устройства, счетчик для количества найденных интересующих устройств и элемент типа SP_DEVICE_INTERFACE_DATA для записи информации об устройствах.
  • 4. Если функция вернёт false, нужно вызвать GetLastError () и проверить наличие ошибки ERROR_NO_MORE_ITEMS. Если она есть, значит программа дошла до конца списка и можно выходить из цикла.
  • 5. Теперь можно получить путь к девайсу. Для этого надо вызвать функцию SetupDiGetDeviceInterfaceDetail (), передавая ей информацию о девайсе, полученную с помощью SetupDiEnumDeviceInterfaces (), и дескрипор массива девайсов. Путь надо получать отдельно для каждого девайса. Это лучше делать в цикле. Нужно отметить, что для получения пути к девайсу функцию необходимо вызвать дважды, так как при первом вызове она возвращает размер структуры PSP_DEVICE_INTERFACE_DETAIL_DATA, содержащей инвормацию об устройтве. При втором вызове функция записывает путь к устройству в следующий параметр functionClassDeviceData->DevicePath структуры PSP_DEVICE_INTERFACE_DETAIL_DATA.
  • 6. После того, как программа узнала путь к устройству, она может определить PID и VID устройства. Для этого вызывается функция GetVID_PID (). Определив VID и PID устройства программа сравнивает их с VID и PID, интересующими разработчика. Если они равны, можно сделать вывод, что это требуемое устройство.
  • 7. Теперь можно открывать девайс. Для этого необходимо вызвать функцию CreateFile (), задав в качестве имени файла путь к девайсу. Функция возвращает дескриптор hRead, позволяющий производить чтение из устройства при передаче ей в качестве второго параметра GENERIC_READ. Функция возвращает дескриптор hWrite, позволяющий производить запись на устройство при передаче ей в качестве второго параметра GENERIC_WRIGHT.
  • 8. После того, как все нужные девайсы уже открыты (или не найдены), необходимо удалить набор устройств, полученный в пункте 2. Это делается вызовом функции SetupDiDestroyDeviceInfoList ().

Листинг 4.3.1.

hDevInfoList = SetupDiGetClassDevs (&Guid, NULL, NULL, (DIGCF_PRESENT));

if (hDevInfoList ≠ INVALID_HANDLE_VALUE).

{.

SP_DEVICE_INTERFACE_DATA deviceInfoData; // здесь хранится информация об отдельном девайсе…

for (int i=0; i<127; i++).

{.

ZeroMemory (&deviceInfoData, sizeof (deviceInfoData));

deviceInfoData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);

if (SetupDiEnumDeviceInterfaces (hDevInfoList, 0, &Guid, i, &deviceInfoData)) //Если нашлось устройство с данным GUID вернет true.

{.

functionClassDeviceData = NULL;

requiredLength = 0;

SetupDiGetDeviceInterfaceDetail (hDevInfoList, &deviceInfoData, NULL, 0, &requiredLength, NULL); //The first time returns the size of the structure in Length.

functionClassDeviceData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc (requiredLength);

functionClassDeviceData->cbSize = sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);

//The second time returns a pointer to the data in hDevInfoList (functionClassDeviceData).

if (SetupDiGetDeviceInterfaceDetail (hDevInfoList, &deviceInfoData, functionClassDeviceData, requiredLength, &requiredLength, NULL)).

{.

wcscpy (OutPipe, functionClassDeviceData->DevicePath);

/*Параметры.

strDestinati cтрока, являющаяся выходным значением.

strSource исходная строка с нулевым символом в конце.*/.

wcscat (OutPipe, L" PIPE01″);

wcscpy (InPipe, functionClassDeviceData->DevicePath);

wcscat (InPipe, L" PIPE00″);

result = GetVID_PID (functionClassDeviceData->DevicePath, &VID, &PID);

free (functionClassDeviceData);

//для первого CAN1.

if (result && (VID == 0xACD1)).

{.

if (PID == 0x2F24) status = true;

}.

//для второго CAN2.

if (result && (VID == 0xACD1)).

{.

if (PID == 0x2E47) status = true;

}.

if (status).

{.

CloseHandle (hWrite);

CloseHandle (hRead);

hWrite = CreateFile (OutPipe, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);

if (hWrite == INVALID_HANDLE_VALUE).

{.

strTemp = «Невозможно открыть OutPipe: «+ SysErrorMessage (GetLastError ());

Application->MessageBox (strTemp.w_str (), ProgName, MB_OK|MB_ICONERROR);

status = false;

break;

}.

hRead = CreateFile (InPipe, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);

if (hRead == INVALID_HANDLE_VALUE).

{.

strTemp = «Невозможно открыть InPipe: «+ SysErrorMessage (GetLastError ());

Application->MessageBox (strTemp.w_str (), ProgName, MB_OK|MB_ICONERROR);

CloseHandle (hWrite);

status = false;

break;

Функции WriteUSB () и ReadUSB () работают предельно просто. Вся их суть заключается в вызове функций WriteFile (hWrite, tmp_buf1, kol, &dwBytesWritten, NULL) и ReadFile (hRead, InFile, kol, &dwBytesRead, NULL). Обеим функциям в качестве параметров передаются созданные ранее дескрипторы чтения и записи, указатель на буфер, куда записывать прочитанную информацию или откуда считывать передаваемую. Помимо этого задается требуемое количество байт для чтения и записи и задается параметр, куда записывается фактическое количество прочитанных или записанных байт. Далее при сравнении требуемого и фактического количества можно выявить ошибки чтения и записи.

Листинг 4.3.2.

bool __fastcall TForm1: WriteUSB (unsigned char* tmp_buf1, int kol).

{.

int err;

UnicodeString asTemp;

bool status;

status = false;

if (bUSBEnable == true) {.

if (!WriteFile (hWrite, tmp_buf1, kol, &dwBytesWritten, NULL)) {.

err = GetLastError ();

asTemp = «Ошибка посылки запроса. Код ошибки: «+ IntToStr ((int)err);

Application->MessageBoxW (asTemp.w_str (), ProgName, MB_OK|MB_ICONERROR);

status = false;

goto LabExitWUSB;

}.

if (dwBytesWritten ≠ kol) {.

Application->MessageBoxW (L" Посылка ушла не полностью!!!", ProgName, MB_OK|MB_ICONERROR);

status = false;

goto LabExitWUSB;

}.

}.

status = true;

LabExitWUSB:

return status;

}.

//—————————————————————————————————————;

bool __fastcall TForm1: ReadUSB (int kol).

{.

int err;

UnicodeString asTemp;

bool status;

status = false;

if (bUSBEnable == true) {.

if (!ReadFile (hRead, InFile, kol, &dwBytesRead, NULL)) {.

err = GetLastError ();

asTemp = «Ошибка приема посылки. Код ошибки: «+ IntToStr ((int) err);

Application->MessageBoxW (asTemp.w_str (), ProgName, MB_OK|MB_ICONERROR);

status = false;

goto LabExitRUSB;

}.

if (dwBytesRead ≠ kol) {.

Application->MessageBoxW (L" Посылка пришла не полностью!!!", ProgName, MB_OK|MB_ICONERROR);

status = false;

goto LabExitRUSB;

}.

}.

status = true;

LabExitRUSB:

return status;

}.

Показать весь текст
Заполнить форму текущей работой