Can I use Heap Memory in CyBle_GattsNotification() API ?

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

cross mob
shrac_2642471
Level 4
Level 4
5 likes given First like received First like given

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

0 Likes
10 Replies
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

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

0 Likes

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); 
0 Likes

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

0 Likes

I cannot see anything wrong at first sight.

Bob

0 Likes

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

0 Likes
Anonymous
Not applicable

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...

0 Likes

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

Bob

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.

0 Likes
Anonymous
Not applicable

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

0 Likes

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.