|
|
View previous topic :: View next topic |
Author |
Message |
Ttelmah
Joined: 11 Mar 2010 Posts: 19550
|
|
Posted: Sat Dec 10, 2016 4:21 am |
|
|
I suspect it is related to RAM bank switching.
I notice that the interrupt code always places it's reserved variables in the low memory.
With the array declared, the timer variables are sitting in bank 4.
When the array is smaller than about 220, the timer variables are in bank 0.
Now the code seems to have the correct bank switches present, so possibly something in the interrupt handler (looking now). #locating the array, means the timer variables can again be located in bank 0. Declaring the array after the timer variables has the same effect and also fixes the problem.
Accessing 'Seconds_flag', forces a bank switch.
The bank switching code is identical in chips compiled for address 0 builds, or 0x2000. I'm suspecting something in the bootloader interrupt relocation.
A look shows what is wrong.
At some point, the interrupt relocation in the USB bootloader, has been incorrectly modified.
It should read:
Code: |
#int_global
void isr(void)
{
jump_to_isr(APPLICATION_ISR);
}
|
It's been set to 'int_default'.....
Now this means that it is not correctly being programmed to relocate the interrupt handler. Won't show if your code doesn't use interrupts, and my own USB bootloader, had my own relocation code that handles this correctly.
So try this one change.
What causes the problem is that there is a double save and then 'half restore', this clears the BSR, as well as wasting time...
Ugh.
I have already posted details to CCS. |
|
|
spilz
Joined: 30 Jan 2012 Posts: 220
|
|
Posted: Sat Dec 10, 2016 9:40 am |
|
|
That seems to solve lot of thing !!
It seems the usb bootloader has an error.
Good job !!!
I'm not sure to understand all, does it change/solve bank stuff ?
Let see if PCM_programmer find something else.
Thanks again both for time spend on my question. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19550
|
|
Posted: Sat Dec 10, 2016 10:09 am |
|
|
What happens is a bit complex.
#int_global, makes the code become the 'master' handler, without any save/restore.
#int_default, makes the code save all the registers then be called.
Now remember that the code already placed in the upper bank, saves and restores everything.
With #int_global, the hardware saves the W reg, BSR and status, then the code immediately jumps to the code in the upper bank, this then saves everything else, executes the handler, then restores everything and returns, and the return restores the W, BSR & status. What is wanted.
With #int_default, the code in the low memory saves everything, then _calls_ this as the interrupt handler, which then jumps to the upper handler. This call also updates the 'shadow registers, then saves the other registers again. Then jumps to the handler. Problem then is that the upper handler then uses RETFIE1 to return to the low handler. This restores the W, BSR & status back to the value from the low handler, and returns to the handler in the low memory. This calls RETFIE1 _again_. Since the shadow registers were updated by the call from #int_default, the W, BSR and status may have then been damaged. Problem.... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Dec 11, 2016 12:02 am |
|
|
Thank you for solving this, Ttelmah. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19550
|
|
Posted: Sun Dec 11, 2016 2:10 am |
|
|
Your simplified version was what allowed me to track what was happening.
I felt right at the start that it sounded like a BSR problem. This was why much earlier on in the thread, I asked what happened if the array was declared after the timer variables, but this was not tested.
With your version, the first thing was that the code was small enough, and 'complete', allowing me to take the time and make sure that it was correctly being 'relocated' at 2000. Compiled it both at address zero, and relocated, then compared the assembler and checked everything was OK. It was. This then pointed to the problem being in the bootloader, and (of course), except for a slight delay at initialisation, and some registers being changed, the only thing that entered the equation when the bootloader was used, was the interrupt relocation. A look at this code gave the 'ah ha' moment!... I then made a 'combined' file of bootloader and code, and (since USB is not used in the 'normal boot' path), could run this up in the simulator and see what actually happened. Team 'CCS users'. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19550
|
|
Posted: Thu Dec 22, 2016 4:00 pm |
|
|
Just for information, this has now been fixed in compiler version 5.066. |
|
|
|
|
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
|