Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

How to reset stack

Status
Not open for further replies.

jhanus

New Member
Hello,

How to clear call Stack and write to it?
For example after interrupt execution it goes where I want it to go(beginning of the main loop), address where interrupt should return is deleted and all other on stack are cleared but a new one, user defined is put on stack, so when interrupt is done, it goes where I want it to go. As when PIC would start from "clean state" after reset or if he was just turned on.

I also could redirect with GOTO, ie 0x0040(start of main loop), but problem remains - the stack, there would be addresses which are not valid any more, of course if everything would be ok, this would be "the new" starting point, stack has depth of 31, but this device will remain active for who knows how long and there can't be this kind of errors.

I need to do this, because I have 6 different I2C devices, I don't have proper equipment to debug, neither do I have any more will to torture myself. If he hangs in some infinite loop this will bring him back on track, in combination with manual I2C release/reset.
Just for information, this "lock up" happens once, always random in between 45min - 3h.
Watchdog is not an option, because just to build main menu on 240x128 GLCD he needs 5s...

Using: 18F4550, C18


Thanks
 
Hi,

You can use the RESET instruction at any point in your code to force a software device reset.

As to changing the stack values, if it was possible, then everytime you did any program mods you would probably have to compute new stack values ..

With all due respect, have to say it sounds like you have lost control of your program flow, perhaps if you step back and spend some time working the logic steps out on a flow chart you will better see how to organise things that avoid your current problems.
 
Hi,

You can use the RESET instruction at any point in your code to force a software device reset.

As to changing the stack values, if it was possible, then everytime you did any program mods you would probably have to compute new stack values ..

With all due respect, have to say it sounds like you have lost control of your program flow, perhaps if you step back and spend some time working the logic steps out on a flow chart you will better see how to organise things that avoid your current problems.


Hello,
executing RESET would put me in the same place as using Watchdog, doing a complete initialization of every device connected, it would take +5s, which is not acceptable.

And yes, any program mode, new value, but since all the program is "under" main loop, it ain't a big problem.

:) I didn't lost control of my program flow, although it could definitely be more efficient, but that is another story. I detected a problem in I2C communication(probably ISR interference), and since I'm just helping on a project, I simply don't have time, nor will to do exhaustive debugging without proper equipment, so to avoid long initialization, stack forcing looks like a relatively good idea(if it's possible, since it's hw stack)
 
You can't just change the stack pointer like that without opening an already opened can of worms, you're obviously having a stack overflow, you need to determine where it's coming from. If this is a school project perhaps I could see overlooking it and just hacking the stack to get it to work, but this is BAD practice for even a nearly due school project.
 
Looking at the Data Sheet, it sounds like you want to adjust the STKPTR register, yes, no?

Yes, thanks, right now I'm observing how to operate with stack pointer, TOSU:TOSH:TOSL and top of stack access.


You can't just change the stack pointer like that without opening an already opened can of worms, you're obviously having a stack overflow, you need to determine where it's coming from. If this is a school project perhaps I could see overlooking it and just hacking the stack to get it to work, but this is BAD practice for even a nearly due school project.

My problem is not stack overflow, I detected a problem inside I2C library, it stays inside in infinitive loop. I managed to recreate the error when I want to, problem is, since it's on a breadboard, external interference. So I have to somehow jump out of the loop and continue with the program, since the program 99% of the time only reads data, this is for first patch ok.

I'm going to approach the problem in 3 phases:
1. software controlled WDT - last line of defense: implemented today(solves(better bypasses) the problem)
2. stack control: returning to beginning of the main loop: will implement today or tomorrow
3. changing functions of I2C library, so when a device misses the ACK,and takes the control of line(infinite loop), manual I2C line restart and continuing at the same point where the problem occurred: this will be problematic, since I can't just issue a restart, start or stop where I like
 
As the I²C is in hardware on that chip it suggests that the problem is in the software. Can you post a code snippet that demonstrates this problem?

Mike.
 
It would help others if you post what you eventually found and how you fixed it. We share, you share, ne'st ce pas?
Take care.

Hey,I got to phase two, my friend was satisfied, I'm satisfied. :]

First, C18 assembler is terrible, in my experience, use it only if you have to. I was confused for 10min, with it 'weird' parameters request while using inlining in C18, disassembly listing helped to solve that.

What this program does is relative simple, as always reading datasheet more carefully, I could have avoided torturing others... So since only TOS(top of the stack) is writable and readable, which again is defined and accessed trough STKPTR(stack pointer), we select with STKPTR level of STACK and write trough three registers(TOSU:TOSH:TOSL) new return address. For example we could set all three registers to zero, which would lead to reset vector(not same as RESET). Also upper(), high() and low(), which work in assembler, don't work in C18 assembler, so we can get lower 12bits, but rest of address is problematic, I didn't go inside of this to much and simply used fixed manual address which I got trough disassambly listing, which works well for me, since I don't change the program above my target adress.

Maybe this is not the best way to solve my problem if any, but it could be used for tight loops and branching.

Code:
		_asm
		    clrf    STKPTR, ACCESS                      // Clear the hardware stack
		   	movlw   0x1F                        		// 31 of H/W stack entries
		clrHWStack:
		   	incf    STKPTR, 1, ACCESS                   //fill all H/W stack with 0x0000
		   	clrf    TOSU, ACCESS                        // I am using >64KB programm memmory
		   	clrf    TOSH, ACCESS
		   	clrf    TOSL, ACCESS
		   	cpfseq  STKPTR, ACCESS                      // Compare with WREG, Skip =
		   	bra    	clrHWStack
		   
		   	clrf    STKPTR, ACCESS                      // reset STKPTR
	
		   	incf    STKPTR, 1, ACCESS					// increment STKPTR to 1, so it can return to my destination 
														//  and after reading TOSU, TOSH and TOSL on STACK level "1"
														//  auto decrement STKPTR to 0, as a RESTART would have been isued
	
														// i pazi svaka promjena koda iznad doticne adrese, mjenja nju samu
		   	clrf    TOSU, ACCESS						// * wanted destination, LED speed two
		   	movlw   0x01								// *
		   	movwf   TOSH, ACCESS						// *
		   	movlw   0x18								// *
			movwf 	TOSL, ACCESS						// *
		_endasm
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top