Author Topic: pucTopOfHeap, ucTopOfStack, and OUR_HEAP_SIZE  (Read 6846 times)

Offline Richard

  • Newbie
  • *
  • Posts: 44
    • View Profile
pucTopOfHeap, ucTopOfStack, and OUR_HEAP_SIZE
« on: June 07, 2009, 07:12:35 AM »
Hi, Mark.

So far as I can tell, ucTopOfStack, defined as an unsigned char in fnInitialiseHeap(), is never actually used.  Only its address is ever referenced, here in this
Code: [Select]
while (ucPattern <= &ucTopOfStack) {                                 // this pattern is used later for Stack use monitoring
    *ucPattern++ = UNUSED_STACK_PATTERN;
}
Apparently, the compiler never actually allocates a location for the variable.  Indeed, it does not appear in uTasker_full.elf.xMAP.  The result is that the while loop that is supposed to fill the heap with UNUSED_STACK_PATTERN doesn't do anything.

Did I miss something?

I found this because, in my program,
Code: [Select]
pucTopOfHeap += ctOurHeap->need_this_amount;
causes pucTopOfHeap to be set to 0x20008340.  Since there is no memory there, calling fnStackFree() fails with an access error exception on an operand read.  If the while loop in fnInitialiseHeap() actually did anything, an access error would have occurred at that point, as the program was starting up.

My next question is this: can I safely reduce the value of OUR_HEAP_SIZE below the 21K it is set to and by how much?

Since I'm using CodeWarrior and use only uMalloc() and never malloc(), it looks like I can change HEAP_SIZE = 0x1000; to HEAP_SIZE = 0; in M52235EVB_FLASH.lcf.  The note in the file is a little difficult to interpret: by "This can be left as zero..." do you mean that it can be reduced to zero?  If so, it may be enough to save me without reducing OUR_HEAP_SIZE ... for now.

Thanks,
    Richard

P.S. Thinking about your comment,
Quote
If the pattern is not being set it suggests that its address is below the top of heap (system variables plus OUR_HEAP_SIZE)
I've modified the code in fnInitialiseHeap() to be
Code: [Select]
if (pucTopOfHeap <= &ucTopOfStack) {
    while (ucPattern <= &ucTopOfStack) {                                 // this pattern is used later for Stack use monitoring
        *ucPattern++ = UNUSED_STACK_PATTERN;
    }
}
else                   // not enough memory for heap!
    while (1) {}; // hang here to make the problem obvious while debugging.
« Last Edit: June 07, 2009, 07:35:15 PM by Richard »

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3234
    • View Profile
    • uTasker
Re: pucTopOfHeap, ucTopOfStack, and OUR_HEAP_SIZE
« Reply #1 on: June 07, 2009, 12:30:59 PM »
Hi Richard

See:
extern void fnInitialiseHeap(const HEAP_NEEDS *ctOurHeap, void *HeapStart)
{
    unsigned char *ucPattern;
    unsigned char ucTopOfStack;                                          // put a temporary variable on stack


ucTopOfStack is a local variable that only exists when the function fnInitialiseHeap() is executed. The variable is on the stack and so its address represents the stack pointer address while this function is executing. It will therefore not appear in the map file.

It is used to set a pattern to all memory between the top of heap and the present stack pointer so that the use of the stack can be later monitored (any addresses which are not still at this pattern value are considered to have been used; this is checked when the routine fnStackFree() is called.

If the pattern is not being set it suggests that its address is below the top of heap (system variables plus OUR_HEAP_SIZE). This may happen if you have added large amounts of new variables (in relation to the SRAM size that is) and it looks to be so since your top of heap is outside the 32K RAM area (assuming you are not using a Kirim3 with up to 64k SRAM).

Reducing OUR_HEAP_SIZE is of course possible and it will then ensure that the first problem doesn't occur - you will however need to ensure that the smaller size is still adequate for the system uMalloc() and your own uMalloc() use. This can be checked (when the system runs - assuming it can run) by calling fnHeapFree() and fnStackFree(), whereby fnStackFree() should always have a non-zero value when the system operates (using all features). See also http://www.utasker.com/forum/index.php?topic=468.0




The HEAP_SIZE can be reduced to 0 when malloc() is not used (only uMalloc()). It seems a recent SP had this set to non-zero by default, which was not intended. This is also discussed here: http://www.utasker.com/forum/index.php?topic=598.0

This will probably give you adequate SRAM again and the you can regularly monitor the memory use (using functions above) to see whether it is becoming critical as further code is added.

Regards

Mark




Offline Richard

  • Newbie
  • *
  • Posts: 44
    • View Profile
Re: pucTopOfHeap, ucTopOfStack, and OUR_HEAP_SIZE
« Reply #2 on: June 07, 2009, 06:56:02 PM »
Hi, Mark.  Thanks for the very fast and helpful response.

I should be more careful about writing emails well after midnight (my time).  In particular, I should have realized why ucTopOfStack doesn't show up in uTasker_full.elf.xMAP; but even with a full night's sleep, I still can't explain why the CW7.1 debugger displays it without any address.

Even if I eventually have to reduce OUR_HEAP_SIZE, I doubt I'll run out of heap very soon.  I no longer use uMalloc() to obtain RAM space for parameter blocks, reducing the amount of required heap space by PAR_BLOCK_SIZE.  I'll post some more information to http://www.utasker.com/forum/index.php?topic=574 to explain what I did instead.

Cheers,
    Richard