|
|
View previous topic :: View next topic |
Author |
Message |
spilz
Joined: 30 Jan 2012 Posts: 220
|
How to stop/kill (not pause) an action with interruption ? |
Posted: Wed Jan 21, 2015 3:36 am |
|
|
hello,
I'm trying to do something that I know it's not good, but I need your help/experience to do it better.
I wrote a code which receive data through RS232 interruption.
I have something like this :
Code: |
char c;
int new_c = 0;
#INT_RDA
void RDA_isr(void){
c = getc();
new_c = 1;
}
functionA(void){
// stuff than can take 30s or 1min
...
}
functionB(void){
// stuff than can take 30s or 1min
...
}
functionC(void){
// stuff than can take 30s or 1min
...
}
void main(){
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
while(true){
if(new_c == 1){
new_c = 0;
switch(c){
case 'A' : functionA();
break;
case 'B' : functionB();
break;
case 'C' : functionC();
break;
default : break;
}
}
}
} |
So I would like to kill functionA/B/C when a new char is received without always checking "new_c" at each step in functionA/B/C.
is there a way do to it ?
thanks for your help
Spilz |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Wed Jan 21, 2015 7:22 am |
|
|
The processor does not multitask, and there is no concept of multithreading. Also there is no pre-emptive operating system to deal with "killing" tasks. Indeed, there are no tasks (the RTOSes available for PICs are very limited even for embedded processors and don't support the idea of stopping/killing a task, only for setting a flag to ask the code to "commit suicide".
You have to set a flag in the ISR. The function then has to periodically check the flag and, if set, terminate itself, or do whatever it is that you want.
Interrupts are simply requests from peripherals and outside hardware to temporarily interrupt whatever the processor is doing, and quickly service the interrupting device. Simple things like, a character has been received: store the character, a timer has timed out: reset the timer, a button has been pressed, note that the button has been pressed so that main code can deal with it appropriately. |
|
|
ELCouz
Joined: 18 Jul 2007 Posts: 427 Location: Montreal,Quebec
|
|
Posted: Wed Jan 21, 2015 5:15 pm |
|
|
RF_Developer wrote: | The processor does not multitask, and there is no concept of multithreading. Also there is no pre-emptive operating system to deal with "killing" tasks. Indeed, there are no tasks (the RTOSes available for PICs are very limited even for embedded processors and don't support the idea of stopping/killing a task, only for setting a flag to ask the code to "commit suicide".
You have to set a flag in the ISR. The function then has to periodically check the flag and, if set, terminate itself, or do whatever it is that you want.
Interrupts are simply requests from peripherals and outside hardware to temporarily interrupt whatever the processor is doing, and quickly service the interrupting device. Simple things like, a character has been received: store the character, a timer has timed out: reset the timer, a button has been pressed, note that the button has been pressed so that main code can deal with it appropriately. |
You come up with an interesting subject about real-time os.
Does using a RTOS makes coding easier?
What are the real purpose (I mean for a PIC) ?
We already write directly to the hardware (minus the C layer)... _________________ Regards,
Laurent
-----------
Here's my first visual theme for the CCS C Compiler. Enjoy! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19548
|
|
Posted: Thu Jan 22, 2015 2:07 am |
|
|
No, the RTOS wouldn't make it easier. They are not pre-emptive.
I have to ask 'why' the functions need so long?. Can you reverse the approach?.
If the functions need to take a long time because they are waiting for something, then wait outside the function, not inside.
So (for example):
Code: |
//timer and external events already setup using interrupts.
while (TRUE)
{
if (clock_finished || external event)
{
//advance to another state
//including testing for errors etc..
//and setup clock for the next state etc.
clock=something;
clock_finished=false;
}
switch (operation)
{
case func1:
do_fast_things_func1();
break;
case func2:
do_fast_things_func2();
break;
//for as many cases as you need.
}
if (exit_flag)
{
//here something (not time) has said 'do something'
//do whatever needs to be handled when the exit is flagged
//set to whatever state this needs to change to etc...
}
}
|
Basically if functions need to wait for a time, don't. Instead start a clock, and loop in a fast routine, till the clock ends ('clock_finished' here). When this triggers, advance to the new state. An 'exit' can then be flagged at any point.
My systems typically loop at least 1000* per second, and change to a state based upon the passage of time, or external triggers (keys, serial events, etc.. etc..). I usually use an enum for the state, with logical names like 'pump_on', 'start_wash', 'sample_for' etc.. Then once ever (perhaps) 12 hours, a timer triggers a re-calibrate, but at any time (signal from an alarm, keyboard, external PLA, etc..), external events can trigger state changes. |
|
|
|
|
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
|