GP32 Perform A Stack Analysis


I downloaded some code which is a minimum real time threading operating system for embedded and low memory 8bit -> 32bit systems, and it has a document with it to help you port it to other platforms (it's already been ported to quite a few). The document references a 'stack analysis' of compiled code on numerous occasions:

Code:
PORTING XMK TO A NEW HARDWARE PLATFORM
==============================================================================
General instructions porting XMK to a target  platform.  NOTE: ONLY the
services listed in this file have dependencies on the target platform and
require porting.


Porting the Kernel (xmk/kernel.h)
------------------------------------------------------------------------------
TIP: Use the xmk/platform/hitachi/h8300l/kernel as your example and/or guide!

1. Create a new platform specific directory tree under the xmk/platform/
   directory.

2. If neccesary provide any platform specific modfications to XMK's 
   basic types (xmk/types.h).  This modification should be in a single
   header file somewhere in your platform directory tree.  It will eventually
   be included by the project's xmkcfg.h header file.

3. The following platform specific methods must be implemented.
        PAL__XMK_disableInts()
        PAL__XMK_enableInts()
        PAL__XMK_areIntsEnabled()
        PAL__XMK_createThreadStackFrame(t,f,s);
        PAL__XMK_fromThreadContextSwitch()  
        PAL__XMK_fromISRSwitchContext()
        PAL__XMK_startIdle()
    Typically, enable/disable interrupts will map to inlined assembly
    or compiler specific intrinsic functions.  The remaining functions will
    probably need to implemented in assembly (with the possible exception of
    PAL__XMK_createThreadStackFrame()).

4. Define the macro _XMK_TOP_OF_STACK(b,s).  This macro is platform specific
   since it contains the information if the stack uses a pre/post decrement
   scheme.

5. Create two interrupt vectors stubs to be used as the templates for building
   the application's interrupt vector table.  One template for non-nested
   interrupts, and the second for nested interrupts.  This will typically be
   done in assembler.

6. Perform a stack analysis on the platform specific code to provide the 
   the values for the following #defines (in .../palkrn.h):
        XMK_ISR_KERNEL_OVERHEAD     
        XMK_ADDER_STACK_APP_THREAD  
        XMK_ADDER_STACK_IDLE_THREAD 

7. Perform a stack analysis on the compiled code of ./schpri/... directories to 
   provide the platform specific value for the following #define (in the
   src/config/<platform>/pal-<xxxx>.h header file):
        XMK_ADDER_SCHPRI_ISR_STACK



Porting the System Timer (xmk/tmsys.h)
------------------------------------------------------------------------------
TIP: Use the xmk/platform/hitachi/h8300l/tmsys as your example and/or guide!

1. Create a new platform specific directory tree under the xmk/platform/
   directory.  The new directory should be a peer to the 'kernel' directory
   created when porting the scheduler.

2. The only platform dependent code for System Timer is in suppling the
   templates for the ISR that drives the timer.  Create two interrupt vectors 
   stubs (non-nested and nested) to be used as the templates for building the 
   application's ISR that is used for the system timer.

3. Perform a stack analysis on the compiled code of _Xmk_sysTickISR() to 
   provide the platform specific value for the following #define (in the
   src/config/<platform>/pal-<xxxx>.h header file):
        XMK_ADDER_TMSYS_ISR_STACK



Porting the System Timer (xmk/sleep.h)
------------------------------------------------------------------------------
TIP: Use the xmk/config/hitachi/pal-h8300l-hew2.h as your example and/or guide!

1. There is no platform dependent code for this interface.
2. Perform a stack analysis on the compiled code of _Xmk_sysTickISR() to 
   provide the platform specific value for the following #define (in the
   src/config/<platform>/pal-<xxxx>.h header file):
        XMK_ADDER_SLEEP_ISR_STACK



Porting the Extended Thread Interface (xmk/xthread.h)
------------------------------------------------------------------------------
TIP: Use the xmk/platform/hitachi/h8300l/xthread as your example and/or guide!

1. Create a new platform specific directory tree under the xmk/platform/
   directory.  The new directory should be a peer to the 'kernel' directory
   created when porting the scheduler.

2. The following platform specific methods must be implemented.
        PAL__XMK_createThreadStackFrameEx()
    PAL__XMK_createThreadStackFrameEx() is very similar to 
    PAL__XMK_createThreadStackFrame(), except that it has the added 
    responsiblity of pushing a thread-exit-handler onto the stack frame.
    It is recommended that you create a method: PAL__Xmk_pushExitHandler(),
    that just creates the necesarry stack frame for an exit-handler.  Then
    the implementation of PAL__XMK_createThreadStackFrameEx() is simply a matter
    of first calling PAL__Xmk_pushExitHandler() and then calling
    PAL__XMK_createThreadStackFrame().

3. Perform a stack analysis on the thread-exit-handler to provide the 
   the values for the following #defines (in .../palxthr.h):
        XMK_STACK_EXIT_HANDLER   


Setting the platform specific configuration
------------------------------------------------------------------------------
Provide the default platform speficic config header file and build list for 
the new platform.  These confg files will be located under the 
src/xmk/config/ directory tree.  

TIP: Use src/xmk/config/hitachi/pal-h8300l-hew2.[h|b] as an examples.
 
Looks like its working out how much the compiler puts on the stack for a number of simple function calls. e.g. ISR routine. So I guess you'd have to disassemble and look at how many bytes the code pushes onto the stack.

This may also be of use:
What are and how are the "_XMK_xxxx_STACK" macros defined?

These macros are used to calculate the amount of stack overhead that is required by 1) the context registers; and 2) the XMK's calling sequence when doing context switches from an ISR and/or from a thread. This overhead becomes the absolute minimum size for a thread's stack. These macros are also compiler specific because they depended on the compiler's ABI.

_XMK_1LEVEL_ISR_STACK - This is the size, in bytes, of the stack frame that is generated when an interrupt occurs, i.e. what is pushed onto the stack by the hardware and the prolog of the interrupt service routine. It includes: the return address, the program status word, and the volatile hardware registers

_XMK_ISRHOOK_STACK - This is the amount of overhead, in bytes, required by XMK's ISR stubs. Typically it is only the size of a 'return address' since the XMK stub calls the applications ISR.

_XMK_ISR_SWITCH_GETNEXT - This is the amount of stack, in bytes, required by XMK's function: Xmk_getNext(). Xmk_getNext() returns the thread handle of the new thread when a context is performed. Typically this is only the size of a 'return address' since the function has no functions args, no local variables, and has minimal code (i.e. all the work can be done using the volatile hardware registers - this is all up to the compiler though).

_XMK_ISR_KERNEL_WAKEUP - This the amount of stack, in bytes, required by XMK's function: Xmk_requestContextSwitch(). This method is called internally when an ISR 'wakes-up' a thread. Typically this is only the size of a 'return address' since the function has no functions args, no local variables, and has minimal code (i.e. all the work can be done using the volatile hardware registers - this is all up to the compiler though).

_XMK_GP_STACK - This is the size, in bytes, of the non-volatile hardware registers.

Course the whole thing looks like its intended for hardware much less powerful than the GP32. That said I didn't look at the site much!

Good luck!

Mark
 
Yeah, it is intended for very low-spec hardware, but says it was designed to also work (and work even better) on 16 and 32 bit systems.

I think at the moment it all looks a bit much for me. It may have to wait for a few applications down the track until I have more experience... unless someone happens to port it to the GP32 before then :) :p
 
Back
Top