problem reserving memory for the ICD debuggers

Discuss the Firewing development environment

problem reserving memory for the ICD debuggers

Postby Jerry Messina » Mon Sep 29, 2014 8:11 pm

It seems that to use any of the ICD debuggers with the pic24/33 you need to reserve 0x50 bytes at the start of ram for the debugger's use,
either 0x0800-0x084F (24HJ/24F) or 0x1000-0x104F (24EP). When you use XC16 this is done by the MPLAB project which defines a symbol __ICD2RAM for the linker .gld script, which takes care of reserving the memory space.

I thought maybe I could accomplish the same thing for Firewing by doing the following in my main bas file:
Code: Select all
device = 24HJ128GP502

#define MPLAB_ICD = true
#if defined(MPLAB_ICD)
  #warning "building for MPLAB_ICD"
  #define _reserve_ICD = &H50                        ' ICD requires 0x50 ram locations
  #variable _xramstart = _xramstart + _reserve_ICD   ' x RAM start in bytes
  #variable _xram = _xram - _reserve_ICD             ' x RAM size in bytes
#endif


It looked to me like that worked ok, but now I'm not so sure... I'm seeing variables getting overwritten when I try the following:
Code: Select all
device = 24HJ128GP502

#define MPLAB_ICD = true
#if defined(MPLAB_ICD)
  #warning "building for MPLAB_ICD"
  #define _reserve_ICD = &H50                        ' ICD requires 0x50 ram locations
  #variable _xramstart = _xramstart + _reserve_ICD   ' x RAM start in bytes
  #variable _xram = _xram - _reserve_ICD             ' x RAM size in bytes
#endif

imports uart
imports uarttypes

sub main()
    dim b as byte
    dim s as string
   
    dim stat(16) as USTAReg
    dim st, last_st as USTAReg

    dim ix as ushort
    dim wait as boolean

//--------------------------------------------------------------------------------------
    uart.write("microstickII", 13, 10)      // <<< THIS WRITE IS GARBLED

    // when the code copies ROM to RAM it looks like [WREG14] is pointing into the middle of
    // where the temp ram string buffer is located, and the temp ram string gets overwritten.
    // it ends up writing "micros{" instead of "microstickII"
    // the temp string starts at 0x0864, and WREG14 is 0x86A
//--------------------------------------------------------------------------------------


   // the remaining code is just along for the ride...
    delayms(100)

    ix = 0
    wait = false

    st = uart.USTAT       
    last_st = st
    erase(stat)
   
    while (true)
        while (wait)
        end while
   
        st = uart.USTAT       
        if (st <> last_st) then
            last_st = st
            stat(ix) = st
            if (ix < ubound(stat)) then
                ix += 1
            end if
            if (st.OERR = 1) then
                uart.USTAT.OERR = 0
            end if
            if (st.FERR = 1) then
                b = uart.RCREG
            end if
            if (st.URXDA = 1) then
                b = uart.RCREG
            end if
        end if
    end while

end sub


I guess I'm causing some sort of allocation issue by moving the start of ram?
Jerry Messina
 
Posts: 280
Joined: Thu Feb 14, 2013 10:16 am

Re: problem reserving memory for the ICD debuggers

Postby David John Barker » Tue Sep 30, 2014 7:32 am

what's getting overwritten?
User avatar
David John Barker
 
Posts: 491
Joined: Thu Nov 08, 2012 12:21 pm

Re: problem reserving memory for the ICD debuggers

Postby Jerry Messina » Tue Sep 30, 2014 9:42 am

When it goes to copy the rom->ram string for the call
Code: Select all
    uart.write("microstickII", 13, 10)
the temp ram string is getting corrupted and it ends up being "micros{" + some garbage instead of "microstickII".

Something to do with the stack/frame pointer??? [WREG14] points into the middle of where the temp ram string is located, and the ram string gets munged halfway into the rom->ram copy.

The asm for the copy looks something like this (EDIT: this isn't the exact asm code for the source above, but it's similar)
Code: Select all
   mov WREG, _TBLPAG
   mov   _a0,w0
   mov   w0,[w14]
.L26:
; 538 "main.c" 1
   tblrdl.b   [w13++], w0
; 538 "main.c" 1
   mov.b   WREG, ___nv__breg0
;   mov.b   ___nv__breg0,WREG
   mov   [w14],w1
   mov.b   w0,[w1]
   inc   [w14],[w14]                                    <<<<<<<<<<<<<<< THIS IS WHERE IT GETS CORRUPTED
   mov.b   ___nv__breg0,WREG
   sub.b   w0,#0,[w15]
   .set ___BP___,0
   bra   nz,.L26
   mov   [w14],w0
   mov   w0,_a0


I also tried using
Code: Select all
 
#define _ram_protect = $800
#define _ram_protect_length = $50

instead of changing the '#variable _xramstart' but that only moved my variables and not the sysVars since they're placed absolute.
Jerry Messina
 
Posts: 280
Joined: Thu Feb 14, 2013 10:16 am

Re: problem reserving memory for the ICD debuggers

Postby David John Barker » Tue Sep 30, 2014 5:45 pm

Have you taken a look at the "C" code generated? Might be easier to debug...
User avatar
David John Barker
 
Posts: 491
Joined: Thu Nov 08, 2012 12:21 pm

Re: problem reserving memory for the ICD debuggers

Postby Jerry Messina » Tue Sep 30, 2014 7:34 pm

Here's what I see in the resulting C files...

test#1: without adding 0x50 to _xramstart (#define MPLAB_ICD commented out)
Code: Select all
// system registers...
asm("SYSTEM_RAM   = 0x0800;");      

// relocatable data...
asm("USER_RAM   = 0x0814;");
asm("_P0_U112 = USER_RAM + 0x000000;"); extern  volatile BYTE P0_U112;
asm("_P0_U08 = USER_RAM + 0x000000;"); extern  volatile BYTE P0_U08;
  <snip>
asm("_M0_U08 = USER_RAM + 0x000042;"); extern  volatile BYTE M0_U08;
asm("USER_RAM_END   = 0x0858;");
volatile unsigned char map[88];
// ALLOC = 68


test#2: with adding 0x50 to _xramstart (#define MPLAB_ICD uncommented:)
Code: Select all
// system registers...
asm("SYSTEM_RAM   = 0x0850;");

// relocatable data...
asm("USER_RAM   = 0x0864;");
asm("_P0_U112 = USER_RAM + 0x000000;"); extern  volatile BYTE P0_U112;
asm("_P0_U08 = USER_RAM + 0x000000;"); extern  volatile BYTE P0_U08;
  <snip>
asm("_M0_U08 = USER_RAM + 0x000042;"); extern  volatile BYTE M0_U08;
asm("USER_RAM_END   = 0x08A8;");
volatile unsigned char map[88];
// ALLOC = 68

So, when '#define MPLAB_ICD' is enabled the SYSTEM_RAM and USER_RAM data are both offset by 0x50. That part seems to work.


HOWEVER, for either test the stack and frame pointer end up in the same place, not offset by 0x50!
One or two steps into main() and the registers are:
Code: Select all
WREG14 = 0x0868      // FRAME PTR when #option _gccOptimise = O0
WREG15 = 0x086C      // STACK PTR

which is ok for test#1 since the stack is outside the USER_RAM/USER_RAM_END region (as it should be), but for test#2
the stack points smack in the middle of USER_RAM region, so it overwrites what's in USER_RAM. So does the frame pointer (if its used)


It seems that just adding an offset to _xramstart isn't good enough to let whoever's responsible know that the stack needs to move as well.


NOTE:
I just noticed that the frame ptr [WREG14] only seems to be used by main() when optimizations are off ('#option _gccOptimise = O0').
If you compile with _gccOptimise = O1 then the code to setup the uart.write() call is different and you don't immediately see the problem.
I had to remember to add that option to the .bas file so that the code would build the same in the FW IDE and MPLAB w/the FW toolsuite.
Initially I left that out so they were compiling with different optimization levels, and the code that used the frame ptr trashed USER_RAM as well.

The stack ptr is an issue either way. Any calls from inside main() are going to overwrite USER_RAM.
Jerry Messina
 
Posts: 280
Joined: Thu Feb 14, 2013 10:16 am

Re: problem reserving memory for the ICD debuggers

Postby David John Barker » Tue Sep 30, 2014 7:42 pm

So how would you go about resetting the frame and stack pointers using "C"?
User avatar
David John Barker
 
Posts: 491
Joined: Thu Nov 08, 2012 12:21 pm

Re: problem reserving memory for the ICD debuggers

Postby Jerry Messina » Tue Sep 30, 2014 7:51 pm

I suppose I should change it when it's first initialized (or soon after).

Is there some variable where I can get what the startup value for the stack is?
Jerry Messina
 
Posts: 280
Joined: Thu Feb 14, 2013 10:16 am

Re: problem reserving memory for the ICD debuggers

Postby David John Barker » Tue Sep 30, 2014 7:57 pm

No, Firewing does not set up the stack or frame pointer - you can specify your own linker script, if that helps

http://www.firewing.info/forum/viewtopic.php?f=17&t=136&hilit=linker
User avatar
David John Barker
 
Posts: 491
Joined: Thu Nov 08, 2012 12:21 pm

Re: problem reserving memory for the ICD debuggers

Postby Jerry Messina » Tue Sep 30, 2014 8:03 pm

Since you never return from Main(), think I could just change the stack as the first thing in Main() or should I do it before any of the module Startup initializers run?
Jerry Messina
 
Posts: 280
Joined: Thu Feb 14, 2013 10:16 am

Re: problem reserving memory for the ICD debuggers

Postby David John Barker » Tue Sep 30, 2014 8:09 pm

best place to put startup code is in the "OnStartup" handler, like this
Code: Select all
sub OnStartup() handles Pic.OnStartup
  ' code here
end sub

sub main()
end sub

which ensures that any code in the handler is executed before any module initialisation code.
User avatar
David John Barker
 
Posts: 491
Joined: Thu Nov 08, 2012 12:21 pm

Next

Return to Development Environment

Who is online

Users browsing this forum: No registered users and 2 guests

x