Общая идея получить данные USB устройством и переслать их в комп.
Есть USB устройство создано на основе книг Аругова. на базе процессора AT89C5131 и для передачи имеет конечтую точку типа bulk и передаёт 8 байт. Прошивка загружена и работает
также написал дрйвер с помощью NuMega Driver Studio 2.6 в Microsoft Visual C++ 6.0 через визард. установил драйвер.
Но при написание пользовательского ПО (пишу в C++ Builder 6) в созданном классе TAT89DriverLoader есть ошибка EAccessViolation. код программы:
Код | #include "classDRV.h" __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { TAT89DriverLoader Driver = TAT89DriverLoader(); Driver.CreateServ(); Driver.StartServ(); Driver.Open(); Label1->Caption=Driver.Read(); }
|
classDRV.h
Код | class TAT89DriverLoader{ public: //набор открытых операций TAT89DriverLoader(); //конструктор ~TAT89DriverLoader(); //деструктор public: //регистрация дравера void CreateServ(); //удаление драйвера void RemoveServ(); //старт драйвера void StartServ(); //остановка драйвера void StopServ(); public: //открытие драйвера bool Open(); //закрытие драйвера void Close(); public: //вызов функции чтения String Read(); private: //закрытые функции обеспецивающие реализацию HANDLE hDevice; //хранить дескриптор драйвера };
TAT89DriverLoader::TAT89DriverLoader(){ hDevice = INVALID_HANDLE_VALUE; };
TAT89DriverLoader::~TAT89DriverLoader(){ //Close(); };
void TAT89DriverLoader::CreateServ(){ SC_HANDLE hSCMan; SC_HANDLE hService;
hSCMan=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); if (!hSCMan){};
hService=CreateService( hSCMan, "ATDriver", "ATDriver", SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, "ATDriver.sys", NULL, NULL, NULL, NULL, NULL);
CloseServiceHandle(hService); CloseServiceHandle(hSCMan); };
void TAT89DriverLoader::RemoveServ(){ SC_HANDLE hSCMan; SC_HANDLE hService;
hSCMan=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); if (!hSCMan){};
hService=OpenService(hSCMan,"ATDriver",SERVICE_ALL_ACCESS);
DeleteService(hService); CloseServiceHandle(hService); CloseServiceHandle(hSCMan); };
void TAT89DriverLoader::StartServ(){ SC_HANDLE hSCMan; SC_HANDLE hService;
hSCMan=OpenSCManager(NULL,NULL,SC_MANAGER_CONNECT);
hService=OpenService(hSCMan,"ATDriver",SERVICE_START);
CloseServiceHandle(hSCMan);
StartService(hService,0,NULL); CloseServiceHandle(hService); CloseServiceHandle(hSCMan); };
void TAT89DriverLoader::StopServ(){ SERVICE_STATUS ServiceStatus; SC_HANDLE hSCMan; SC_HANDLE hService;
hSCMan=OpenSCManager(NULL,NULL,SC_MANAGER_CONNECT); hService=OpenService(hSCMan,"ATDriver",SERVICE_STOP);
CloseServiceHandle(hSCMan);
ControlService(hService,SERVICE_CONTROL_STOP,&ServiceStatus); CloseServiceHandle(hService); CloseServiceHandle(hSCMan); };
bool TAT89DriverLoader::Open(){
hDevice=CreateFile( "\\\\.\\USB#Vid_03e8&Pid_0020#1.0.0#{a5dcbf10-6530-11d2-901f-00c04fb951ed}", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if (hDevice == INVALID_HANDLE_VALUE){ MessageDlg(SysErrorMessage(GetLastError()),mtError,TMsgDlgButtons() << mbOK,0); }; return hDevice != INVALID_HANDLE_VALUE; };
void TAT89DriverLoader::Close(){ if (hDevice != INVALID_HANDLE_VALUE){ CloseHandle(hDevice); hDevice = INVALID_HANDLE_VALUE; }; };
String TAT89DriverLoader::Read(){ byte A[8]; LPDWORD ReadBytes; int i; String Cap;
for (i=0;i<8;i++){ A[i]=0; };
if (hDevice == INVALID_HANDLE_VALUE){ exit; };
if (!ReadFile(hDevice,A,8,ReadBytes,NULL)){ MessageDlg(SysErrorMessage(GetLastError()),mtError,TMsgDlgButtons() << mbOK,0); }else{ for (int i=0;i<8;i++){ Cap=Cap+IntToHex(A[i],2)+" "; }; }; return Cap; };
|
тут билдер пишет что ошибка EAccessViolation в строке if (!ReadFile(hDevice,A,8,ReadBytes,NULL)){ , Стал разбираться в чём дело. Программка UsbIDCheck показала: ***Device Descriptor тут всё нормально как надо!
***ConnectionStatus: DeviceConnected Current Config Value: 0x01 Device Bus Speed: Full Device Address: 0x02 Open Pipes: 0
***Endpoint Descriptor ... wMaxPacketSize: 0x0000 (0) ... bInterval: 0x01
***Configuration Descriptor: тут тоже всё норм
***Interface Descriptor: тут всё как указано в микропроцессоре
***Endpoint Descriptor: как указано в микропроцессоре wMaxPaketSize: 0x0008 (8) ... bInterval: 0x01
но при открытии и попытки чтении через эту прогу MaxPacketSize считается = 0 и длина прочтённого сообщения тоже 0
насколько я понял первый приведённый Endpoint Descriptor читается из драйвера а остальные из микропроцессора. Капаясь в файлах драйвера, в инклюдах Driver Studio нашо в файле kusb.h строчку
inline USHORT KUsbPipe::MaximumPacketSize(void) { ASSERT(m_Information); if(!IsOpen()) return 0; return m_Information->MaximumPacketSize; }
что значит ASSERT(m_Information); я так и не полян но строчка IsOpen() привлекла внимание
дописал в начале и конце функции Read соотвенственно m_Endpoint1IN.Open(m_Interface); и m_Endpoint1IN.Close();
В программе UsbIDCheck есть изменение, в ****ConnectionStatus: DeviceConnected тепаерь Open Pipes: 1 Но wMaxPaketSize всё ещё =0 помоги, что мне ещё надо исправить в драйвере ? почему wMaxPaketSize =0 ?
|