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 CCS Technical Support

Very Peculiar Problem [SOLVED]

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



Joined: 27 Jul 2013
Posts: 6

View user's profile Send private message

Very Peculiar Problem [SOLVED]
PostPosted: Sun Jul 28, 2013 11:57 am     Reply with quote

Hi all,
I am facing a peculiar problem, there are five tasks and each task will be executed at different interval time (200ms, 1 sec, 6 sec, 3 sec and ten min).
Tasks are executing perfectly for some time say few hours, vafter that No tasks are executing exactly for fixed time say 1 hour 9 mins and after that time duration again the tasks are started to executing. The peculiar problem I noticed is it is entering the interrupt and flag is getting set, but in main loop the if condition is getting false but it should not be so.
Example :

Isr Routine
Code:

isr     
{
interrupt disable
flag=true;     //flag is getting enabled here correctly each time
interrupt enable
}

under main routine
Code:
 
while(1)
{
if(flag==true) //while i place break point here and watch the flag value , //flag is equal to true only , but it is not entering into the condition loop.
{
interrupt disable
tasks;
flag=false;
interrupt enable
}
}
 

This is my actual code snippet

Code:

#INT_TIMER0
void timer0_isr(void) //3 Seconds
   {
   disable_interrupts(GLOBAL); 
   TASK_LSTSMS=D_TRUE;
   _6secDelay++;               //six Sec
   _cumulativeUpdateDelay++;   //ten Min
   restart_wdt();
   if(_6secDelay>D_TIME_RELATED_DLY)   
      {
       _6secDelay=0;
       TASK_TMRLTD=D_TRUE;
      }
   else // For Latency
     {
      if(_cumulativeUpdateDelay>=D_CUM_UPD_DLY)//every ten mins
         {
          _cumulativeUpdateDelay=0;
          TASK_CUMUPD2MEM=D_TRUE;
         }
     }
    set_timer0(D_TM0_DLY);
    enable_interrupts(GLOBAL); //very important
   }


#INT_TIMER1
void timer1_isr(void) //100 Ms
 {
  disable_interrupts(GLOBAL);
  restart_wdt();
  _200msDelay++;
  _1secDelay++;
  if(_1secDelay>=D_LST_SMS_DLY)
   {
     _1secDelay=0;
     TASK_TAMPCHK=D_TRUE;
   }
  if(_200msDelay>D_ENERGYAH_UPD_DLY)
   {
     _200msDelay=0;
     TASK_AHCALC=D_TRUE;
   }
 set_timer1(D_TM1_DLY);
 enable_interrupts(GLOBAL);
 }


 in main

  while(1)
  {
    if(TASK_AHCALC==D_TRUE)
   {   
   disable_interrupts(GLOBAL);
     //ah tasks goes here
        TASK_AHCALC=D_FALSE;
        enable_interrupts(GLOBAL);
   }
   if(TASK_TAMPCHK==D_TRUE)
   {
        disable_interrupts(GLOBAL);
   //sensing tasks goes here
 
    TASK_TAMPCHK=D_FALSE;
        enable_interrupts(GLOBAL);
   }
   if(TASK_TMRLTD==D_TRUE)
   {
        disable_interrupts(GLOBAL);
   //time related tasks
   TASK_TMRLTD=D_FALSE;
   enable_interrupts(GLOBAL);
   }
   if(TASK_LSTSMS==D_TRUE)
   {
        disable_interrupts(GLOBAL);
    //tasks
        TASK_LSTSMS=D_FALSE;
   enable_interrupts(GLOBAL);
   }
   if(TASK_CUMUPD2MEM==D_TRUE)
   {
        disable_interrupts(GLOBAL);
        //tasks
        TASK_CUMUPD2MEM=D_FALSE;
   enable_interrupts(GLOBAL);
   }


Last edited by Es_prog on Thu Aug 01, 2013 6:25 am; edited 1 time in total
Mike Walne



Joined: 19 Feb 2004
Posts: 1785
Location: Boston Spa UK

View user's profile Send private message

PostPosted: Sun Jul 28, 2013 1:16 pm     Reply with quote

Speed things up by a factor of 1,000 or more.
Then you won't have to wait so long for the error to occur.
You should then be able to see the problem for yourself.

Mike
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jul 28, 2013 2:24 pm     Reply with quote

Why do you think you should manually disable and enable global interrupts
while still inside the interrupt service routine ? I don't think you have seen
that in any CCS example or in the manual. I'm curious, because you have
labeled it "very important".

Also, what's your PIC and compiler version ?
Quote:

#INT_TIMER0
void timer0_isr(void) //3 Seconds
{
disable_interrupts(GLOBAL);
TASK_LSTSMS=D_TRUE;
_6secDelay++; //six Sec
_cumulativeUpdateDelay++; //ten Min
restart_wdt();
if(_6secDelay>D_TIME_RELATED_DLY)
{
_6secDelay=0;
TASK_TMRLTD=D_TRUE;
}
else // For Latency
{
if(_cumulativeUpdateDelay>=D_CUM_UPD_DLY)//every ten mins
{
_cumulativeUpdateDelay=0;
TASK_CUMUPD2MEM=D_TRUE;
}
}
set_timer0(D_TM0_DLY);
enable_interrupts(GLOBAL); //very important
}


#INT_TIMER1
void timer1_isr(void) //100 Ms
{
disable_interrupts(GLOBAL);
restart_wdt();
_200msDelay++;
_1secDelay++;
if(_1secDelay>=D_LST_SMS_DLY)
{
_1secDelay=0;
TASK_TAMPCHK=D_TRUE;
}
if(_200msDelay>D_ENERGYAH_UPD_DLY)
{
_200msDelay=0;
TASK_AHCALC=D_TRUE;
}
set_timer1(D_TM1_DLY);
enable_interrupts(GLOBAL);
}
temtronic



Joined: 01 Jul 2010
Posts: 9225
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Sun Jul 28, 2013 3:03 pm     Reply with quote

Also you only need one ISR,set for 200ms, your 'smallest' time unit.
Besides simplifying the code,all tasks are 'synced' to a 'master' time unit.

If you check the software RTC in the code library, you can see another way to have several tasks execute.

hth
jay
Es_prog



Joined: 27 Jul 2013
Posts: 6

View user's profile Send private message

PostPosted: Sun Jul 28, 2013 3:23 pm     Reply with quote

@ Mike Walne
How to speed up, give me some hint plz
@ PCM Programmer
I have used global interrupt disable to avoid recurrence of same interrupt. Using 4.127 version.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jul 28, 2013 3:27 pm     Reply with quote

Quote:
Also, what's your PIC and compiler version ?

Using 4.127 version

What is your PIC ?
Es_prog



Joined: 27 Jul 2013
Posts: 6

View user's profile Send private message

PostPosted: Sun Jul 28, 2013 3:30 pm     Reply with quote

@ PCM

It is PIC 18F67K90
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jul 28, 2013 3:52 pm     Reply with quote

Quote:
I have used global interrupt disable to avoid recurrence of same interrupt

The PIC automatically disables Global interrupts in hardware when it
gets an interrupt. You don't have to do it. When your interrupt routine
is done and the compiler returns the interrupt, then Global interrupts
are re-enabled. You don't have to do it, and you should not do it.
Es_prog



Joined: 27 Jul 2013
Posts: 6

View user's profile Send private message

PostPosted: Sun Jul 28, 2013 4:03 pm     Reply with quote

@ PCM
Problem i m facing is due to manual entry of global disable and enable?
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jul 28, 2013 5:22 pm     Reply with quote

It could be. When you re-enable Global interrupts at the end of your
user code in the interrupt routine the program execution is as shown below.
See all those instructions in the middle ? You have prematurely allowed
a new interrupt to occur in the middle of the exit code of the CCS
interrupt dispatcher:
Code:

.................... enable_interrupts(GLOBAL); //very important 
000A6:  MOVLW  C0
000A8:  IORWF  INTCON,F    // User manually enables Global ints

=======
000AA:  BCF    INTCON.T0IF
000AC:  GOTO   0058
00058:  MOVFF  0E,00
0005C:  MOVFF  0F,01
00060:  MOVFF  10,02
00064:  MOVFF  11,03
00068:  MOVFF  0C,FSR0L
0006C:  MOVFF  07,FSR0H
00070:  BSF    07.7
00072:  MOVFF  08,FSR1L
00076:  MOVFF  09,FSR1H
0007A:  MOVFF  0A,FSR2L
0007E:  MOVFF  0B,FSR2H
00082:  MOVFF  12,PRODL
00086:  MOVFF  13,PRODH
0008A:  MOVFF  14,PCLATH
0008E:  MOVFF  15,PCLATU
00092:  MOVF   04,W
00094:  MOVFF  06,BSR
00098:  MOVFF  05,STATUS
=========
0009C:  RETFIE 0  // The 18F67K90 re-enables Global interrupts here

When you do this, you allow a new interrupt (from a different timer)
to enter the CCS interrupt dispatcher code before the previous interrupt
is finished exiting the interrupt dispatcher. There is only one instance of
interrupt dispatcher code. It's not re-entrant. Do not do this. Do not
manually enable global interrupts while still inside your user code.
Let the CCS interrupt dispatcher handle it.
Es_prog



Joined: 27 Jul 2013
Posts: 6

View user's profile Send private message

PostPosted: Sun Jul 28, 2013 11:54 pm     Reply with quote

@ PCM

Thanks, I have changed the code as you said and its now in testing phase.
Es_prog



Joined: 27 Jul 2013
Posts: 6

View user's profile Send private message

PostPosted: Wed Jul 31, 2013 3:48 am     Reply with quote

@PCM,

Thanks, your solution have solved my problem.
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