|
|
View previous topic :: View next topic |
Author |
Message |
ZextroM
Joined: 10 Apr 2012 Posts: 10
|
How can I return to the main position from interrupt? |
Posted: Fri Nov 23, 2012 9:42 am |
|
|
How can I return to the main position without using either reset instruction or goto statement ?
I'm looking forward to hearing this question's answer to make up a newly kind of a go-back algorithm to the main place in order to check and re-execute all conditions (some kind of task execution in rtos) to scan main cycle consecutively.
I'm waiting for your entire responses impatiently to see the results of your solutions.
Best regards, ZextroM |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Fri Nov 23, 2012 12:03 pm |
|
|
I'm not certain I understand what you want.
You mention interrupt in your title, but not in the main text.
Show us in some sort of pseudo code of what you really want.
Or, better still what you've tried.
Mike |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Fri Nov 23, 2012 2:01 pm |
|
|
I think they want what we have seen requested earlier a number of times,
the program receives an interrupt then, after the interrupt, it starts from the
beginning rather than where it left off. Then they throw the no reset and no
goto caveat in. Sounds to me like a school project where they don't fully
understand how to structure a program. Most of his problem can be solved
using flag(s) and a background loop in main _________________ Google and Forum Search are some of your best tools!!!! |
|
|
ZextroM
Joined: 10 Apr 2012 Posts: 10
|
|
Posted: Fri Nov 23, 2012 2:25 pm |
|
|
In my main file, lots of function and its sub-functions. When the suitable interrupt routine occurs, the system checks conditions then brunch the endless loop to maintain in the endless loop. In order to expel my working from the endless loop, I use break command, but I do want to go back to the top of the main (not go back to where the int happened in the program counter) without reset instruction ... (like using the program counter's main address to go back its address) (here I don't know how to call the pc's counter type in ccs).
Something like below:
Code: |
#int_ext1
{
.....
....
....
while(true)
{
....
....
...
break; (from this point to --->)
}
}
main()
{
( >----- to this point)
while(true)
{
function1
function2
function3
function4
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Nov 23, 2012 2:48 pm |
|
|
Why don't you like the reset_cpu() function ? |
|
|
ZextroM
Joined: 10 Apr 2012 Posts: 10
|
|
Posted: Fri Nov 23, 2012 2:56 pm |
|
|
This shown interrupt routine keeps one output as a 'high'. If I reset the mcu it is gonna be low, and all general working (I/O) affects another real-time (soft-plc system) system's working. When I reset my mcu, all I/O's position shows so weird movement in the real-time. That's why I need to keep the control of system in my hand always. That's why I don't want to reset my mcu rather than go back to below of main to check entire software from overall. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19516
|
|
Posted: Fri Nov 23, 2012 3:41 pm |
|
|
At the end of the day, this is down to hardware design. Add a pull up resistor to the line that must be 'high', so when it floats, it goes high.... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
ZextroM
Joined: 10 Apr 2012 Posts: 10
|
|
Posted: Fri Nov 23, 2012 4:21 pm |
|
|
Thanks PCM Programmer for your links, but i wrote above, not with goto statement ... because, in the help manual is written as:
Statement: goto label;
The goto statement cause an unconditional branch to the label
I cannot take this risk for my 2500 rows codes ...
I want to get my mcu worked as plc system or rtos system as called as parallel working ... each time i should return the main and scan entire my codes and when interrupts invokes which should interrupt the program.
In my case, I basically need to check program counter and where the main process begin to return its address by using pointer ... but i don't know how to read or control the program counter in ccs c 4.134 ...
Another question, how mcus of plc scan the main routine even in 10 ms ? If we have a minor problem to be able to go back to main ? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19516
|
|
Posted: Sat Nov 24, 2012 2:29 am |
|
|
You do understand, that if you jump 'out' of an interrupt routine, you will leave the stack unbalanced, unless you pop the stack. This will eventually cause the chip to do a reset.
Also though, you may well get a glitch to the signal you are worried about, if you do this, since the peripherals will all be re-initialised.
This is why using a flag is the 'right' way to do this, if your code is properly written.
10mSec is an absolute 'age'. Depends on the speed of your PIC, but one of the modern PIC18's, will execute over 100000 instructions in this time. Now, if your individual states are designed to be quick - no waiting for things - if you want data, and it is not available, you immediately exit. The same for things like doing timings they are all based on using timers, rather than delays, and if the timer has not triggered you again exit the state. Then the master state machine loop, tests for the flag from the interrupt, and if this is triggered force the state to where you want to start. 'example type code':
Code: |
enum {START, PULSEON, PULSEOFF, WAITSERIAL} states=START;
//Initialisation etc.
do {
switch (states) {
case START:
//Initialise system here
states++; //next operation
break;
case PULSEON:
set_timer1(SOMETIME);
clear_interrupt(INT_TIMER1);
output_high(PULSE_PIN);
state++;
break;
case PULSEOFF:
if (interrupt_active(INT_TIMER1)) {
//Timer has triggered to turn off the pulse
output_low(PULSE_PIN);
state++;
}
break; //note returns immediately if the timer has not triggered
//retries in a few _uSec_
case WAITSERIAL:
if (bkbhit()) {
//Here handle the serial that has been received by the interrupt
}
state=PULSEON;
break;
}
if (flag_from interrupt) state=START;
} while (TRUE);
}
|
Now the code here sits looping in the do...while. Where I want to do something for a 'time', (PULSEON/PULSEOFF), I don't sit in the state, but continuously exit the state till the hardware timer triggers. This way the code is spending all it's 'spare' time out in the loop, where the test for 'flag_from_interrupt' is tested.
Similarly serial is not handled in the individual states, but by using an interrupt triggered (EX_SISR) type receive, and at some point in the states the buffer is tested (bkbhit), and if data has been received, this is processed. The processing of this can be done using another state machine. The key point is that each sub state is very fast - taking no more than a handful of uSec, and getting back to the outer loop, which can then react to the flag from the interrupt, and take the code 'back' to START. I have a state machine like this handling PWM control of opto-encoded servos, and at the same time reading four ADC's, two buttons, and a serial connection (again use the hardware - trigger the ADC, and read it a few states _later_, rather than waiting for the conversion), and executes the outside loop at around 10000*/second. Not 10mSec, but 0.1mSec. It is all down to design.
Best Wishes |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Sat Nov 24, 2012 2:48 am |
|
|
You have two things to consider:-
1) PC, the program counter.
2) The stack.
With the way you're looking at things one or the other is going to get screwed up.
The approach you're suggesting should not be necessary.
So, let's start again.
Tell us:-
a) How much time must each of your functions take.
b) How often each function must execute.
c) How often the interrupt occurs.
Mike
EDIT Ttelmah's done it for you, whilst I was at the keyboard |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Sat Nov 24, 2012 3:21 am |
|
|
The suggested methods to implement the intended behaviour ("return to the main position") by regular
C language constructs are preferable also in my opinion. Nevertheless it's possible to realize a kind of
soft reset that skips the hardware initialization involved with reset_cpu() and possibly other actions,
e.g. initialize only a selected part of the variables.
A soft_reset needs to manipulate the stack, as already mentioned. It can be done by a few inline
assembly instructions, but requires a certain understanding of low-level PIC programming. Your posts,
e.g. what you said related to goto statement, gives the impression that you should better refer to regular C. |
|
|
ZextroM
Joined: 10 Apr 2012 Posts: 10
|
|
Posted: Sun Nov 25, 2012 2:59 pm |
|
|
Thanks guys for your all replies ...
To Mike Walne:
One of my overall function takes 45 seconds that includes 15 sub-functions and 6 infinite loops (they are broken to assign value from another functions) as well. Also I let the ext (h to L) interrupt occur in this function brunch. However i also want to turn the main cases to begin + scan the entire programme from this one big 45 seconds function. If I choose to restart my cpu in this function, my output affects one real-time-working system to creates so weird condition. That's why I need to soft-reset (so-called) to scan my working after returning from the interrupt.
I also measure adc values within sequently 500us and evaluate their differences within 2ms in this big (45 secs function) function as well.
I've no chance to do as you all mentioned above to figure out one flag position, because I don't know where & when my interrupt occurs to terminate my big function. If I proceed normal interrupt routine, it turns where it stopped by popping out stack. It means my related registers are triggered again and my function again work though I'll ever never prefer !!!
Ttelmah, mentions if you do want to change any situation when the stacks read and re-back, it automatically generates the glitch in my cpu and again force to restart (as far as i understand).
At the end, it is not simple to solve this type of strength in the mcu's world. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19516
|
|
Posted: Sun Nov 25, 2012 3:37 pm |
|
|
Seriously, 'one big 45 second function', just sounds like bad design.
If (for example), the ADC part is done as a state machine, you trigger the ADC, and keep looping in the outer loop, till ADIF says the value is ready. Then read the value, select the next channel, and again loop in the outer function till Tacq has completed. Then trigger the ADC, etc. etc.
There is no reason in any program to stay inside a function like this.
It is just a matter of changing how you think.
You speak about your 2500 lines, as if this is large.
The current project I'm on runs to 60000 lines. It's handling USB, an SD card five ADC channels, an RS485 serial port, an I2C link, keyboard, LCD, a DAC, a dozen solenoids, two PWM outputs, signal routing etc., yet no part of it is ever left 'unserviced' for more than 10mSec. You can push a key at any point, send a USB command, and all are responded to, including things like an emergency stop command from the I2C, which is responded to by flags exactly as being described.
Best Wishes |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Sun Nov 25, 2012 3:52 pm |
|
|
You talk about dangerous...messing with the processor stack directly is
about the most dangerous thing I can imagine!
I have done some of that in some real time embedded control C++ stuff on
a QNX PC104 stack but I avoid it like the plague when possible.
All that being said, as Ttelmah said one huge function is not good design.
It's better to call a series of functions to service a particular area, a "state
machine" if you will.
I currently maintain a PC104 program with 390,000+ lines of code. It uses a
state machine dispatcher for real time processing of a sort control
system handling three items per second. Using semaphores(flags) the
entire program completes all of the servicing loops (there are 9)
approximately 20 times per second running at 133MHZ with quite a bit of
time left over. _________________ Google and Forum Search are some of your best tools!!!! |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|