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

Array - memory leaks ?

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



Joined: 11 Dec 2011
Posts: 4

View user's profile Send private message

Array - memory leaks ?
PostPosted: Fri Aug 16, 2013 2:51 pm     Reply with quote

I have simple program with struct and array.
Program is working, but I can write to p.data[1], program hangup.

Code:

//working
            p.data[0]=0x22;
            p.data[2]=0x33;

//not working
            p.data[0]=0x22;
            p.data[1]=0x33;


Only one byte change, what is going on? Any idea ? Compiller 5.010 & pic16f1825


Code:

struct Packet
{   
    int8 data[8];
    int8  x; //current byte
    int8 addr; //adres
    int8 len;
    int8 crc;
    int8 tx_cnt;
    int8 cnt;
    int1 busy;
    int1 ok; //packet rx ok
    int1 tx;
    int1 timeout_on; //timeout enable
    int1 xx;
    int1 y;
    int1 z;
    int1 w;
};

struct Packet p;


#int_TBE                                         
void TBE_isr(void)                                       
{
   p.tx_cnt++;
   
   if(p.tx_cnt==2)  //addr
      putc(p.addr);
   else if(p.tx_cnt==3)  //len
      putc(p.len);   
   else if(p.tx_cnt == p.len) //crc
      putc(p.crc);
   else if(p.tx_cnt>=4 && p.tx_cnt<p.len)  //data
   {
      putc(p.data[p.tx_cnt - 4]);
   }       
   else if(p.tx_cnt>p.len)  //tx stop
   {
      p.tx=0;
      p.cnt=0;
      disable_interrupts(INT_TBE);
      delay_ms(1);
      output_low(RS485_ENABLE_PIN);
      enable_interrupts(INT_RDA);
   }
   clear_interrupt(INT_TBE);
}

#int_RDA
void  RDA_isr(void)
{
   p.x = getc(); 

   if(p.cnt == 3) //len
   {
      p.len=p.x;
      p.cnt++;
   }
   else if(p.cnt >= 4) //dane
   {
      p.data[p.cnt-4]=p.x;
        p.cnt++;
      }         
   }
   clear_interrupt(INT_RDA);
 }


void p_send(void)
{
   p.busy=1;
   p.tx=1;
   output_high(RS485_ENABLE_PIN);

   p.tx_cnt=1;   
   putc(START_PACKET);
   
   enable_interrupts(INT_TBE);
}


void main()
{
   while(true)
   {
      if(p.ok==1)
      {
         if(p.data[0] == 0x01)
         {
            output_high(LED);
            p.data[0]=0x22;
            p.data[3]=0x33;
            p.len = 6;
            p_send();
        }   
      }   
    }
}
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Fri Aug 16, 2013 5:53 pm     Reply with quote

have you considered making each data item within your struct
be a separate array of its own?
( sharing common indexing)
it really simplifies what you are asking the compiler to do.
ie: breakout DATA as unitary , and define the other vars as unitary wihtout the struct wrapper .

Recall that the 16F parts have nasty small BANK SELECT static ram segments ,
and such an elaborate STRUCT can really over stress the HARDWARE limitation- IMHO......

i don't see what you gain with the complexity of making such a kloogy STRUCT in the first place, at least in the basic code you show.

There is only ONE instance of the struct as "p" anyway...
Ttelmah



Joined: 11 Mar 2010
Posts: 19467

View user's profile Send private message

PostPosted: Sat Aug 17, 2013 2:43 am     Reply with quote

Some other comments:

Hopefully you have got 'ERRORS' in your RS232 declaration?.
If not, the UART _will_ become hung, if any data arrives, while INT_RDA is disabled. Remember also, that when you enable INT_RDA, up to two characters of data received while the interrupt was disabled, will be in the hardware buffer. It is _better_ to never disable INT_RDA, and instead set a flag to say 'throw away data', and have the interrupt routine just discard any data received while this flag is set.

Get rid of the clear_interrupt lines. Read the manual for interrupt declarations. The _compiler_ automatically clear interrupts for you, unless you specifically ask it not to.

How is the TX enable on your RS485 driver wired?. How is the RX input on the PIC wired?.
Assuming the enable turns 'off' the receive part of the driver, you _must_ have a pull-up resistor on the RX line, or this will float, and garbage will be arriving at the PIC. If is doesn't turn off the RX part, then everything transmitted will be being received. In either case the UART could be hung.

Though large complex structures make it possible to join lots of things together, they have problems. The first is as mentioned by asmboy, but the second is 'performance'. If you access an offset variable in a structure, the chip has to calculate 'where' this is. Then access an array, and the overhead can begin to become rather worrying. So structures with lots of odd elements, are something that should be used 'with care'.

I'd doubt if the problem is actually accessing the array, but possibly the UART. 'Hangup' is hard to trigger, and a UART hang is one of the few things that can trigger this.

Other thing really problematic. Delay_ms, in an interrupt. Get rid of this. Use a hardware timer interrupt to start the transmission. Having a delay in an interrupt, _will_ result in interrupts being disabled in every delay in the main code (even ones in standard function code). Could again, cause the UART to be hung.

Best Wishes
omcdr



Joined: 11 Dec 2011
Posts: 4

View user's profile Send private message

PostPosted: Sun Aug 18, 2013 1:13 pm     Reply with quote

Thanks for the advice. I have to redesign my program and optimize ram usage and interrupts.
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