⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 4.c

📁 基于80C196KC微处理器的高速串行通讯、单片机将FIFO中的数据读取出来后
💻 C
📖 第 1 页 / 共 3 页
字号:

parameters = ExAllocatePool(PagedPool, 
sizeof(RTL_QUERY_REGISTRY_TABLE) * queriesPlusOne); 

if (!parameters) { 
RS_DbgPrint("RS485NT: ExAllocatePool failed for Rtl in GetConfiguration\n"); 
status = STATUS_UNSUCCESSFUL; 
} else { 

RtlZeroMemory(parameters, sizeof(RTL_QUERY_REGISTRY_TABLE) * queriesPlusOne); 

// 
// Form a path to this driver's Parameters subkey. 
// 

RtlInitUnicodeString(&amt;parametersPath, NULL); 

parametersPath.MaximumLength = RegistryPath->Length + sizeof(L"\\Parameters"); 

parametersPath.Buffer = ExAllocatePool(PagedPool, parametersPath.MaximumLength); 

if (!parametersPath.Buffer) { 
RS_DbgPrint("RS485NT: ExAllocatePool failed for Path in GetConfiguration\n"); 
status = STATUS_UNSUCCESSFUL; 
} 
} 

if (NT_SUCCESS(status)) { 

// 
// Form the parameters path. 
// 

RtlZeroMemory(parametersPath.Buffer, parametersPath.MaximumLength); 
RtlAppendUnicodeToString(&amt;parametersPath, path); 
RtlAppendUnicodeToString(&amt;parametersPath, L"\\Parameters"); 

// 
// Gather all of the "user specified" information from 
// the registry. 
// 

parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT; 
parameters[0].Name = L"Port Address"; 
parameters[0].EntryContext = &amt;PortAddressDefault; 
parameters[0].DefaultType = REG_DWORD; 
parameters[0].DefaultData = &amt;notThereDefault; 
parameters[0].DefaultLength = sizeof(ULONG); 

parameters[1].Flags = RTL_QUERY_REGISTRY_DIRECT; 
parameters[1].Name = L"IRQ Line"; 
parameters[1].EntryContext = &amt;IRQLineDefault; 
parameters[1].DefaultType = REG_DWORD; 
parameters[1].DefaultData = &amt;notThereDefault; 
parameters[1].DefaultLength = sizeof(ULONG); 

parameters[2].Flags = RTL_QUERY_REGISTRY_DIRECT; 
parameters[2].Name = L"Baud Rate"; 
parameters[2].EntryContext = &amt;BaudRateDefault; 
parameters[2].DefaultType = REG_DWORD; 
parameters[2].DefaultData = &amt;notThereDefault; 
parameters[2].DefaultLength = sizeof(ULONG); 

parameters[3].Flags = RTL_QUERY_REGISTRY_DIRECT; 
parameters[3].Name = L"Buffer Size"; 
parameters[3].EntryContext = &amt;BufferSizeDefault; 
parameters[3].DefaultType = REG_DWORD; 
parameters[3].DefaultData = &amt;notThereDefault; 
parameters[3].DefaultLength = sizeof(ULONG); 

status = RtlQueryRegistryValues( 
RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, 
parametersPath.Buffer, 
parameters, 
NULL, 
NULL); 

if (!NT_SUCCESS(status)) { 
RS_DbgPrint("RS485NT: RtlQueryRegistryValues failed\n"); 
} 

status = STATUS_SUCCESS; 
} 

// 
// Go ahead and assign driver defaults. 
// 

if (PortAddressDefault == notThereDefault) { 
DeviceExtension->PortAddress = (PUCHAR) DEF_PORT_ADDRESS; 
} else { 
DeviceExtension->PortAddress = (PVOID) PortAddressDefault; 
} 

if (IRQLineDefault == notThereDefault) { 
DeviceExtension->IRQLine = DEF_IRQ_LINE; 
} else { 
DeviceExtension->IRQLine = (KIRQL) IRQLineDefault; 
} 

if (BaudRateDefault == notThereDefault) { 
DeviceExtension->BaudRate = DEF_BAUD_RATE; 
} else { 
DeviceExtension->BaudRate = BaudRateDefault; 
} 

if (BufferSizeDefault == notThereDefault) { 
DeviceExtension->BufferSize = DEF_BUFFER_SIZE; 
} else { 
DeviceExtension->BufferSize = BufferSizeDefault; 
} 

// 
// Free the allocated memory before returning. 
// 

if (parametersPath.Buffer) 
ExFreePool(parametersPath.Buffer); 
if (parameters) 
ExFreePool(parameters); 
return (status); 
} 


//--------------------------------------------------------------------------- 
// Initialize_RS485 
// 
// Description: 
// Initializes all data structures and hardware necessary for 
// driver execution 
// 
// Arguments: 
// DeviceExtension - Pointer to the device extension. 
// 
// Return Value: 
// NSTATUS 
// 
NTSTATUS Initialize_RS485 (IN PRS485NT_DEVICE_EXTENSION DeviceExtension) 
{ 
UCHAR ch, Divisor; 
NTSTATUS status = STATUS_SUCCESS; 

// 
// Initialize all of the 8250 register addresses 
// 

DeviceExtension->ComPort.RBR = DeviceExtension->PortAddress + RX_REGISTER_8250; 
DeviceExtension->ComPort.TBR = DeviceExtension->PortAddress + TX_REGISTER_8250; 
DeviceExtension->ComPort.IER = DeviceExtension->PortAddress + IER_8250; 
DeviceExtension->ComPort.IIR = DeviceExtension->PortAddress + IIR_8250; 
DeviceExtension->ComPort.LCR = DeviceExtension->PortAddress + LCR_8250; 
DeviceExtension->ComPort.MCR = DeviceExtension->PortAddress + MCR_8250; 
DeviceExtension->ComPort.LSR = DeviceExtension->PortAddress + LSR_8250; 
DeviceExtension->ComPort.MSR = DeviceExtension->PortAddress + MSR_8250; 
DeviceExtension->ComPort.BAUD = DeviceExtension->PortAddress + DIVISOR_REGISTER_8250; 

// 
// Initialize any Events 
// 

KeInitializeEvent (&amt;DeviceExtension->XmitDone, SynchronizationEvent, FALSE); 

// 
// Allocate memory for the Transmit and Receive data buffers 
// 

DeviceExtension->RcvBuffer = ExAllocatePool(NonPagedPool, DeviceExtension->BufferSize); 

if (DeviceExtension->RcvBuffer == NULL) { 
RS_DbgPrint("RS485NT: ExAllocatePool failed for RcvBuffer\n"); 
status = STATUS_INSUFFICIENT_RESOURCES; 
} else { 

// 
// Setup buffer pointers and counts 
// 

DeviceExtension->RcvBufferPosition = DeviceExtension->RcvBuffer; 
DeviceExtension->RcvBufferEnd = DeviceExtension->RcvBuffer + 
(DeviceExtension->BufferSize - 1); 
DeviceExtension->RcvBufferCount = 0; 

} 

if (NT_SUCCESS(status)) { 
DeviceExtension->XmitBuffer = ExAllocatePool(NonPagedPool, DeviceExtension->BufferSize); 
if (DeviceExtension->RcvBuffer == NULL) { 
RS_DbgPrint("RS485NT: ExAllocatePool failed for XmitBuffer\n"); 
status = STATUS_INSUFFICIENT_RESOURCES; 
} else { 

// 
// Setup buffer pointers and counts 
// 
DeviceExtension->XmitBufferPosition = DeviceExtension->XmitBuffer; 
DeviceExtension->XmitBufferEnd = DeviceExtension->XmitBuffer + 
(DeviceExtension->BufferSize - 1); 
DeviceExtension->XmitBufferCount = 0; 
} 
} 

// 
// Clear the interrupt/error Count and get current system time 

DeviceExtension->InterruptCount = 0; 
DeviceExtension->RcvError = 0; 
KeQuerySystemTime (&amt;DeviceExtension->LastQuerySystemTime); 

// 
// Determine the UART divisor value 
// 

switch (DeviceExtension->BaudRate) { 
case 1200: 
Divisor = BAUD_RATE_DIVISOR_1200; 
break; 
case 2400: 
Divisor = BAUD_RATE_DIVISOR_2400; 
break; 
case 4800: 
Divisor = BAUD_RATE_DIVISOR_4800; 
break; 
case 9600: 
Divisor = BAUD_RATE_DIVISOR_9600; 
break; 
case 19200: 
Divisor = BAUD_RATE_DIVISOR_19200; 
break; 
case 38400: 
Divisor = BAUD_RATE_DIVISOR_38400; 
break; 
case 57600: 
Divisor = BAUD_RATE_DIVISOR_57600; 
break; 
case 115200: 
Divisor = BAUD_RATE_DIVISOR_115200; 
break; 
default: 
Divisor = BAUD_RATE_DIVISOR_19200; 
break; 
} 

// 
// Set the baud rate to the divisor value. 
// 

ch = ((READ_PORT_UCHAR (DeviceExtension->ComPort.LCR)) | LCR_ENABLE_DIVISOR_LATCH); 
WRITE_PORT_UCHAR (DeviceExtension->ComPort.LCR, ch); 

ch = READ_PORT_UCHAR (DeviceExtension->ComPort.LCR); 
WRITE_PORT_UCHAR (DeviceExtension->ComPort.BAUD, Divisor); 

ch = ((READ_PORT_UCHAR (DeviceExtension->ComPort.LCR)) &amt; LCR_DISABLE_DIVISOR_LATCH); 
WRITE_PORT_UCHAR (DeviceExtension->ComPort.LCR, ch); 

// 
// The data format = 1 start bit, 8 data bits, 1 stop bit, no parity. 
// 

ch = (LCR_EIGHT_BITS_PER_WORD | LCR_ONE_STOP_BIT | LCR_NO_PARITY); 
WRITE_PORT_UCHAR (DeviceExtension->ComPort.LCR, ch); 

// 
// Enable all UART interrupts on the IBM PC by asserting the GP02 general 
// purpose output. Clear all other MCR bits. Activate DTR for RS485 use. 
// 

ch = MCR_ACTIVATE_GP02 | MCR_ACTIVATE_DTR; 
WRITE_PORT_UCHAR (DeviceExtension->ComPort.MCR, ch); 

// 
// Enable Specific Interrupts 
// 

ch = (IER_ENABLE_RX_DATA_READY_IRQ | IER_ENABLE_TX_BE_IRQ | IER_ENABLE_RX_ERROR_IRQ); 
WRITE_PORT_UCHAR (DeviceExtension->ComPort.IER, ch); 

return status; 
} 


//--------------------------------------------------------------------------- 
// RS485_Write 
// 
// Description: 
// Called by DispatchRoutine in response to a Write request. 
// 
// Arguments: 
// DeviceExtension - The device extension strtucture 
// Irp - The Irp associated with this IO 
// 
// Return Value: 
// NTSTATUS 
// 
NTSTATUS RS485_Write (IN PRS485NT_DEVICE_EXTENSION DeviceExtension, IN PIRP Irp) 
{ 
ULONG Length; 
UCHAR ch; 

Length = IoGetCurrentIrpStackLocation(Irp)->Parameters.Write.Length; 
Irp->IoStatus.Information = 0L; 

// 
// Check for a zero length write. 
// 

if (Length) { 

if (Length >= DeviceExtension->BufferSize) { 

// 
// Not enough room in the buffer 
// 

Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 
} else { 

// 
// Clear the Transmit complete event 
// 

KeClearEvent (&amt;DeviceExtension->XmitDone); 

// 
// Copy the buffer into the DeviceExtension 
// 

RtlMoveMemory (DeviceExtension->XmitBuffer, 
Irp->AssociatedIrp.SystemBuffer, Length); 

DeviceExtension->XmitBufferCount = Length; 
DeviceExtension->XmitBufferPosition = DeviceExtension->XmitBuffer; 

// 
// Assert RTS 
// 

ch = READ_PORT_UCHAR (DeviceExtension->ComPort.MCR) | MCR_ACTIVATE_RTS; 
WRITE_PORT_UCHAR (DeviceExtension->ComPort.MCR, ch); 

// 
// Kick start the UART by jamming one byte out 
// 

WRITE_PORT_UCHAR (DeviceExtension->ComPort.TBR, 
*DeviceExtension->XmitBufferPosition); 

DeviceExtension->XmitBufferPosition++; 
DeviceExtension->XmitBufferCount--; 

// 
// Wait for the complete buffer to be sent 
// 
RS_DbgPrint ("RS485NT: Write KeWaitForSingleObject\n"); 
KeWaitForSingleObject (&amt;DeviceExtension->XmitDone, Executive, 
FALSE, KernelMode, NULL); 

// 
// Set the number of bytes written 
// 

Irp->IoStatus.Information = Length; 
} 

} else { 
// 
// Nothing to write, so return SUCCESS (and do nothing!) 
// 
Irp->IoStatus.Status = STATUS_SUCCESS; 
} 

return STATUS_SUCCESS; 
} 


//--------------------------------------------------------------------------- 
// RS485_Read 
// 
// Description: 
// Called by DispatchRoutine in response to a Read request. 
// 
// Arguments: 
// DeviceExtension - The device extension strtucture 
// Irp - The Irp associated with this IO 
// 
// Return Value: 
// NTSTATUS 
// 
NTSTATUS RS485_Read (IN PRS485NT_DEVICE_EXTENSION DeviceExtension, IN PIRP Irp) 
{ 
ULONG Length; 
KIRQL OldIrql; 

Length = IoGetCurrentIrpStackLocation(Irp)->Parameters.Read.Length; 
Irp->IoStatus.Information = 0L; 

// 
// Check for a zero length read. 
// 

if (Length) { 

// 
// Read in the minimum amount (User buffer or Device Extension buffer) 
// 

if (Length > DeviceExtension->RcvBufferCount) { 
Length = DeviceExtension->RcvBufferCount; 
} 

// 
// Synchronize - LOCK 
// 

KeRaiseIrql ((KIRQL)(DeviceExtension->Irql+1), &amt;OldIrql); 

// 
// Copy the buffer from the DeviceExtension 
// 
RtlMoveMemory (Irp->AssociatedIrp.SystemBuffer, 
DeviceExtension->RcvBuffer, Length); 

// 
// Clear the Rcv buffer info 
// 

DeviceExtension->RcvBufferCount = 0; 
DeviceExtension->RcvBufferPosition = DeviceExtension->RcvBuffer; 

// 
// Synchronize - UNLOCK 
// 

KeLowerIrql (OldIrql); 

// 
// Set the number of bytes actually read 
// 

Irp->IoStatus.Information = Length; 

} else { 
// 
// Nothing to read, so return SUCCESS (and do nothing!) 
// 
Irp->IoStatus.Status = STATUS_SUCCESS; 
} 

return STATUS_SUCCESS; 
} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -