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.

Compiler/CC2640R2F: SPI control table segment size change causes problems with BLE connection

Part Number: CC2640R2F


Tool/software: TI C/C++ Compiler

Hi!

Some time ago I reported a strange issue caused by SPI_Init() function: if the function is called from main(), BIOS_start() will crash after some time. It was really strange because SPI driver wasn't used at all and there is no connection between SPI_Init() function and TI-RTOS. I solved the problem just by upgrading my SDK (from v1.50 to v3.40). But now I see a new strange bug, which has different symptoms but may have the same cause.

New symptoms: my IOS device doesn't discover BLE services of my custom CC2640R2F board. An Android device does. First, I thought that this is an IOS caching issue, but then I found that it works well if I comment out SPI_Init() function and everything related to SPI driver. Then I found that SPI_Init() doesn't cause the problem if I comment out SPI1 in the board configuration (I'm going to use SPI0 only):

typedef enum CUSTOM_BOARD_SPIName {
    CUSTOM_BOARD_SPI0 = 0,
//    CUSTOM_BOARD_SPI1,

    CUSTOM_BOARD_SPICOUNT
} CUSTOM_BOARD_SPIName;

const SPICC26XXDMA_HWAttrsV1 spiCC26XXDMAHWAttrs[CUSTOM_BOARD_SPICOUNT] = {
    {
        .baseAddr           = SSI0_BASE,
        .intNum             = INT_SSI0_COMB,
        .intPriority        = ~0,
        .swiPriority        = 0,
        .powerMngrId        = PowerCC26XX_PERIPH_SSI0,
        .defaultTxBufValue  = 0xFF,
        .rxChannelBitMask   = 1<<UDMA_CHAN_SSI0_RX,
        .txChannelBitMask   = 1<<UDMA_CHAN_SSI0_TX,
        .mosiPin            = CUSTOM_BOARD_SPI0_MOSI,
        .misoPin            = CUSTOM_BOARD_SPI0_MISO,
        .clkPin             = CUSTOM_BOARD_SPI0_CLK,
        .csnPin             = CUSTOM_BOARD_SPI0_CSN,
        .minDmaTransferSize = 10
    },
//    {
//        .baseAddr           = SSI1_BASE,
//        .intNum             = INT_SSI1_COMB,
//        .intPriority        = ~0,
//        .swiPriority        = 0,
//        .powerMngrId        = PowerCC26XX_PERIPH_SSI1,
//        .defaultTxBufValue  = 0xFF,
//        .rxChannelBitMask   = 1<<UDMA_CHAN_SSI1_RX,
//        .txChannelBitMask   = 1<<UDMA_CHAN_SSI1_TX,
//        .mosiPin            = CUSTOM_BOARD_SPI1_MOSI,
//        .misoPin            = CUSTOM_BOARD_SPI1_MISO,
//        .clkPin             = CUSTOM_BOARD_SPI1_CLK,
//        .csnPin             = CUSTOM_BOARD_SPI1_CSN,
//        .minDmaTransferSize = 10
//    }
};

const SPI_Config SPI_config[CUSTOM_BOARD_SPICOUNT] = {
    {
         .fxnTablePtr = &SPICC26XXDMA_fxnTable,
         .object      = &spiCC26XXDMAObjects[CUSTOM_BOARD_SPI0],
         .hwAttrs     = &spiCC26XXDMAHWAttrs[CUSTOM_BOARD_SPI0]
    },
//    {
//         .fxnTablePtr = &SPICC26XXDMA_fxnTable,
//         .object      = &spiCC26XXDMAObjects[CUSTOM_BOARD_SPI1],
//         .hwAttrs     = &spiCC26XXDMAHWAttrs[CUSTOM_BOARD_SPI1]
//    },
};

const uint_least8_t SPI_count = CUSTOM_BOARD_SPICOUNT;

I thought the issue is fixed, but then I got a new one: my IOS device doesn't discover BLE services when I create a new task. There are a few tasks in my project already, but the issue is caused by a new one. It's really strange because the task is empty!!! It looks like this:

static void Test_taskFxn(UArg a0, UArg a1)
{
    Task_sleep(2000*100);

    for (;;) {
        Task_sleep(1000*100);
    }
}

I felt really frustrated and decided to compare 2 map files: with the empty task and without it. Mostly, the files look the same. There are little address offsets because of the new function. But I also found this strange unnamed segment size change near the dmaSpi1TxControlTableEntry:

The following map file is created when the empty task is commented out and IOS discovers the services successfully. You can see that the unnamed segment size is 0x00002a1f.

The following map file is created when the empty task is running and IOS is not able to discover the services. You can see that the unnamed segment is larger now (0x00002c4f). Please, note that there are similar unnamed segments for every control table entry. They have the same address and size as their entry segments. The unnamed segment I'm talking about has the same address as dmaSpi1TxControlTableEntry, but its length is really huge and it overlaps other stuff. I am not sure why it happens and if this is the cause of my problem, but it looks strange. What do you think?

I hope someone could help to find what's going wrong there.

Thanks,

Eugene

  • Hi Eugene, 

    Assigning an expert to comment. 

    Thanks, 
    Elin

  • Hi Eugene,

    Could you fill out more details on which toolchain you are using CSS, GCC or IAR (I assume CCS based on the map file). Also, could you fill in which SDK version you are running etc? As far as I can verify, the size of all DMA tables are "10" for examples compiled with the latest SDK.

  • Hi M-W,

    I use CCS 9.3.0.00012 and "simplelinkcc2640r2sdk_3_40_00_10".

    It's really easy to reproduce. Just import "ProjectZero" from "examples\rtos\CC2640R2_LAUNCHXL\blestack\project_zero" and call SPI_Init() from main().

    You will get a map file with this content:

    If you don't call SPI_Init() function, there will not be any DMA SPI Control Table Entry in the map file. It seems like I understand now how SPI_Init() function could cause a crash of TI-RTOS described in my previous post. A memory region can get corrupted due to this overlapping.

    Thanks,

    Eugene

  • Hi Eugene,

    I doubt that is has anything to do with the DMA table entries. First of all, as long as you don't use SPI module 1, then this memory would never bee used by the SPI driver and you would not have a conflict, even if it overlapped with another variable.

    Second of all, the size of the entry is perfectly fine at "0x10". Notice how .data and .bss is grouped together with the last entry in the map file. This means that the length is the combined length of entry + data + bss and not just 0x10.

    The fact that is also works Android and not iOS points more towards some BLE issues rather than a issue with for example the SPI driver. Are you running the vanilla project zero, or do you have your own custom project running?

  • Hi M-W,

    Finally, I've found the issue. My project was based on the project zero, which is configured to use the auto-sized heap memory by default: the remaining RAM (not used by the system) is fully assigned to the heap. I had a lack of heap memory, but didn't know about that: ROV doesn't work with the auto-sized heap. When I added a SPI_Init() call, the linker allocated some memory for the SPI control tables and the heap size got smaller, which caused the connection problem. Unfortunately, I didn't get any error logs about memory allocation failure. The stack worked well with Android, but it didn't work with the latest IOS. I think it was because the latest IOS sends a request to increase MTU Size right after connection. It required more heap memory and failed, so the IOS device didn't get any response.

    Anyway, thanks for your time. I hope this post will be useful for someone to fix a similar problem.

    Eugene