How to avoid CYBLE_ERROR_MEMORY_ALLOCATION_FAILED

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
AnSa_1225656
Level 4
Level 4
50 replies posted 25 replies posted 10 replies posted

This is a followup question to a previous question about timeouts on attribute writes.  Turns out the timeouts are happening because the stack is failing to send the CyBle_GattsWriteRsp (from the Main BLE event handler called by BLE stack) because it fails with CYBLE_ERROR_MEMORY_ALLOCATION_FAILED when in the presence of heavy custom PSM L2CAP traffic.

The question is how can one avoid the CYBLE_ERROR_MEMORY_ALLOCATION_FAILED error?

0 Likes
1 Solution

Hi Andrew,

  Yes. It is expected behavior. When the stack is busy it will report memory allocation failed error as a return value of API which needs internal buffer pools.

Please test the below two scenarios at let me know your observations.

1) Try to increase the BLE stack internal buffer size. For this please refer below steps.

A) In PSoC Creator, go to Tools>Options>Design Entry>Component Catalog and then select Enable Param Edit Views and click OK.

B) Open BLE component configuration( Double Click on BLE component ). Right-click on Advanced Tab and select Expression view.

C) Increase the MaxAttrNoOfBuffer. You can start with 3 or 4 and test.

2) Test by disabling direct L2CAP transmission and see if the issue still persists.

-Gyan

View solution in original post

15 Replies
GyanC_36
Employee
Employee
250 replies posted 100 replies posted 50 replies posted

Hi Andrew,

   Are you making any change in BLE Stack initialization code ?

I see that you are also sending data directly over the L2CAP channels but I could not really think if this can cause the memory allocation error.

Could you please send your simplified project where I can reproduce the issue ?

-Gyan

0 Likes

The client won't allow me to share code publicly.  Is there a way to send directly?  Its actually two fairly large projects.  One on the sensor device and one on the USB receiver dongle.  They both run Free RTOS 10.  I can try and pare things down.

Note: I have been able to work around to some degree (not perfect) by taking the CyBle_GattsWriteRsp outside of the BLE event handler and just setting a flag to have the main task loop send the CyBle_GattsWriteRsp if the flag is set.  I don't like this solution very much because it still fails occasionally and it seems rather kludgey.  I am wondering if this temporary work around might help you to understand what might be going on.  I am having a hard time figuring it out from here since I don't have the BLE stack source available.

0 Likes

Forgot to answer the question about initialization code.  I am using the standard initialization since I am using the Start API.

0 Likes

Hi Andrew,

Ideally the code should look like below code snippet.

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

case CYBLE_EVT_GATTS_WRITE_REQ:

    /*  user action  */

/* Add code to send response to the write request received */

CyBle_GattsWriteRsp(cyBle_connHandle);

break;

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

Could you please try by setting the highest priority to your BLE task in your project ?

-Gyan

0 Likes

Thanks for the suggestion.  Still testing.  Was same priority, but set higher.  It does affect my sample latency now, but I might be able to live with it.  WDT is triggering now, so trying to figure out why that is since the feed WDT is right in the BLE task loop!  I'll add more as I find out more.  Thank you so far for the suggestions.

0 Likes

I disable the WDT around the call to CyBle_GattsWriteRsp  and it looks like the CyBle_GattsWriteRsp hangs when I run with the task at a higher priority.  What could cause it to hang?  Sure wish I had the source code

void StackEventHandler(uint32 event, void* eventParam)

{

  CYBLE_L2CAP_CBFC_CONN_CNF_PARAM_T cbfcResponse; // CBFC (Credit Based FLow Control) response event parameters

  CYBLE_GATTS_WRITE_REQ_PARAM_T *wrReqParam; // Local variable to store the data received as part of the Write request events

  switch(event)

  {

    .

    .

    .

    case CYBLE_EVT_GATTS_WRITE_REQ:

    case CYBLE_EVT_GATTS_WRITE_CMD_REQ:

      wrReqParam = (CYBLE_GATTS_WRITE_REQ_PARAM_T *)eventParam;

    .

    .

    .

      CYBLE_API_RESULT_T result = CyBle_GattsWriteRsp(connHandle); // Send the response to the write request received.

      if (CYBLE_ERROR_OK != result)

      {

        switch (result)

        {

          case CYBLE_ERROR_INVALID_PARAMETER: debugConsole_puts("CyBle_GattsWriteRsp: 'connHandle' value does not represent any existing entry in the Stack");

            break;

          case CYBLE_ERROR_INVALID_OPERATION: debugConsole_puts("CyBle_GattsWriteRsp: This operation is not permitted");

            break;

          case CYBLE_ERROR_MEMORY_ALLOCATION_FAILED: debugConsole_puts("CyBle_GattsWriteRsp: Memory allocation failed");

            break;

          default:

            break;

        }

     }

     break;

    .

    .

    .

}

0 Likes

Last message was a bit premature.  It doesn't hang, it returns the memory allocation error as before.

0 Likes

I think I found something that might be useful.  GyanC_36 can you verify how this should work?

Added the following:

      if (CYBLE_ERROR_OK == CyBle_IsStackIdle())

        debugConsole_puts("BLE is IDLE");

      else

        debugConsole_puts("BLE is BUSY");

inside BLE event handler switch case:

    case CYBLE_EVT_GATTS_WRITE_REQ:

    case CYBLE_EVT_GATTS_WRITE_CMD_REQ:

If it prints B USY, then we get the memory allocation error, otherwise, it seems to work.

0 Likes

Hi Andrew,

  Apologizes for the delayed response. Unfortunately, I missed your response on this thread. 

I could think two possible scenarios which might cause this issue-

1) As I stated earlier as well , a higher priority task might pre-empt the BLE task in between.

2) Yo can try increasing heap size in RTOS config file.

As per your response #5 , I believe that this issue is because of some kind of non synchronization among your tasks.

Could you please share a simplified version of your project where I can reproduce the issue ?

Also, could you please try by disabling the other tasks and run only BLE task and see if the issue still persists?

-Gyan

0 Likes

Gyan,

Thank you so much for getting back to me!  This has been a particularly tricky issue.  Per your suggestion that it might be a higher priority task getting int the way, I have put a counter to check max time between StackEventHandler calls from the CyBle_ProcessEvents.  The CyBle_ProcessEvents is getting called every connection interval (10 mSec) or less.  I added a taskENTER_CRITICAL and taskEXIT_CRITICAL around the CyBle_ProcessEvents to be absolutely certain that it is not being interrupted by another task.  Also made the task running CyBle_ProcessEvents the highest priority task.  I think we can be certain at this point that the BLE service task is running regularly and not being interrupted.

Per your second suggestion, I will look at increasing the heap size.  Do you have a recommendation for heap size?

Also, in my previous post I stated:

Added the following:

      if (CYBLE_ERROR_OK == CyBle_IsStackIdle())

        debugConsole_puts("BLE is IDLE");

      else

        debugConsole_puts("BLE is BUSY");

inside BLE event handler switch case:

    case CYBLE_EVT_GATTS_WRITE_REQ:

    case CYBLE_EVT_GATTS_WRITE_CMD_REQ:

If it prints BUSY, then we get the memory allocation error, otherwise, it seems to work.  Is his expected behavior?

Unfortunately, there is not a good way to simplify the project and still keep the L2CAP communications going behind the scenes.  I will try and see what I can do there, but it is a major rewrite.  Its not a case of simply ripping out stuff

0 Likes

Hi Andrew,

  Yes. It is expected behavior. When the stack is busy it will report memory allocation failed error as a return value of API which needs internal buffer pools.

Please test the below two scenarios at let me know your observations.

1) Try to increase the BLE stack internal buffer size. For this please refer below steps.

A) In PSoC Creator, go to Tools>Options>Design Entry>Component Catalog and then select Enable Param Edit Views and click OK.

B) Open BLE component configuration( Double Click on BLE component ). Right-click on Advanced Tab and select Expression view.

C) Increase the MaxAttrNoOfBuffer. You can start with 3 or 4 and test.

2) Test by disabling direct L2CAP transmission and see if the issue still persists.

-Gyan

Gyan,

Progress.  Increasing the stack buffers to 3 seems to solve the original memory error problem.  It did, however halve my L2CAP throughput.  Why is this?

0 Likes

I want to mark your last response as correct, but I really would like to know if he negative effect on L2CAP throughput is expected behavior from this solution.  If it is, then it is not a solution for my application.

0 Likes

Hi Andrew,

    Ideally increasing #of buffers should not affect the L2CAP throughput very much. I just tested with our existing code example available at Github (PSoC-4-BLE/100_Projects_in_100_Days/Day024_Throughput at master · cypresssemiconductorco/PSoC-4-BLE ... )  and do not see any L2CAP throughput reduction with increasing buffer number. You can try the code example available at above link.

-Gyan

0 Likes

Gyan,

Increasing the BLE stack internal buffer size worked for the problem that I had asked about, so I marked your response as correct.  With your latest suggestion, I'll dig into the throughput issue since it appears to be a separate issue.  Thanks for all your help!

0 Likes