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.

RTOS/CC1310: Application depending of debugger XDS110

Part Number: CC1310

Tool/software: TI-RTOS

Hi,

I have implemented two firmwares: a bootloader and a application.

I have stored both in the CC1310 flash memory.

The processor starts at bootloader, verifies the content of a external flash memory using the SPI driver and, depending of the content, jump to application at address 0x6000.

EVERYTHING is working perfectly fine, I can read all the content from the external flash, I can do the jump, the application starts running. All happens as expected.

The problem is that it only happens this way when I am debugging the code in the CCS.

If I disconect the debugger and try to power on my board, it fails to read the external flash.

I also tested without using the SPI driver, only start the bootloader and then jump to application. The jump doesn't work either.

Why are things only working when I am debugging?

  • When the debugger is connected the system does not enter true standby. When not connected by a debugger, the power manager may be taking the system into standby. Can you try setting the Task.enableIdleTask to flase in your .cfg file and see if the behavior changes?
    Regards,
    Prashanth
  • PrashanthS said:
    When the debugger is connected the system does not enter true standby. When not connected by a debugger, the power manager may be taking the system into standby. Can you try setting the Task.enableIdleTask to flase in your .cfg file and see if the behavior changes?
    Regards,
    Prashanth

    Hi Prashanth,

    I tried what you suggested, but nothing changed.

    Just to make it clear, the application runs without the debbuger connected. It still shows all the texts in the display. The PWM driver still runs well.

    The problems I am having without the debbuger are:

    1. Can't read from the external memória using the SPI driver. I am using blocking mode and infinite timeout, the application should "block" if it is not able to communicate, but the application continues to run, so the SPI is not "blocked". I suppose it is only reading '0's.

    2. Can't jump to another program in the flash memory. I am using the following code to jump. Please, tell if there is a better way to do that:

                                SPI_close(spi0Handle);
                                SPI_close(spi1Handle);
                                PWM_close(pwmHandle);
                                PIN_close(pinHandle);
    
    
                                asm(" MOV R0, #0x00000 ");
                                asm(" LDR R1, [R0, #0x4] ");
                                asm(" LDR SP, [R0, #0x0] ");
                                asm(" BX R1 ");

  • I made a very simple program to ilustrate the problem. It is based in the CC1310 empty_min.c example. The only change is that I enabled the SPI driver.

    It writes a known pattern to the external memory and reads it.

    If the pattern matches it blinks the led in a way, if it doesn't matches blinks the led in another way.

    Very simple, there isn't much to go wrong here.

    When I run that program using CCS and debbuger it works: the pattern matches and the led blink according.

    When I disconnect the debbuger and simple power on the board, the led blink as the pattern is wrong.

    The code:

    /*
     * Copyright (c) 2015-2016, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /*
     *  ======== empty_min.c ========
     */
    #include "empty_min.h"
    
    #define TASKSTACKSIZE   1024
    
    Task_Struct task0Struct;
    Char task0Stack[TASKSTACKSIZE];
    
    /* Pin driver handle */
    PIN_Handle ioPinHandle;
    PIN_State ioPinState;
    
    /*
     * Application LED pin configuration table:
     *   - All LEDs board LEDs are off.
     */
    PIN_Config ioPinTable[] = {
        Board_LED0 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW  | PIN_PUSHPULL  | PIN_DRVSTR_MAX,
        Board_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW  | PIN_PUSHPULL  | PIN_DRVSTR_MAX,
        SPI0_CS    | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL  | PIN_DRVSTR_MIN,
        Board_SPI_FLASH_CS | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MIN,
        PIN_TERMINATE
    };
    
    uint32_t milli_to_ticks(uint32_t milli)
    {
        // 1. Converte de ms para us
        // 2. Converte de us para ticks
        return((milli * 1000) / Clock_tickPeriod);
    }
    
    #define PATTERN_SIZE 10
    
    /*
     *  ======== heartBeatFxn ========
     *  Toggle the Board_LED0. The Task_sleep is determined by arg0 which
     *  is configured for the heartBeat Task instance.
     */
    Void heartBeatFxn(UArg arg0, UArg arg1)
    {
        uint8_t wPattern[PATTERN_SIZE];
        uint8_t rPattern[PATTERN_SIZE];
        uint32_t addr = 0x00;
    
        spi_init();
    
        M25PExx_read_memory_info();
    
        memset(wPattern, 0x55, PATTERN_SIZE);
        memset(rPattern, 0x00, PATTERN_SIZE);
    
        M25PExx_write(addr, wPattern, PATTERN_SIZE);
    
        M25PExx_read(addr, rPattern, PATTERN_SIZE);
    
        while (1) {
            PIN_setOutputValue(ioPinHandle, Board_LED1, !PIN_getOutputValue(Board_LED1));
    
            if(memcmp(wPattern, rPattern, PATTERN_SIZE))
            {
                Task_sleep(milli_to_ticks(1000));
            }
            else
            {
                Task_sleep(milli_to_ticks(250));
            }
        }
    }
    
    /*
     *  ======== main ========
     */
    int main(void)
    {
        Task_Params taskParams;
    
        /* Call board init functions */
        Board_initGeneral();
        // Board_initI2C();
        Board_initSPI();
        // Board_initUART();
        // Board_initWatchdog();
    
        /* Open LED pins */
        ioPinHandle = PIN_open(&ioPinState, ioPinTable);
        if(!ioPinHandle) {
            System_abort("Error initializing board LED pins\n");
        }
    
        PIN_setOutputValue(ioPinHandle, Board_LED1, 1);
    
        /* Construct heartBeat Task  thread */
        Task_Params_init(&taskParams);
        taskParams.arg0 = 1000000 / Clock_tickPeriod;
        taskParams.stackSize = TASKSTACKSIZE;
        taskParams.stack = &task0Stack;
        Task_construct(&task0Struct, (Task_FuncPtr)heartBeatFxn, &taskParams, NULL);
    
        /* Start BIOS */
        BIOS_start();
    
        return (0);
    }
    

  • Mad River said:

    I made a very simple program to ilustrate the problem. It is based in the CC1310 empty_min.c example. The only change is that I enabled the SPI driver.

    It writes a known pattern to the external memory and reads it.

    If the pattern matches it blinks the led in a way, if it doesn't matches blinks the led in another way.

    Very simple, there isn't much to go wrong here.

    When I run that program using CCS and debbuger it works: the pattern matches and the led blink according.

    When I disconnect the debbuger and simple power on the board, the led blink as the pattern is wrong.

    The problem with the SPI is fixed.

    It turned out to be a hardware problem. One of the external memory pins were floating. Somehow, the debugger was stabilizing this pin.

    Now, the only remaining problem is the jump.

    As I said, I have two firmwares stored in the flash memory: bootloader and application.

    Bootloader is stored at address 0x0000.

    Application is stored at address 0x6000.

    I have tested each jump individually:

    1. I can start at the bootloader and jump to application. It is working;

    1
    2
    3
    4
    asm(" MOV R0, #0x06000 ");
    asm(" LDR R1, [R0, #0x4] ");
    asm(" LDR SP, [R0, #0x0] ");
    asm(" BX R1 ");

    2. I can start at the application and jump to bootloader. It is working.

    1
    2
    3
    4
    asm(" MOV R0, #0x00000 ");
    asm(" LDR R1, [R0, #0x4] ");
    asm(" LDR SP, [R0, #0x0] ");
    asm(" BX R1 ");

    But what I really need to do is this: The application is running, it receives the new firmware through the air, stores it in the external memory and jumps to bootloader. Bootloader replaces the old firmware and then jumps back to application.

    Right now, the application receives the new firmware, checks it (checksum and header info), jumps to bootloader, bootloader double checks it, replaces the firmware and then fails to jump back to application. The second jump is not working.

    Putting it simple: I can jump from one firmware to the other, but I can't jump back to the first one.

    I don't think the problem is the firmware replacement, because I tried the same process without it and the problem remains.

    Do you have some clue?

    Is there a better way to do the jump?