Re: [fpc-pascal] Microsecond Delay Suggestions?
>Look at synaser, its TBlockSerial class has a RecvTerminated method that does just that. >http://synapse.ararat.cz/doc/help/synaser.TBlockSerial.html#RecvTerminated >https://sourceforge.net/p/synalist/code/HEAD/tree/trunk/ >Bye >-- >Luca Thank you for the suggestion and the links, that does look like it would take care of the issue for me. James ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Microsecond Delay Suggestions?
On 26/07/16 13:58, James Richters wrote: but I don’t want it to get stuck in an endless loop which could happen if: A: nothing is ever received B: garbage is being received due to bad connection or baudrate mismatch.. etc.. Look at synaser, its TBlockSerial class has a RecvTerminated method that does just that. http://synapse.ararat.cz/doc/help/synaser.TBlockSerial.html#RecvTerminated https://sourceforge.net/p/synalist/code/HEAD/tree/trunk/ Bye -- Luca ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Microsecond Delay Suggestions?
Thank You I found the sleep procedure Thank you for explaining that it was looking for a pointer, that was helpful. A little cutting and pasting and now I have 3 more ways to sleep... Sleep_S will probably be sufficient and is the most flexible, because if you have 1,000,000,000 seconds you don't need precision down to 100nS.. but you have it anyway, you could specify 10.001 seconds and it would work... it comes out to 10001 intervals... I'm not going to wait over 31 years to test it though :) Thanks for the help everyone, now I can adjust my delay from 36uS for baudrates of 25 all the way to 30mS for a baudrate of 300. I know sleep isn't exact, it's more of a minimum and then you need to also wait for the processor to get back to you, but I think it will be close enough without excessive delays. I posted it on github if anyone happens across this doing a search they can find it here: https://github.com/Zaaphod/FPC-Delay >You need to declare a LargeInteger and pass the pointer to it to NtDelayExecution(). LargeInteger itself is declared as a case-record >consisting of two 32-bit values (LowPart and HighPart) and a 64-bit value (QuadPart). Best is you assign your value to QuadPart, as > that sets the record in one go. >Oh and I forgot to mention that you need to use a negative value for relative sleeps (otherwise you'll wait until that time from the >system start on has passed, so "1" would be a no-op basically ;) ) >For an example see the implementation of Sleep in the SysUtils unit of the NativeNT target: rtl/nativent/sysutils.pp (near the end of the file) >Regards, >Sven ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Microsecond Delay Suggestions?
On 26.07.2016 21:52, James Richters wrote: >> An alternative would be NtDelayExecution from unit jwanative. Its interval > argument is in multiples of 100ns >> and is essentially what Windows' Sleep() uses internally. >> Note: The first argument "Alertable" determines whether the function can be > interrupted by NtAlertThread >> (and whatever Windows API functions use that internally). > > This sounds like it would work, but I can't figure out how to use it. Do > you have an example? > I've tried just a quick test like this: > > uses > windows,jwanative; > Var > DelayInterval : PLarge_Integer; > Variable1:integer; > begin > DelayInterval:=1; > Variable1:=NtDelayExecution(true,DelayInterval); > end. > > It won't let me set DelayInterval with a constant, I get "Incompatible > Types: got "shortint" expected "Plarge_Integer" > I really don't undertand these variable types that it wants. You need to declare a LargeInteger and pass the pointer to it to NtDelayExecution(). LargeInteger itself is declared as a case-record consisting of two 32-bit values (LowPart and HighPart) and a 64-bit value (QuadPart). Best is you assign your value to QuadPart, as that sets the record in one go. Oh and I forgot to mention that you need to use a negative value for relative sleeps (otherwise you'll wait until that time from the system start on has passed, so "1" would be a no-op basically ;) ) For an example see the implementation of Sleep in the SysUtils unit of the NativeNT target: rtl/nativent/sysutils.pp (near the end of the file) Regards, Sven ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Microsecond Delay Suggestions?
>An alternative would be NtDelayExecution from unit jwanative. Its interval argument is in multiples of 100ns >and is essentially what Windows' Sleep() uses internally. >Note: The first argument "Alertable" determines whether the function can be interrupted by NtAlertThread >(and whatever Windows API functions use that internally). This sounds like it would work, but I can't figure out how to use it. Do you have an example? I've tried just a quick test like this: uses windows,jwanative; Var DelayInterval : PLarge_Integer; Variable1:integer; begin DelayInterval:=1; Variable1:=NtDelayExecution(true,DelayInterval); end. It won't let me set DelayInterval with a constant, I get "Incompatible Types: got "shortint" expected "Plarge_Integer" I really don't undertand these variable types that it wants. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Microsecond Delay Suggestions?
On 26.07.2016 19:05, Dmitry Boyarintsev wrote: > On Tue, Jul 26, 2016 at 12:38 PM, James Richters > mailto:ja...@productionautomation.net>> > wrote: > > What I need is a timer that I can specify in microseconds, a > millisecond is too long. I am using it for timing to read in a > string on a serial connection. My fastest baudrate is 25, so at > that rate I would need to delay only 36 microseconds. So I can’t > use sleep () or delay () because they only go down to 1mS and that’s > too slow. > > > Here's an example of Sleep with microseconds that I came up with > > procedure SleepMcs(mcs: Int64); > var > ct : TLargeInteger; > fr : TLargeInteger; > af : TLargeInteger; > trg : TLargeInteger; > const > NanoInMicro = 1000; > begin > QueryPerformanceCounter(ct); > QueryPerformanceFrequency(fr); > trg:=round(mcs * NanoInMicro / (NSInSec/fr)); > repeat > QueryPerformanceCounter(af); > until trg<=(af-ct); > end; > > I'm hoping that there's a better solution out there, because this > procedure will end up with 100% CPU load. > I doubt it's possible to unload the CPU, since the windows scheduler is > in milliseconds accuracy. > May be a lower (kernel/driver) level allows that. An alternative would be NtDelayExecution from unit jwanative. Its interval argument is in multiples of 100ns and is essentially what Windows' Sleep() uses internally. Note: The first argument "Alertable" determines whether the function can be interrupted by NtAlertThread (and whatever Windows API functions use that internally). Regards, Sven ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Microsecond Delay Suggestions?
On Tue, Jul 26, 2016 at 1:58 PM, James Richters < ja...@productionautomation.net> wrote: > I think there may be a solution with this performance counter for my > purposes… here’s what I’m trying to accomplish: > Well, Windows provides a different means of waiting (and waiting with time out) for the Serial port communication. The whole topic is discussed here: https://msdn.microsoft.com/en-us/library/ff802693.aspx#serial_topic1 I'm thinking that using performance counter is a little of over-engineering thanks, Dmitry ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Microsecond Delay Suggestions?
I think there may be a solution with this performance counter for my purposes… here’s what I’m trying to accomplish: I’m trying to read a string from a serial port until I get a linefeed, but I don’t want it to get stuck in an endless loop which could happen if: A: nothing is ever received B: garbage is being received due to bad connection or baudrate mismatch.. etc.. So I keep reading the port in a loop until A: I try 10 times and still get nothing B: I get the data I’m looking for ending with a #10 C: I get too much data, then I stop after 254 bytes, the response should never be that long, so I’ll flag that as garbage. D: I try 1000 times and still do not have a #10 but I also do not have 254+ bytes For fast baud rates, this works fine, but for slow baudrates, I reach 1000 tries way before the string is finished, so I planned on putting in a delay calculated from the baudrate… however I think I can take a different approach here. I don’t really care the exact amount of time between retries, I just want to try for a long enough length of total time before giving up, so I don’t get stuck in a loop. Perhaps I can read QueryPerformanceCounter(ct); during the loop and if it exceeds the set amount of time, then use that to end the loop and give up. Here’s my function as it is.. fyi, my entire project is in turbo pascal compatibility mode: Function ReadSerial(SerPortNum:Byte):String; Var Loopcount:Word; CharCount:Byte; InputString:String; InputLetter:Char; Begin LoopCount:=0; CharCount:=0; InputString:=''; repeat Status:= SerRead(SerialHandle[SerPortNum], Inputletter, 1); if (status > 0) {and ((InputLetter<>#10) AND (InputLetter<>#13))} then begin Inc(CharCount); case InputLetter of ' ':InputString:=InputString+'.'; #10:InputString:=InputString+'#10'; #13:InputString:=InputString+'#13'; else InputString:=InputString+(InputLetter); end; end; Inc(Loopcount); {need delay here for slow baud rates} Until (InputLetter=#10) OR ((Loopcount>10) AND (InputString='')) OR (CharCount>254) OR (Loopcount>1000); ReadSerial:=InputString; end; From: fpc-pascal-boun...@lists.freepascal.org [mailto:fpc-pascal-boun...@lists.freepascal.org] On Behalf Of Dmitry Boyarintsev Sent: Tuesday, July 26, 2016 1:05 PM To: FPC-Pascal users discussions Subject: Re: [fpc-pascal] Microsecond Delay Suggestions? On Tue, Jul 26, 2016 at 12:38 PM, James Richters mailto:ja...@productionautomation.net> > wrote: What I need is a timer that I can specify in microseconds, a millisecond is too long. I am using it for timing to read in a string on a serial connection. My fastest baudrate is 25, so at that rate I would need to delay only 36 microseconds. So I can’t use sleep () or delay () because they only go down to 1mS and that’s too slow. Here's an example of Sleep with microseconds that I came up with procedure SleepMcs(mcs: Int64); var ct : TLargeInteger; fr : TLargeInteger; af : TLargeInteger; trg : TLargeInteger; const NanoInMicro = 1000; begin QueryPerformanceCounter(ct); QueryPerformanceFrequency(fr); trg:=round(mcs * NanoInMicro / (NSInSec/fr)); repeat QueryPerformanceCounter(af); until trg<=(af-ct); end; I'm hoping that there's a better solution out there, because this procedure will end up with 100% CPU load. I doubt it's possible to unload the CPU, since the windows scheduler is in milliseconds accuracy. May be a lower (kernel/driver) level allows that. thanks, Dmitry ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Microsecond Delay Suggestions?
On Tue, Jul 26, 2016 at 12:38 PM, James Richters < ja...@productionautomation.net> wrote: > What I need is a timer that I can specify in microseconds, a millisecond > is too long. I am using it for timing to read in a string on a serial > connection. My fastest baudrate is 25, so at that rate I would need to > delay only 36 microseconds. So I can’t use sleep () or delay () because > they only go down to 1mS and that’s too slow. > Here's an example of Sleep with microseconds that I came up with procedure SleepMcs(mcs: Int64); var ct : TLargeInteger; fr : TLargeInteger; af : TLargeInteger; trg : TLargeInteger; const NanoInMicro = 1000; begin QueryPerformanceCounter(ct); QueryPerformanceFrequency(fr); trg:=round(mcs * NanoInMicro / (NSInSec/fr)); repeat QueryPerformanceCounter(af); until trg<=(af-ct); end; I'm hoping that there's a better solution out there, because this procedure will end up with 100% CPU load. I doubt it's possible to unload the CPU, since the windows scheduler is in milliseconds accuracy. May be a lower (kernel/driver) level allows that. thanks, Dmitry ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Microsecond Delay Suggestions?
That looks great. I’ll give it a try! Thank you very much for the suggestion and the example From: fpc-pascal-boun...@lists.freepascal.org [mailto:fpc-pascal-boun...@lists.freepascal.org] On Behalf Of Dmitry Boyarintsev Sent: Tuesday, July 26, 2016 11:45 AM To: FPC-Pascal users discussions Subject: Re: [fpc-pascal] Microsecond Delay Suggestions? On Tue, Jul 26, 2016 at 11:21 AM, Dmitry Boyarintsev mailto:skalogryz.li...@gmail.com> > wrote: Maybe you want to look into QueryPerformanceCounter. https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx <https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904%28v=vs.85%29.aspx> Here's an example: {$mode objfpc}{$H+} uses Windows; const MSInSec = 1000; MCInSec = MSInSec * 1000; NSInSec = MCInSec * 1000; function LargeLoop: Integer; var i : integer; begin Result:=0; for i:=0 to 1000 do inc(Result); //or you can verify Sleep(milliseconds) //Sleep(100); end; var fr : TLargeInteger; ct : TLargeInteger; af : TLargeInteger; d : double; diff : TLargeInteger; begin QueryPerformanceFrequency(fr); writeln('Frequency: ' ,fr); d:=(1/fr) * NSInSec; writeln('Freq in Time: ', d:0:0, ' ns (roughly)'); QueryPerformanceCounter(ct); LargeLoop; QueryPerformanceCounter(af); diff := af - ct; writeln('Loop:'); writeln(' Ticks: ', diff); writeln(' Time: ', ((diff/fr) * NSInSec):0:0,' ns' ); writeln(' ', ((diff/fr) * MCInSec):0:6,' mcs' ); writeln(' ', ((diff/fr) * MSInSec):0:6,' ms' ); end. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Microsecond Delay Suggestions?
I don’t need a 55mS tick, there was a DOS timer that ticked every 55mS, which I used to calibrate a delayloop.. however I can’t use any of that on windows, I can’t even make the DOS function call, and even if I had a way to calibrate my delay loop, it would be meaningless because I have to share the processor with windows, so creating a delay by just looping a lot doesn’t work at all in windows… depending on what else is running I would get totally different time delays out of the loop. What I need is a timer that I can specify in microseconds, a millisecond is too long. I am using it for timing to read in a string on a serial connection. My fastest baudrate is 25, so at that rate I would need to delay only 36 microseconds. So I can’t use sleep () or delay () because they only go down to 1mS and that’s too slow. From: fpc-pascal-boun...@lists.freepascal.org [mailto:fpc-pascal-boun...@lists.freepascal.org] On Behalf Of Dmitry Boyarintsev Sent: Tuesday, July 26, 2016 11:19 AM To: FPC-Pascal users discussions Subject: Re: [fpc-pascal] Microsecond Delay Suggestions? On Tue, Jul 26, 2016 at 11:16 AM, James Richters mailto:ja...@productionautomation.net> > wrote: Any suggestions on how to do this on windows with a console application? I don't have an answer, but I'm wondering what kind of task is that? Why do you need this 55mS tick? thanks, Dmitry ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Microsecond Delay Suggestions?
On Tue, Jul 26, 2016 at 11:21 AM, Dmitry Boyarintsev < skalogryz.li...@gmail.com> wrote: > Maybe you want to look into QueryPerformanceCounter. > > https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx > > Here's an example: {$mode objfpc}{$H+} uses Windows; const MSInSec = 1000; MCInSec = MSInSec * 1000; NSInSec = MCInSec * 1000; function LargeLoop: Integer; var i : integer; begin Result:=0; for i:=0 to 1000 do inc(Result); //or you can verify Sleep(milliseconds) //Sleep(100); end; var fr : TLargeInteger; ct : TLargeInteger; af : TLargeInteger; d : double; diff : TLargeInteger; begin QueryPerformanceFrequency(fr); writeln('Frequency: ' ,fr); d:=(1/fr) * NSInSec; writeln('Freq in Time: ', d:0:0, ' ns (roughly)'); QueryPerformanceCounter(ct); LargeLoop; QueryPerformanceCounter(af); diff := af - ct; writeln('Loop:'); writeln(' Ticks: ', diff); writeln(' Time: ', ((diff/fr) * NSInSec):0:0,' ns' ); writeln(' ', ((diff/fr) * MCInSec):0:6,' mcs' ); writeln(' ', ((diff/fr) * MSInSec):0:6,' ms' ); end. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Microsecond Delay Suggestions?
On Tue, Jul 26, 2016 at 11:19 AM, Dmitry Boyarintsev < skalogryz.li...@gmail.com> wrote: > On Tue, Jul 26, 2016 at 11:16 AM, James Richters < > ja...@productionautomation.net> wrote: > >> Any suggestions on how to do this on windows with a console application? >> > > I don't have an answer, but I'm wondering what kind of task is that? > Why do you need this 55mS tick? > Maybe you want to look into QueryPerformanceCounter. https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx thanks, Dmitry ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Microsecond Delay Suggestions?
On Tue, Jul 26, 2016 at 11:16 AM, James Richters < ja...@productionautomation.net> wrote: > Any suggestions on how to do this on windows with a console application? > I don't have an answer, but I'm wondering what kind of task is that? Why do you need this 55mS tick? thanks, Dmitry ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal