View previous topic :: View next topic |
Author |
Message |
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
Specific Variable Assignment Hangs Code Prior to it |
Posted: Thu Apr 05, 2007 10:05 am |
|
|
18F6627 40MHz
FM25256 SPI DIV4
3.236
This one has me stumped....
In the following code if I assign the value 512 to current_fram_addr, the prgram hangs in the for loop to write values to the FRAM. If I assign 511 or 513 it works fine. Or if I uncomment the debug print statement in the loop it works.
current_fram_addr is a value that is passed into the function.
Code: | fprintf(XBEE,"1\n\r");
disable_interrupts(INT_AD);
fprintf(XBEE,"2\n\r");
for(i = 0; i < NUMBER_OF_FRAM_SAMPLES; i++)
{
write_int16_fram(i*2, i);
//fprintf(XBEE,"@%lu\n\r",i);
}
fprintf(XBEE,"3\n\r");
current_fram_addr = 512;
fprintf(XBEE,"4\n\r"); |
Any ideas?
Thanks,
John |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Apr 05, 2007 10:32 am |
|
|
1. You didn't show the declaration for 'i'.
2. Do you have the 'XINST' fuse enabled ? The default state is NOXINST.
If it's enabled, you will get erratic operation of the code.
3. Re-install the compiler. |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Thu Apr 05, 2007 10:40 am |
|
|
PCM,
Thanks for looking.
Code: | #FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled (Legacy mode) |
I guess I'm left with number three....
John |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Fri Apr 06, 2007 8:25 am |
|
|
I've tried:
Re-installation of 3.236.
Fresh install of 3.249.
Preventing 512 from being passed into the function with an 'if' statement that re-assigns to 511 or 513.
When I comment out debug printf statements after the assignment code it works if I get rid of enough of them.
Any ideas of where I could look or a new tact I could take on debugging?
Thanks,
John |
|
|
Ttelmah Guest
|
|
Posted: Fri Apr 06, 2007 9:06 am |
|
|
What do you actually do 'with' this value?. Do you have any interrupt routines in use?. What does the memory useage printout show when the printf's are present (remember these wll use significant memory - it is possible that the problem relates to perhaps a bank switch occuring in the RAM at this point)?. What is the chip?. What does the .sym file show for this variable's memory allocation?.
Best Wishes |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Fri Apr 06, 2007 9:26 am |
|
|
18F6627
The value is the 'index' of the value last read by the ADC and stored in FRAM by the ADC interrupt. I need to 'freeze' that value to pass it to the function that will be pulling the values out of the FRAM.
Here is the ISR:
Code: | ////////////////////////////////////////////////////////////////////////////////
// AD ISR
////////////////////////////////////////////////////////////////////////////////
#INT_AD
void AD_isr(void) {
int16 adc_val;
adc_val = read_adc(ADC_READ_ONLY); //read ADC
if(adc_val < CLIP_VAL) //if ADC isn't going to be clipped
{
write_int16_fram(g_current_fram_addr, adc_val); //put the current ADC value in FRAM
//if(g_current_fram_addr == 4094)
//{
//fprintf(XBEE,"*\n\r");
//}
g_current_fram_addr = ((g_current_fram_addr + 2) & (FRAM_ADDR_MINUS_ONE)); //increment address by two for int16 value, rollover if necessary
g_pending_clip_flag = FALSE;
if(adc_val > g_current_adc_peak)
{
g_current_adc_peak = adc_val;
}
}
else //if ADC is going to be clipped
{
g_pending_clip_flag = TRUE; //set flag so readings get thrown out and start over
}
g_clear_to_read_flag = TRUE;
} |
I tried making the 'frozen' value a global variable instead of passing it into the function. I got further with that, but the symptoms returned as I added printf's to debug....
Yes, the AD interrupt is always active.
Quote: | What does the .sym file show for this variable's memory allocation?. |
I looked and didn't find it... that's what gave me the idea to stop passing it in and just make it a global to see what would happen. (I just realized now, that I didn't find it because I may have been looking at a .sym for a previous version...arghhh)
What is the best way to debug bank switching issues?
Thanks,
John
EDIT:
Yes. It appears that adding or commenting out fprintf's immediately affects the results.... |
|
|
Ttelmah Guest
|
|
Posted: Fri Apr 06, 2007 9:58 am |
|
|
There are a series of things that could cause problems here. The first is you are using the fram write code, both inside, and outside an ISR. This is potentially dangerous. The compiler on latter versions, should disable interrupts to prevent re-entrancy, but it is better to design your code to not do this.
Now, I'd be looking very carefully, at how the multiple byte writes to FRAM work. I'd be very suspicious, that something is going wrong when the second bit in the MSB is set in this address value, which is not actually 'in' the part of the code where the fault appears to be. Remember that the other effect of the debug prints, will be to intoduce delays. Is it possible that something is needing these to be present to prevent the problem. What happens if you substitute a delay for the print statement?. If this works, what event, is requiring this delay to work?...
Best Wishes |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Fri Apr 06, 2007 10:03 am |
|
|
OK. It appears that the problem may be solved (but I'm not what sure what I did that fixed it.)
I found a divide by zero when the value was 512, but that was later in the code than where it would hang. WAIT! I was debugging with fprintf's to see where the code was hanging. If I was using the hardware UART could that give me a false indication of where it was hanging? i.e. the data was sent to the UART but hadn't been output, then the divide by zero occurs and hangs the processor and the data never gets pooped out the UART?
Thanks,
John
EDIT:
RJ,
I was writing this as you were writing your response I'll take a look... but see if you agree with the above. |
|
|
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Fri Apr 06, 2007 10:17 am |
|
|
OK!
I reverted to my original code, problem, and debug printf's. When I added delays after the printf's to allow the UART to finish its business, it showed correctly where the processor was hanging.
NOTE TO SELF:
When trying to localize bugs with printf's and the hardware UART ALWAYS add a delay to allow the UART to complete its transmission. |
|
|
Ttelmah Guest
|
|
Posted: Fri Apr 06, 2007 2:32 pm |
|
|
Shows how hardware buffering can lead to misleading results with the debug print.
Glad you have found it.
Best Wshes |
|
|
|