1 2 Previous Next 15 Replies Latest reply on Jun 12, 2019 7:28 AM by AnSa_1225656

    How to avoid CYBLE_ERROR_MEMORY_ALLOCATION_FAILED

    AnSa_1225656

      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?

        • 1. Re: How to avoid CYBLE_ERROR_MEMORY_ALLOCATION_FAILED
          GyanC_36

          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

          • 2. Re: How to avoid CYBLE_ERROR_MEMORY_ALLOCATION_FAILED
            AnSa_1225656

            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.

            • 3. Re: How to avoid CYBLE_ERROR_MEMORY_ALLOCATION_FAILED
              AnSa_1225656

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

              • 4. Re: How to avoid CYBLE_ERROR_MEMORY_ALLOCATION_FAILED
                GyanC_36

                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

                • 5. Re: How to avoid CYBLE_ERROR_MEMORY_ALLOCATION_FAILED
                  AnSa_1225656

                  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.

                  • 6. Re: How to avoid CYBLE_ERROR_MEMORY_ALLOCATION_FAILED
                    AnSa_1225656

                    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;

                        .

                        .

                        .

                    }

                    • 7. Re: How to avoid CYBLE_ERROR_MEMORY_ALLOCATION_FAILED
                      AnSa_1225656

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

                      • 8. Re: How to avoid CYBLE_ERROR_MEMORY_ALLOCATION_FAILED
                        AnSa_1225656

                        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.

                        • 9. Re: How to avoid CYBLE_ERROR_MEMORY_ALLOCATION_FAILED
                          GyanC_36

                          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

                          • 10. Re: How to avoid CYBLE_ERROR_MEMORY_ALLOCATION_FAILED
                            AnSa_1225656

                            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

                            • 11. Re: How to avoid CYBLE_ERROR_MEMORY_ALLOCATION_FAILED
                              GyanC_36

                              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

                              1 of 1 people found this helpful
                              • 12. Re: How to avoid CYBLE_ERROR_MEMORY_ALLOCATION_FAILED
                                AnSa_1225656

                                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?

                                • 13. Re: How to avoid CYBLE_ERROR_MEMORY_ALLOCATION_FAILED
                                  AnSa_1225656

                                  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.

                                  • 14. Re: How to avoid CYBLE_ERROR_MEMORY_ALLOCATION_FAILED
                                    GyanC_36

                                    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 · GitHub )  and do not see any L2CAP throughput reduction with increasing buffer number. You can try the code example available at above link.

                                     

                                    -Gyan

                                    1 2 Previous Next