![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
Linuxbuilders
Joined: 20 Mar 2010 Posts: 193 Location: Auckland NZ
|
Software INT |
Posted: Tue Aug 23, 2016 1:21 am |
|
|
Hi,
I wonder if anybody used this to build up software interrupt handler?
Or any other way?
https://www.ccsinfo.com/faq.php?page=delay_in_interrupt
Thnx _________________ Help "d" others and then you shell receive some help from "d" others. |
|
![](templates/subSilver/images/spacer.gif) |
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Tue Aug 23, 2016 2:05 am |
|
|
Linuxbuilder, you have been around this forum long enough to know that using delays in ISRs is a bad thing. The article at the link says this: "First, it is not good design practice to call delay_XX() routines inside your interrupt. Try to design your programs so interrupts take as little time as possible."
The workaround doesn't solve all the problems associated with using delays in both ISRs and main code. Any delay in main code will be increased by the delay in the ISR when an interrupt occurs, giving wrong timing. ISRs are not interruptable, so other interrupts are stalled for the delay time when in an ISR. This may well lead to lost data and unresponsiveness.
The key is to take CCS's advice: "Try to design your programs so interrupts take as little time as possible." |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Tue Aug 23, 2016 2:14 am |
|
|
That is not a software interrupt handler.
If you just mean 'how to declare an interrupt handler routine', then look at the examples that come with the compiler. ex_sisr.c, shows how to use a serial interrupt, ex_wakeup.c, shows using an external interrupt, etc. etc..
All this is, is a way of loading a separate delay library, so you don't get the problem of interrupts being disabled in the main code, when you use delays in the interrupts.
However the fundamental problem of using delays in interrupts still remains, that all the while you are in this routine, nothing else can happen.
It's a perfectly good solution if (for instance), you are controlling an external chip that needs a few uSec delay for a hardware timing, and has been used by many posters here for this. For any form of longer delay 'think again'. Look at using a hardware timer interrupt instead or a tick based clock.
I see RF_developer posted while I was typing. ![Smile](images/smiles/icon_smile.gif) |
|
![](templates/subSilver/images/spacer.gif) |
Linuxbuilders
Joined: 20 Mar 2010 Posts: 193 Location: Auckland NZ
|
|
Posted: Tue Aug 23, 2016 2:24 am |
|
|
Thnx,
I was wondering if I could use this method to build up semi software interrupts. Delay is used in this example but I don't need it. I know there is no software interrupts in the CCS so I wonder if there is any semi way to simulate it.
In the past I used to do flags triggered by a timers and then process the flags out of main loop. This is sort of the idea but the issue here is that is floating and not precise. I am sure other people did battle this ground before so maybe some advise is around. I cannot dig anything out. I do not want to use RTOS itself as it is not going to do what I need in longer run but I am after some way to be almost there where RTOS is.
So example:
I would define timers at 100ms, 500ms, 1000ms and then would trigger a function in this time, like check sensors every 1000ms, read serial messages once every 100ms, etc. Do you know if there is any easier way to do this without using RTOS? Thnx 4 helping. Sorry I wasn't precise in my previous question, I have a talent of confusion. _________________ Help "d" others and then you shell receive some help from "d" others. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Tue Aug 23, 2016 2:55 am |
|
|
You describe a perfectly good way of doing it.
Single tick interrupt at an interval (say 10mSec).
State machine in the interrupt handler.
If you want (especially if some of the handler code is slow), then instead just have the tick operated by the interrupt, and the state machine in the main code.
Things won't happen 'at' a point in time, but at the next tick 'after', and (of course) the speed of the loop will be limited by how long each routine takes. |
|
![](templates/subSilver/images/spacer.gif) |
Linuxbuilders
Joined: 20 Mar 2010 Posts: 193 Location: Auckland NZ
|
|
Posted: Tue Aug 23, 2016 3:01 am |
|
|
Thnx, at least I am not alone on the planet ; ) then _________________ Help "d" others and then you shell receive some help from "d" others. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Tue Aug 23, 2016 3:27 am |
|
|
I'll often have loops running at all sorts of fundamental rates, being timed from one master tick.
So (for instance), I have a GSM, that has to have any messages scanned at a reasonable interval (checked a few times a second), so have in a fast 'tick; interrupt (that is also doing other things):
Code: |
#int_timer2
void tick(void)
{
//200Hz tick
static int8 fast_tick=19;
if (fast_tick)
--fast_tick;
else
{
//10Hz GSM tick
if (GSM_tick) //only decrement if non zero.
--GSM_tick;
fast_tick=19;
}
//There are loads of other clocks here for USB timeout, ADC scanning
//etc. The ADC is done by selecting the channel, on one tick, then starting
//the ADC on the next, then performing the read, for each of several
//channels This way the interrupt is quick, and never has to wait
//for the ADC.
}
//Then in the main code
if ((GSM_tick==0) || (old_GSM_tick!=GSM_tick))
{
old_GSM_tick=GSM_tick;
//The test for ==0, ensures this gets called if the
//timer has got to zero, before the next 'tick'
GSM_tick_sub(); //1/10th second call to GSM
}
|
The fastest tick event being handled here is every 1/200th second for the ADC state machine (only thing handled inside the timer interrupt), through 1/10th second for the GSM, 1/second for USB timeout, down to the slowest being one event every 12 hours.
The same 'ticker' for GSM, is actually also being used as a timer. So if a message has to be responded to in 5 seconds, the GSM_tick is set to 49, and then in GSM_tick_sub, the next operation is performed when this gets to zero.
Neat thing is that if the code 'misses' the zero (something delays handling), the tick will stop at zero, and the code will then be handled the next time round the loop.
'Self stopping 'count-down' timers are a great way of scheduling things. ![Smile](images/smiles/icon_smile.gif) |
|
![](templates/subSilver/images/spacer.gif) |
Linuxbuilders
Joined: 20 Mar 2010 Posts: 193 Location: Auckland NZ
|
|
Posted: Wed Aug 24, 2016 12:53 am |
|
|
thnx _________________ Help "d" others and then you shell receive some help from "d" others. |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|