View previous topic :: View next topic |
Author |
Message |
E_Blue
Joined: 13 Apr 2011 Posts: 417
|
Debugging step by step works ok but not on full running |
Posted: Mon Apr 09, 2018 9:21 am |
|
|
I'm debugging a program with ICD3 & MPLAB IDE 8.92
µC PIC18F67J50
CCS V 5.073
Debugging step by step works ok but not on full running.
I'm trying to load a buffer in RAM to send data over UART1; if I do it step by step works ok but if I run the code (in debug mode) the buffer is not full loaded.
Any idea about why such strange behavior?
I mean, if the program is wrong, Why doesn't run wrong in step by step debug? _________________ Electric Blue |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Mon Apr 09, 2018 11:02 am |
|
|
You don't really supply us with enough information.
My gut instinct is that you've got a timing problem.
I suggest you reduce your code to the minimum which still shows the problem.
If the code is reasonably short, you can post it and we will have a go at it.
Mike |
|
|
E_Blue
Joined: 13 Apr 2011 Posts: 417
|
|
Posted: Mon Apr 09, 2018 11:21 am |
|
|
Thanks for your answer.
I don´t know what more can I post.
The code is about 7 years old, so is not more a basic code, it has more than 14K of C code lines(About 47K of asm code).
I'm struggling with this about a week and a half; I really want to start all the stupid program again because it have to many changes within this 7 years.
What do you mean with timing error?
I thought that It can be one of the interrupts like the USART1 or USART2 RX but if it was that it should continue on the same point when return after the interrupt has been handled.
I don't know what to think, I'm stuck. _________________ Electric Blue |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Apr 09, 2018 11:53 am |
|
|
Stepping puts a substantial delay after each line of code.
So, add a delay after all lines in that routine. Run it. Does it now work ?
If so, remove a few of the delays. Does it still work ? If so, keep on
doing that until you find the lines that are the problem. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19551
|
|
Posted: Mon Apr 09, 2018 12:04 pm |
|
|
Is this output code a new addition?.
I'd have to say that the suspicion is that this is loading data without verifying that the transmit buffer has emptied. Result lost data. The delays when single stepping allows this to work. |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Mon Apr 09, 2018 1:38 pm |
|
|
E_Blue wrote: | Thanks for your answer.
I don´t know what more can I post.
The code is about 7 years old, so is not more a basic code, it has more than 14K of C code lines(About 47K of asm code).
I'm struggling with this about a week and a half; I really want to start all the stupid program again because it have to many changes within this 7 years.
What do you mean with timing error?
I thought that It can be one of the interrupts like the USART1 or USART2 RX but if it was that it should continue on the same point when return after the interrupt has been handled.
I don't know what to think, I'm stuck. |
Surely the two tasks, loading the buffer and sending data over the UART, don't take up most of the 14k.
Create SHORT code for these two only and see if you still have the problem.
Mike |
|
|
E_Blue
Joined: 13 Apr 2011 Posts: 417
|
|
Posted: Tue Apr 10, 2018 1:58 pm |
|
|
The strange is that get lost in the middle of the printf.
When is filling the buffer the TX interrupt of UART1 is disabled, so there's no way that can be interrupted or any time error, I think.
Code: |
void LoadGSM_TxBuffer(char XByte)
{
char milisec=0;
if(XByte=='>')
{
while(GSM_TxOffset!=0)//Waits until buffer is empty.
{
delay_ms(1);
milisec++;
if(milisec>=100)
{
break;
}
}
GSM_TxLoadOffset=0;
}
if(GSM_TxLoadOffset>GSM_TxBufferSize)//Overflow
{
GSM_TxLoadOffset=GSM_TxBufferSize;
}
GSM_TxBuffer[GSM_TxLoadOffset]=XByte;
GSM_TxLoadOffset++;
}
void Enter(void)
{
printf(LoadGSM_TxBuffer,"\r\n");
LoadGSM_TxBuffer(0x00);
}
void AT(void)
{
char milisec=0;
while(GSM_TxOffset!=0)
{
delay_ms(1);
milisec++;
if(milisec>=100)
{
break;
}
}
GSM_TxLoadOffset=0;
printf(LoadGSM_TxBuffer,"AT");
ModemAttemps++;
}
void ATE0(void)
{
printf(LoadGSM_TxBuffer,"E0;+QURCCFG=\"urcport\",\"uart1\";+QSIMDET=0,0");//Doesn't finish the printf, it goes away and get back again printing only the first 2 or 3 characters.
Enter();
}
void InitModem()
{
AT();
ATE0();
enable_interrupts(INT_TBE);//Enables TX UART1
WaitingOK=true;
BusyTimer=3;//Waits 3 segundos Max.
}
#INT_TBE
void SendGSM_TxBuffer(void)
{
if(GSM_TxOffset<=GSM_TxBufferSize)
{
if(GSM_TxBuffer[GSM_TxOffset]==26 && GSM_TxBuffer[0]=='>' && SendingAnswer==true && GPRS_Status.MassiveAnswer==false)
{
TXREG1=GSM_TxBuffer[GSM_TxOffset];
disable_interrupts(INT_TBE);
GSM_TxOffset=0;
SendingAnswer=false;
GPRS_Status.ComFromSMS=false;
output_low(RTS);
}
else if(GSM_TxBuffer[GSM_TxOffset]==26 && GSM_TxBuffer[0]=='>' && SendingAnswer==true && GPRS_Status.MassiveAnswer==true)
{
disable_interrupts(INT_TBE);
GSM_TxOffset=0;
GPRS_Status.AnswerGSM=true;
}
else if(GSM_TxBuffer[GSM_TxOffset]=='\n' && GSM_TxBuffer[0]!='>')//&& SendingAnswer=false)
{
TXREG1=GSM_TxBuffer[GSM_TxOffset];
disable_interrupts(INT_TBE);
GSM_TxOffset=0;
if(AnswerTimer==0)
{
output_low(RTS);
}
}
else
{
TXREG1=GSM_TxBuffer[GSM_TxOffset];
GSM_TxOffset++;
if(GSM_TxBuffer[GSM_TxOffset]==0x00)
{
GSM_TxOffset=0;
disable_interrupts(INT_TBE);
output_low(RTS);
}
}
}
else//Overflow
{
TXREG1=26;
disable_interrupts(INT_TBE);
GSM_TxOffset=0;
output_low(RTS);
}
}
|
_________________ Electric Blue |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Tue Apr 10, 2018 2:35 pm |
|
|
Can you supply seriously simplified code which is complete, compilable and demonstrates the issue you're having.
Do that so we can copy, paste and test.
Mike |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19551
|
|
Posted: Mon Apr 16, 2018 7:31 am |
|
|
Been away for a few days, but there is one potential screaming problem:
Code: |
if(GSM_TxLoadOffset>GSM_TxBufferSize)//Overflow
{
GSM_TxLoadOffset=GSM_TxBufferSize;
}
GSM_TxBuffer[GSM_TxLoadOffset]=XByte;
GSM_TxLoadOffset++;
|
Assuming the buffer size if something like 128, this will allow data to write to the 129'th byte of the buffer. Remember offsets are zero referenced, so offset 128, is the 129th byte. It needs to limit at GSM_TXLoadOffset>=GSM_TXBufferSize. and GSM_TxLoadOffset=GSM_TxBufferSize-1;
Now depending what variable is actually in the byte after the buffer, the result could be a complete disaster.....
Now (of course) the data being pumped out at full speed makes it much more likely to hit the end of the buffer. If you are single stepping, bytes _will_ be being emptied from the buffer as the hardware UART sends. |
|
|
E_Blue
Joined: 13 Apr 2011 Posts: 417
|
|
Posted: Tue Apr 17, 2018 11:46 am |
|
|
@Ttelmah
I don't release the interrupt until the buffer is filled by LoadGSM_TxBuffer.
Anyway, I changed the code to avoid overflow situations.
Something strange happened with the printf function; lets say that I have 3 functions.
Code: | void Hello()
{
printf(LoadGSM_TxBuffer,"Hello");
}
void Enter()
{
printf(LoadGSM_TxBuffer,"\r\n");
}
void main ()
{
Hello();
Enter();
}
|
If I run step by step I get on the buffer
'H'
'e'
'l'
'l'
'o'
0x0D
0x0A
That's ok.
But if I full run, also in debug mode, I get
'H'
0x0D
And GSM_TxLoadOffset=2
Like never goes back to end the current printf.
For now I solved by going back to a previous version and slowly added step by step the code of the last two months.
Thanks. _________________ Electric Blue |
|
|
|