Message signaled interrupt with IoConnectInterruptEx

tatuo wrote:

Yes, I do not understand the architectural yet.
Can you be so kind to teach the architectural to me with an instance?
Anything leading to the resolution is appreciated very much.

That is a reasonable request, but a difficult one to satisfy. Your
request spans multiple disciplines, including both the hardware, the
kernel, and the I/O buses, and all of those topics are very, very
large.  It’s possible to find reference sources for small aspects of the
kernel, but to a great extent, this stuff is learned “on the job”.

One thing that has been said in this thread that needs to be repeated is
that Windows is not a real-time system.  You’re never going to get
rock-solid interval timer interrupts.  The system design does not allow
it.  Fortunately, in almost every case where you think you need them,
you don’t.  For example, you said you wanted to send network packets
every 250us.  Surely you have to know that Ethernet itself is
unreliable.  There are unpredictable delays all through a network.  You
can certainly average 4,000 packets per second, but not with precision.

The Network Time Protocol that synchronizes most of the hosts on the
Internet doesn’t rely on absolute time signals.  Instead, as they
exchange messages, they measure the latency and the jitter to narrow in
on exact times.

I would like to find out more about your actual purpose here, to provide
better advice on a design that CAN be achieved.

Surely you have to know that Ethernet itself is unreliable. There are unpredictable delays all through a network. You
can certainly average 4,000 packets per second, but not with precision.

Please note that the term “Ethernet” does not necessarily imply the “conventional” networking (i.e LAN or SAN). Although your statement is 100% true as far as the “conventional” networking is concerned, it does not apply to so-called “Industrial Ethernet” with protocols that provide determinism and real-time control. Certainly, running the “conventional” TCPIP protocol suite on top of it may be “rather problematic”, but this is not what it is meant to be used for…

Anton Bassov

Dear Anton

Thank you for your help.
Our “Ethernet” is not a “conventional” network. The latency of communication is another topic. And it is not a problem in our project.
We are searching for just an interrupt which would call our ISR stably and periodically.

Best regard.

tatuo wrote:

Our “Ethernet” is not a “conventional” network. The latency of communication is another topic. And it is not a problem in our project.

How can you possibly argue that?  It HAS to be a consideration.
Remember, your goal is not to get periodic interrupts.  That’s just a
step.  Your goal (apparently) is to get regular packets to your
network.  In order to achieve that, you HAVE to look at the entire
infrastructure: not only the timer accuracy, but the network software
latency, the NIC latency, the network latency, collisions, delays on the
other end, etc.  It is a waste of time an energy to try to build a timer
with picosecond precision if your network transmission time varies
within a couple of milliseconds, as it probably does.  It’s a
statistical process.

We are searching for just an interrupt which would call our ISR stably and periodically.

There are many, many PCIExpress general purpose I/O boards with
countdown timers that can issue an interrupt.  Here’s one.

https://logical-co.com/product/dual-programmable-timer-pci-express/

Dear Tim
Thank you very much for your help.

It is a waste of time an energy to try to build a timer
with picosecond precision if your network transmission time varies
within a couple of milliseconds,

The period we need is 250~1000microseconds, and jitter is 50 microseconds or so. It is not so hard in some sense. It is not in picosecond.
It is true that the latency is composed of many and many factors. First we have to have a precise timer. It is the base of all. We will leave other problems to the hardware of network. It is doing its best. It is said to have a precision in nanosecond. Thing can become well only after all is perfect. We should do our best ourselves first.
I would appreciate it very much if you could give me some advice about registering an interrupt to ACPI with ASL.

There are many, many PCIExpress general purpose I/O boards with
countdown timers that can issue an interrupt. Here’s one.

After I have failed to all test of possibility, I shall change my design. I think it is not so long.

Thanks again.

On May 16, 2019, at 4:22 PM, tatuo wrote:
>
> The period we need is 250~1000microseconds, and jitter is 50 microseconds or so. It is not so hard in some sense. It is not in picosecond.

I know, I was exaggerating to make a point.

> I would appreciate it very much if you could give me some advice about registering an interrupt to ACPI with ASL.

Do you have the ability to modify the BIOS in your machine? If you have the source code, then you might be able to modify the DSDT in the BIOS to add a device for the HPET that you can provide an INF for. Such a driver would be assigned the appropriate interrupt by the system. No hackery.

However, that requires the BIOS source. Linux has the ability to add DSDT overrides during boot, but Windows (to my knowledge) does not.

Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

Dear Tim

I love you.

Dear Tim

I love you

We all love Mr. Roberts, Mr. Tatuo. We all do.

This is precisely why Mr. Roberts was canonized some years back. You probably missed the announcement. We have yet to establish a particular day in his honor… but we’re open to you suggesting one (sadly, today is already taken by William Hobart Hare, who was not so active on NTDEV but worthy of remembrance nonetheless).

Peter

I would appreciate it very much if you could give me some advice about registering an interrupt to ACPI with ASL.

Please note that setting an interrupt that fires with high precision is not going to solve your problems concerning the precise timing the egress packets leave your machine. You are unable to do send packets in context of ISR, right - you best possible bet is DPC_LEVEL code. At this point the issue of possible jitter arises, because the precise timing of DPC depends on the external factors like the length of DPC queue at the moment. Therefore, your problem is not yet solved…

Anton Bassov

In short… this is yet another case of A/B problem. What can be actually be done, depends on the custom network adapter of the OP - can they hack it to do the scheduling itself? Replace it by a cheap microcontroller with ethernet? Move the whole project to the other OS?

– pa

Dear Mr. viscarola

Thank you very much.
I am sorry replying to you so late due to the weekend days.
Thank you for giving us such a platform to discuss our problem. Thank you for giving me such a chance.
I feel honored to suggest a particular day to give our respect to Mr. Roberts.
I think he is worthy.
Because I am new to this forum, please tell me how to take the procedure.
How about today?

Yours sincerely.

Tatuo

Dear Anton

Thank you for your advice.
I think I had better open another thread to discuss problems that occur when data are sent to network.

Thanks again.

Dear Mr. Pavel_A

Thank you very much for your advice.
You are right.
But I must send data which are produced from a program running on windows.

Thanks again.

Dear Mr. Roberts

Do you have the ability to modify the BIOS in your machine? If you have the source code, then you might be able to modify the DSDT in the BIOS to add >a device for the HPET that you can provide an INF for. Such a driver would be assigned the appropriate interrupt by the system. No hackery.

asl.exe can be used to retrieve the DSDT.
ASL file can even been generated using ACPIGenFx.
The modified DSDT can be stored in registry to test.

But I failed with the test.
First, I set the system to test mode.
bcdedit /set TESTSIGNING ON
I retrieved the current DSDT with below command.
asl.exe /tab=DSDT
It gave me a dsdt.asl.
When I compiled it, so many errors were made that were beyond my ability to fix.

Then I decided to test with the sample asl file GpioSampleKMDF.asl under simdevice.
It succeeded to be loaded to registry.


But it did not appeare in the device manager of windows.

Last, I generated an asl file myself with below code.
static void Main(string args)
{

        x86Platform Platform = Platforms.Createx86Platform(
            OEMID: "MSFT",
            OEMTableID: "EDK2",
            CreatorID: "MSFT",
            Revision: 1, FileName: "DSDT"
            );

        GenericDevice Gen3 = Platform.AddGenericDevice("Tim1", "APIC23", "PNP0003", 1);
        Gen3.AddInterrupt(InterruptType.Edge, InterruptActiveLevel.ActiveHigh, SharingLevel.Exclusive, 23);

        Platform.WriteAsl();
    }

It can be loaded but it did not appear in the device manager of windows too.
Who can give me some hints?
Help me!

Thanks in advance.

tatuo wrote:

When I compiled it, so many errors were made that were beyond my ability to fix.

Yes, this happens.  The Intel and Microsoft ASL compilers use different
rules, and that allows invalid things to slip in.  Most of the errors
are probably the same; you’ll need to do some web searching to find
them.  There are lots of people hacking their DSDTs in the Linux world,
and those posts may provide some tops for you.

Then I decided to test with the sample asl file GpioSampleKMDF.asl under simdevice.
It succeeded to be loaded to registry.

This is a bit dangerous.  When you put a DSDT in the registry you are
REPLACING the DSDT provided by the BIOS.  If you don’t have all of the
entries in the original DSDT, that is an excellent way to turn your
computer into a brick.  You may need to use “last known good” or “safe
mode” to get rid of it.

Better to add you unique devices to the SSDT using this method. Any existing SSDT will be shorter, for sure, than the DSDT. See https://docs.microsoft.com/en-us/windows-hardware/drivers/bringup/generate-acpi-tables-by-using-acpigenfx

Peter

Dear Mr. Viscarola

Thank you very much.
I am using the way you told me today.
But the device cannot appear in the device manager if just this produced file is used without the contend retrieved from windows with iasl or asl command. If the produced file is attached to the file retrieved from system, it workes fine except for strange view of some device.
Anyway, I can communicate to the new device now.
I can verify the resoure information sent to EVT_WDF_DEVICE_PREPARE_HARDWARE.
u.Interrupt.Vector is 0xa0
u.Interrupt.Level is 0x0a
u.Interrupt.Affinity is 0x0f

But when I install the driver, computer crushes.
The source code is as following.

NTSTATUS InterruptPrepareHardware(
In WDFDEVICE Device,
In WDFCMRESLIST ResourcesRaw,
In WDFCMRESLIST ResourcesTranslated
)
{
PCM_PARTIAL_RESOURCE_DESCRIPTOR descriptor;
PDEVICE_CONTEXT deviceContext;

PAGED_CODE();
deviceContext = WdfObjectGet_DEVICE_CONTEXT(Device);

      status = IoConnectInterrupt(
			&deviceContext->InterruptObject,
			InterruptServiceRoutine,
			deviceContext,
			NULL,
			descriptor->u.Interrupt.Vector,
			(KIRQL)descriptor->u.Interrupt.Level,
			(KIRQL)descriptor->u.Interrupt.Level,
			LevelSensitive,
			FALSE,
			descriptor->u.Interrupt.Affinity,
			FALSE
		);
     return STATUS_SUCCESS;

...................

}
InterruptServiceRoutine does nothing now.
I am searching for the cause…

Best regard.

Tatuo

Hi

When I use below code to connect interrupt in EVT_WDF_DEVICE_PREPARE_HARDWARE, error code 0xc000000d is returned, meaning “An invalid parameter was passed to a service or function”.

        RtlZeroMemory(&InterruptParams, sizeof(IO_CONNECT_INTERRUPT_PARAMETERS));
		InterruptParams.Version = CONNECT_LINE_BASED;
		InterruptParams.LineBased.PhysicalDeviceObject = WdfDeviceWdmGetDeviceObject(Device);
		InterruptParams.LineBased.InterruptObject = &deviceContext->InterruptObject;
		InterruptParams.LineBased.ServiceRoutine = InterruptServiceRoutine;
		InterruptParams.LineBased.ServiceContext = deviceContext;
		InterruptParams.LineBased.SpinLock = NULL;
		InterruptParams.LineBased.SynchronizeIrql = 0;
		InterruptParams.LineBased.FloatingSave = FALSE;

		status = IoConnectInterruptEx(&InterruptParams);

What is the problem?

Tatuo

Hi

When I use below code to connect interrupt to my ISR in EVT_WDF_DEVICE_PREPARE_HARDWARE, no error occurs.
But I do not know if interrupt can be triggered yet, because I have not connected it to HPET…

   WDF_INTERRUPT_CONFIG_INIT(&InterruptConfiguration,
			InterruptServiceRoutine,
			DrvInterruptDpc);

		InterruptConfiguration.EvtInterruptEnable = TimerInterruptEnable;
		InterruptConfiguration.EvtInterruptDisable = TimerInterruptDisable;
		InterruptConfiguration.InterruptTranslated = descriptor;
		InterruptConfiguration.InterruptRaw = WdfCmResourceListGetDescriptor(ResourcesRaw, i);

		InterruptConfiguration.AutomaticSerialization = TRUE;

		status = WdfInterruptCreate(Device,
			&InterruptConfiguration,
			WDF_NO_OBJECT_ATTRIBUTES,
			&deviceContext->WdfInterrupt);

Thanks.

Tatuo

Well, that’s the next step.