Problem about EVT_WDF_TIMER

Hi! All,
I’m working on a sensor driver which should automatically read and return data periodically based on the period. The data reading works fine before I implement the EVT_WDF_TIMER call back function, but I get Assertion failure after…

Below are the error log:

Assertion failure - code c0000420 (first chance)
AK8975!DbgRaiseAssertionFailure+0x5:
95801085 cd2c int 2Ch

And below are my codes (interesting parts only):

VOID
ADRV99EvtIoRead (
WDFQUEUE Queue,
WDFREQUEST Request,
size_t Length
)
{
NTSTATUS status;
ULONG_PTR bytesCopied =0;
WDFMEMORY memory;

//Set for Timer
WDF_TIMER_CONFIG timerConfig;
WDF_OBJECT_ATTRIBUTES timerAttributes;
WDFTIMER timerHandle;
BOOLEAN blWdfTimerStart;

UNREFERENCED_PARAMETER(Queue);
UNREFERENCED_PARAMETER(Length);

PAGED_CODE();

status = WdfRequestRetrieveOutputMemory(Request, &memory);
if(NT_SUCCESS(status) ) {

WDF_TIMER_CONFIG_INIT(&timerConfig, ADRV99EvtTimerFunc);
timerConfig.AutomaticSerialization = TRUE;

WDF_OBJECT_ATTRIBUTES_INIT(&timerAttributes);
timerAttributes.ParentObject = Queue;
status = WdfTimerCreate(&timerConfig, &timerAttributes, &timerHandle);

blWdfTimerStart = WdfTimerStart(timerHandle,WDF_REL_TIMEOUT_IN_MS(10));
}
}

VOID
ADRV99EvtTimerFunc(
__in WDFTIMER Timer
)
{
WDFDEVICE device = WdfIoQueueGetDevice((WDFQUEUE)WdfTimerGetParentObject(Timer));
UCHAR ReturnData[10]; //10 bytes Data
int i;
NTSTATUS status;

readData(device, ReturnData);
}

I have tried to adjust the “period” of WdfTimerStart, but nothing changed. Any advise is highly appreciated!

-tftu

For starter call stack would be probably useful here as well as WDF dump log.

Kris

Kris, thanks for reply, below is the client side application code :

int testReadFile(){

printf(“\nTesting ReadFile !\n”);
HANDLE hDevice = CreateFile(
“\\.\AKDV99”, // Open the Device "file
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);

if (hDevice == INVALID_HANDLE_VALUE)
{
printf("Failed to obtain file handle to WRITE device: "
“%s with Win32 error code: %d\n”,
“AKDV99”, GetLastError() );
return 1;
}

UCHAR buffer[10];

ULONG ulRead;
BOOL bRet = ReadFile(hDevice,buffer,10,&ulRead,NULL);
if (bRet)
{
printf(“Read %d bytes:”,ulRead);
for (int i=0;i<(int)ulRead;i++)
{
printf(“%02X “,buffer[i]);
}
printf(”\n”);
}

CloseHandle(hDevice);
return 0;
}

I only got the Assertion failure notice in my original post which was copied from WinDbg, or, is there should be a WDF dump log I can check(sorry, I’m new in driver development)? Thanks!

-tftu

forgot to mention, although not sure if it helpful, WinDbg stopped in wdm.h:

VOID
__int2c (
VOID
);

#pragma intrinsic(__int2c)

__analysis_noreturn
FORCEINLINE
VOID
DbgRaiseAssertionFailure (
VOID
)

{
__int2c(); <------------------ Stop on this line
}

On Fri, Jul 29, 2011 at 2:40 AM, wrote:
> Kris, thanks for reply, below is the client side application code :
I actually meant call stack (k command) not client side code… When
you hit exception execute following:
.symfix+
.reload
!analyze -v
And send us output.

> I only got the Assertion failure notice in my original post which was copied from WinDbg, or, is there should be a WDF dump log I can check(sorry, I’m new in driver development)? Thanks!
http://blogs.msdn.com/b/doronh/archive/2006/07/31/684531.aspx
http://msdn.microsoft.com/en-us/library/ff545531(v=vs.85).aspx

Also what version of OS and KMDF are you using?

Kris

Hi! Kris, following your instruction, below is the logs from the k command:

0: kd> .symfix+
0: kd> .reload
Connected to Windows 7 7601 x86 compatible target at (Fri Jul 29 19:10:18.451 2011 (UTC + 8:00)), ptr64 FALSE
Loading Kernel Symbols



Loading User Symbols

Loading unloaded module list

0: kd> !analyze -v
Connected to Windows 7 7601 x86 compatible target at (Fri Jul 29 19:10:59.001 2011 (UTC + 8:00)), ptr64 FALSE
Loading Kernel Symbols



Loading User Symbols

Loading unloaded module list

*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************

Unknown bugcheck code (0)
Unknown bugcheck description
Arguments:
Arg1: 00000000
Arg2: 00000000
Arg3: 00000000
Arg4: 00000000

Debugging Details:

PROCESS_NAME: System

FAULTING_IP:
AKDV99!DbgRaiseAssertionFailure+5 [c:\winddk\7600.16385.1\inc\ddk\wdm.h @ 955]
90401085 cd2c int 2Ch

EXCEPTION_RECORD: ffffffff – (.exr 0xffffffffffffffff)
ExceptionAddress: 90401085 (AKDV99!DbgRaiseAssertionFailure+0x00000005)
ExceptionCode: c0000420 (Assertion failure)
ExceptionFlags: 00000000
NumberParameters: 0

ERROR_CODE: (NTSTATUS) 0xc0000420 -

EXCEPTION_CODE: (NTSTATUS) 0xc0000420 -

DEFAULT_BUCKET_ID: VISTA_DRIVER_FAULT

BUGCHECK_STR: 0x0

CURRENT_IRQL: 2

LAST_CONTROL_TRANSFER: from 90401633 to 90401085

STACK_TEXT:
8412da5c 90401633 807c7a54 807c6102 8412daac AKDV99!DbgRaiseAssertionFailure+0x5 [c:\winddk\7600.16385.1\inc\ddk\wdm.h @ 955]
8412dacc 90401afb 78fdd2d8 47455257 0000010a AKDV99!evaluateASL+0x43 [d:\tudoc\driverdev\AKDV99\AKDV99.c @ 708]
8412daec 90401564 78fdd2d8 8412dafc 9040bea5 AKDV99!readData+0x4b [d:\tudoc\driverdev\AKDV99\AKDV99.c @ 897]
8412db14 89c5e53a 78f17bb8 8412dba0 00000000 AKDV99!AKDV99EvtTimerFunc+0x64 [d:\tudoc\driverdev\AKDV99\AKDV99.c @ 638]
8412db30 89c5e984 8412db7c 8407f039 870e84a0 Wdf01000!FxTimer::TimerHandler+0x92
8412db38 8407f039 870e84a0 870e8440 e58c1e85 Wdf01000!FxTimer::_FxTimerDpcThunk+0x17
8412db7c 8407efdd 84130d20 8412dca8 00000001 nt!KiProcessTimerDpcTable+0x50
8412dc68 8407ee9a 84130d20 8412dca8 00000000 nt!KiProcessExpiredTimerList+0x101
8412dcdc 8407d00e 000039f7 8727ea88 8413a380 nt!KiTimerExpiration+0x25c
8412dd20 8407ce38 00000000 0000000e 00000000 nt!KiRetireDpcList+0xcb
8412dd24 00000000 0000000e 00000000 00000000 nt!KiIdleLoop+0x38

STACK_COMMAND: kb

FOLLOWUP_IP:
AKDV99!DbgRaiseAssertionFailure+5 [c:\winddk\7600.16385.1\inc\ddk\wdm.h @ 955]
90401085 cd2c int 2Ch

FAULTING_SOURCE_CODE:
951: VOID
952: )
953:
954: {
> 955: __int2c();
956: }
957:
958: #else
959: #pragma warning( push )
960: #pragma warning( disable : 4793 )

SYMBOL_STACK_INDEX: 0

SYMBOL_NAME: AKDV99!DbgRaiseAssertionFailure+5

FOLLOWUP_NAME: MachineOwner

MODULE_NAME: AKDV99

IMAGE_NAME: AKDV99.sys

DEBUG_FLR_IMAGE_TIMESTAMP: 4e312629

FAILURE_BUCKET_ID: 0x0_AKDV99!DbgRaiseAssertionFailure+5

BUCKET_ID: 0x0_AKDV99!DbgRaiseAssertionFailure+5

Followup: MachineOwner
---------

Both target and development machine are Windows7 32bit, and, WDK 7600.16385.1

Studying the materials you provided now …

-tftu

On Fri, Jul 29, 2011 at 12:25 PM, wrote:
> STACK_TEXT:
> 8412da5c 90401633 807c7a54 807c6102 8412daac AKDV99!DbgRaiseAssertionFailure+0x5 [c:\winddk\7600.16385.1\inc\ddk\wdm.h @ 955]
> 8412dacc 90401afb 78fdd2d8 47455257 0000010a AKDV99!evaluateASL+0x43 [d:\tudoc\driverdev\AKDV99\AKDV99.c @ 708]
> 8412daec 90401564 78fdd2d8 8412dafc 9040bea5 AKDV99!readData+0x4b [d:\tudoc\driverdev\AKDV99\AKDV99.c @ 897]
> 8412db14 89c5e53a 78f17bb8 8412dba0 00000000 AKDV99!AKDV99EvtTimerFunc+0x64 [d:\tudoc\driverdev\AKDV99\AKDV99.c @ 638]

This should be pretty obvious. It looks like you failed assertion in
your own code: AKDV99!evaluateASL+0x43
[d:\tudoc\driverdev\AKDV99\AKDV99.c line 708 (well, actually failing
assert statement is in line 707). You can switch to with “.frame 1”.

Kris

Thanks Kris, now I know the problem is about the PAGED_CODE() and IRQL(level 2…) and studying their relation with EVT_WDF_TIMER, any quick hint except manually lower down the IRQL?

On Fri, Jul 29, 2011 at 2:33 PM, wrote:
> any quick hint except
You need to rethink your architecture. You can use system thread or
work items to process data at PASSIVE_LEVEL but it really depends on
what you are trying to do.

> manually lower down the IRQL?
Do NOT do that!

Kris

Let me briefly introduce my project. This driver basically communicate with EC and gets certain output from a sensor which is wired to EC and the protocol is ACPI. When the client application send a time interval and trigger driver’s EvtIoRead call back function, the sensor is supposed to repeatedly returning the data it read based on the input time interval.

My current design is quite simple, EvtIoRead invoke the WDFTimer and WDFTimer repeatedly invoked evaluateASL which is the actual function to communicate with the sensor.

Could I have a reference sample of the system thread or work items you mentioned? Or any suggestion is highly appreciated! Again, thank you for answering my newbee questions.

Have a nice weekend!

-tftu

So, to put it in simple, generic, terms you’re polling this sensor periodically.

I’m not aware of a simple, pure, KMDF method to do this.

I would create a system thread (see PsCreateSystemThread) that sets a periodic kernel timer (KeSetTimerEx) for your polling interval. I would then KeWaitForMultipleObjects to wait for either that timer’s expiration or a second event (created by KeInitializeEvent) that signals the system thread to exit (by calling PsTerminateSystemThread).

This will be efficient, run serially, and all run at IRQL PASSIVE_LEVEL.

Peter
OSR

Hi! Peter,

Many thanks for your advise. I’ll revise my code per your advise, but I foresee I will meet more problems before complete this driver.

I’m very grateful for the helps from all of you, especially NTDEV forum which is my key knowledge base now.

Cordially,

-tftu