irp_mj_read problem

Hi all,

I am not an expert in writeing drivers. I build some software to aquire some
data from serial port. In windows98 works great. In 2000/XP are some
problems.

My function to get data from serial port is something like:

Comm1->Read(buffer,nr_of_bytes_to_read);

wich it’s called from an RXChar event.

In win98 I can get with this blocks of data ( eg 16 bytes to read once ) but
in XP the data arrives in the event chaotic ( sometimes in blocks of 8
bytes, some times one-by-one bytes and never like I expect). I watch the
requests with PortMon.

I tested many components ( drivers ) for Delphi / CBuilder / .NET and all
the same thing. What is the problem ? My app. is just a simple logger of few
bytes givem by a microcontroller on serial port. I can give more details if
needed.

Thanks in advance,

eddy


Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.783 / Virus Database: 529 - Release Date: 10/25/2004


Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.783 / Virus Database: 529 - Release Date: 10/25/2004

Hi Eddy,

I’m not sure what your question is, but I’ll try to explain what I think
you’re asking.

  1. The serial port has a buffer of some sort. The serial driver can set up
    when (at which buffer fill-level) it wants the serial port to interrupt.
    It’s not unlikely that XP and 98 have different setups here.
  2. The handling of interrupts, while on a high-level it’s the same, there
    are most certainly big differences in XP and 98 here, which means, maybe,
    that 98 has a slower response to interrupts.
    3, The handling of process/thread switching is quite different in Win98 and
    XP.
  3. Different hardware platforms have different speeds, which affects all
    sorts of things, includig process/thread switching, interrupt response
    time, I/O port read times, etc.

All the above variables will affect how quickly the OS (driver) can get
data out of the serial port, what size “lumps” it comes in.

Since there isn’t a concept of packet on the basic serial port at the
hardware level, other than a word-size of (usually) 8 bits. (You can add
that layer in software), the serial driver has no idea of what the software
expects, and as such can not tell whether the software expects to read 1,
2, 5, 8, 16, 23 or any other number of bytes (yes, it could look at the
read request, but that’s often misleading, because it may well request to
read 1000 bytes, but the data arriving may only be 3 bytes).

So, when reading data from the serial port, you must expect it to return
ANY number of bytes from the last read (up to the maximum that you specify,
obviously).

I’m sure you can solve your problem by adding a simple loop (with timeout
of course) that reads the expected number of bytes.

If this didn’t actually clarify your situation, please let me know.


Mats

xxxxx@lists.osr.com wrote on 10/26/2004 05:03:18 AM:

Hi all,

I am not an expert in writeing drivers. I build some software to
aquire some data from serial port. In windows98 works great. In
2000/XP are some problems.

My function to get data from serial port is something like:

Comm1->Read(buffer,nr_of_bytes_to_read);

wich it’s called from an RXChar event.
In win98 I can get with this blocks of data ( eg 16 bytes to read
once ) but in XP the data arrives in the event chaotic ( sometimes
in blocks of 8 bytes, some times one-by-one bytes and never like I
expect). I watch the requests with PortMon.

I tested many components ( drivers ) for Delphi / CBuilder / .NET
and all the same thing. What is the problem ? My app. is just a
simple logger of few bytes givem by a microcontroller on serial
port. I can give more details if needed.

Thanks in advance,
eddy

Questions? First check the Kernel Driver FAQ at http://www.
osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: unknown lmsubst tag argument:
‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com


Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.783 / Virus Database: 529 - Release Date: 10/25/2004


Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.783 / Virus Database: 529 - Release Date: 10/25/2004
ForwardSourceID:NT00006072

Hi Mats,

I already spent two days on msdn library to figured out. I’ll try to be more
specific in few lines.

There is a simple communication between PC and some external device on COM,
without handshaking, etc. just simple async. communication. The PC initiate
(request) the transfer with a block of 16 bytes and the device respond with
another block ( in my case 12 bytes ). It’s just a convention, I wrote both
programs ( PC and asm for external device ).

In windows app. ( that?s the ugly part ) I have a lot of interface buttons,
combo, etc and I can’t just put some loop to watch the serial port :slight_smile:
because the program will latch in that loop without the incom data.

So, I get some serial-port-component from net, I dropped into my app. And in
his EV_RXCHAR event I expect to collect the data ONLY when it arrives on COM
port. This event comes with a parameter “Count” wich should indicate the
number of bytes ready to be read. That?s the event code ( cbuilder style ):

void __fastcall TTIGER::Comm1RxChar(TObject *Sender, DWORD Count){

BYTE *sData = new BYTE[Count];

Comm1->Read(sData,Count);

//do something with data

deletesData;
sData=NULL;

}

As I said before, I expect Count = 12 ( whenever arrives ) and in win98
works fine allways, but in 2000/XP the bytes don’t arrives all together. The
event handler is called few times to get all 12 expected bytes.

Sometimes arrives 3, 4, 5, othertimes 8 bytes and after the last 4 but never
all 12 together. I increase app. thread prio to “Time Critical” but nothing.
I don’t have a header in protocol, so I need to watch the number of bytes
arrived and after, some checksum, etc.

How can I force to read all bytes within a time-window ( a timeout ) but
still remain in that event.

Thanks in advance,
eddy

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Mats PETERSSON
Sent: Tuesday, October 26, 2004 11:04 AM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] irp_mj_read problem

Hi Eddy,

I’m not sure what your question is, but I’ll try to explain what I think
you’re asking.

  1. The serial port has a buffer of some sort. The serial driver can set up
    when (at which buffer fill-level) it wants the serial port to interrupt.
    It’s not unlikely that XP and 98 have different setups here.
  2. The handling of interrupts, while on a high-level it’s the same, there
    are most certainly big differences in XP and 98 here, which means, maybe,
    that 98 has a slower response to interrupts.
    3, The handling of process/thread switching is quite different in Win98 and
    XP.
  3. Different hardware platforms have different speeds, which affects all
    sorts of things, includig process/thread switching, interrupt response
    time, I/O port read times, etc.

All the above variables will affect how quickly the OS (driver) can get
data out of the serial port, what size “lumps” it comes in.

Since there isn’t a concept of packet on the basic serial port at the
hardware level, other than a word-size of (usually) 8 bits. (You can add
that layer in software), the serial driver has no idea of what the software
expects, and as such can not tell whether the software expects to read 1,
2, 5, 8, 16, 23 or any other number of bytes (yes, it could look at the
read request, but that’s often misleading, because it may well request to
read 1000 bytes, but the data arriving may only be 3 bytes).

So, when reading data from the serial port, you must expect it to return
ANY number of bytes from the last read (up to the maximum that you specify,
obviously).

I’m sure you can solve your problem by adding a simple loop (with timeout
of course) that reads the expected number of bytes.

If this didn’t actually clarify your situation, please let me know.


Mats

xxxxx@lists.osr.com wrote on 10/26/2004 05:03:18 AM:

Hi all,

I am not an expert in writeing drivers. I build some software to
aquire some data from serial port. In windows98 works great. In
2000/XP are some problems.

My function to get data from serial port is something like:

Comm1->Read(buffer,nr_of_bytes_to_read);

wich it’s called from an RXChar event.
In win98 I can get with this blocks of data ( eg 16 bytes to read
once ) but in XP the data arrives in the event chaotic ( sometimes
in blocks of 8 bytes, some times one-by-one bytes and never like I
expect). I watch the requests with PortMon.

I tested many components ( drivers ) for Delphi / CBuilder / .NET
and all the same thing. What is the problem ? My app. is just a
simple logger of few bytes givem by a microcontroller on serial
port. I can give more details if needed.

Thanks in advance,
eddy

Questions? First check the Kernel Driver FAQ at http://www.
osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: unknown lmsubst tag argument:
‘’
To unsubscribe send a blank email to xxxxx@lists.osr.com


Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.783 / Virus Database: 529 - Release Date: 10/25/2004


Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.783 / Virus Database: 529 - Release Date: 10/25/2004
ForwardSourceID:NT00006072


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

You are currently subscribed to ntdev as: xxxxx@hcv.ro
To unsubscribe send a blank email to xxxxx@lists.osr.com


Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.783 / Virus Database: 529 - Release Date: 10/25/2004


Outgoing mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.783 / Virus Database: 529 - Release Date: 10/25/2004

It is perfectly normal that the message arrives in several parts. Increasing
the priority will not help, on the contrary, lowering the priority may help bit,
but it will not guarantee you something. Creating a thread and successive
waiting within that thread for all characters is the solution. Your thread should
communicate with the main thread through messages when all characters
have arrived . This is all perfectly feasible within C++Builder.

C.

----- Original Message -----
From: “Eddy Gora”
To: “Windows System Software Devs Interest List”
Sent: Tuesday, October 26, 2004 12:46 PM
Subject: RE: [ntdev] irp_mj_read problem

> Hi Mats,
>
> I already spent two days on msdn library to figured out. I’ll try to be more
> specific in few lines.
>
> There is a simple communication between PC and some external device on COM,
> without handshaking, etc. just simple async. communication. The PC initiate
> (request) the transfer with a block of 16 bytes and the device respond with
> another block ( in my case 12 bytes ). It’s just a convention, I wrote both
> programs ( PC and asm for external device ).
>
> In windows app. ( that?s the ugly part ) I have a lot of interface buttons,
> combo, etc and I can’t just put some loop to watch the serial port :slight_smile:
> because the program will latch in that loop without the incom data.
>
> So, I get some serial-port-component from net, I dropped into my app. And in
> his EV_RXCHAR event I expect to collect the data ONLY when it arrives on COM
> port. This event comes with a parameter “Count” wich should indicate the
> number of bytes ready to be read. That?s the event code ( cbuilder style ):
>
> void __fastcall TTIGER::Comm1RxChar(TObject *Sender, DWORD Count){
>
> BYTE *sData = new BYTE[Count];
>
> Comm1->Read(sData,Count);
>
> //do something with data
>
> deletesData;
> sData=NULL;
>
> }
>
> As I said before, I expect Count = 12 ( whenever arrives ) and in win98
> works fine allways, but in 2000/XP the bytes don’t arrives all together. The
> event handler is called few times to get all 12 expected bytes.
>
> Sometimes arrives 3, 4, 5, othertimes 8 bytes and after the last 4 but never
> all 12 together. I increase app. thread prio to “Time Critical” but nothing.
> I don’t have a header in protocol, so I need to watch the number of bytes
> arrived and after, some checksum, etc.
>
> How can I force to read all bytes within a time-window ( a timeout ) but
> still remain in that event.
>
> Thanks in advance,
> eddy
>
>
>
>
>
>
> -----Original Message-----
> From: xxxxx@lists.osr.com
> [mailto:xxxxx@lists.osr.com] On Behalf Of Mats PETERSSON
> Sent: Tuesday, October 26, 2004 11:04 AM
> To: Windows System Software Devs Interest List
> Subject: Re: [ntdev] irp_mj_read problem
>
>
>
>
>
>
> Hi Eddy,
>
> I’m not sure what your question is, but I’ll try to explain what I think
> you’re asking.
>
> 1. The serial port has a buffer of some sort. The serial driver can set up
> when (at which buffer fill-level) it wants the serial port to interrupt.
> It’s not unlikely that XP and 98 have different setups here.
> 2. The handling of interrupts, while on a high-level it’s the same, there
> are most certainly big differences in XP and 98 here, which means, maybe,
> that 98 has a slower response to interrupts.
> 3, The handling of process/thread switching is quite different in Win98 and
> XP.
> 4. Different hardware platforms have different speeds, which affects all
> sorts of things, includig process/thread switching, interrupt response
> time, I/O port read times, etc.
>
> All the above variables will affect how quickly the OS (driver) can get
> data out of the serial port, what size “lumps” it comes in.
>
> Since there isn’t a concept of packet on the basic serial port at the
> hardware level, other than a word-size of (usually) 8 bits. (You can add
> that layer in software), the serial driver has no idea of what the software
> expects, and as such can not tell whether the software expects to read 1,
> 2, 5, 8, 16, 23 or any other number of bytes (yes, it could look at the
> read request, but that’s often misleading, because it may well request to
> read 1000 bytes, but the data arriving may only be 3 bytes).
>
> So, when reading data from the serial port, you must expect it to return
> ANY number of bytes from the last read (up to the maximum that you specify,
> obviously).
>
> I’m sure you can solve your problem by adding a simple loop (with timeout
> of course) that reads the expected number of bytes.
>
> If this didn’t actually clarify your situation, please let me know.
>
> –
> Mats
>
>
> xxxxx@lists.osr.com wrote on 10/26/2004 05:03:18 AM:
>
> > Hi all,
> >
> > I am not an expert in writeing drivers. I build some software to
> > aquire some data from serial port. In windows98 works great. In
> > 2000/XP are some problems.
> >
> > My function to get data from serial port is something like:
> >
> > Comm1->Read(buffer,nr_of_bytes_to_read);
> >
> > wich it’s called from an RXChar event.
> > In win98 I can get with this blocks of data ( eg 16 bytes to read
> > once ) but in XP the data arrives in the event chaotic ( sometimes
> > in blocks of 8 bytes, some times one-by-one bytes and never like I
> > expect). I watch the requests with PortMon.
> >
> > I tested many components ( drivers ) for Delphi / CBuilder / .NET
> > and all the same thing. What is the problem ? My app. is just a
> > simple logger of few bytes givem by a microcontroller on serial
> > port. I can give more details if needed.
> >
> > Thanks in advance,
> > eddy
> > —
> > Questions? First check the Kernel Driver FAQ at http://www.
> > osronline.com/article.cfm?id=256
> >
> > You are currently subscribed to ntdev as: unknown lmsubst tag argument:
> ‘’
> > To unsubscribe send a blank email to xxxxx@lists.osr.com
> >
> > —
> > Outgoing mail is certified Virus Free.
> > Checked by AVG anti-virus system (http://www.grisoft.com).
> > Version: 6.0.783 / Virus Database: 529 - Release Date: 10/25/2004
> >
> > —
> > Outgoing mail is certified Virus Free.
> > Checked by AVG anti-virus system (http://www.grisoft.com).
> > Version: 6.0.783 / Virus Database: 529 - Release Date: 10/25/2004
> > ForwardSourceID:NT00006072
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at
> http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: xxxxx@hcv.ro
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>
> —
> Incoming mail is certified Virus Free.
> Checked by AVG anti-virus system (http://www.grisoft.com).
> Version: 6.0.783 / Virus Database: 529 - Release Date: 10/25/2004
>
>
> —
> Outgoing mail is certified Virus Free.
> Checked by AVG anti-virus system (http://www.grisoft.com).
> Version: 6.0.783 / Virus Database: 529 - Release Date: 10/25/2004
>
>
>
>
> —
> Questions? First check the Kernel Driver FAQ at http://www.osronline.com/article.cfm?id=256
>
> You are currently subscribed to ntdev as: unknown lmsubst tag argument: ‘’
> To unsubscribe send a blank email to xxxxx@lists.osr.com
>
>

DQoNCg0KDQoNClNvLCBob3cgYWJvdXQgc29tZXRoaW5nIGxpa2UgdGhpczoNCg0Kdm9pZCBfX2Zh
c3RjYWxsIFRUSUdFUjo6Q29tbTFSeENoYXIoVE9iamVjdCAqU2VuZGVyLCBEV09SRCBDb3VudCl7
DQoNCiAgICAgIHN0YXRpYyBCWVRFIGJ1ZmZlciA9IG5ldyBCWVRFW0NvdW50XTsNCiAgICAgIHN0
YXRpYyBpbnQgQ291bnRTb0ZhciA9IDA7DQogICAgICBzdGF0aWMgaW50IENvdW50UmVtYWluaW5n
ID0gMDsNCiAgICAgIGludCByZWFkQnl0ZXM7DQoNCiAgICAgIGlmIChDb3VudFJlbWFpbmluZyA9
PSAwKQ0KICAgICAgew0KICAgICAgICAgICAgQ291bnRTb0ZhciA9IDA7DQogICAgICAgICAgICBD
b3VudFJlbWFpbmluZyA9IENvdW50Ow0KICAgICAgfQ0KDQogICAgICBCWVRFICpzRGF0YSA9ICZi
dWZmZXJbQ291bnRTb0Zhcl07DQoNCiAgICAgIHJlYWRCeXRlcyA9IENvbW0xLT5SZWFkKHNEYXRh
LENvdW50UmVtYWluaW5nKTsgICAgICAgIC8vIEkgYXNzdW1lDQp0aGF0IHlvdSBjYW4gZ2V0IHRo
ZSBhY3R1YWwgY291bnQuDQogICAgICBDb3VudFNvRmFyICs9IHJlYWRCeXRlczsNCiAgICAgIENv
dW50UmVtYWluaW5nIC09IHJlYWRCeXRlczsNCiAgICAgIGlmIChDb3VudFNvRmFyID09IENvdW50
KQ0KICAgICAgew0KICAgICAgICAgICAgLy8vIERvIHlvdXIgcHJvY2Vzc2luZy4NCg0KICAgICAg
fQ0KfQ0KDQpbVGhhdCBjb2RlIGlzIGEgYml0IHVnbHksIGJ1dCBJIHRoaW5rIHlvdSBjYW4gZm9s
bG93IHRoZSBwcmluY2lwbGUsIGFuZA0KcGVyaGFwcyB3cml0ZSBzb21ldGhpbmcgYSBiaXQgbmVh
dGVyLiBJJ20ganVzdCBhIGJpdCBsYXp5Li4uXS4NCg0KQW5vdGhlciBtZXRob2Qgd291bGQgYmUg
dG8gY3JlYXRlIGEgc2VwYXJhdGUgdGhyZWFkIHRoYXQgZG9lcyB0aGUgbG9vcCwgYW5kDQp0aGVu
IHNpZ25hbCBzb21lIHNvcnQgb2YgZXZlbnQgdG8gaW5kaWNhdGUgdGhhdCB0aGUgZGF0YSBwYWNr
ZXQgaXMgcmVhZHkuDQoNCkknbSB2ZXJ5IHN1cnByaXNlZCB0aGF0IHRoZSBXaW45OCB2ZXJzaW9u
IGFjdHVhbGx5IHJlYWxpYWJseSB3b3JrcyBpbiB0aGUNCm1hbm5lciB5b3UgZGVzY3JpYmUuLi4g
QnV0IHRoYXQgbWF5IGJlIGFzIGl0IGlzLCBJIHRoaW5rIGVpdGhlciBvZiB0aGUNCmFib3ZlIHR3
byBzb2x1dGlvbnMgc2hvdWxkIHdvcmsuDQoNCi0tDQpNYXRzDQoNCmJvdW5jZS0xOTE0MTItMTQw
NzlAbGlzdHMub3NyLmNvbSB3cm90ZSBvbiAxMC8yNi8yMDA0IDExOjQ2OjM3IEFNOg0KDQo+IEhp
IE1hdHMsDQo+DQo+IEkgYWxyZWFkeSBzcGVudCB0d28gZGF5cyBvbiBtc2RuIGxpYnJhcnkgdG8g
ZmlndXJlZCBvdXQuIEknbGwgdHJ5IHRvIGJlDQptb3JlDQo+IHNwZWNpZmljIGluIGZldyBsaW5l
cy4NCj4NCj4gVGhlcmUgaXMgYSBzaW1wbGUgY29tbXVuaWNhdGlvbiBiZXR3ZWVuIFBDIGFuZCBz
b21lIGV4dGVybmFsIGRldmljZSBvbg0KQ09NLA0KPiB3aXRob3V0IGhhbmRzaGFraW5nLCBldGMu
IGp1c3Qgc2ltcGxlIGFzeW5jLiBjb21tdW5pY2F0aW9uLiBUaGUgUEMNCmluaXRpYXRlDQo+IChy
ZXF1ZXN0KSB0aGUgdHJhbnNmZXIgd2l0aCBhIGJsb2NrIG9mIDE2IGJ5dGVzIGFuZCB0aGUgZGV2
aWNlIHJlc3BvbmQNCndpdGgNCj4gYW5vdGhlciBibG9jayAoIGluIG15IGNhc2UgMTIgYnl0ZXMg
KS4gSXQncyBqdXN0IGEgY29udmVudGlvbiwgSSB3cm90ZQ0KYm90aA0KPiBwcm9ncmFtcyAoIFBD
IGFuZCBhc20gZm9yIGV4dGVybmFsIGRldmljZSApLg0KPg0KPiBJbiB3aW5kb3dzIGFwcC4gKCB0
aGF04oCZcyB0aGUgdWdseSBwYXJ0ICkgSSBoYXZlIGEgbG90IG9mIGludGVyZmFjZQ0KYnV0dG9u
cywNCj4gY29tYm8sIGV0YyBhbmQgSSBjYW4ndCBqdXN0IHB1dCBzb21lIGxvb3AgdG8gd2F0Y2gg
dGhlIHNlcmlhbCBwb3J0IDopDQo+IGJlY2F1c2UgdGhlIHByb2dyYW0gd2lsbCBsYXRjaCBpbiB0
aGF0IGxvb3Agd2l0aG91dCB0aGUgaW5jb20gZGF0YS4NCj4NCj4gU28sIEkgZ2V0IHNvbWUgc2Vy
aWFsLXBvcnQtY29tcG9uZW50IGZyb20gbmV0LCBJIGRyb3BwZWQgaW50byBteSBhcHAuIEFuZA0K
aW4NCj4gaGlzIEVWX1JYQ0hBUiBldmVudCBJIGV4cGVjdCB0byBjb2xsZWN0IHRoZSBkYXRhIE9O
TFkgd2hlbiBpdCBhcnJpdmVzIG9uDQpDT00NCj4gcG9ydC4gVGhpcyBldmVudCBjb21lcyB3aXRo
IGEgcGFyYW1ldGVyICJDb3VudCIgd2ljaCBzaG91bGQgaW5kaWNhdGUgdGhlDQo+IG51bWJlciBv
ZiBieXRlcyByZWFkeSB0byBiZSByZWFkLiBUaGF04oCZcyB0aGUgZXZlbnQgY29kZSAoIGNidWls
ZGVyIHN0eWxlDQopOg0KPg0KPiB2b2lkIF9fZmFzdGNhbGwgVFRJR0VSOjpDb21tMVJ4Q2hhcihU
T2JqZWN0ICpTZW5kZXIsIERXT1JEIENvdW50KXsNCj4NCj4gQllURSAqc0RhdGEgPSBuZXcgQllU
RVtDb3VudF07DQo+DQo+IENvbW0xLT5SZWFkKHNEYXRhLENvdW50KTsNCj4NCj4gLy9kbyBzb21l
dGhpbmcgd2l0aCBkYXRhDQo+DQo+IGRlbGV0ZVtdc0RhdGE7DQo+IHNEYXRhPU5VTEw7DQo+DQo+
IH0NCj4NCj4gQXMgSSBzYWlkIGJlZm9yZSwgSSBleHBlY3QgQ291bnQgPSAxMiAoIHdoZW5ldmVy
IGFycml2ZXMgKSBhbmQgaW4gd2luOTgNCj4gd29ya3MgZmluZSBhbGx3YXlzLCBidXQgaW4gMjAw
MC9YUCB0aGUgYnl0ZXMgZG9uJ3QgYXJyaXZlcyBhbGwgdG9nZXRoZXIuDQpUaGUNCj4gZXZlbnQg
aGFuZGxlciBpcyBjYWxsZWQgZmV3IHRpbWVzIHRvIGdldCBhbGwgMTIgZXhwZWN0ZWQgYnl0ZXMu
DQo+DQo+IFNvbWV0aW1lcyBhcnJpdmVzIDMsIDQsIDUsIG90aGVydGltZXMgOCBieXRlcyBhbmQg
YWZ0ZXIgdGhlIGxhc3QgNCBidXQNCm5ldmVyDQo+IGFsbCAxMiB0b2dldGhlci4gSSBpbmNyZWFz
ZSBhcHAuIHRocmVhZCBwcmlvIHRvICJUaW1lIENyaXRpY2FsIiBidXQNCm5vdGhpbmcuDQo+IEkg
ZG9uJ3QgaGF2ZSBhIGhlYWRlciBpbiBwcm90b2NvbCwgc28gSSBuZWVkIHRvIHdhdGNoIHRoZSBu
dW1iZXIgb2YgYnl0ZXMNCj4gYXJyaXZlZCBhbmQgYWZ0ZXIsIHNvbWUgY2hlY2tzdW0sIGV0Yy4N
Cj4NCj4gSG93IGNhbiBJIGZvcmNlIHRvIHJlYWQgYWxsIGJ5dGVzIHdpdGhpbiBhIHRpbWUtd2lu
ZG93ICggYSB0aW1lb3V0ICkgYnV0DQo+IHN0aWxsIHJlbWFpbiBpbiB0aGF0IGV2ZW50Lg0KPg0K
PiBUaGFua3MgaW4gYWR2YW5jZSwNCj4gZWRkeQ0KPg0KPg0KPg0KPg0KPg0KPg0KPiAtLS0tLU9y
aWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiBGcm9tOiBib3VuY2UtMTkxMzkxLTE3MTk2QGxpc3RzLm9z
ci5jb20NCj4gW21haWx0bzpib3VuY2UtMTkxMzkxLTE3MTk2QGxpc3RzLm9zci5jb21dIE9uIEJl
aGFsZiBPZiBNYXRzIFBFVEVSU1NPTg0KPiBTZW50OiBUdWVzZGF5LCBPY3RvYmVyIDI2LCAyMDA0
IDExOjA0IEFNDQo+IFRvOiBXaW5kb3dzIFN5c3RlbSBTb2Z0d2FyZSBEZXZzIEludGVyZXN0IExp
c3QNCj4gU3ViamVjdDogUmU6IFtudGRldl0gaXJwX21qX3JlYWQgcHJvYmxlbQ0KPg0KPg0KPg0K
Pg0KPg0KPg0KPiBIaSBFZGR5LA0KPg0KPiBJJ20gbm90IHN1cmUgd2hhdCB5b3VyIHF1ZXN0aW9u
IGlzLCBidXQgSSdsbCB0cnkgdG8gZXhwbGFpbiB3aGF0IEkgdGhpbmsNCj4geW91J3JlIGFza2lu
Zy4NCj4NCj4gMS4gVGhlIHNlcmlhbCBwb3J0IGhhcyBhIGJ1ZmZlciBvZiBzb21lIHNvcnQuIFRo
ZSBzZXJpYWwgZHJpdmVyIGNhbiBzZXQNCnVwDQo+IHdoZW4gKGF0IHdoaWNoIGJ1ZmZlciBmaWxs
LWxldmVsKSBpdCB3YW50cyB0aGUgc2VyaWFsIHBvcnQgdG8gaW50ZXJydXB0Lg0KPiBJdCdzIG5v
dCB1bmxpa2VseSB0aGF0IFhQIGFuZCA5OCBoYXZlIGRpZmZlcmVudCBzZXR1cHMgaGVyZS4NCj4g
Mi4gVGhlIGhhbmRsaW5nIG9mIGludGVycnVwdHMsIHdoaWxlIG9uIGEgaGlnaC1sZXZlbCBpdCdz
IHRoZSBzYW1lLCB0aGVyZQ0KPiBhcmUgbW9zdCBjZXJ0YWlubHkgYmlnIGRpZmZlcmVuY2VzIGlu
IFhQIGFuZCA5OCBoZXJlLCB3aGljaCBtZWFucywgbWF5YmUsDQo+IHRoYXQgOTggaGFzIGEgc2xv
d2VyIHJlc3BvbnNlIHRvIGludGVycnVwdHMuDQo+IDMsIFRoZSBoYW5kbGluZyBvZiBwcm9jZXNz
L3RocmVhZCBzd2l0Y2hpbmcgaXMgcXVpdGUgZGlmZmVyZW50IGluIFdpbjk4DQphbmQNCj4gWFAu
DQo+IDQuIERpZmZlcmVudCBoYXJkd2FyZSBwbGF0Zm9ybXMgaGF2ZSBkaWZmZXJlbnQgc3BlZWRz
LCB3aGljaCBhZmZlY3RzIGFsbA0KPiBzb3J0cyBvZiB0aGluZ3MsIGluY2x1ZGlnIHByb2Nlc3Mv
dGhyZWFkIHN3aXRjaGluZywgaW50ZXJydXB0IHJlc3BvbnNlDQo+IHRpbWUsIEkvTyBwb3J0IHJl
YWQgdGltZXMsIGV0Yy4NCj4NCj4gQWxsIHRoZSBhYm92ZSB2YXJpYWJsZXMgd2lsbCBhZmZlY3Qg
aG93IHF1aWNrbHkgdGhlIE9TIChkcml2ZXIpIGNhbiBnZXQNCj4gZGF0YSBvdXQgb2YgdGhlIHNl
cmlhbCBwb3J0LCB3aGF0IHNpemUgImx1bXBzIiBpdCBjb21lcyBpbi4NCj4NCj4gU2luY2UgdGhl
cmUgaXNuJ3QgYSBjb25jZXB0IG9mIHBhY2tldCBvbiB0aGUgYmFzaWMgc2VyaWFsIHBvcnQgYXQg
dGhlDQo+IGhhcmR3YXJlIGxldmVsLCBvdGhlciB0aGFuIGEgd29yZC1zaXplIG9mICh1c3VhbGx5
KSA4IGJpdHMuICAoWW91IGNhbiBhZGQNCj4gdGhhdCBsYXllciBpbiBzb2Z0d2FyZSksIHRoZSBz
ZXJpYWwgZHJpdmVyIGhhcyBubyBpZGVhIG9mIHdoYXQgdGhlDQpzb2Z0d2FyZQ0KPiBleHBlY3Rz
LCBhbmQgYXMgc3VjaCBjYW4gbm90IHRlbGwgd2hldGhlciB0aGUgc29mdHdhcmUgZXhwZWN0cyB0
byByZWFkIDEsDQo+IDIsIDUsIDgsIDE2LCAyMyBvciBhbnkgb3RoZXIgbnVtYmVyIG9mIGJ5dGVz
ICh5ZXMsIGl0IGNvdWxkIGxvb2sgYXQgdGhlDQo+IHJlYWQgcmVxdWVzdCwgYnV0IHRoYXQncyBv
ZnRlbiBtaXNsZWFkaW5nLCBiZWNhdXNlIGl0IG1heSB3ZWxsIHJlcXVlc3QgdG8NCj4gcmVhZCAx
MDAwIGJ5dGVzLCBidXQgdGhlIGRhdGEgYXJyaXZpbmcgbWF5IG9ubHkgYmUgMyBieXRlcykuDQo+
DQo+IFNvLCB3aGVuIHJlYWRpbmcgZGF0YSBmcm9tIHRoZSBzZXJpYWwgcG9ydCwgeW91IG11c3Qg
ZXhwZWN0IGl0IHRvIHJldHVybg0KPiBBTlkgbnVtYmVyIG9mIGJ5dGVzIGZyb20gdGhlIGxhc3Qg
cmVhZCAodXAgdG8gdGhlIG1heGltdW0gdGhhdCB5b3UNCnNwZWNpZnksDQo+IG9idmlvdXNseSku
DQo+DQo+IEknbSBzdXJlIHlvdSBjYW4gc29sdmUgeW91ciBwcm9ibGVtIGJ5IGFkZGluZyBhIHNp
bXBsZSBsb29wICh3aXRoIHRpbWVvdXQNCj4gb2YgY291cnNlKSB0aGF0IHJlYWRzIHRoZSBleHBl
Y3RlZCBudW1iZXIgb2YgYnl0ZXMuDQo+DQo+IElmIHRoaXMgZGlkbid0IGFjdHVhbGx5IGNsYXJp
ZnkgeW91ciBzaXR1YXRpb24sIHBsZWFzZSBsZXQgbWUga25vdy4NCj4NCj4gLS0NCj4gTWF0cw0K
Pg0KPg0KPiBib3VuY2UtMTkxMzc0LTE0MDc5QGxpc3RzLm9zci5jb20gd3JvdGUgb24gMTAvMjYv
MjAwNCAwNTowMzoxOCBBTToNCj4NCj4gPiBIaSBhbGwsDQo+ID4NCj4gPiBJIGFtIG5vdCBhbiBl
eHBlcnQgaW4gd3JpdGVpbmcgZHJpdmVycy4gSSBidWlsZCBzb21lIHNvZnR3YXJlIHRvDQo+ID4g
YXF1aXJlIHNvbWUgZGF0YSBmcm9tIHNlcmlhbCBwb3J0LiBJbiB3aW5kb3dzOTggd29ya3MgZ3Jl
YXQuIEluDQo+ID4gMjAwMC9YUCBhcmUgc29tZSBwcm9ibGVtcy4NCj4gPg0KPiA+IE15IGZ1bmN0
aW9uIHRvIGdldCBkYXRhIGZyb20gc2VyaWFsIHBvcnQgaXMgc29tZXRoaW5nIGxpa2U6DQo+ID4N
Cj4gPiBDb21tMS0+UmVhZChidWZmZXIsbnJfb2ZfYnl0ZXNfdG9fcmVhZCk7DQo+ID4NCj4gPiB3
aWNoIGl0J3MgY2FsbGVkIGZyb20gYW4gUlhDaGFyIGV2ZW50Lg0KPiA+IEluIHdpbjk4IEkgY2Fu
IGdldCB3aXRoIHRoaXMgYmxvY2tzIG9mIGRhdGEgKCBlZyAxNiBieXRlcyB0byByZWFkDQo+ID4g
b25jZSApIGJ1dCBpbiBYUCB0aGUgZGF0YSBhcnJpdmVzIGluIHRoZSBldmVudCBjaGFvdGljICgg
c29tZXRpbWVzDQo+ID4gaW4gYmxvY2tzIG9mIDggYnl0ZXMsIHNvbWUgdGltZXMgb25lLWJ5LW9u
ZSBieXRlcyBhbmQgbmV2ZXIgbGlrZSBJDQo+ID4gZXhwZWN0KS4gSSB3YXRjaCB0aGUgcmVxdWVz
dHMgd2l0aCBQb3J0TW9uLg0KPiA+DQo+ID4gSSB0ZXN0ZWQgbWFueSBjb21wb25lbnRzICggZHJp
dmVycyApIGZvciBEZWxwaGkgLyBDQnVpbGRlciAvIC5ORVQNCj4gPiBhbmQgYWxsIHRoZSBzYW1l
IHRoaW5nLiBXaGF0IGlzIHRoZSBwcm9ibGVtID8gTXkgYXBwLiBpcyBqdXN0IGENCj4gPiBzaW1w
bGUgbG9nZ2VyIG9mIGZldyBieXRlcyBnaXZlbSBieSBhIG1pY3JvY29udHJvbGxlciBvbiBzZXJp
YWwNCj4gPiBwb3J0LiBJIGNhbiBnaXZlIG1vcmUgZGV0YWlscyBpZiBuZWVkZWQuDQo+ID4NCj4g
PiBUaGFua3MgaW4gYWR2YW5jZSwNCj4gPiBlZGR5DQo+ID4gLS0tDQo+ID4gUXVlc3Rpb25zPyBG
aXJzdCBjaGVjayB0aGUgS2VybmVsIERyaXZlciBGQVEgYXQgaHR0cDovL3d3dy4NCj4gPiBvc3Jv
bmxpbmUuY29tL2FydGljbGUuY2ZtP2lkPTI1Ng0KPiA+DQo+ID4gWW91IGFyZSBjdXJyZW50bHkg
c3Vic2NyaWJlZCB0byBudGRldiBhczogdW5rbm93biBsbXN1YnN0IHRhZyBhcmd1bWVudDoNCj4g
JycNCj4gPiBUbyB1bnN1YnNjcmliZSBzZW5kIGEgYmxhbmsgZW1haWwgdG8gbGVhdmUtbnRkZXYt
MTQwNzlDQGxpc3RzLm9zci5jb20NCj4gPg0KPiA+IC0tLQ0KPiA+IE91dGdvaW5nIG1haWwgaXMg
Y2VydGlmaWVkIFZpcnVzIEZyZWUuDQo+ID4gQ2hlY2tlZCBieSBBVkcgYW50aS12aXJ1cyBzeXN0
ZW0gKGh0dHA6Ly93d3cuZ3Jpc29mdC5jb20pLg0KPiA+IFZlcnNpb246IDYuMC43ODMgLyBWaXJ1
cyBEYXRhYmFzZTogNTI5IC0gUmVsZWFzZSBEYXRlOiAxMC8yNS8yMDA0DQo+ID4NCj4gPiAtLS0N
Cj4gPiBPdXRnb2luZyBtYWlsIGlzIGNlcnRpZmllZCBWaXJ1cyBGcmVlLg0KPiA+IENoZWNrZWQg
YnkgQVZHIGFudGktdmlydXMgc3lzdGVtIChodHRwOi8vd3d3LmdyaXNvZnQuY29tKS4NCj4gPiBW
ZXJzaW9uOiA2LjAuNzgzIC8gVmlydXMgRGF0YWJhc2U6IDUyOSAtIFJlbGVhc2UgRGF0ZTogMTAv
MjUvMjAwNA0KPiA+IEZvcndhcmRTb3VyY2VJRDpOVDAwMDA2MDcyDQo+DQo+DQo+DQo+IC0tLQ0K
PiBRdWVzdGlvbnM/IEZpcnN0IGNoZWNrIHRoZSBLZXJuZWwgRHJpdmVyIEZBUSBhdA0KPiBodHRw
Oi8vd3d3Lm9zcm9ubGluZS5jb20vYXJ0aWNsZS5jZm0/aWQ9MjU2DQo+DQo+IFlvdSBhcmUgY3Vy
cmVudGx5IHN1YnNjcmliZWQgdG8gbnRkZXYgYXM6IGVkZHlAaGN2LnJvDQo+IFRvIHVuc3Vic2Ny
aWJlIHNlbmQgYSBibGFuayBlbWFpbCB0byBsZWF2ZS1udGRldi0xNDA3OUNAbGlzdHMub3NyLmNv
bQ0KPg0KPiAtLS0NCj4gSW5jb21pbmcgbWFpbCBpcyBjZXJ0aWZpZWQgVmlydXMgRnJlZS4NCj4g
Q2hlY2tlZCBieSBBVkcgYW50aS12aXJ1cyBzeXN0ZW0gKGh0dHA6Ly93d3cuZ3Jpc29mdC5jb20p
Lg0KPiBWZXJzaW9uOiA2LjAuNzgzIC8gVmlydXMgRGF0YWJhc2U6IDUyOSAtIFJlbGVhc2UgRGF0
ZTogMTAvMjUvMjAwNA0KPg0KPg0KPiAtLS0NCj4gT3V0Z29pbmcgbWFpbCBpcyBjZXJ0aWZpZWQg
VmlydXMgRnJlZS4NCj4gQ2hlY2tlZCBieSBBVkcgYW50aS12aXJ1cyBzeXN0ZW0gKGh0dHA6Ly93
d3cuZ3Jpc29mdC5jb20pLg0KPiBWZXJzaW9uOiA2LjAuNzgzIC8gVmlydXMgRGF0YWJhc2U6IDUy
OSAtIFJlbGVhc2UgRGF0ZTogMTAvMjUvMjAwNA0KPg0KPg0KPg0KPg0KPiAtLS0NCj4gUXVlc3Rp
b25zPyBGaXJzdCBjaGVjayB0aGUgS2VybmVsIERyaXZlciBGQVEgYXQgaHR0cDovL3d3dy4NCj4g
b3Nyb25saW5lLmNvbS9hcnRpY2xlLmNmbT9pZD0yNTYNCj4NCj4gWW91IGFyZSBjdXJyZW50bHkg
c3Vic2NyaWJlZCB0byBudGRldiBhczogdW5rbm93biBsbXN1YnN0IHRhZyBhcmd1bWVudDoNCicn
DQo+IFRvIHVuc3Vic2NyaWJlIHNlbmQgYSBibGFuayBlbWFpbCB0byBsZWF2ZS1udGRldi0xNDA3
OUNAbGlzdHMub3NyLmNvbQ0KDQo+IEZvcndhcmRTb3VyY2VJRDpOVDAwMDA2MDk2