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 Chan's FatFS memory issues

Other Parts Discussed in Thread: CC2540, CC2541, CC2640

Hello everyone.

I am currently developing on CC2540. I have a custom board with a serial port peripheral and an SDCard reader peripheral. I have successfully developed serial port communication and BLE relay on my main project, and have a lot of logic there that is not easily portable.

Separately, on another project based on SimpleBLEPeripheral example, I have enabled SD-SPI communication using bit-banging (I enable SPI Master mode, initialize the card, and then set SPI to faster speeds). It's important to mention that I have commented out "SimpleBLEPeripheral_Init(uint8 task_id)" and "SimpleBLEPeripheral_ProcessEvent" for my tests, since I didnt need the functionality provided by the examples, just the testbench they provided. I then managed to get Chan's FatFS library working with this SD-SPI implementation (interfacing with mmc.h, more details here: http://elm-chan.org/fsw/ff/en/appnote.html).

I can do everything FatFS related, opens, reads, writes, seeks, etc, with the standard configurations and tiny option _disabled_, but I have limited the use of FatFS lib for my necessary constraints (I needed f_readdir and "above"). I can even format (f_mkfs) but I have disabled it since I don't need it. The card gets written, and everyhting works OK.

Now the problems arise when I uncomment SimpleBLEPeripheral_Init and associated event - when debugging, it passes the example's initialization (SimpleBLEPeripheral_Init), initializes SD-SPI with disk-initialize, but as soon as it reaches code that uses FatFS, specifically a global variable of type FATFS (a struct) essential for chan's lib, I'm getting XSTACK-IDATA overflows in the debugger. Sometimes the stacks just fill and cc2540 hangs, sometimes it goes into HAL_SYSTEM_RESET and keeps throwing me back to start of main(), sometimes I don't even know what's happening (although I always get debugger xdata full warnings after I break the debugger). To the best of my knowledge, it has something to do with the big 512 BYTE array in the FATFS-struct type global - "BYTE win[_MAX_SS]" (the sector map). The struct size amounts to a 560 bytes total instance, and I believe this is too much for the IDATA/XSTACK/RAM...

When I tried porting the code that initially worked to my main project, which also uses BLE functionalities like SimpleBLEPeripheral, I get similar results since it also works with my BLE code commented out, doesn't work with it uncommented.

So, what I don't get is why the device allows all related fatfs methods to work perfectly when not enabling BLE stuff, and does not allow it with the features on. I am 99% sure it's memory allocation issues (heap, stack, code size...), but maybe it has something to do with UART "collisions" as SimpleBLEPeripheral supposedly uses it for a peripheral not present in my board configuration. But I can't really debug anything after the stacks fill .  

Can anyone shed a light on this issue?

  • There is not a huge amount of memory legroom once the BLE stack is added. The default configuration does not allow for a large number of static variables as a fair chunk >3000 bytes is allocated to the heap. Have you tried using the heap to dynamically allocate the sector map as a long lived dynamic variable (i.e. allocated inside main process init function), or reducing the heap size?

  • I'm not sure I follow. Do you mean declaring the whole object in my init function and allocating the big array (sector map/window) with osal_mem_alloc(512), as bellow?

    void osalInitTasks( void ){

    //...

    FATFS* sdcard;

    sdcard->win = osal_mem_alloc(512*sizeof(byte));

    //do my stuff

    //osal_mem_free(sdcard->win); 

    // want my filesystem available for infinity, so no free

    }

    About reducing the heap, I did try reducing INT_HEAP_LEN preprocessor to no success. I have used 2048 and 1024 besides the default 3k.

    P.S: For this type of allocation, which needs not be freed as I regularly need reads/writes to the card and filesystem constantly mounted, could I do something like using the ROM allocation API (I believe the functions were called osal_nv_something but I don't have documentation at hand).

  • Yes you have the right idea, but you should do it inside the init function for the task it is associated with for cleanliness. If it is done there, before osal_mem_kick(); it will be placed in long term heap and you shouldn't have to free the memory once it has been allocated. Is the device a central or peripheral role & how many concurrent connections do you need? - this will have an effect on heap needed by the stack. From experience allocating 512 with the default hep length should be ok, but is starting to push the limit. There are some debug functions in OSAL_Memory that you can use to profile your memory use and record the high water mark. This is useful to see if you are getting close to the heap limit. My instinct tells me something else is amiss other than the amount of memory if you still have the same issue after implementing these suggestions.

  • Thanks for the reply Eng351.

    I am already doing it like that, initializing the object inside osal_init_tasks(), before osal_mem_kick(), so it's not the issue.

    To answear your questions, I have two devices directly connected to the chip: an ISR periodic information broadcaster that can also receive stuff on demand, and the SPI SDCard reader. I'm not sure what you mean by central role, but the broadcaster device is definitely central, as the application makes no sense without a connection to it. They both connect to USART0, on alt1 and 2. The ISR device broadcasts stuff in customizable periods, from 1 to 30 seconds, and that stuff is parsed and relayed to the BLE stack to reach a connected iPhone. The stuff itself is usually no longer than 40 bytes (might require two GATT messages but that is transparent to me), and I only ever need one single BLE device (iPhone) connected at a time.

    About debugging the memory, I have set OSALMEM_METRICS to true in order to debug the various memory values at runtime, but they seem inconsistent even when running working examples.

  • What I mean is the bluetooth low energy role of your CC254x chip, not concerning any peripherals wired up to it. If you are connecting to an iphone with GATT you will most probably be a peripheral role device - just check what library is included with your project. Peripheral with only max 1 connection shouldn't need an excessive amount of memory. It sounds as if the stack is overflowing somewhere - does the file system code allocate any large auto variables in any of its functions? Have you looked at your memory usage via the map file?

  • Hi...

    I'm looking to do this too...   I have gotten the Chan code to compile, and am about ready to test with my CC2541 application.

    My biggest concern has been the inclusion of the "dly_us" function in Chan's code.   I suspect that this will break the BLE functionality if the SD card doesn't respond right away.   How have you dealt with this?   Have you gotten your combination of SDcard/BLE to work?

    I was considering breaking the Chan code into multiple tasks so the delays can be "hidden", but this would be a major re-write of the code and I don't know if I have the time to do this.

    Thanks!

  • Hello,

    Any ideas/progress?

    I tried to use SerialApplication + FatFS. Each part is working itself good. But there is no multi-tasking. So when both components are running (BT + mmc access with blocking delays) BT connection breaks and not working until restart. 

  • Hello. You are correct...the cc254x is not designed fort his. You need to ensure that the stack gets to process before each connection event. That is, if a BLE connection is established at 20 ms, the stack needs to process every 20 ms. You can attempt to manage this by configuring one of the available hardware timers to keep track of this. However, a better solution is to move to the cc2640 which does support multitasking.
  • Hello,

    What do you mean TimC ? I need to interface a SD card to the cc2540 in order to save files, for example "message.txt". and then to send this file to my phone. Could I do it?
  • Hello Tiago Borba,

    Have you achieved to interface a SD card with CC2540? Could you please give some guidelines?
    I use the Chan's library and especially, the generic example of elm-chan.org/.../ffsample.zip
    Also, I use the spi example for the spi communication with the sd. I also have posted at this place (e2e.ti.com/.../1862673 .
    Could you please help me with any advice if you have achieved it?

    Thank you very much in advance,
  • Hello Tiago Borba,

    Have you achieved the SD interface with CC2540 through SPI. I don't care about BLE disconnection.
    The only I want to achieve is to create a file in the SD card.
    I have built my code without errors, based on SimpleBLEPeripheral but I don't understand where I should call my function for the SD initialization,. I am trying from osal_init_tasks, but nothing happens.
    Any help please ?

    Thank you,
  • Hi there,

    If you are not interested in BLE then I would recommend starting from from a basic 8051 based IAR project without the BLE stack. However that doesn't make much sense when using the CC2541 as this is a BLE SoC. As Tim suggested, the ideal case would be to use a device that supports multi-tasking with an RTOS such as the CC2640.
  • Hi Sean2,

    Thank you for your response and the sharing of your experience.
    Please let me share my thought. I thought that I could "shut down" BLE advrtisement/operation when I tranfer a file (sensors_data.txt) with the data from sensors (e.g accelerometer) to the external memory and when the transfer would be done succesfully I would "shut down" the SPI-memory-interface (no files would be transferred) and then to turn on BLE advertisement/connection. Could this be done with cc2540?

    When you say "a basic 8051 based IAR project", in which did you mention?

    Thank you again for your feedback.

    Kind Regards,
  • Hi,

    Based on your last reply it sounded like you weren't interested in BLE which is why I suggested the other project. You can ignore that.
    What you have described sounds possible. So long as you only try to write to the SD card when the BLE stack/connection is not active then you should be okay.

    However I do not know about the requirements of the FatFS library. You may run into trouble trying to fit this into the internal memory of the device.
  • Hello Sean2,

    Since I don't need BLE connection, I should use an example, where this is disabled. Do you know which this is?
    Generally, when you want to call a new function that you have already added in your project, from which point/function you should call it?

    Thank you,