|
|
View previous topic :: View next topic |
Author |
Message |
omcdr
Joined: 11 Dec 2011 Posts: 4
|
Array - memory leaks ? |
Posted: Fri Aug 16, 2013 2:51 pm |
|
|
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
|
|
Posted: Fri Aug 16, 2013 5:53 pm |
|
|
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: 19559
|
|
Posted: Sat Aug 17, 2013 2:43 am |
|
|
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
|
|
Posted: Sun Aug 18, 2013 1:13 pm |
|
|
Thanks for the advice. I have to redesign my program and optimize ram usage and interrupts. |
|
|
|
|
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
|