CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Software INT

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Linuxbuilders



Joined: 20 Mar 2010
Posts: 193
Location: Auckland NZ

View user's profile Send private message

Software INT
PostPosted: Tue Aug 23, 2016 1:21 am     Reply with quote

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.
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Tue Aug 23, 2016 2:05 am     Reply with quote

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."
Ttelmah



Joined: 11 Mar 2010
Posts: 19369

View user's profile Send private message

PostPosted: Tue Aug 23, 2016 2:14 am     Reply with quote

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
Linuxbuilders



Joined: 20 Mar 2010
Posts: 193
Location: Auckland NZ

View user's profile Send private message

PostPosted: Tue Aug 23, 2016 2:24 am     Reply with quote

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.
Ttelmah



Joined: 11 Mar 2010
Posts: 19369

View user's profile Send private message

PostPosted: Tue Aug 23, 2016 2:55 am     Reply with quote

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.
Linuxbuilders



Joined: 20 Mar 2010
Posts: 193
Location: Auckland NZ

View user's profile Send private message

PostPosted: Tue Aug 23, 2016 3:01 am     Reply with quote

Thnx, at least I am not alone on the planet ; ) then
_________________
Help "d" others and then you shell receive some help from "d" others.
Ttelmah



Joined: 11 Mar 2010
Posts: 19369

View user's profile Send private message

PostPosted: Tue Aug 23, 2016 3:27 am     Reply with quote

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
Linuxbuilders



Joined: 20 Mar 2010
Posts: 193
Location: Auckland NZ

View user's profile Send private message

PostPosted: Wed Aug 24, 2016 12:53 am     Reply with quote

thnx
_________________
Help "d" others and then you shell receive some help from "d" others.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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