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

Interrupts disabled during call to prevent re-entrancy

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



Joined: 11 Nov 2008
Posts: 2

View user's profile Send private message

Interrupts disabled during call to prevent re-entrancy
PostPosted: Tue Nov 11, 2008 6:08 am     Reply with quote

Hello everyone,
I program a procedure, but the compiler give me a warining:

"ledtest.c" Line 132(1,1): Condition always TRUE
>>> Warning 216 "ledtest.c" Line 135(0,1): Interrupts disabled during call to prevent re-entrancy: (@delay_ms1)

But I don't know the reason. The program can't work properly, external interrupt no function. Would you pls tell me?
The source code as below:
Code:
#include "d:\Program Files\Microchip\Source\ledtest.h"
const int digled[10]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,\
0x80,0x98}; //define the number 0,1,2,3,4,5,6,7,8,9
short desk=0; //define the bonousmode at the desk
short chair=0;    //define the bonousmode at the chair
int bonousno=0;   //define the bonousno
#int_EXT
void  EXT_isr(void)
{
   delay_us(200);    //delay a long time to test if external interrupt
   if(input_state(pin_b0)==0)
   {
      int temp0=0;
      int temp1=0;
      do{
         temp0=bonousno/10;
         temp1=bonousno-temp0*10;
         output_c(digled[temp0]);
         output_a(0xfe);         //display shiwei
         delay_ms(5);
         output_a(0xff);         //shut off led
         output_c(digled[temp1]);
         output_a(0xfd);         //display gewei
         delay_ms(5);
         output_a(0xff);         //shut off led
      } while(input_state(pin_b1)==1);
   }

}

void mydelay(int m)  //define the delay used to count the bonousno
{
   int n=0;
   for(n=0;n<m;n++)
   {
      if(desk==1)    //judge if at the mode of bonous--desk
      {
         if(bonousno<=44)  //define the desk max
            bonousno++;
         else
            bonousno=0;
      }
      if(chair==1)   //judge if at the mode of bonous-chair
      {
         if(bonousno<10)   //define the chair max
            bonousno++;
         else
            bonousno=0;
      }
      delay_us(10);        //call the build delay
   }
}



void main()
{

   port_b_pullups(TRUE);
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_spi(SPI_SS_DISABLED);
//   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1););
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   //enable_interrupts(INT_EXT);
   //enable_interrupts(GLOBAL);

   // TODO: USER CODE!!
   do
   {
      if(input_state(pin_b2)==0)    //normal work
      {
         desk=0;
         chair=0;
         disable_interrupts(global);
         disable_interrupts(int_ext);
         output_a(0xff);   //shut off the LED
         output_c(digled[0]); //display shiwei
         output_a(0xfe);
         delay_ms(5);
         output_a(0xff);   //shut off the LED
         output_c(digled[0]); //display gewei
         output_a(0xfd);
         delay_ms(5);
         output_a(0xff);   //shut off the LED
         
      }
      if(input_state(pin_b3)==0)    //bonous mode--desk
      {
         int a=0;
         int b=0;             //define temp varibles
         desk=1;
         chair=0;             //set the relative flag
         enable_interrupts(global); //enable global interrupt
         enable_interrupts(int_ext);   //enable external interrupt         
         for(a=0;a<5;a++)
         for(b=0;b<10;b++)
         {
            output_c(digled[a]);
            output_a(0xfe);      //display the shiwei led
            mydelay(200);
            output_a(0xff);      //shut off LED
            output_c(digled[b]);
            output_a(0xfd);      //display the gewei led
            mydelay(200);
            output_a(0xff);      //shut off the led
         }
      }
      if(input_state(pin_b4)==0)    //bounous mode--chair
      {
         int c=0;
         int d=0;             //define the temp varibles
         desk=0;
         chair=1;             //set the relative flag
         enable_interrupts(global); //enable the global interrupt
         enable_interrupts(int_ext);   //enable the external interrupt
         
         for(c=0;c<2;c++)
         for(d=0;d<10;d++)
         {
            output_c(digled[c]);
            output_a(0xfe);      //display shiwei led
            mydelay(200);
            output_a(0xff);
            output_c(digled[d]);
            output_a(0xfd);      //display gewei led
            mydelay(200);
            output_a(0xff);      //shut off led
         }
      }
   } while(1);     
}
Ttelmah
Guest







PostPosted: Tue Nov 11, 2008 8:59 am     Reply with quote

The 'warning', about 'condition always true', is just that, a 'warning', to make sure you realise the test will never be false.
A search here, would have found a huge number of threads explaining the 'reentrancy' error. This is because you are using delays in both your main code, and in the interrupt. A function _cannot call itself_. This is a hardware limitation of the PIC, since it does not have a 'stack' for variables. If an interrupt occured _inside_ one of the external delays, you would get a delay, called inside a delay. hence the compiler disables interrupts in the external delays.
Seriously, the use of delays in the interrupt should be avoided anyway. If you want a delay, and then re-test of the pin, setup a hartdware timer, in the interrupt, and check the pin when _this_ expires, and interrupts. Follow the 'mantra' (not always right, but close enough for most things), _keep interrupt handlers as fast as possible_. Do _not_ sit in a delay inside the interrupt.

Best Wishes
bkamen



Joined: 07 Jan 2004
Posts: 1611
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Tue Nov 11, 2008 4:22 pm     Reply with quote

Ttelmah wrote:
Follow the 'mantra' (not always right, but close enough for most things), _keep interrupt handlers as fast as possible_. Do _not_ sit in a delay inside the interrupt.


Amen to that!
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
clw_zxq



Joined: 11 Nov 2008
Posts: 2

View user's profile Send private message

PostPosted: Tue Nov 18, 2008 6:09 am     Reply with quote

Thank you very much, although I don't know why the CCS compiler can't
realise this item, but I rectified my source code, as follows:
Code:
#int_EXT
void  EXT_isr(void)
{
//   delay_us(200);    //delay a long time to test if external interrupt
//   if(input_state(pin_b0)==0)
//   {
      int temp0=0;
      int temp1=0;
      do{
         temp0=bonousno/10;
         temp1=bonousno-temp0*10;
         output_c(digled[temp0]);
         output_a(0xfe);         //display shiwei
         delay_us(500);
         delay_us(500);
         delay_us(500);
         delay_us(500);          //To avoid warning,using delay_us
//         delay_ms(5);
         output_a(0xff);         //shut off led
         output_c(digled[temp1]);
         output_a(0xfd);         //display gewei
         delay_us(500);
         delay_us(500);
         delay_us(500);
         delay_us(500);
//         delay_ms(5);
         output_a(0xff);         //shut off led
      } while(input_state(pin_b1)==1);
//   }

}

Now, it can work rightly, but when I use delay_ms, it can't work properly again. I need to delay at the external interrupt program.
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

PostPosted: Tue Nov 18, 2008 6:59 am     Reply with quote

delay_us() and delay_ms() probably share a common delay function in the library, or at least a common variable, so you cannot get around it that way. It you really need to get around the problem, then write your own delay function for the interrupt code that does not use any library functions at all. However, let me add my voice to the chorus of others who have said that it is bad, bad practice to use delays inside of interrupt code!
_________________
Robert Scott
Real-Time Specialties
Embedded Systems Consulting
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Nov 18, 2008 1:02 pm     Reply with quote

See this thread. It shows how to add a 2nd #use delay() statement
to prevent the message "Interrupts disabled to prevent re-entrancy"
http://www.ccsinfo.com/forum/viewtopic.php?t=27345&highlight=delay
isururivi



Joined: 09 Aug 2011
Posts: 3

View user's profile Send private message Send e-mail

Interrupts disabled during call to prevent re-entrancy
PostPosted: Tue Aug 09, 2011 12:13 pm     Reply with quote

when compile this program 4 warnings appear
warnings are as follows.
Quote:

Warning 216"line follow.c"Line 553(0,1): Interrupts disabled during call to prevent re-entrancy: (@PUTCHAR_2_)
Warning 216"line follow.c"Line 553(0,1): Interrupts disabled during call to prevent re-entrancy: (reset_encoders)
Warning 216"line follow.c"Line 553(0,1): Interrupts disabled during call to prevent re-entrancy: (set_motorspeed1)
Warning 216"line follow.c"Line 553(0,1): Interrupts disabled during call to prevent re-entrancy: (set_motorspeed2)



Code:
#include "line follow.h"

void set_motorspeed1(unsigned char speed);
void set_motorspeed2(unsigned char speed);
void set_mode(unsigned char mode);
long get_encoder(unsigned char en);
void reset_encoders(void);

void line_follow(unsigned char base);
void go_slow(void);
void go_medium(void);
void go_speed(void);
void stop(void);
void done(void);
void line_count(void);
void set_SR_pins(void);
void sendupdates(void);
void get_acceleration(unsigned int8 accel);
void line_follow_flag_on(void);
void line_follow_flag_off(void);

void enc_turn_right_reverse(void);
void enc_1000_forward(void);
void enc_angle(void);
void enc_turn90_left(void);
void enc_turn90_right(void);
void enc_300_forward(void);
void enc_1500_forward(void);
void enc_turn_left_reverse(void);
void enc_right_angle(void);

void set_motorspeed11(unsigned int8 sp);
void set_motorspeed22(unsigned int8 sp);
void reset_encoders1(void);


#define SYNC_BYTE       0x00
#define SET_SPEED1      0x31
#define SET_SPEED2      0x32       
#define SET_MODES       0x34
#define GET_ENC1        0x23
#define GET_ENC2        0x24
#define RESET_ENCS      0x35
#define GET_ACCEL       0x33



unsigned int1 S1,S2,S3,S4,S5,S6,S7,S8,S9,S10,S11,S12,S13,S14,S15,S16,S17,S18,S19,S20,S21,S22,S23,S24;
unsigned int8 line_reading=0;
unsigned int1 sendlineupdate=0;
unsigned int1 line_follow_flag=0;

float Kp=5;       //Range of Kp -73 ~ +73          previous values 3 ,0.01,0.2
float Ki=0.01;    //Range of Ki
float Kd=0.2;     //Range of Kd -36 ~ +36


float normalized_line_reading=0,error=0,prev_error=0,P=0,I=0,D=0,I_error=0,duty=0;
unsigned int line_sts =0;
unsigned char base =128;
char Rx_data=0;
int1 new_data=0;


#int_RDA
void  RDA_isr(void)
{
   enable_interrupts(GLOBAL);

   Rx_data =getc();
   new_data=1;
   
   if(Rx_data==1)
   {
      go_slow();
   }
   if(Rx_data==2)
   {
      go_medium();
   }
   if(Rx_data==3)
   {
      go_speed();
   }
   if(Rx_data==4)
   {
      stop();
   }
   if(Rx_data==5)
   {
      sendlineupdate=1;
   }
   if(Rx_data==6)
   {
      sendlineupdate=0;
   }
   if(Rx_data==7)
   {
      enc_turn_right_reverse();
   }
   if(Rx_data==8)
   {
      enc_1000_forward();
   }
   if(Rx_data==9)
   {
      enc_angle();
   }
   if(Rx_data==10)
   {
      get_acceleration(3);
   }
   if(Rx_data==11)
   {
      enc_turn90_left();
   }
   if(Rx_data==12)
   {
      enc_turn90_right();
   }
   if(Rx_data==13)
   {
      enc_300_forward();
   }
   if(Rx_data==14)
   {
      line_follow_flag=1;
   }
   if(Rx_data==15)
   {
      line_follow_flag=0;
   }
   if(Rx_data==16)
   {
      enc_1500_forward();
   }
   if(Rx_data==17)
   {
      enc_turn_left_reverse();
   }
   if(Rx_data==18)
   { 
      enc_right_angle();
   }
   
     enable_interrupts(GLOBAL);
}


void main()
{

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_CLOCK_DIV_2);
   ////////////////setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   
   set_mode(2);
   reset_encoders1();
   while(true)
   {
      if(line_follow_flag==1){
         set_SR_pins();
         line_follow(base);
         line_count();
      }
     else
     {
     }
     
   }

}

////////////////////////////       METHODS        /////////////////


void done(void){
   fputc(150,MASTER);
}

void set_SR_pins (void){
      S1=input_state(PIN_C0);  //PORTCbits.RC0; //Left
      S2=input_state(PIN_C1);  //PORTDbits.RD0;
      S3=input_state(PIN_C2);  //PORTDbits.RD1;
      S4=input_state(PIN_C3);  //PORTDbits.RD2;
      S5=input_state(PIN_C4);  //PORTDbits.RD3;
      S6=input_state(PIN_C5);  //PORTDbits.RD7;
      S7=input_state(PIN_A0);  //PORTCbits.RC5;
      S8=input_state(PIN_A1);  //PORTCbits.RC1;
      S9=input_state(PIN_A2);  //PORTDbits.RD4;
      S10=input_state(PIN_A3);  //PORTCbits.RC2;
      S11=input_state(PIN_A4);  //PORTCbits.RC0;
      S12=input_state(PIN_A5);  //PORTDbits.RD0;
      S13=input_state(PIN_B0);  //PORTDbits.RD1;
      S14=input_state(PIN_B1);  //PORTDbits.RD2;
      S15=input_state(PIN_B2);  //PORTDbits.RD3;
      S16=input_state(PIN_B3);  //PORTDbits.RD7;
      S17=input_state(PIN_B4);  //PORTCbits.RC5;
      S18=input_state(PIN_B5);  //PORTCbits.RC1;
      S19=input_state(PIN_D0);  //PORTDbits.RD4;
      S20=input_state(PIN_D1);  //PORTCbits.RC2;
      S21=input_state(PIN_D2);  //PORTDbits.RD5;
      S22=input_state(PIN_D3);  //PORTDbits.RD6; 
      S23=input_state(PIN_D4);  //PORTDbits.RD5;
      S24=input_state(PIN_D5);  //PORTDbits.RD6;  //Right
       
}


void go_slow(void){
   base=160;
}

void go_medium(void){
   base=200;
}

void go_speed(void){
   base=240;
}

void stop(void){
//!   base=128;
   set_motorspeed1(128);
   set_motorspeed2(128);
}

void line_follow(unsigned char b){
     
      //----------------------------------------------------------------------------
     
      line_reading=(S1*1)+(S2*2)+(S3*3)+(S4*4)+(S5*5)+(S6*6)+(S7*7)+(S8*8)+(S9*9)+(S10*10)+(S11*11)+(S12*12)+(S13*13)+(S14*14)+(S15*15)+(S16*16)+(S17*17)+(S18*18)+(S19*19)+(S20*20)+(S21*21)+(S22*22)+(S23*23)+(S24*24);
     
      if (line_reading==0)
      {
         set_motorspeed11(128);
         set_motorspeed22(128);
      }
      else
      {
         normalized_line_reading=(float)line_reading/(S1+S2+S3+S4+S5+S6+S7+S8+S9+S10+S11+S12+S13+S14+S15+S16+S17+S18+S19+S20+S21+S22+S23+S24);
         error=normalized_line_reading-12.5;
         if (error == 0)
         {
             set_motorspeed11(b);
             set_motorspeed22(128);
         }else
         {
            P=Kp*error;                 
           
            I_error=I_error+error;     
            I=Ki*I_error;             
           
            D=(prev_error-error)*Kd;
            duty=P+D+I;
            prev_error=error;
           
            set_motorspeed22(128-duty);
         }         
      }

}




void sendupdates(void){
   fputc(151,MASTER);
}

void line_count(void){
   if(sendlineupdate==1){
      if ((S1+S2+S3+S4+S5+S6+S7+S8+S9+S10+S11+S12+S13+S14+S15+S16+S17+S18+S19+S20+S21+S22+S23+S24)>=12){
         if(line_sts==0){
            sendupdates();
            line_sts=1;
         }
      }
      else{
         line_sts=0;
      }
   }
}

void reset_encoders(void)
{
   fputc(SYNC_BYTE,DRIVER);      // Send sync byte 0x00
   fputc(RESET_ENCS,DRIVER);      // Send command to reset encoder values   
}

void set_mode(unsigned char mode)
{
   fputc(SYNC_BYTE,DRIVER); // Send sync byte 0x00
   fputc(SET_MODES,DRIVER);      // Send command for setting mode
   fputc(mode,DRIVER);            // Mode to be set
}

void set_motorspeed1(unsigned char speed)
{
   fputc(SYNC_BYTE,DRIVER);      // Send sync byte 0x00
   fputc(SET_SPEED1,DRIVER);      // Send command for setting motor speed
   fputc(speed,DRIVER);         // Send speed to be set
}

void set_motorspeed2(unsigned char speed)
{
   fputc(SYNC_BYTE,DRIVER);      // Send sync byte 0x00
   fputc(SET_SPEED2,DRIVER);      // Send command for setting motor speed
   fputc(speed,DRIVER);         // Send speed to be set
}

void set_motorspeed11(unsigned int8 sp){
//!   fputc(SYNC_BYTE,DRIVER);
//!   fputc(SET_SPEED1,DRIVER);
//!   fputc(sp,DRIVER);
   set_motorspeed1(sp);
}
void set_motorspeed22(unsigned int8 sp){
//!   fputc(SET_SPEED2,DRIVER);
//!   fputc(SET_SPEED2,DRIVER);
//!   fputc(sp,DRIVER);
   set_motorspeed2(sp);
}
void reset_encoders1(void){
//!   fputc(SYNC_BYTE,DRIVER);
//!   fputc(RESET_ENCS,DRIVER);
   reset_encoders();
}
long get_encoder(unsigned char e)
{
   long encval,x = 0;

   if(e==1)
   {
      fputc(SYNC_BYTE,DRIVER);         // Send sync byte 0x00
      fputc(GET_ENC1,DRIVER);      // Send command to get the version of MD49 software

      // Read back the four bytes that make up the encoder value
      encval = fgetc(DRIVER);
      encval <<= 24;
      x = fgetc(DRIVER);
      x <<= 16;
      encval |= x;
      x = fgetc(DRIVER);
      x <<= 8;
      encval |= x;
      x = fgetc(DRIVER);
      encval |= x;
   }
   else if(e==2)
   {
      fputc(SYNC_BYTE,DRIVER);         // Send sync byte 0x00
      fputc(GET_ENC2,DRIVER);      // Send command to get the version of MD49 software

      // Read back the four bytes that make up the encoder value
     
      // Read back 4 bytes for the encoder value
      encval = fgetc(DRIVER);
      encval <<= 24;
      x = fgetc(DRIVER);
      x <<= 16;
      encval |= x;
      x = fgetc(DRIVER);
      x <<= 8;
      encval |= x;
      x = fgetc(DRIVER);
      encval |= x;
   }
   else
   {
      // No action
   }
   return(encval);
}

void enc_go_forward(void){
   reset_encoders();
   while(get_encoder(1)<6000){
      set_motorspeed1(240);
      set_motorspeed2(128);
   }
   done();
   
}

void enc_turn_right_reverse(void){
   reset_encoders();
   while(get_encoder(2)<520){
      set_motorspeed1(230);
      set_motorspeed2(128);
   }
   set_motorspeed1(128);
   set_motorspeed2(128);
   delay_ms(100);
   reset_encoders();
   while( get_encoder(2)<1400){             //////pr 1140 @ speed2=108
      set_motorspeed1(128);
      set_motorspeed2(80);
     
   }
   set_motorspeed1(128);
   set_motorspeed2(128);
   delay_ms(400);
   stop();
   reset_encoders();
   set_motorspeed1(20);
   set_motorspeed2(128);
   delay_ms(400);
   
   while(!input_state(pin_B7) && !input_state(pin_B6) ){
      delay_us(20);
      if(!input_state(pin_B7) && !input_state(pin_B6) ){   
         set_motorspeed1(20);
         set_motorspeed2(128);
      }
     
      else{
         stop();
         
             
      }     
   }
   stop();
   done();
 }
 
 void enc_1000_forward(void){
   
//!   set_motorspeed1(128);
//!   set_motorspeed2(128);
   delay_ms(1000);
   reset_encoders();
   while(get_encoder(1)<1600){
      set_motorspeed1(240);
      set_motorspeed2(128);
   }
   done();
 }
 
 void enc_angle(void){
   reset_encoders();
//!   while(get_encoder(1)<400){
//!      set_motorspeed1(200);
//!      set_motorspeed2(110);
//!   }
//!   stop();
   while(get_encoder(2)<1000){
      set_motorspeed1(200);
      set_motorspeed2(100);
   }
   done();
}

void get_acceleration(unsigned int8 accel){
   fputc(SYNC_BYTE,DRIVER);      // Send sync byte 0x00
   fputc(GET_ACCEL,DRIVER);      // Send command for setting motor acceleration
   fputc(accel,DRIVER);         // Send acceleration to be set
}

void enc_turn90_left(void){
   reset_encoders();
//!   while(get_encoder(2)<1230){
//!      set_motorspeed1(128);
//!      set_motorspeed2(108);
//!   }
   while(get_encoder(2)<1550){
      set_motorspeed1(128);
      set_motorspeed2(80);
   }
   done();
}
void enc_turn90_right(void){
   reset_encoders();
   while(get_encoder(1)<1550){
      set_motorspeed1(128);
      set_motorspeed2(180);
   }
   done();
}
void enc_300_forward(void){
   delay_ms(1000);
   reset_encoders();
   while(get_encoder(1)<150){
      set_motorspeed1(230);
      set_motorspeed2(128);
   }
   done();
}
void enc_1500_forward(void){
   delay_ms(1000);
   reset_encoders();
   while(get_encoder(1)<1600){
      set_motorspeed1(220);
      set_motorspeed2(128);
   }
   done();
}
void enc_turn_left_reverse(void){
   reset_encoders();
   while(get_encoder(1)<420){
      set_motorspeed1(230);
      set_motorspeed2(128);
   }
   set_motorspeed1(128);
   set_motorspeed2(128);
   delay_ms(100);
   reset_encoders();
   while(get_encoder(1)<1400){
      set_motorspeed1(128);
      set_motorspeed2(180);
   }
   set_motorspeed1(128);
   set_motorspeed2(128);
   delay_ms(400);
//!   stop();
//!   reset_encoders();
   set_motorspeed1(20);
   set_motorspeed2(128);
   delay_ms(100);
   
   while(!input_state(pin_B7) && !input_state(pin_B6) ){
      delay_us(20);
      if(!input_state(pin_B7) && !input_state(pin_B6) ){   
         set_motorspeed1(20);
         set_motorspeed2(128);
      }
     
      else{
         stop();
         
             
      }     
   }
   stop();
   done();
 }
 void enc_right_angle(void){
   reset_encoders();
   while(get_encoder(1)<800){
      set_motorspeed1(200);
      set_motorspeed2(148);
   }
   done();
 }
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

PostPosted: Tue Aug 09, 2011 3:09 pm     Reply with quote

I assume you want to know why you get the warnings? It is because those functions can be called both from the RDA interrupt, indirectly through stop(), and the main code. This could cause re-entrancy which messes up the compilers call tree.

The best way to fix this is to absolutely minimize the code in your interrupt routines. Have the interrupt quickly set a status word and exit. Let the main code check the status word on its own schedule, and if the status has changed, then the main code does the work needed for the new status. It looks like your Rx_data could be that status word.
_________________
The search for better is endless. Instead simply find very good and get the job done.
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