Reply
Posts: 13
Registered: ‎05-05-2017
Accepted Solution

Code hang in loop C8051F996

 

I run example code SWITCHLED.C 

but It has a problem that it hangs at C startup I wanna know why?

 

 

hang in loop

0816 F6 MOV @R0,A
0817 D8 FD DJNZ R0,FDH

 


void main (void)
{
PCA0MD &= ~0x40; // WDTE = 0 (clear watchdog timer
// enable)


PORT_Init(); // Initialize Port I/O
OSCILLATOR_Init (); // Initialize Oscillator

while (1)
{


// Set the state of the red LED
if (SW2 == 0) // If switch pressed
{
RED_LED = LED_OFF; // Turn off Red LED
}
else
{
RED_LED = LED_ON; // Else, turn it on
}

// Set the state of the yellow LED
if (SW3 == 0) // If switch pressed
{
YELLOW_LED = LED_OFF; // Turn off Yellow LED
}
else
{
YELLOW_LED = LED_ON; // Else, turn it on
}
} // end of while(1)
}

Posts: 8,134
Registered: ‎08-13-2003

Re: Code hang in loop C8051F996

because you have not disabled the watchdog in startup.a51

erik
Posts: 13
Registered: ‎05-05-2017

Re: Code hang in loop C8051F996

I wrote PCA0MD &= ~0x40;  at main function at beginning.

 

How come WDT be forced on.    Sorry I was wondering.

Posts: 3,092
Registered: ‎02-07-2002

Re: Code hang in loop C8051F996

Well it doesn't reach main, because the watchdog bites before the small loop is over.

 

SiLabs has created this problem a decade ago in their first C8051F3xx and never bothered to fix it in all subsequent variants. IMHO the watchdog should be either OFF after reset or set to its longest instead of its shortest interval. If someone wanted it on ASAP he could still reconfigure it in startup.a51, but currently everyone has to.

 

And on some devices erasing a page of flash can even take longer than the longest watchdog interval which is a design flaw as well if you ask me. But you didn't, now did you?

Posts: 2,312
Registered: ‎10-14-2014

Re: Code hang in loop C8051F996

Posts: 8,134
Registered: ‎08-13-2003

Re: Code hang in loop C8051F996

[ Edited ]

SiLabs has created this problem a decade ago in their first C8051F3xx and never bothered to fix it in all subsequent variants. IMHO the watchdog should be either OFF after reset or set to its longest instead of its shortest interval. If someone wanted it on ASAP he could still reconfigure it in startup.a51, but currently everyone has to.

 

I guess some heavy-duty customer suckered SiLabs into "the watchdog has to be enabled always". I have, actually, worked in a case where it was so. I do agree, Maarten, that they should have said' "enable it in startup" and left the rest of us happy. What REALLY makes me wonder is WHY DOES THE STARTUP VERSIONS PROVIDED BY SILABS NOT INCLUDE WATCHDOG DISABLE.

erik
Posts: 3,092
Registered: ‎02-07-2002

Re: Code hang in loop C8051F996


erikm wrote:

What REALLY makes me wonder is WHY DOES THE STARTUP VERSIONS PROVIDED BY SILABS NOT INCLUDE WATCHDOG DISABLE.


Apparently they couldn't be bothered with that either.

 

And I fear it wasn't a customer who wanted this but a SiLabs engineer who thought to be smart.

Posts: 13
Registered: ‎05-05-2017

Re: Code hang in loop C8051F996

I still didn't get it.

Why WDT stuck in my code.   it is independent of MCU processor.

 

I check my asm code out.    It is a loop at (0813 to 0817).

 

 

0000 02 08 13   LJMP 0813H

0813 78 7F        MOV R0,#7FH
0815 E4             CLR A
0816 F6             MOV @R0,A
0817 D8 FD       DJNZ R0,FDH

Posts: 8,134
Registered: ‎08-13-2003

Re: Code hang in loop C8051F996

in the other current thread re this there is "back up Keil one release and it works".  two threads on same subject are running

erik
Posts: 3,092
Registered: ‎02-07-2002

Re: Code hang in loop C8051F996

What do you mean the WDT is independent of your MCU? It is integrated into it and it is armed at reset with the shortest possible interval. So what happens is that during the loop of clearing the first 128 bytes the watchdog bites and pulls the MCU through a reset and restarts the loop waiting for another watchdog event.

 

You should copy and modify startup.a51 and disable the watchdog before it starts this clearing loop. And while you're at it, make sure to extend this to clear all 256 bytes instead of just the first half.

Posts: 8,134
Registered: ‎08-13-2003

Re: Code hang in loop C8051F996

. And while you're at it, make sure to extend this to clear all 256 bytes

 

another thing that should be set in the SiLabs provided startups

erik
Posts: 2
Registered: ‎05-08-2017

Re: Code hang in loop C8051F996

Hi.

 

I not see all code. But i think you allocate some memory in the C code. How work standard C kernel:

1. Star "startup.a51"

2. Clear DATA, size=IDATALEN-1

3. Clear XDATA, size=XDATALEN

4. Clear PDATA, size=PDATALEN

5. Set stack for virtual XDATA

6. Set stack pointer for core SP=?STACK-1

7. Init banks for C-Kernel ?B_SWITCH1

8. JUMP to main ?C_START

9. AND only now execute your C-code

 

Problem Situation #1:

1. Allocate some memory

volatile char m[8000];
void main (void)
{
   int p=0;
    while (1)
    {
      m[p] ^= m[p+1];
      p=(p+1) % (sizeof(m)-2);
    }
}

2 When start "startup.a51" XDATALEN=8000(minimum)

3 For  memory clearance need many states of CPU

4 WDT is generate reset. You will be got a infinity loop

 

Problem Situation #2:

1 We see in the "startup.a51" this code

		CSEG AT 0
?C_STARTUP:	LJMP STARTUP1
STARTUP1: MOV R0,#IDATALEN - 1 CLR A IDATALOOP: MOV @R0,A DJNZ R0,IDATALOOP

2 In the C-code. In the some part of C-code we write this

        ORL PSW,#18H
        MOV RSTSRC,#10H

3 Previous example generate software reset. But reset not update PSW register

4 When execute after reset "startup.a51" you got stuck and infinity loop

Software reset not update PSW register. As result address of R0 = 18H. When counter R0 have value 18H then R0 is cleared. And DJNZ R0 start write to the 0FFH and do this and do and do ... This situation correct if reset PSW before clear DATA in the "startup.a51".

 

Resume:

1. Need disable WDT in "startup.a51"

2. Need clear PSW register before clear DATA memory

 

I hope help you understand what happened. Sorry for my English.

Highlighted
Posts: 466
Registered: ‎02-21-2014

Re: Code hang in loop C8051F996


erikm wrote:

SiLabs has created this problem a decade ago in their first C8051F3xx and never bothered to fix it in all subsequent variants. IMHO the watchdog should be either OFF after reset or set to its longest instead of its shortest interval. If someone wanted it on ASAP he could still reconfigure it in startup.a51, but currently everyone has to.

 

I guess some heavy-duty customer suckered SiLabs into "the watchdog has to be enabled always". I have, actually, worked in a case where it was so. I do agree, Maarten, that they should have said' "enable it in startup" and left the rest of us happy. What REALLY makes me wonder is WHY DOES THE STARTUP VERSIONS PROVIDED BY SILABS NOT INCLUDE WATCHDOG DISABLE.


You know, this damn watchdog of ours has bitten us in the ass so many times... I'm going to see if I can push to get us to update the startup file with it disabled.

Posts: 3,092
Registered: ‎02-07-2002

Re: Code hang in loop C8051F996

Better late than never.

 

But while you're at it, see if you can also convince the hardware engineers to change this in the hardware in upcoming 8051 derivatives.

Posts: 466
Registered: ‎02-21-2014

Re: Code hang in loop C8051F996

Well, since the F850, all new 8-bit designs have had a different watchdog (standalone, instead of built into one of the PCA channels) that has a 13-second default time-out (it's still enabled by default, though). Of course, randomly resetting after 13 seconds into your application, without knowing about the watchdog, can be equally confounding.

Posts: 3,092
Registered: ‎02-07-2002

Re: Code hang in loop C8051F996

I was pretty sure I had seen reports about this problem for EFM8 devices as well. But I did not investigate and I will take your word for it.

 

13 seconds should be long enough for every code to reach main where it is much easier to disable the watchdog than having to muck with assembly. The main() is in C and is part of the users program, not part of the C runtime library. It's much easier to patch your own code than to modify others.

Posts: 466
Registered: ‎02-21-2014

Re: Code hang in loop C8051F996

Yeah, some of the EFM8 devices do have the older PCA watchdog - SB1, SB2, UB2 - since they were based on older designs (F990, F930, F380...). The BB1/2/3, LB1, and UB1 don't have this problem, however (and neither will our future new 8-bit MCUs).

Posts: 8,134
Registered: ‎08-13-2003

Re: Code hang in loop C8051F996

. I'm going to see if I can push to get us to update the startup file with it disabled.

great! at the same time, get datalength updated to 256

erik
Posts: 466
Registered: ‎02-21-2014

Re: Code hang in loop C8051F996

IDATALEN, so that all of the 256 bytes of IDATA are cleared after startup?

 

EH - I'm not so sure. If we were starting from scratch, I would agree with you - why not zero out all of RAM after a reset? But that should also include XDATA as well, right, which we're also currently not touching.

 

So then, it already seems arbitrary. Why are we only zeroing out a small portion of the RAM? I guess if we did XDATA too, that could lead to a lot longer reset-to-main time. So, will we zero out all of RAM, or some of it, and where do we stop if we only partially erase some of RAM? Why is 128 bytes better or worse than 256 bytes?

 

And maybe some customers are relying on this not-zeroing-out addresses 0x80-0xFF behavior. If we go and change it for everyone by default, maybe someone's project will start breaking for some unapparent reason.

 

So I guess what I'm saying is that it's pretty arbitrary already, and 256 bytes would be equally arbitrary. But, we also have to worry about people that might already be relying on it being 128 bytes. AND, if they need it to be something else, they can always just change the defaults.

 

Of course, if you could make a good argument for it, I'm all ears.

Posts: 8,134
Registered: ‎08-13-2003

Re: Code hang in loop C8051F996

[ Edited ]

IDATALEN, so that all of the 256 bytes of IDATA are cleared after startup?

 

EH - I'm not so sure. If we were starting from scratch, I would agree with you - why not zero out all of RAM after a reset? But that should also include XDATA as well, right, which we're also currently not touching.

 

well ,the next loop in startup clears XDATA (XDATALEN correctly set)

 

Why is 128 bytes better or worse than 256 bytes?

the 128 is a leftover from the originals where '51 ment 128 and '52 ment 256

 

And maybe some customers are relying on this not-zeroing-out addresses 0x80-0xFF behavior. If we go and change it for everyone by default, maybe someone's project will start breaking for some unapparent reason.

for Keil users that has always meant "modify startup"

 

 

Of course, if you could make a good argument for it, I'm all ears.

try this

unsigned char blah = 0;

void main(void)

{

 

and you will see that 'blah' is not zeroed since the Keil initializer code relies on a memory clear.

erik
Posts: 3,092
Registered: ‎02-07-2002

Re: Code hang in loop C8051F996


erikm wrote:

Why is 128 bytes better or worse than 256 bytes?

the 128 is a leftover from the originals where '51 ment 128 and '52 ment 256 


Or for weird derivatives that made the SFR space indirectly addressable as well. I can assure you there are.

 


unsigned char blah = 0;

void main(void)

{


Well with the default small memory model blah will end up in DATA and thus is cleared even when only 128 bytes are cleared. But if you place blah in IDATA it might not be cleared! And it depends on if the linker placed it below or above 0x80. Happy debugging...

 

Btw blah doesn't even need the 0 initializer. Every uninitialized global must be cleared according to the C standard as well.

Posts: 8,134
Registered: ‎08-13-2003

Re: Code hang in loop C8051F996

Btw blah doesn't even need the 0 initializer.

right

Every uninitialized global must be cleared according to the C standard as well.

then the change of IDATALEN is mandatory

erik