This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC2540 Memory Limitations

Other Parts Discussed in Thread: CC2540

I am working on a system with both Peripheral and Central devices. I am close to having implemented all required functionality and have used the simpleBLECentral and simpleBLEPeripheral examples as a basis.

I have recently hit the available memory limit for the CC2540 on the peripheral side. I have not changed the OSAL heap size and my application allocates all arrays and large data structures using osal_mem_alloc() to minimize usage of memory outside the heap. My application does not have excessive memory use outside the heap.

It appears the BLE stack, particularly the link layer uses a fair chunk of memory outside the heap no doubt for link buffers etc.

Two questions arise:

1. What are the consequences of reducing the heap size by say a few hundred bytes.

2. Which variables in the project settings and within the code itself need to be changed? Should all of the Far:, Far22 and Huge values be changed from 0xFFF to a smaller value?

Thanks

  • Hello,

    For the BLEv1.1 stack, the code size of the stack + profiles + simple application + OSAL + HAL is somewhere in the range of 100-120kB. In BLEv1.2 it will be more configurable, with a pure broadcaster or observer stack size being around 40k, with master / slave around 120k, and a full featured stack (supports master or slave role; this is new for BLEv1.2) consuming around 140k.

     As far as RAM goes, changing INT_HEAP_LEN is just for heap memory (for dynamic allocation) that’s managed by OSAL. The BLE stack uses dynamic allocation for a few functions- primarily for performing encryption and for storing security keys. If you reduce the heap size too much, encryption will fail. Now think about a central role device that can connect to three simultaneous peripherals with encryption on all three links. Here the heap size needs to be particularly large to support that. There isn’t much room left for the application when doing this…

     The rest of the RAM is just used for static variables used by the BLE stack and other parts of the software, and also some RAM is set aside for the data stack.

    BR

    Greg

  • Thanks Greg,

    I understand how the memory is split between the OSAL, stack and static variables, but was really looking for some real data points around how much heap is consumed for a single master / slave link and by how much the memory usage would increase with each additional connected device. I guess this would also depend on the nuber and size of attributes exposed in the connection.

    What is the reason for the 20 byte limit for attributes? Is this an artificial limit to conserve resources or is there another reason? Is there any plans to increase this limit?

    Also, Is there any update on the v1.2 release?

    Thanks

  • Hi Michael,

    Michael Gormack said:
    What is the reason for the 20 byte limit for attributes?

    That's due to the LL2CAP layer which only allows 23 Bytes per channel. The main reason, I believe, is to minimize the data OTA since BLE is design to send as little data as possible giving a low power consumption. You can read more about this in the BT Core Specification.

    Michael Gormack said:
    Is there any plans to increase this limit?

    I do not think BT SIG are working on anything like that. Do note that you can use blob read/write for longer data, even though it will split the data into smaller chunks to pass through LL2CAP.

    BR

  • I think the BT SIG is not going to change this at all.

    In fact, my boss is doing some IP over BLE things with some IEEE guys and they are working having this limitation into account.

    Bye.

  • Thanks Nick,

    I read that the Max Attribute length is 512B and assumed this could possibly be transmitted in one go, but I see now it has to be broken up. It seems strange the BT designers would have such a low maximum given the 1Mbps speed of the LL. I understand this is for low power consumption, but even a modest increase in this would have a major impact on data rate, and of course the designer could slow down the connect rate to improve power consumption where necessary.

    I can only find the BLOB read in the API - ATT_ReadBlobRsp (uint16 connHandle, attReadBlobRsp_t *pRsp). How would I go about using a BLOB read/write? I cant seem to find much information anywhere as to how BLOB reads and writes are done.

    Currently I am using GATT_WriteCharValue() and application to stream data to the Server and I am getting a max of 1.1KB/s with connect interval set to 6 (minimum connect interval - any lower and connect interval goes back to 100ms). Would the BLOB functions offer any improvement on this?

    I have tried the GATT_WriteNoRsp (uint16 connHandle, attWriteReq_t *pReq) to speed things up but get an INVALIDPARAMETER error - any ideas why this is happening?

    Finally I am now working on notifications to send data in the other direction - hopefully faster.

  • Hi Michael,

    Michael Gormack said:
    How would I go about using a BLOB read/write? I cant seem to find much information anywhere as to how BLOB reads and writes are done.

    You can use GATT_WriteLong to write up to 512 Bytes and to read a long attribute you would use the ATT_ReadBlobReq

    Michael Gormack said:
    Currently I am using GATT_WriteCharValue() and application to stream data to the Server and I am getting a max of 1.1KB/s with connect interval set to 6 (minimum connect interval - any lower and connect interval goes back to 100ms). Would the BLOB functions offer any improvement on this?

    I think you are actually sending 22 Bytes per packet if you are using blob, so maybe. Have a go and share your results :) Note that with a 6 (9ms) connection interval you should be able to send with a data rate around ~2.2B/s, with 20Bytes packet each connection interval. Have you tested the sniffer to see if data is sent every connection interval?

    Michael Gormack said:
    I have tried the GATT_WriteNoRsp (uint16 connHandle, attWriteReq_t *pReq) to speed things up but get an INVALIDPARAMETER error - any ideas why this is happening?

    Maybe you set up the pReq wrong, in this thread: http://e2e.ti.com/support/low_power_rf/f/538/t/158542.aspx#602821, Sasha suggests the following setup:

    attWriteReq_t writeReq;
    writeReq.handle = handle;
    writeReq.len = msgSize + 1;
    writeReq.sig=0; 
    writeReq.cmd = 1;//ATT_WRITE_REQ;  
    GATT_WriteNoRsp( 0, &writeReq)

    Try that.

    Br

  • Hi! I am new to CC2540. I am trying to modify simpleBLECentral.c to send/receive multiple bytes of data at once. I read up to 20bytes can be sent using GATT_WriteLongCharValue() but I am not sure how. Can anyone please explain. It will be a great help. Thank you.

  • Hi all!

    Sorry for the late answer but a good working example of this can be found in:

    http://e2e.ti.com/support/low_power_rf/f/538/t/221165.aspx

    Now I'm able to work with BLOBs.