View previous topic :: View next topic |
Author |
Message |
Guest Guest
|
goto_address and label_address problems! |
Posted: Wed Dec 28, 2005 6:23 pm |
|
|
I'm having problems when using the goto_address and label_address functions. They seem to work perfectly when used within the same function as the label is located, but as soon as I move the label outside the function that calls the goto_address(label_address(....)) bit of my code, the compiler complains with error 88: Undefined label that was used in a GOTO > start2
My code looks like this:
start2:
function1(void)
{
.....
.....
}
function2(void)
{
....
goto_address(label_address(start2));
....
}
Thanks for any help on why this appears/how to fix it! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Dec 28, 2005 6:27 pm |
|
|
You can't put a label outside of a function.
Tell us what your overall purpose is. |
|
|
Guest Guest
|
|
Posted: Wed Dec 28, 2005 6:39 pm |
|
|
PCM programmer wrote: | You can't put a label outside of a function.
Tell us what your overall purpose is. |
OK it still gives me the same error whether I put the label inside or outside the function.
The purpose of this is to give a 'software reset' functionality to my program when it receives the character '#' via the RS232 using the hardware USART and interrupt. i.e. it will jump to my initialisation routine. I dont want to use the reset_cpu() function as I need to bypass the initial welcome screen display on the LCD and the likes.
Thanks for your help. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Dec 28, 2005 6:48 pm |
|
|
Normally this would be done from main(). You would have a while(1)
loop in main() that periodically checks an interrupt-driven RS-232 receive
buffer to see if there is a char available. If there is a char available,
then fetch it, and check it to see if it's your "reset" command char.
If so, then call your init function. |
|
|
Guest Guest
|
|
Posted: Wed Dec 28, 2005 8:15 pm |
|
|
PCM programmer wrote: | Normally this would be done from main(). You would have a while(1)
loop in main() that periodically checks an interrupt-driven RS-232 receive
buffer to see if there is a char available. If there is a char available,
then fetch it, and check it to see if it's your "reset" command char.
If so, then call your init function. |
Thats what its doing now (in one form or another) but I would also like it to be able to be reset to my initialisation routines if the '#' char is received ANYWHERE in the program flow. i.e. in functions other than main. I don't want to keep having to poll to see if this char has been received everywhere in the program - Ideally I would like my RS232 ISR to detect this and goto the initialisation straight away. I don't care about registers getting destroyed as it is as I said essentially a full reset and initialisation but without the intro screen on the LCD.
The CCS documentation for the function goto_address() states: "Jumps outside of the current function should be done only with great caution." So presumably this means I CAN jump to a point outside the current function, but the compiler seems to think otherwise.
Thanks. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Dec 28, 2005 8:24 pm |
|
|
You shouldn't have to check for the incoming character at several
places in the program. There should be just one central routine
that checks incoming characters and calls the appropriate function
based on the received command. If you want to do something
else, maybe someone else can respond. |
|
|
Guest Guest
|
|
Posted: Wed Dec 28, 2005 8:37 pm |
|
|
OK thanks for your help PCM Programmer. Perhaps I didn't explain myself quite right.
Anyways, I had a closer look at the documentation and found in the explanation for label_address() it says:
"Parameters: label is a C label anywhere in the function"
So aparantly it cannot handle labels outside the function, but the goto_address() function can. I find that a bit odd to have 2 functions that complement each other not working as you would expect.
I think I will just make a workaround and fix the initilisation routine in ROM at a known address and use the goto_address() function to goto that known ROM address.
Thanks. |
|
|
Ttelmah Guest
|
|
Posted: Thu Dec 29, 2005 5:25 am |
|
|
In the 'long term', what your are trying to do, would cause problems. There is nothing to tidy up the stack. When you are inside 'function2', the return address on the stack, is the point at which this function was called. If you jump into 'function1', then when it finishes, it will return you to the function2 return address...
This is why jumps 'trans function', are potentially lethal traps.
You can 'cross jump', by coding like this:
Code: |
int32 location;
function1(void)
{
start2:
location=label_address(start2);
.......
}
function2(void)
{
goto_address(location);
}
|
However you are going to have to start considering how to tidy up the stack, and make 'function1', return to where you want. It is really easier (and a lot safer), to use the normal C program structure...
Best Wishes |
|
|
Guest Guest
|
|
Posted: Thu Dec 29, 2005 6:50 am |
|
|
Thanks Ttelmah. You have solved my problem!
I never thought about declaring the address as a global variable. Very annoying because its such a simple fix. I would buy you a beer if I could!
I don't believe I will have any stack issues in my case, because where I will be jumping to is inside main() (where I will then call my initialisation function) and becuase main() never returns then it shouldn't be a problem. The values on the stack before will just stay there and possibly drop off the end when the stack fills up (if my knowledge is correct).
Thanks again! |
|
|
Ttelmah Guest
|
|
Posted: Thu Dec 29, 2005 7:36 am |
|
|
OK. A target inside main, should be alright in this regard.
You should make sure you disable the stack full 'reset' option on your chip (if it has this), otherwise you may get a problem (NOSTVREN in the fuses).
Happy New Year to everybody
Best Wishes |
|
|
|