主頁 > 後端開發 > U盤的插拔偶爾會影響其它USB設備(公司開發的產品)的通信,望高手~~

U盤的插拔偶爾會影響其它USB設備(公司開發的產品)的通信,望高手~~

2020-10-04 12:04:45 後端開發

USB驅動程式是通過DriverStudio3.2生成的。
USB硬體設備是公司開發的。
在正常情況下,上下位機通信都很正常。但如果此時PC上有U盤進行插拔操作,偶爾會出現通信失敗的情況。
當通信失敗時上位機的情況表現為:
1.ReadFile讀失敗,但不會導致函式被阻塞。
2.WriteFile寫失敗,但會導致函式阻塞,直到拔掉USB設備此函式才會回傳。


出現這種例外不知道是USB驅動沒有寫好,還是下位機設備抗干擾性不強。

望高手指點。
謝謝,專案急!!!!!!!

uj5u.com熱心網友回復:

網上有人懷疑是設備號寫錯了,但我的程式是通過工具自己生成的。所以。。。。。。

uj5u.com熱心網友回復:

我把驅動代碼貼上來:總共六個檔案,是WDM開發的。工具是DriverStudio3.2
//-------------------------------------------------------------------------
Communication_dataDriver.h
//-------------------------------------------------------------------------
// Communication_dataDriver.h
//
// Generated by DriverWizard 3.2.0 (Build 2485)
// Requires DDK and DriverWorks
// File created on 11/2/2011
//
// This include file contains the definition of a subclass of KDriver.
// WDM drivers declare a subclass of KDriver and override member
// function DriverEntry and AddDevice.
//
#ifndef __COMMUNICATION_DATADRIVER_H__
#define __COMMUNICATION_DATADRIVER_H__

class Communication_dataDriver : public KDriver
{
SAFE_DESTRUCTORS
public:
// Member functions
virtual NTSTATUS DriverEntry(PUNICODE_STRING RegistryPath);
virtual NTSTATUS AddDevice(PDEVICE_OBJECT Pdo);
virtual VOID Unload(VOID);

protected:
// Member data
int m_Unit;
};

#endif // __COMMUNICATION_DATADRIVER_H__
//-------------------------------------------------------------------
Communication_dataDriver.cpp
//-------------------------------------------------------------------
// Communication_dataDriver.cpp
//
// Generated by DriverWizard 3.2.0 (Build 2485)
// Requires DDK and DriverWorks
// File created on 11/2/2011
//
// This source file contains the implementation of a subclass of KDriver.
// WDM drivers implement a subclass of KDriver and override member
// function DriverEntry and AddDevice.
//

#define VDW_MAIN
#include <vdw.h>
#include <kusb.h>
#include <kusbbusintf.h>
#include "function.h"
#include "Communication_dataDriver.h"
#include "Communication_dataDevice.h"

#pragma hdrstop("Communication_data.pch")

// Memory allocation pool tag
// Override this value using the global function SetPoolTag().
POOLTAG DefaultPoolTag('mmoC');

// Global driver trace object
// TODO: Use KDebugOnlyTrace if you want trace messages
// to appear only in checked builds.  Use KTrace if
// you want trace messages to always appear.  Call
// method SetOutputLevel to set the output threshold.
KDebugOnlyTrace T("Communication_data");

///////////////////////////////////////////////////////////////////////////////////////////////////
// Begin INIT section
#pragma code_seg("INIT")

DECLARE_DRIVER_CLASS(Communication_dataDriver, NULL)

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Communication_dataDriver::DriverEntry
// This routine is called when the driver is loaded.  Drivers often 
// read the registry for configurable parameters.
//
// Arguments:
// IN RegistryPath
// pointer to a unicode string representing the path to
// driver-specific key in the registry.  Look for:
// HKLM\SYSTEM\CurrentControlSet\Services\Communication_data
//
// Return Value:
// NTSTATUS code
//
NTSTATUS Communication_dataDriver::DriverEntry(PUNICODE_STRING RegistryPath)
{
T.Trace(TraceInfo, __FUNCTION__"++. Compiled at " __TIME__ " on " __DATE__ "\n");

#ifdef DBG
//DbgBreakPoint();
#endif

NTSTATUS status = STATUS_SUCCESS;

m_Unit = 0;

// This macro suppresses compiler warning for unreferenced variable.
// If you reference this parameter, simply remove the macro.
UNREFERENCED_PARAMETER(RegistryPath);

T.Trace(TraceInfo, __FUNCTION__"--. STATUS %x\n", status);

return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma code_seg() // end INIT code
///////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Communication_dataDriver::AddDevice
// This routine is called when the system detects a device for which this
// driver is responsible.  This function creates the Functional Device 
// Object, or FDO. The FDO enables this driver to handle requests for  
// the physical device.
//
// Arguments:
// IN Pdo
// Physical Device Object.  This is a pointer to a system device
// object that represents the physical device.
//
// Return Value:
// NTSTATUS
//
NTSTATUS Communication_dataDriver::AddDevice(PDEVICE_OBJECT Pdo)
{
T.Trace(TraceInfo, __FUNCTION__"++.\n");

NTSTATUS status = STATUS_SUCCESS;

// Create Communication_dataDevice using a form of "placement" new
// that is a member operator of KDevice.  This will use storage
// in the system device object extension to store the class instance.
Communication_dataDevice* pDevice = new (
            NULL,                    // no name
FILE_DEVICE_UNKNOWN,
            NULL,                    // no name
0,
DO_DIRECT_IO
| DO_EXCLUSIVE
| DO_POWER_PAGABLE
)
Communication_dataDevice(Pdo, m_Unit);

if (pDevice == NULL)
{
status = STATUS_INSUFFICIENT_RESOURCES;
}
else
{
status = pDevice->ConstructorStatus();
if (!NT_SUCCESS(status))
{
delete pDevice;
}
else
{
m_Unit++;
pDevice->ReportNewDevicePowerState(PowerDeviceD0);
}
}

T.Trace(TraceInfo, __FUNCTION__"--. STATUS %x\n", status);

return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Communication_dataDriver::Unload
// This routine is called when the driver is unloaded.  Delete any
// device objects created in DriverEntry by calling base class method
// Unload().  Cleanup any allocations made for registry values in
// DriverEntry.  
//
// Arguments:
// none
//
// Return Value:
// none
//
VOID Communication_dataDriver::Unload(VOID)
{
T.Trace(TraceInfo, __FUNCTION__"++.\n");

// If you don't need to perform any functions
// except to call the base class KDriver::Unload(),
// then this entire routine may be safely deleted.

    // Call base class to delete all devices.
KDriver::Unload();

T.Trace(TraceInfo, __FUNCTION__"--.\n");
}
//---------------------------------------------------------------------
function.h
//---------------------------------------------------------------------
// function.h
//
// Generated by DriverWizard 3.2.0 (Build 2485)
// Requires DDK and DriverWorks
// File created on 11/2/2011
//
// This include file specifies the set of request handlers that the
// driver implements.  This controls which driver functions are enabled.
//
#ifndef __FUNCTION_H__
#define __FUNCTION_H__

#define DRIVER_FUNCTION_CREATE
#define DRIVER_FUNCTION_CLOSE
#define DRIVER_FUNCTION_READ
#define DRIVER_FUNCTION_WRITE
#define DRIVER_FUNCTION_DEVICE_CONTROL
#define DRIVER_FUNCTION_CLEANUP
#define DRIVER_FUNCTION_ADD_DEVICE
#define DRIVER_FUNCTION_PNP
#define DRIVER_FUNCTION_POWER
#define DRIVER_FUNCTION_SYSTEM_CONTROL
#define DRIVER_FUNCTION_UNLOAD

#endif // __FUNCTION_H__

//-------------------------------------------------------------
intrface.h
//-------------------------------------------------------------
// intrface.h
//
// Generated by C DriverWizard 3.2.0 (Build 2485)
// Requires DDK Only
// File created on 11/2/2011
//

// Define an Interface Guid for Communication_data device class.
// This GUID is used to register (IoRegisterDeviceInterface)
// an instance of an interface so that user application
// can control the Communication_data device.
//
//  {8D96C3F0-627C-490D-BAA2-3F7D1D789F3D}
DEFINE_GUID(GUID_DEVINTERFACE_COMMUNICATION_DATA,
    0x8D96C3F0, 0x627C, 0x490D, 0xBA, 0xA2, 0x3F, 0x7D, 0x1D, 0x78, 0x9F, 0x3D);

// Define a Setup Class GUID for Communication_data Class. This is same
// as the COMMUNICATION_DATA CLASS guid in the INF files.
//
//  {C14F5235-5790-436F-B6BA-AEF87EE15AF2}
DEFINE_GUID(GUID_DEVCLASS_COMMUNICATION_DATA,
    0xC14F5235, 0x5790, 0x436F, 0xB6, 0xBA, 0xAE, 0xF8, 0x7E, 0xE1, 0x5A, 0xF2);

// GUID definition are required to be outside of header inclusion pragma to avoid
// error during precompiled headers.
//

#ifndef __INTRFACE_H__
#define __INTRFACE_H__

#define FILE_DEVICE_COMMUNICATION_DATA  0x8000

// Define Interface reference/dereference routines for
// Interfaces exported by IRP_MN_QUERY_INTERFACE

#define COMMUNICATION_DATA_IOCTL(index) \
    CTL_CODE(FILE_DEVICE_COMMUNICATION_DATA, index, METHOD_BUFFERED, FILE_READ_DATA)


#endif // __INTRFACE_H__

uj5u.com熱心網友回復:

// Communication_dataDevice.h
//
// Generated by DriverWizard 3.2.0 (Build 2485)
// Requires DDK and DriverWorks
// File created on 11/2/2011
//
// This include file contains the definition of a subclass of KPnpDevice.
// WDM drivers declare a subclass of KPnpDevice and override member
// functions to handle requests (IRPs) from the system.
//
#ifndef __COMMUNICATION_DATADEVICE_H__
#define __COMMUNICATION_DATADEVICE_H__

class Communication_dataDevice : public KPnpDevice
{
public:
SAFE_DESTRUCTORS;
Communication_dataDevice(PDEVICE_OBJECT Pdo, ULONG Unit);
~Communication_dataDevice();
VOID Invalidate(void);

// Member functions
DEVMEMBER_DISPATCHERS

virtual NTSTATUS OnStartDevice(KIrp I);
virtual NTSTATUS OnStopDevice(KIrp I);
virtual NTSTATUS OnRemoveDevice(KIrp I);
virtual NTSTATUS OnQueryCapabilities(KIrp I);
MEMBER_COMPLETEIRP(Communication_dataDevice, OnQueryCapabilitiesComplete)
virtual NTSTATUS OnDevicePowerUp(KIrp I);
virtual NTSTATUS OnDeviceSleep(KIrp I);
virtual NTSTATUS DefaultPnp(KIrp I);
virtual NTSTATUS DefaultPower(KIrp I);

typedef struct _USB_COMPLETION_INFO
{
PURB m_pUrb;
Communication_dataDevice* m_pClass;
} USB_COMPLETION_INFO, *PUSB_COMPLETION_INFO;

MEMBER_COMPLETEIRPWITHCONTEXT(USB_COMPLETION_INFO, IoComplete)
void TestBusInterface();

protected:
// Member data
KUsbLowerDevice m_Lower;
KUsbInterface    m_Interface;
KUsbPipe Pipe2; // Pipe for USB endpoint address 82, type BULK
KUsbPipe Pipe3; // Pipe for USB endpoint address 3, type BULK
#if (_WDM_ && (WDM_MAJORVERSION > 1 || ((WDM_MAJORVERSION == 1) && (WDM_MINORVERSION >= 0x20))))
KUsbBusInterface m_BusIntf; // Direct client access to USB bus on Windows XP and above
BOOLEAN m_fBusIntfAvailable;
#endif
#ifdef __COMMENT_ONLY
// The following member functions are actually defined by 
// a DEVMEMBER_XXX or MEMBER_XXX macro (such as DEVMEMBER_DISPATCHERS).
// The macro __COMMENT_ONLY never gets defined.  These comment-only
// definitions simply allow easy navigation to the functions within
// the Visual Studio IDE using the class browser.
virtual NTSTATUS Create(KIrp I);  // COMMENT_ONLY
virtual NTSTATUS Close(KIrp I); // COMMENT_ONLY
virtual NTSTATUS Read(KIrp I);    // COMMENT_ONLY
virtual NTSTATUS Write(KIrp I); // COMMENT_ONLY
virtual NTSTATUS DeviceControl(KIrp I); // COMMENT_ONLY
virtual NTSTATUS CleanUp(KIrp I);  // COMMENT_ONLY
virtual NTSTATUS SystemControl(KIrp I); // COMMENT_ONLY
#endif // __COMMENT_ONLY
};

#endif // __COMMUNICATION_DATADEVICE_H__

uj5u.com熱心網友回復:

我給你頂頂,接著貼

uj5u.com熱心網友回復:

//---------------------------------------------------
Communication_dataDevice.cpp
//--------------------------------------------------
// Communication_dataDevice.cpp
//
// Generated by DriverWizard 3.2.0 (Build 2485)
// Requires DDK and DriverWorks
// File created on 11/2/2011
//
// This source file contains the implementation of a subclass of KDevice.
// WDM drivers implement a subclass of KPnpDevice and override member
// functions to handle requests (IRPs) from the system.
//

#include <vdw.h>
#include <kusb.h>
#include <kusbbusintf.h>
#include "Communication_dataDriver.h"
#include "Communication_dataDevice.h"
#include "..\\intrface.h"

#pragma hdrstop("Communication_data.pch")

// Global driver trace object
// TODO: Use KDebugOnlyTrace if you want trace messages
// to appear only in checked builds.  Use KTrace if
// you want trace messages to always appear.  Call
// method SetOutputLevel to set the output threshold.
extern KDebugOnlyTrace T;

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Communication_dataDevice::Communication_dataDevice
// This is the constructor for the class representing the Functional
// Device Object, or FDO.  It is derived from KPnpDevice, which builds
// in automatic dispatching of subfunctions of IRP_MJ_POWER and IRP_MJ_PNP
// to virtual member functions.
// The object being constructed contains a data member (m_Lower) of type
// KPnpLowerDevice. By initializing it, the driver binds the FDO to the
// PDO and creates an interface to the upper edge of the system class driver.
//
// Arguments:
// IN Pdo
// Physical Device Object.  This is a pointer to a system
// device object that represents the physical device.
//
// IN Unit
// Unit number to append to the device's base device name 
// to distinguish multiple units of this device type.
//
// Return Value:
// none
//
Communication_dataDevice::Communication_dataDevice(PDEVICE_OBJECT Pdo, ULONG Unit) :
KPnpDevice(Pdo, &GUID_DEVINTERFACE_COMMUNICATION_DATA)
{
if (!NT_SUCCESS(m_ConstructorStatus))
{
T.Trace(TraceError, __FUNCTION__": Failed to create device Communication_dataDevice"
" unit number %d status %x\n", Unit, m_ConstructorStatus);
ASSERT(FALSE);
return;
}

// Initialize the lower device
m_Lower.Initialize(this, Pdo);

// Initialize the interface object.  The wizard generates code 
// to support a single interface.  You may create and add additional 
// interfaces.  By default, the wizard uses InterfaceNumber 0 (the 
// first interface descriptor), ConfigurationValue 1 (the first
// configuration descriptor), and initial interface alternate
// setting of 0.  If your device has multiple interfaces or alternate
// settings for an interface, you can add additional KUsbInterface
// objects or adjust the parameters passed to this function.
m_Interface.Initialize(
m_Lower, //KUsbLowerDevice
0,  //InterfaceNumber
1,  //ConfigurationValue 
0  //Initial Interface Alternate Setting
); 

// Initialize each Pipe object
Pipe2.Initialize(m_Lower, 0x82, 512);
Pipe3.Initialize(m_Lower, 0x3, 512);

#if (_WDM_ && (WDM_MAJORVERSION > 1 ||((WDM_MAJORVERSION == 1) && (WDM_MINORVERSION >= 0x20))))
// Initialize USB direct client access interface
if (STATUS_SUCCESS == m_BusIntf.Initialize(m_Lower.TopOfStack()))
m_fBusIntfAvailable = TRUE;
else
m_fBusIntfAvailable = FALSE;
#endif

// Inform the base class of the lower edge device object
SetLowerDevice(&m_Lower);

// Initialize the PnP Policy settings to the "standard" policy
SetPnpPolicy();

// TODO: Customize the PnP Policy for this device by setting
//  flags in m_Policies.

// Initialize the Power Policy settings to the "standard" policy
SetPowerPolicy();

// TODO: Customize the Power Policy for this device by setting
//  flags in m_PowerPolicies.

}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Communication_dataDevice::~Communication_dataDevice
// This is the destructor for the class. 
//
// Arguments:
// none
//
// Return Value:
// none
//
Communication_dataDevice::~Communication_dataDevice()
{
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Communication_dataDevice::DefaultPnp
// Default handler for IRP_MJ_PNP. 
// This routine just passes the IRP through to the lower device. IRPs 
// that correspond to any virtual members of KpnpDevice that handle 
// minor functions of IRP_MJ_PNP and that are not overridden get 
// passed to this routine.
//
// Arguments:
// IN I
// the plug and play IRP
//
// Return Value:
// NTSTATUS
// Result returned from lower device
//
NTSTATUS Communication_dataDevice::DefaultPnp(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);
T << I; 

I.ForceReuseOfCurrentStackLocationInCalldown();
NTSTATUS status = m_Lower.PnpCall(this, I);

T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Communication_dataDevice::DefaultPower
// Default handler for IRP_MJ_POWER. 
// This routine just passes the IRP through to the lower device. IRPs 
// that correspond to any virtual members of KpnpDevice that handle 
// minor functions of IRP_MJ_POWER and that are not overridden get 
// passed to this routine.
//
// Arguments:
// IN I
// the power IRP
//
// Return Value:
// NTSTATUS
// Result returned from lower device
//
NTSTATUS Communication_dataDevice::DefaultPower(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);
T << I; 

I.IndicatePowerIrpProcessed();
I.CopyParametersDown();
NTSTATUS status = m_Lower.PnpPowerCall(this, I);

T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Communication_dataDevice::SystemControl
// Default handler for IRP_MJ_SYSTEM_CONTROL. 
// This routine just passes the IRP through to the next device since 
// this driver is not a WMI provider.
//
// Arguments:
// IN I
// the system control (WMI) IRP
//
// Return Value:
// NTSTATUS
// Result returned from lower device
//
NTSTATUS Communication_dataDevice::SystemControl(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);
T << I; 

NTSTATUS status = STATUS_SUCCESS;

I.ForceReuseOfCurrentStackLocationInCalldown();
status = m_Lower.PnpCall(this, I);

T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Communication_dataDevice::OnStartDevice
// Handler for IRP_MJ_PNP subfcn IRP_MN_START_DEVICE. 
// Initialize the hardware device. Typically, the driver initializes
// physical resources here.  Call I.AllocatedResources() for a list
// of the raw resources that the system has assigned to the device,
// or I.TranslatedResources() for the translated resource list.
//
// Arguments:
// IN I
// the start device IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS Communication_dataDevice::OnStartDevice(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

NTSTATUS status = STATUS_SUCCESS;

I.Information() = 0;
status = STATUS_UNSUCCESSFUL;

AC_STATUS acStatus = AC_SUCCESS;

// By default, the wizard passes a ConfigurationValue of 1 to 
// ActivateConfiguration().  This corresponds to the first configuration 
// that the device reports in its configuration descriptor.  If the device 
// supports multiple configurations, pass the appropriate
// ConfigurationValue of the configuration to activate here.
acStatus = m_Lower.ActivateConfiguration(
1 // ConfigurationValue 1 (the first configuration)
);

switch (acStatus)
{
case AC_SUCCESS:
T << "USB ActivateConfiguration OK\n";
status = STATUS_SUCCESS;

// TODO: Use the USB direct client access
TestBusInterface();
break;

case AC_COULD_NOT_LOCATE_INTERFACE:
T << "ActivateConfiguration Error: Could not locate interface\n";
break;

case AC_COULD_NOT_PRECONFIGURE_INTERFACE:
T << "ActivateConfiguration Error: Could not get configuration descriptor\n";
break;

case AC_CONFIGURATION_REQUEST_FAILED:
T << "ActivateConfiguration Error: H/W did not accept configuration URB\n";
break;

case AC_FAILED_TO_INITIALIZE_INTERFACE_OBJECT:
T << "ActivateConfiguration Error: Failed to initialize interface object\n";
break;

case AC_FAILED_TO_GET_DESCRIPTOR:
T << "ActivateConfiguration Error: Failed to get device descriptor\n";
break;

case AC_FAILED_TO_OPEN_PIPE_OBJECT:
// NOTE: this may not be an error.  It could mean that
// the device has an endpoint for which a KUsbPipe object has
// not been instanced.  If the intention is to not use this endpoint,
// then it's likely not a problem.  
status = STATUS_SUCCESS;
T << "ActivateConfiguration Warning: Failed to open pipe object\n";
break;

default:
T << "ActivateConfiguration Error: Unexpected error activating USB configuration\n";
break;
}

// TODO: Add USB device-specific code to start the hardware.

T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

return status;
}

uj5u.com熱心網友回復:

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Communication_dataDevice::OnStopDevice
// Handler for IRP_MJ_PNP subfcn IRP_MN_STOP_DEVICE. 
// The system calls this when the device is stopped.  Release any 
// hardware resources in this routine.
//
// Arguments:
// IN I
// the stop device IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS Communication_dataDevice::OnStopDevice(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

NTSTATUS status = STATUS_SUCCESS;

// TODO: Add device-specific code to stop your hardware device.
    // The base class will handle completion of the IRP

// Release the system resources
Invalidate();

T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, STATUS_SUCCESS);

// Can't fail this IRP
return STATUS_SUCCESS;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Communication_dataDevice::OnRemoveDevice
// Handler for IRP_MJ_PNP subfcn IRP_MN_REMOVE_DEVICE. 
// The system calls this when the device is removed.
// Our PnP policy will take care of 
// (1) giving the IRP to the lower device
// (2) detaching the PDO
// (3) deleting the device object
//
// Arguments:
// IN I
// the remove device IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS Communication_dataDevice::OnRemoveDevice(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

NTSTATUS status = STATUS_SUCCESS;

// TODO: Add device-specific code to remove your hardware device.
    // The base class will handle completion of the IRP

// Release the system resources
Invalidate();

T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, STATUS_SUCCESS);

// Can't fail this IRP
return STATUS_SUCCESS;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Communication_dataDevice::OnQueryCapabilities
// Handler for IRP_MJ_PNP subfcn IRP_MN_QUERY_CAPABILITIES. 
// The system calls this to query the device capabilities.
// The Bus driver fills in the device capabilities structure.
// This method is usually only overridden to alter the 
// device capabilities reported by the bus driver.
//
// Arguments:
// IN I
// the query capabilities IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS Communication_dataDevice::OnQueryCapabilities(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

NTSTATUS status = STATUS_SUCCESS;

I.CopyParametersDown();
I.SetCompletionRoutine(LinkTo(OnQueryCapabilitiesComplete), this, TRUE, TRUE, TRUE);

status = m_Lower.PnpCall(this, I);

T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Communication_dataDevice::OnQueryCapabilitiesComplete
// Completion routine for IRP_MJ_PNP subfcn IRP_MN_QUERY_CAPABILITIES. 
// The system calls OnQueryCapabilities to query the device capabilities.
// The Bus driver fills in the device capabilities structure.
// This method is called when the IRP is completed to alter the 
// device capabilities reported by the bus driver.
//
// Arguments:
// IN I
// the query capabilities IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS Communication_dataDevice::OnQueryCapabilitiesComplete(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++.");

NTSTATUS status = I.Status();


if (I->PendingReturned)
I.MarkPending();

if (NT_SUCCESS(status)) 
{
// TODO: Adjust device capabilities structure as required.
I.DeviceCapabilities()->SurpriseRemovalOK = TRUE;
}

T.Trace(TraceInfo, __FUNCTION__"--.");

return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Communication_dataDevice::TestBusInterface
// This routine uses the USB direct client interface to 
// query information.
//
// Arguments:
// none
//
// Return Value:
// none
//
void Communication_dataDevice::TestBusInterface()
{
#if (_WDM_ && (WDM_MAJORVERSION > 1 ||((WDM_MAJORVERSION == 1) && (WDM_MINORVERSION >= 0x20))))

if (m_fBusIntfAvailable) 
{
T.Trace(TraceInfo, "USB Bus Interface Version: %u\n", m_BusIntf.Version());
T.Trace(TraceInfo, "High Speed Device: %S\n", (m_BusIntf.IsDeviceHighSpeed()?"TRUE":"FALSE"));

USBD_VERSION_INFORMATION UsbVerInfo;
RtlZeroMemory(&UsbVerInfo, sizeof(USBD_VERSION_INFORMATION));
ULONG HcdCapabilities = 0;

m_BusIntf.GetUSBDIVersion(&UsbVerInfo, &HcdCapabilities);

T.Trace(TraceInfo, "USBDI_Version: %u\n", UsbVerInfo.USBDI_Version);
T.Trace(TraceInfo, "Supported_USB_Version: %u\n", UsbVerInfo.Supported_USB_Version);

ULONG TotalBW, ConsumedBW;
NTSTATUS Status = m_BusIntf.GetBandwidth(&TotalBW,&ConsumedBW);

if (STATUS_SUCCESS == Status) 
{
T.Trace(TraceInfo, "Total Bandwidth: %u\n", TotalBW);
T.Trace(TraceInfo, "Consumed Bandwidth: %u\n", ConsumedBW);
}

PWSTR HcName = NULL;
Status = m_BusIntf.GetControllerName(HcName);

if (STATUS_SUCCESS == Status && HcName) 
{
T.Trace(TraceInfo, "HC Name: %s\n", HcName);
delete HcName;
}

ULONG CurrentFrame;
m_BusIntf.QueryBusTime(&CurrentFrame);

T.Trace(TraceInfo, "Current Frame: %u\n", CurrentFrame);
}
#endif
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Communication_dataDevice::OnDevicePowerUp
// Handler for IRP_MJ_POWER subfcn IRP_MN_SET_POWER 
// for a request to go to power on state from low power state
// This function was called by the framework from the completion
// routine of the IRP_MJ_POWER dispatch handler in KPnpDevice.
// The bus driver has completed the IRP and this driver can now
// access the hardware device.  
// This routine runs at DISPATCH_LEVEL.
//
// Arguments:
// IN I
// the power IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS Communication_dataDevice::OnDevicePowerUp(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

NTSTATUS status = STATUS_SUCCESS;

// TODO: Add device-specific code to:
//  Restore any context to the hardware device that
//  was saved during the handling of a power down request.
//  See the OnDeviceSleep function.
//  Do NOT complete this IRP.
    //  The base class will handle completion of the IRP

T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Communication_dataDevice::OnDeviceSleep
// Handler for IRP_MJ_POWER subfcn IRP_MN_SET_POWER 
// for a request to go to a low power state from a high power state
// This function was called by the framework from the IRP_MJ_POWER 
// dispatch handler in KPnpDevice prior to forwarding to the PDO.
// The hardware has yet to be powered down and this driver can now
// access the hardware device.  
// This routine runs at PASSIVE_LEVEL.
//
// Arguments:
// IN I
// the power IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS Communication_dataDevice::OnDeviceSleep(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

NTSTATUS status = STATUS_SUCCESS;

// TODO: Add device-specific code to:
//  Save any context to the hardware device that will be required 
//  during a power up request. See the OnDevicePowerUp function.
//  Do NOT complete this IRP.  The base class handles forwarding
//  this IRP to the PDO.

T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

return status;
}


///////////////////////////////////////////////////////////////////////////////////////////////////
//  Communication_dataDevice::Create
// Dispatch routine for IRP_MJ_CREATE requests.  
//
// Arguments:
// IN I 
// the create IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS Communication_dataDevice::Create(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

// TODO: For any IRP, to display the contents of the IRP
//  in a formatted way, use the KTrace << operator:
//  T << I;

NTSTATUS status = STATUS_SUCCESS;

// For devices that expose an interface instead of symbolic 
// link, DO_EXCLUSIVE flag is not used by the I/O manager.   
// So, exclusivity must be enforced here.
if (m_OpenCounter.Test() > 0)
{
status = STATUS_SHARING_VIOLATION;

I.Information() = 0;
I.PnpComplete(this, status);

T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

return status;
}

// TODO: At this point, perform custom processing for IRP_MJ_CREATE
// Generally a create IRP is targeted at our FDO, so its not needed
// to pass it down to the PDO.  

I.Information() = 0;
I.PnpComplete(this, status);

T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

return status;
}

uj5u.com熱心網友回復:

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Communication_dataDevice::Close
// Dispatch routine for IRP_MJ_CLOSE requests.  
//
// Arguments:
// IN I 
// the close IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS Communication_dataDevice::Close(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

NTSTATUS status = STATUS_SUCCESS;

// TODO: At this point, perform custom processing for IRP_MJ_CLOSE
// Generally a close IRP is targeted at our FDO, so we don't need
// to pass it down to the PDO.  

I.Information() = 0;
I.PnpComplete(this, status);

T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Communication_dataDevice::Read
// Dispatch routine for IRP_MJ_READ requests.  
//
// Arguments:
// IN I 
// the read IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS Communication_dataDevice::Read(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

NTSTATUS status = STATUS_SUCCESS;

// TODO: Validate the parameters of the IRP.  Replace "FALSE"
//  in the following line with error checking code that
//  evaulates to TRUE if the request is not valid.
if (FALSE)
{
status = STATUS_INVALID_PARAMETER;
I.Information() = 0;
I.PnpComplete(status);

T.Trace(TraceWarning, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

return status;
}

// Always ok to read 0 elements
if (I.ReadSize() == 0)
{
I.Information() = 0;
I.PnpComplete(this, status);

T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

return status;
}

KMemory Mem(I.Mdl()); // Declare a memory object

// Get a pointer to the caller's buffer.  Note that this
// routine is safe on all platforms. 
PUCHAR pBuffer = (PUCHAR) Mem.MapToSystemSpace();
ULONG readSize = I.ReadSize();
ULONG bytesRead = 0;


PURB pUrb = Pipe2.BuildBulkTransfer(
             pBuffer,
             readSize,
             TRUE,
             NULL,
             TRUE,
             NULL);
 if (pUrb == NULL)
 {
  status = STATUS_INSUFFICIENT_RESOURCES;
 }
 else 
 {
  status = Pipe2.SubmitUrb(pUrb,NULL,NULL,NULL);//100MS
  bytesRead = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;//pUrb->UrbInterruptTransfer.TransferBufferLength;
  delete pUrb;
 }

I.Information() = bytesRead;

I.PnpComplete(this, status);

T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Communication_dataDevice::Write
// Dispatch routine for IRP_MJ_WRITE requests.  
//
// Arguments:
// IN I 
// the write IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS Communication_dataDevice::Write(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

NTSTATUS status = STATUS_SUCCESS;

// TODO: Validate the parameters of the IRP.  Replace "FALSE"
//  in the following line with error checking code that
//  evaulates to TRUE if the request is not valid.
if (FALSE)
{
status = STATUS_INVALID_PARAMETER;
I.Information() = 0;
I.PnpComplete(status);

T.Trace(TraceWarning, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

return status;
}

// Always ok to write 0 elements
if (I.WriteSize() == 0)
{
I.Information() = 0;
I.PnpComplete(this, status);

T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

return status;
}

KMemory Mem(I.Mdl()); // Declare a memory object

// Get a pointer to the caller's buffer.  Note that this
// routine is safe on all platforms. 
PUCHAR pBuffer = (PUCHAR) Mem.MapToSystemSpace();
ULONG writeSize = I.WriteSize();
ULONG bytesSent = 0;

PURB pUrb = Pipe3.BuildBulkTransfer(
             pBuffer,
             writeSize,
             FALSE,
             NULL,
             TRUE,
             NULL);
 if (pUrb == NULL)
 {
  status = STATUS_INSUFFICIENT_RESOURCES;
 }
 else 
 {
  status = Pipe3.SubmitUrb(pUrb,NULL,NULL,NULL);
  bytesSent = pUrb->UrbBulkOrInterruptTransfer.TransferBufferLength;//pUrb->UrbInterruptTransfer.TransferBufferLength;
  delete pUrb;
 }

I.Information() = bytesSent;

I.PnpComplete(this, status);

T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Communication_dataDevice::DeviceControl
// Dispatch routine for IRP_MJ_DEVICE_CONTROL requests.  
//
// Arguments:
// IN I 
// the ioctl IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS Communication_dataDevice::DeviceControl(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

NTSTATUS status = STATUS_SUCCESS;

switch (I.IoctlCode())
{
    case 0:

default:
status = STATUS_INVALID_DEVICE_REQUEST;
break;
}

// If the IRP's IOCTL handler deferred processing using some driver
// specific scheme, the status variable is set to STATUS_PENDING.
// In this case we simply return that status, and the IRP will be
// completed later.  Otherwise, complete the IRP using the status
// returned by the IOCTL handler.
if (status != STATUS_PENDING)
{
I.PnpComplete(this, status);
}

T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Communication_dataDevice::CleanUp
// Dispatch routine for IRP_MJ_CLEANUP requests.  
//
// Arguments:
// IN I 
// the cleanup IRP
//
// Return Value:
// NTSTATUS
//
NTSTATUS Communication_dataDevice::CleanUp(KIrp I)
{
T.Trace(TraceInfo, __FUNCTION__"++.  IRP %p\n", I);

NTSTATUS status = STATUS_SUCCESS;

// TODO: At this point, perform custom processing for IRP_MJ_CLEANUP

I.PnpComplete(this, status);

T.Trace(TraceInfo, __FUNCTION__"--.  IRP %p, STATUS %x\n", I, status);

return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  Communication_dataDevice::Invalidate
// This method performs resource cleanup.
// This function is called from OnStopDevice, OnRemoveDevice and
// OnStartDevice (in error conditions).  It calls the Invalidate
// member funcitons for each resource to free the underlying system
// resource if allocated.  It is safe to call Invalidate more than
// once for a resource, or for an uninitialized resource.
//
// Arguments:
// none
//
// Return Value:
// none
//
VOID Communication_dataDevice::Invalidate()
{
NTSTATUS status = STATUS_SUCCESS;

status = m_Lower.DeActivateConfiguration();
if (!NT_SUCCESS(status))
{
T.Trace(TraceWarning, __FUNCTION__" DeActivateConfiguration failed, STATUS %x\n", status);
}

m_Lower.ReleaseResources();
}
--------------結束----------

uj5u.com熱心網友回復:

木有回帖的,幫你頂一下

uj5u.com熱心網友回復:

把你的USB設備和U盤一個插在電腦后面,一個插在前面,如果還有影響, 是你驅動問題的可能性大. 如果都插在相鄰介面才有影響, 是硬體問題.

看你的驅動,是用的BULK傳輸模式. 高速模式還是低速模式?是否占滿了USB帶寬? 這些都有關系.
另外也要試試如果同時插拔U口的攝像頭等USB設備,是否有影響. 

uj5u.com熱心網友回復:

另外把殺毒查木馬之類的監控軟體關了.

uj5u.com熱心網友回復:

我們用的是用的BULK傳輸模式,全速。前面后面都插過都有這樣的問題。
上位機用執行緒不間斷呼叫ReadFile函式,如果設備沒有資料上來次函式不會回傳。不知道這種情況是不是占滿帶寬?
殺毒查木馬之類的監控軟體 關掉還沒有試過,明天回公司去試試。

uj5u.com熱心網友回復:

試過了,殺毒、防火墻和監控軟體都關閉了,還是會出現插拔U盤,USB設備通信通信失敗的問題

uj5u.com熱心網友回復:

那就是USB帶寬影響的. USB全速帶寬你是不能全部占用的. 每秒500-600K位元組就很不錯了. U盤插入時候, 系統要去讀取USB的Device資訊, 讀取U盤的檔案分配表等, 如果支持自動運行, 還會讀取U盤程式運行. 對U盤檔案的操作都是用BULK傳輸。

或者你降低帶寬的占用,這需要設備開發人員配合, 或者你允許失敗,軟體里面重試幾次。 寫失敗停止程式就停止回應,是你跟下位機配合不好,驅動發的IRP沒有回傳。

uj5u.com熱心網友回復:

謝謝你給的建議。我先去查查看

uj5u.com熱心網友回復:

上位機和USB設備建立(邏輯上的)通信后,上位機會用執行緒讀USB設備資料,但資料不是每次都能讀到,在讀不到資料的時候,USB設備也沒有傳空資料給上位機,導致USB協議層會不間斷的發送N ACK狀態,通過USB總線監控工具看了,每產生一個N ACK時間大約7-12ms之間,是不是因為N ACK發送太頻繁導致USB總線帶寬被搶占,此時插拔U盤就會出現問題?
下位機開發人員不在,今天沒有辦法測驗了。

我看了U盤也是BULK傳輸模式,它們發送是out -> IN  的回圈發送,每此IN都有資料被讀取。估計固定時間會向USB控制器放入空資料。所以,有個問題,一般多長時間向USB控制器放入空資料比較優呢?

uj5u.com熱心網友回復:

重點看PC跟設備傳輸資料的時候, 帶寬占用多少. 其它時間進行的協議性的通訊不用理會.

uj5u.com熱心網友回復:

如果不用管USB協議的傳輸方式,那么我們的總線帶寬占有率并不高,1秒中發送一個12位元組的報文

uj5u.com熱心網友回復:

不懂 windows 的驅動,但是 Linux 下的驅動都是不會引起 read、write 阻塞的
都是驅動中使用緩沖區保存資料,應用軟體呼叫時檢查驅動緩沖資料或者設定緩沖資料、打開中斷函式的

uj5u.com熱心網友回復:

每秒12位元組, 控制傳輸就夠用了.USB協議為控制傳輸留了綠色通道.

uj5u.com熱心網友回復:

沒做過驅動,學習。

uj5u.com熱心網友回復:

我也遇到了此種情況,但我用的是高速模式啊,此問題最后確認問題原因了沒?

uj5u.com熱心網友回復:

這個driver studio生成的驅動程式難道不用修改的嗎?

uj5u.com熱心網友回復:

用Libusb吧

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/154353.html

標籤:網絡及通訊開發

上一篇:qt widget提升后不能顯示背景圖片

下一篇:c語言

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more