10 Replies Latest reply on May 18, 2018 7:02 AM by e.pratt_1639216

    Can I use Heap Memory in CyBle_GattsNotification() API ?

    shreyas.ravindra_2642471

      Hi Guys,

      I am using C++ in PSoC project as a software programming language and I am using PSoC Creator 3.3 for my PSoC 4200 Chip. I am trying t send the data from my BLE device to the mobile phone with the following API -->

      bool IonicDataController::SendIonicSessionData()
      {
           int bufferLength = 0x0; 
           nt lastPackage = 0x0;
           int mtuSize = 0x0; 
           int i = 0x0; 
           uint8* ptrToBuffer= NULL; 
           mtuSize = GetMTUSize();
           if(mtuSize <=3)
           {
                tracer.Trace()<<"Invalid MTU size";
           }
           ptrToBuffer = (uint8*)buffer;
           tracer.Trace()<< "IONIC :: SendIonicSessionData "; 
           bufferLength= strlen((const char*)buffer);
           mtuSize -= MTU_OPCODE_BYTES;
           tracer.Trace()<<"SHREY:: mtuSize ="<<mtuSize;
           lastPackage = (bufferLength + mtuSize - 1)/mtuSize;
           tracer.Trace()<<"SHREY:: lastPackage ="<<lastPackage; 
           for(i=0; i<lastPackage; i++)
           {
                char *partofDataBuffer = new char[mtuSize+1];
                if(NULL== partofDataBuffer)
                {
                     tracer.Trace()<<"ERROR allocating buffer";
                     return false; 
                }
                //if successful memory allocation
                memset(partofDataBuffer, 0x0, sizeof(partofDataBuffer));
                memcpy(partofDataBuffer, &ptrToBuffer[i*mtuSize], sizeof(char)*mtuSize);
                CYBLE_GATT_HANDLE_VALUE_PAIR_T handleVal;
                handleVal.attrHandle = CYBLE_FEED_TX_CHAR_HANDLE;
                handleVal.value.val = (uint8*)partofDataBuffer;
                handleVal.value.len = strlen((const char*)partofDataBuffer);
                while (CyBle_GattGetBusyStatus() != CYBLE_STACK_STATE_FREE)
                {
                     CyBle_ProcessEvents();
                }
                if(CyBle_GattsNotification(cyBle_connHandle, &handleVal)!= CYBLE_ERROR_OK)
                {
                     tracer.Trace()<<"Packet Transmission Error = " << i; 
                }
                delete[] partofDataBuffer; 
           }
           return true;
      }
      

      As you guys are aware that some of the phones support an MTU size of 20Bytes only. Now can I create a temporary buffer in the heap to send these 20 byte packets? I see that when I do that, the data transmission over BLE is intermittent. I can see that the first 2 packets of 20 byte goes, however the rest of the packets don't go.

       

      With the above code, I am trying to send 78 Bytes of data

      Now, this means I need to send five 20 Byte packets, assuming MTU size is 23 bytes.

      Packet 0 is successfully transferred

      and Packet 1 is successfully transferred after that it fails.

       

      However if I use a stack memory in the above snippet, everything works! Do you know why?

       

      Regards,

      Shrey

        • 1. Re: Can I use Heap Memory in CyBle_GattsNotification() API ?
          bob.marlowe

          It is always easier for us when you upload your complete project.

          Did you set the heap size to something like 0x0200 (in System view)?

          PSoC Creator 3.3 is very old and partly outdated. I strongly suggest you to upgrade to current version which is 4.2 at this time (co-existent with v3.3)

           

          Bob

          • 2. Re: Can I use Heap Memory in CyBle_GattsNotification() API ?
            shreyas.ravindra_2642471

            Hi bob.marlowe

            I cannot really upload my entire project here as it is more confidential. I see that I have enabled the Heap. 

            Flash used: 234240 of 262144 bytes (89.4 %). Bootloader: 16384 bytes. Application: 217600 bytes. Metadata: 256 bytes.

            SRAM used: 28796 of 32768 bytes (87.9 %). Stack: 2048 bytes. Heap: 2048 bytes.

            I can understand and download PSoC creator 4.2, however my project is thoroughly tested with PSoC Creator 3.3 and close to the launch I don't want to risk it by migrating it to a new Creator version.

             

            Basically when I pass a dynamically allocated buffer in the snippet below, I am getting problems. The data transfer doesn't really happen as expected

             

            1.           CYBLE_GATT_HANDLE_VALUE_PAIR_T handleVal; 
            2.           handleVal.attrHandle = CYBLE_FEED_TX_CHAR_HANDLE; 
            3.           handleVal.value.val = (uint8*)partofDataBuffer; 
            4.           handleVal.value.len = strlen((const char*)partofDataBuffer); 
            • 3. Re: Can I use Heap Memory in CyBle_GattsNotification() API ?
              shreyas.ravindra_2642471

              I also see that the standard C++ new and free is not supported in PSoC creator

               

              So I have to sort of improvise

               

              #ifdef FEATURE_DYNAMIC_MTU_SUPPORT
              void * operator new[](size_t size)
              {
                  return malloc(size);
              }
              
              void operator delete[](void * ptr)
              {
                  free(ptr);
              }
              #endif
              
              • 4. Re: Can I use Heap Memory in CyBle_GattsNotification() API ?
                bob.marlowe

                I cannot see anything wrong at first sight.

                Bob

                • 5. Re: Can I use Heap Memory in CyBle_GattsNotification() API ?
                  shreyas.ravindra_2642471

                  The surprising part is as soon as I make the buffer in STACK, everything works

                  bool IonicDataController::SendIonicSessionData()
                  {
                  #ifdef FEATURE_DYNAMIC_MTU_SUPPORT
                      int bufferLength = 0x0;
                      int lastPackage = 0x0;
                      int mtuSize = 0x0;
                      int i = 0x0;
                      uint8* ptrToBuffer= NULL;
                      mtuSize = GetMTUSize();
                      if(mtuSize <=3)
                      {
                            tracer.Trace()<<"Invalid MTU size";
                      }
                      ptrToBuffer = (uint8*)buffer;
                      tracer.Trace()<< "IONIC :: SendIonicSessionData ";
                      bufferLength= strlen((const char*)buffer);
                      mtuSize -= MTU_OPCODE_BYTES;
                      lastPackage = (bufferLength + mtuSize - 1)/mtuSize;
                      for(i=0; i<lastPackage; i++)
                      {
                            char partofDataBuffer[mtuSize + 1];
                            memset(partofDataBuffer, 0x0, sizeof(partofDataBuffer));
                            memcpy(partofDataBuffer, &ptrToBuffer[i*mtuSize], sizeof(char)*mtuSize);
                            CYBLE_GATT_HANDLE_VALUE_PAIR_T handleVal;
                            handleVal.attrHandle = CYBLE_FEED_TX_CHAR_HANDLE;
                            handleVal.value.val = (uint8*)partofDataBuffer;
                            handleVal.value.len = strlen((const char*)partofDataBuffer);
                            while (CyBle_GattGetBusyStatus() != CYBLE_STACK_STATE_FREE)
                            {
                                CyBle_ProcessEvents();
                            }
                            if(CyBle_GattsNotification(cyBle_connHandle, &handleVal)!= CYBLE_ERROR_OK)
                            {
                                tracer.Trace()<<"Packet Transmission Error = " << i;
                            }
                      }
                      return true;
                  #endif
                  }
                  

                  I am not sure why this happens.

                   

                  Regards,
                  Shrey

                  • 6. Re: Can I use Heap Memory in CyBle_GattsNotification() API ?
                    e.pratt_1639216

                    I'm not sure, but I think dynamic memory allocation doesn't work in the PSoC Creator? I tried it at one point and ran into a wall of being unable to allocate/deallocate memory. The compiler underneath is the GNU/GCC compiler, so I would expect it to work, but I think the PSoC Creator overrides non-compile-time constant functions/memory which prevents mallocs from working.

                    That would explain why allocating your buffers to the stack works...

                    • 7. Re: Can I use Heap Memory in CyBle_GattsNotification() API ?
                      bob.marlowe

                      I wrote an RTOS running on PSoC4 using lots of malloc() and free(). Only sprintf() with floats didn't work...

                       

                      Bob

                      1 of 1 people found this helpful
                      • 8. Re: Can I use Heap Memory in CyBle_GattsNotification() API ?
                        shreyas.ravindra_2642471

                        e.pratt_1639216

                        The memory allocation on the heap works and Cypress PSoC also provides the capability for us to create new() and delete() operator in C++ using a user defined function as is shown in the below snippet.

                         

                        #ifdef FEATURE_DYNAMIC_MTU_SUPPORT
                        void * operator new[](size_t size) 
                        { 
                            return malloc(size); 
                        } 
                        
                        void operator delete[](void * ptr) 
                        { 
                            free(ptr); 
                        }
                        #endif
                        

                        My problem however is when I pass this buffer to BLE controller, the data transfer doesn't happen completely. For example if I have MTU size of 20 bytes and I have say 10 packets to transfer, I can only transfer 2 packets and rest doesn't transfer. However if I allocate the memory on Stack and then pass that buffer to BLE controller, then the transfers work as expected. I am not sure internally (hardware side) if the BLE controller has some sort of limited memory access to HEAP memory or not. Or there is some bug in the bus that the access is lost after sometime.

                        1 of 1 people found this helpful
                        • 9. Re: Can I use Heap Memory in CyBle_GattsNotification() API ?
                          shreyas.ravindra_2642471

                          bob.marlowe

                          You are right malloc() and calloc() and free() functions work. My problem with this is just that when I pass the memory created using this to BLE controller, the data transfers become highly intermittent.

                          • 10. Re: Can I use Heap Memory in CyBle_GattsNotification() API ?
                            e.pratt_1639216

                            Hmmm; Not sure why I ran into trouble with it before then