Thank you for your reply, blue screen termination code: IRQL GT ZERO AT SYSTEM
SERVICE, I have now removed the KeWaitForSingleObject, you are right that can't
wait, I have now increased the FIFO buffer
Also changed the GetPosition method, more precise timing by
KeQueryInterruptTime into KeQueryPerformanceCounter, in addition to reset the
position over fragments of noise, can cause delay problems, don't know whether
it is correct, if there is a good way to solve this problem?
GetPosition code:
if (m_ksState == KSSTATE_RUN)
{
//
// Get the current time and update position.
//
LARGE_INTEGER ilQPC = KeQueryPerformanceCounter(NULL);
// Convert ticks to 100ns units.
LONGLONG hnsCurrentTime =
KSCONVERT_PERFORMANCE_TIME(m_ullPerformanceCounterFrequency.QuadPart, ilQPC);
// Calculate the time elapsed since the last call to GetPosition() or since the
// DMA engine started. Note that the division by 10000 to convert to
milliseconds
// may cause us to lose some of the time, so we will carry the remainder
forward
// to the next GetPosition() call.
//
ULONG TimeElapsedInMS = (ULONG)(hnsCurrentTime - m_ullDmaTimeStamp +
m_ullElapsedTimeCarryForward) / 10000;
// Carry forward the remainder of this division so we don't fall behind with
our position too much.
//
m_ullElapsedTimeCarryForward = (hnsCurrentTime - m_ullDmaTimeStamp +
m_ullElapsedTimeCarryForward) % 10000;
// Calculate how many bytes in the DMA buffer would have been processed in the
elapsed
// time. Note that the division by 1000 to convert to milliseconds may cause
us to
// lose some bytes, so we will carry the remainder forward to the next
GetPosition() call.
//
// need to divide by 1000 because m_ulDmaMovementRate is average bytes per sec.
ULONGByteDisplacement =
((m_ulDmaMovementRate * TimeElapsedInMS) + m_ulByteDisplacementCarryForward) /
1000;
// Carry forward the remainder of this division so we don't fall behind with
our position.
m_ulByteDisplacementCarryForward = (
(m_ulDmaMovementRate * TimeElapsedInMS) + m_ulByteDisplacementCarryForward ) %
1000;
_data_trans_t* dt = (_data_trans_t*)this->m_pOwner->m_hDataTrans;
if (m_fCapture) {
//dt-> req_size is CopyFrom ByteCount- *
existing data length in the buffer *
m_ulDmaPosition = (m_ulDmaPosition+(ByteDisplacement - dt->req_size)) %
m_ulDmaBufferSize;
InterlockedExchange(&dt->req_size, 0);
}
else {
m_ulDmaPosition = (m_ulDmaPosition+ByteDisplacement) % m_ulDmaBufferSize;
}
*Position = m_ulDmaPosition;
m_ullDmaTimeStamp = hnsCurrentTime;
}
At 2018-10-30 02:25:09, "Tim Roberts" <timr@xxxxxxxxx> wrote:
何海洲 wrote:
When I use the KeWaitForSingleObject to wait for the buffering to complete, the
blue screen will occur. How do I resolve it
Why would you not tell us which blue screen you got? I'm pretty sure I know
what it was, but you need to do some of your own debugging here.
The CopyFrom process happens in real-time at a raised IRQL. You can't wait for
anything. If you don't have the data, you'll have to return and hope that you
catch up sooner or later.
This is a tricky environment. The system asks for 10ms at a time. If the
entity that is producing your data works in larger blocks than that, it's up to
you to provide the glue, usually by buffering up enough initial data to work
through the mismatch.
--
Tim Roberts, timr@xxxxxxxxx
Providenza & Boekelheide, Inc.