Configure a larger heap on the nRF51 devices

I know the nRF51 MCUs are outdated but I am having issues trying to allocate some space on the heap, and it does not appear that its a memory limitation given the size. Here are the results from the Keil compile:

Program Size: Code=28132 RO-data=1916 RW-data=500 ZI-data=6908  

Yet as I step through the code during setup, I am getting calloc returning NULL. The size of the item being calloced is not large. Is there a way to configure more space on the heap? Perhaps one of the 1000's of possible parameters in the sdk.config?

I am using just SoftDevice for bluetooth and flash. I am using the latest possible version of both SoftDevice and the SDK for the nRF51x platform.

  • As it turns out I am not using CODE_END. I am doing the following in the nRF52 SDK

        uint32_t pg_size = NRF_FICR->CODEPAGESIZE;
        uint32_t pg_num  = NRF_FICR->CODESIZE - (NRF_FICR->CODESIZE * pg_size - 0xE0000) / pg_size;
        
        // Okay, what are we doing here. On the dongle, the bootloader occupies flash above 0xE0000. So I have to find how big flash is,
        // subtract 0xE0000 from it, find the number of pages there, and then subtract that number of pages from the total. THAT gives the
        // page where the boot record starts (0xE0000). Now I have to drop a few pages to where I can start. I drop two pages here
        // I still don't know how to dynamically find the page at the top of MY app which gives the
        // area of free flash between my app and the bootloader at the top. The DK, by the way, has no bootloader so I don't need all this.
    
        NRF_LOG_INFO("Total pages is %u, pg_num is %u pg_size is %u", NRF_FICR->CODESIZE, pg_num, NRF_FICR->CODEPAGESIZE);
        pg_num = pg_num - 2;

    Still not good as there is probably a lot more flash available to me.

    For the CODE_END I see lots of options but using segger emb stud I see

    #elif defined(__SES_ARM)
    extern uint32_t * _vectors;
    extern uint32_t __FLASH_segment_used_end__;
    #define CODE_START ((uint32_t)&_vectors)
    #define CODE_END   ((uint32_t)&__FLASH_segment_used_end__)
    #define CODE_SIZE  (CODE_END - CODE_START)

    Should that be the location of where I start writing to flash? Would that always be a page boundary or do I need to calculate that?

    How would the macro differ if I were using nRF51 (where I am having the problem)?

    I increased the HEAP size and all my problems went away.

  • I did increase the HEAP size but I did it directly in the assembly code. I also needed to increase the STACK size for another version of the model but again, I did it directly in the code. When I looked at the preprocessor defines for my settings, their was neither a HEAP or STACK size option present. If I use the preprocessor above will that override the values in code?

    What is the preprocessor for STACK size?

  • brianreinhold said:
    Should that be the location of where I start writing to flash? Would that always be a page boundary or do I need to calculate that?

    CODE_END returns the address of where the application FW ends in flash, which typically is not on a page boundary. But you can use the ALIGN_NUM() macro to calculate the next page aligned address.

    Something like this may work:

     uint32_t application_end = ALIGN_NUM(NRF_FICR->CODEPAGESIZE, CODE_END)

    brianreinhold said:
    How would the macro differ if I were using nRF51 (where I am having the problem)?

    The macro is the same, but the implementation of it is different as you are using Keil uVision (__CC_ARM) now. 

    brianreinhold said:
    What is the preprocessor for STACK size?

    __STACK_SIZE

Related