diff mbox

[U-Boot] xyz-modem: Change getc timeout loop waiting

Message ID 1479716331-94776-1-git-send-email-tomas.melin@vaisala.com
State Accepted
Commit 2c77c0d6524ebc2e34ea7a4485120225d2b936e6
Delegated to: Tom Rini
Headers show

Commit Message

Tomas Melin Nov. 21, 2016, 8:18 a.m. UTC
This fixes the loop delay when using a hw watchdog.

In case a watchdog is used that accesses CPU registers,
the defined delay of 20us in a tight loop will cause a
huge delay in the actual timeout seen. This is caused
by the fact that udelay will inheritantly call WATCHDOG_RESET.
Together with the omap wdt implementation, the seen timeout increases up to
around 30s. This makes the loop very slow and causes long
delays when using the modem.

Instead, implement the 2 sec loop by using the timer interface to know
when to break out of the timeout loop. Watchdog kicking is taken care of
by getc().

Signed-off-by: Tomas Melin <tomas.melin@vaisala.com>
---
 common/xyzModem.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

Comments

Tom Rini Nov. 29, 2016, 1:07 a.m. UTC | #1
On Mon, Nov 21, 2016 at 10:18:51AM +0200, tomas.melin@vaisala.com wrote:

> This fixes the loop delay when using a hw watchdog.
> 
> In case a watchdog is used that accesses CPU registers,
> the defined delay of 20us in a tight loop will cause a
> huge delay in the actual timeout seen. This is caused
> by the fact that udelay will inheritantly call WATCHDOG_RESET.
> Together with the omap wdt implementation, the seen timeout increases up to
> around 30s. This makes the loop very slow and causes long
> delays when using the modem.
> 
> Instead, implement the 2 sec loop by using the timer interface to know
> when to break out of the timeout loop. Watchdog kicking is taken care of
> by getc().
> 
> Signed-off-by: Tomas Melin <tomas.melin@vaisala.com>

Applied to u-boot/master, thanks!
Alexander Sverdlin Aug. 1, 2018, 12:15 a.m. UTC | #2
Hello!

On Mon, 21 Nov 2016 10:18:51 +0200
Tomas Melin <tomas.melin@vaisala.com> wrote:

> This fixes the loop delay when using a hw watchdog.
> 
> In case a watchdog is used that accesses CPU registers,
> the defined delay of 20us in a tight loop will cause a
> huge delay in the actual timeout seen. This is caused
> by the fact that udelay will inheritantly call WATCHDOG_RESET.
> Together with the omap wdt implementation, the seen timeout increases up to
> around 30s. This makes the loop very slow and causes long
> delays when using the modem.
> 
> Instead, implement the 2 sec loop by using the timer interface to know
> when to break out of the timeout loop. Watchdog kicking is taken care of
> by getc().
> 
> Signed-off-by: Tomas Melin <tomas.melin@vaisala.com>

This commit breaks YMODEM SPL->U-Boot boot on Beagle Bone,
transfer is aborted (because of timeout) after 497kb
(u-boot.img is around 570kb).
Reverting the commit repairs YMODEM boot.

> ---
>  common/xyzModem.c | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
> 
> diff --git a/common/xyzModem.c b/common/xyzModem.c
> index 5656aac..e0d87db 100644
> --- a/common/xyzModem.c
> +++ b/common/xyzModem.c
> @@ -71,12 +71,12 @@ typedef int cyg_int32;
>  static int
>  CYGACC_COMM_IF_GETC_TIMEOUT (char chan, char *c)
>  {
> -#define DELAY 20
> -  unsigned long counter = 0;
> -  while (!tstc () && (counter < xyzModem_CHAR_TIMEOUT * 1000 / DELAY))
> +
> +  ulong now = get_timer(0);
> +  while (!tstc ())
>      {
> -      udelay (DELAY);
> -      counter++;
> +      if (get_timer(now) > xyzModem_CHAR_TIMEOUT)
> +        break;
>      }
>    if (tstc ())
>      {
Tomas Melin Aug. 1, 2018, 5:44 a.m. UTC | #3
Hi,

On 08/01/2018 03:15 AM, Alexander Sverdlin wrote:

> This commit breaks YMODEM SPL->U-Boot boot on Beagle Bone,
> transfer is aborted (because of timeout) after 497kb
> (u-boot.img is around 570kb).
> Reverting the commit repairs YMODEM boot.

Is the timeout a watchdog timeout or some communication freeze?
In case watchdog is correctly configured, kicking should still
happen.

Tomas

>> ---
>>   common/xyzModem.c | 10 +++++-----
>>   1 file changed, 5 insertions(+), 5 deletions(-)
>>
>> diff --git a/common/xyzModem.c b/common/xyzModem.c
>> index 5656aac..e0d87db 100644
>> --- a/common/xyzModem.c
>> +++ b/common/xyzModem.c
>> @@ -71,12 +71,12 @@ typedef int cyg_int32;
>>   static int
>>   CYGACC_COMM_IF_GETC_TIMEOUT (char chan, char *c)
>>   {
>> -#define DELAY 20
>> -  unsigned long counter = 0;
>> -  while (!tstc () && (counter < xyzModem_CHAR_TIMEOUT * 1000 / DELAY))
>> +
>> +  ulong now = get_timer(0);
>> +  while (!tstc ())
>>       {
>> -      udelay (DELAY);
>> -      counter++;
>> +      if (get_timer(now) > xyzModem_CHAR_TIMEOUT)
>> +        break;
>>       }
>>     if (tstc ())
>>       {
>
Alexander Sverdlin Aug. 1, 2018, 5:54 a.m. UTC | #4
Hi!

On Wed, 1 Aug 2018 08:44:13 +0300
Tomas Melin <tomas.melin@vaisala.com> wrote:

> > This commit breaks YMODEM SPL->U-Boot boot on Beagle Bone,
> > transfer is aborted (because of timeout) after 497kb
> > (u-boot.img is around 570kb).
> > Reverting the commit repairs YMODEM boot.
> 
> Is the timeout a watchdog timeout or some communication freeze?

I suppose, it reports false-positive timeout back to ymodem code.
Because all it does is terminating communication gracefully (with 'C'
and a bunch of CANs).
I need to check if timer overflow is possible on Beaglebone,
because the code is obviously not overflow-proof, but on the
other hand it happens within minutes and at least the timer variable
is 32 bit...

> In case watchdog is correctly configured, kicking should still
> happen.
Tomas Melin Aug. 1, 2018, 6:16 a.m. UTC | #5
Hi,

On 08/01/2018 08:54 AM, Alexander Sverdlin wrote:
>> Is the timeout a watchdog timeout or some communication freeze?
> I suppose, it reports false-positive timeout back to ymodem code.
> Because all it does is terminating communication gracefully (with 'C'
> and a bunch of CANs).
If you are using omap_wdt then check the configured value of the timeout 
(WDT_HW_TIMEOUT).
Time the y-modem loading, and if the reset happens just after that 
configured value, it would indicate that the watchdog is not kicked, for 
one reason or another.

Tomas
Alexander Sverdlin Aug. 2, 2018, 2:47 p.m. UTC | #6
Hello Tomas,

On Wed, 1 Aug 2018 09:16:38 +0300
Tomas Melin <tomas.melin@vaisala.com> wrote:

> >> Is the timeout a watchdog timeout or some communication freeze?
> > I suppose, it reports false-positive timeout back to ymodem code.
> > Because all it does is terminating communication gracefully (with 'C'
> > and a bunch of CANs).
> If you are using omap_wdt then check the configured value of the timeout 
> (WDT_HW_TIMEOUT).
> Time the y-modem loading, and if the reset happens just after that 
> configured value, it would indicate that the watchdog is not kicked, for 
> one reason or another.

Yes, I'm using omap_wdt with default 60 seconds timeout, but as I mentioned
already, it's not WDT kicking in, but your patch breaking YMODEM protocol
reporting false timeout back to YMODEM code.
diff mbox

Patch

diff --git a/common/xyzModem.c b/common/xyzModem.c
index 5656aac..e0d87db 100644
--- a/common/xyzModem.c
+++ b/common/xyzModem.c
@@ -71,12 +71,12 @@  typedef int cyg_int32;
 static int
 CYGACC_COMM_IF_GETC_TIMEOUT (char chan, char *c)
 {
-#define DELAY 20
-  unsigned long counter = 0;
-  while (!tstc () && (counter < xyzModem_CHAR_TIMEOUT * 1000 / DELAY))
+
+  ulong now = get_timer(0);
+  while (!tstc ())
     {
-      udelay (DELAY);
-      counter++;
+      if (get_timer(now) > xyzModem_CHAR_TIMEOUT)
+        break;
     }
   if (tstc ())
     {