This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

NRF_ERROR_NO_MEM

Hi, I have created up to 5 custom services with several characteristics (4 at maximum) each one. They all use the same base UUID. The problem I'm facing now is that when I execute 'services_init' function, the function 'sd_ble_gatts_service_add' gives error 0x000004 (NRF_ERROR_NO_MEM). I have changed services ordes inside 'services_init' function and then the same error is given but now by the 'sd_ble_gatts_characteristic_add' function. (This is maybe due to the fact that not all the services have the same number of characteristics). Do you know which is the reason of this problem? Best regards, Dani.

Parents
  • ok so there are two places using RAM, one is the heap, do you need a heap at all? If you aren't using malloc or anything which uses malloc(), you don't need it, you can turn it to 0Kb, that saves you 2Kb. (Note: in the projects I've tested 0KB heap is the default, but I don't use Keil so perhaps it's different).

    Now that 5964 bytes of RAM, that's a lot. So you need to figure out what it is. First you need to understand what Zi-data is. It's RAM (i.e. it's memory which can be written) which is set to zero by default at the start of program execution. For instance if you had this line of code in your code

    static uint8_t MY_BIG_BUFFER[ 5694 ];
    

    that would generate 5694 bytes of Zi-Data. Why? Because it's a static buffer, it's writable (not constant) and it has no initialisation which means it's initialized to zero.

    Obviously that's not what you have in your code, Zi-data will come from lots of different places and add up to 5694 bytes, but the general point is there is static, writable zero-filled data and if it's of that kind of size, it's probably array data, so have you added any variables with static arrays? You say for instance that you created 5 custom services, do they have static arrays of data in them?

    If I wanted to find out what was generating this I would go and look at the .map file generated by the linker. I don't know how you do that with whatever tools you're using, but if you can generate one and look at it, you should find the names of the symbols taking up space.

    Finally I will add one piece of confusion. This is all static memory allocation. I would have expected the linker to fail if you used more RAM than was on the device, this looks more like something runtime when you're running out of memory. I did wonder if your services were taking up more than the 700 bytes available for service data, only with the very latest softdevice 8.0.0 can you allocate more than that. I don't know how 5 services with a total of 11 characteristics take up 700 bytes but it's possible, that to me seemed more likely to generate this type of runtime error.

Reply
  • ok so there are two places using RAM, one is the heap, do you need a heap at all? If you aren't using malloc or anything which uses malloc(), you don't need it, you can turn it to 0Kb, that saves you 2Kb. (Note: in the projects I've tested 0KB heap is the default, but I don't use Keil so perhaps it's different).

    Now that 5964 bytes of RAM, that's a lot. So you need to figure out what it is. First you need to understand what Zi-data is. It's RAM (i.e. it's memory which can be written) which is set to zero by default at the start of program execution. For instance if you had this line of code in your code

    static uint8_t MY_BIG_BUFFER[ 5694 ];
    

    that would generate 5694 bytes of Zi-Data. Why? Because it's a static buffer, it's writable (not constant) and it has no initialisation which means it's initialized to zero.

    Obviously that's not what you have in your code, Zi-data will come from lots of different places and add up to 5694 bytes, but the general point is there is static, writable zero-filled data and if it's of that kind of size, it's probably array data, so have you added any variables with static arrays? You say for instance that you created 5 custom services, do they have static arrays of data in them?

    If I wanted to find out what was generating this I would go and look at the .map file generated by the linker. I don't know how you do that with whatever tools you're using, but if you can generate one and look at it, you should find the names of the symbols taking up space.

    Finally I will add one piece of confusion. This is all static memory allocation. I would have expected the linker to fail if you used more RAM than was on the device, this looks more like something runtime when you're running out of memory. I did wonder if your services were taking up more than the 700 bytes available for service data, only with the very latest softdevice 8.0.0 can you allocate more than that. I don't know how 5 services with a total of 11 characteristics take up 700 bytes but it's possible, that to me seemed more likely to generate this type of runtime error.

Children
  • Thank you RK. But there is anything that does not match here. As a comparison:

    • My App --> ZI-Data:5964
    • ble_app_hrs demo --> ZI-Data: 5664
    • ble_app_lbs demo --> ZI-Data: 5880 So, there is no much difference between them in terms of space... So, where is the key of this subject?
  • I just took the ble_app_hrs demo in the 7.2.0 SDK and compiled it 1) with gcc and 2) in Crossworks which is the IDE I use. GCC, with optimization turned off gives me

     text	   data	    bss	    dec	    hex	
    34016	    100	   1892	  36008	   8ca8	
    

    Crossworks gives me similar code size and 1776 bytes of bss. BSS is Zi, it's the zeroed data. So I don't know where your 5880 is coming from, I don't get anything like that much.

    I've stopped believing this is the problem. If there was too much static RAM usage the link should fail or the program would crash, the softdevice doesn't use any heap at all anyway so it's not dynamically allocating memory so this isn't a malloc() failure. I can only think you are exhausting a fixed buffer in the softdevice, the only one of those I know of is the 0x700 byte limit for GATT server table but there might be others.

  • .. and I wish comments weren't so limited to 900 chars ..

    So I'd try removing a service or characteristic until it doesn't crash, you may be right on the limit and just removing one or two would work.

    The new Softdevice 8.0.0 allows you to change that 0x700 byte limit. You could try that, although there's so many changes in that version and the SDK isn't out yet you may run into other issues, probably better to wait for SDK v8

    I don't have the code for the softdevice else I could look at see exactly in what circumstances NRF_ERROR_NO_MEM is returned from those two calls. Basically that's a controlled error message, so it's an internal check inside the softdevice against its own memory usage.

  • Yesterday I spent all day trying to make the Keil working with GCC but I have not succeeded. Do you have any guide explaining how to setup GCC/CNU with Keil? Furthermore, at the same time, I have built the same ble_app_hrs in another computer with Keil (keil compiler) and I get the same results I wrote some comments above: 5664 in ZI-Data. Do you know what is the reason of such figures?

  • Don't have Keil - don't use Keil, no interest in Keil at all, know absolutely nothing about the product. I don't even know if you can make Keil work with GCC or not, I thought it used its own internal compiler.

    Either way this still isn't the problem, the softdevice is running out of memory inside the softdevice, which is why it's reporting the out of memory condition. The size of your code doesn't affect the softdevice, it uses 8Kb in a fixed place, it doesn't allocate dynamic memory so the only way it can report that it's out of memory is because it's run out of memory out of its fixed allocation.

    Have you yet tried removing services and characteristics until you don't run out of memory?

Related