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: Jump to application

Part Number: CC1310

Tool/software: TI-RTOS

Hi,

I loaded two applications in the CC1310 flash.

The first one is located at address 0x0000 and the second at address 0xA000.

In the first application, I want to jump to the second application if the button is pressed.

I made the following program and it is working! I am able to jump to the second application when using that program:

/*
 *  ======== pinInterrupt.c ========
 */

/* XDCtools Header files */
#include <xdc/std.h>
#include <xdc/runtime/System.h>
#include <xdc/runtime/Assert.h>

/* BIOS Header files */
#include <ti/sysbios/BIOS.h>
#include <ti/drivers/Power.h>
#include <ti/drivers/power/PowerCC26XX.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Clock.h>

/* TI-RTOS Header files */
#include <ti/drivers/PIN.h>
#include <ti/drivers/pin/PINCC26XX.h>
#include <driverlib/flash.h>
#include <driverlib/vims.h>
#include <ti/drivers/UART.h>

/* Example/Board Header files */
#include "Board.h"

#include <string.h>

#define TASKSTACKSIZE     768

Task_Struct task0Struct;
Char task0Stack[TASKSTACKSIZE];

static Clock_Struct clockStruct;

static UART_Handle uart;

/* Pin driver handles */
static PIN_Handle buttonPinHandle;
static PIN_Handle ledPinHandle;

/* Global memory storage for a PIN_Config table */
static PIN_State buttonPinState;
static PIN_State ledPinState;

/*
 * Initial LED pin configuration table
 *   - LEDs Board_LED0 is on.
 *   - LEDs Board_LED1 is off.
 */
PIN_Config ledPinTable[] = {
    Board_LED0 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    Board_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW  | PIN_PUSHPULL | PIN_DRVSTR_MAX,
    PIN_TERMINATE
};

/*
 * Application button pin configuration table:
 *   - Buttons interrupts are configured to trigger on falling edge.
 */
PIN_Config buttonPinTable[] = {
    Board_BUTTON0  | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_NEGEDGE,
    Board_BUTTON1  | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_NEGEDGE,
    PIN_TERMINATE
};


/*
 *  ======== buttonCallbackFxn ========
 *  Pin interrupt Callback function board buttons configured in the pinTable.
 *  If Board_LED3 and Board_LED4 are defined, then we'll add them to the PIN
 *  callback function.
 */
void buttonCallbackFxn(PIN_Handle handle, PIN_Id pinId) {
    uint32_t currVal = 0;

    /* Debounce logic, only toggle if the button is still pushed (low) */
    CPUdelay(8000*50);
    if (!PIN_getInputValue(pinId)) {
        /* Toggle LED based on the button pressed */
        switch (pinId) {
            case Board_BUTTON0:
                currVal =  PIN_getOutputValue(Board_LED0);
                PIN_setOutputValue(ledPinHandle, Board_LED0, !currVal);
                break;

            case Board_BUTTON1:

                // Load address of reset function from the fixed location of the image's
                // reset vector and jump.
                asm(" MOV R0, #0x0A000 ");
                asm(" LDR R1, [R0, #0x4] ");

                // Reset the stack pointer,
                asm(" LDR SP, [R0, #0x0] ");

                // And jump.
                asm(" BX R1 ");

                break;

            default:
                /* Do nothing */
                break;
        }
    }
}

uint32_t milli_to_ticks(uint32_t milli)
{
    return((milli * 1000) / Clock_tickPeriod);
}


uint32_t sec_to_ticks(uint32_t sec)
{
    return(milli_to_ticks(sec * 1000));
}

void blink_led(UArg arg0)
{
    PIN_setOutputValue(ledPinHandle,Board_LED1,!PIN_getOutputValue(Board_LED1));
}


void echoFxn(UArg arg0, UArg arg1)
{
    uint8_t ch;

    while (1)
    {

        Task_sleep(1000);

//        if(!UART_read(uart, &ch, 1))
//        {
//            // Do something
//        }
//        else
//        {
//            // Do something
//        }
    }
}


/*
 *  ======== main ========
 */
int main(void)
{
    /* Call board init functions */
    Board_initGeneral();
    Board_initUART();

    /* Open LED pins */
    ledPinHandle = PIN_open(&ledPinState, ledPinTable);
    if(!ledPinHandle) {
        System_abort("Error initializing board LED pins\n");
    }

    buttonPinHandle = PIN_open(&buttonPinState, buttonPinTable);
    if(!buttonPinHandle) {
        System_abort("Error initializing button pins\n");
    }

    /* Setup callback for button pins */
    if (PIN_registerIntCb(buttonPinHandle, &buttonCallbackFxn) != 0) {
        System_abort("Error registering button callback function");
    }

    Clock_Params clockParams;
    Clock_Params_init(&clockParams);
    clockParams.period = milli_to_ticks(250);
    clockParams.startFlag = TRUE;

    Clock_construct(&clockStruct, blink_led, clockParams.period, &clockParams);

    UART_Params uartParams;
    UART_Params_init(&uartParams);
    uartParams.baudRate = 9600;
    uartParams.dataLength = UART_LEN_8;
    uartParams.stopBits = UART_STOP_ONE;
    uartParams.parityType = UART_PAR_NONE;
    uartParams.readDataMode = UART_DATA_BINARY;
    uartParams.writeDataMode = UART_DATA_BINARY;
    uartParams.readEcho = UART_ECHO_OFF;
    uartParams.readMode = UART_MODE_BLOCKING;
    uartParams.writeMode = UART_MODE_BLOCKING;
    uartParams.readReturnMode = UART_RETURN_FULL;
    uartParams.readTimeout = UART_WAIT_FOREVER;
    uartParams.writeTimeout = UART_WAIT_FOREVER;
    uart = UART_open(Board_UART0, &uartParams);

    /* Construct BIOS objects */
    Task_Params taskParams;
    Task_Params_init(&taskParams);
    taskParams.stackSize = TASKSTACKSIZE;
    taskParams.stack = &task0Stack;
    Task_construct(&task0Struct, (Task_FuncPtr)echoFxn, &taskParams, NULL);

    /* Start kernel. */
    BIOS_start();

    return (0);
}

The problem appear when I uncomment the following code:

void echoFxn(UArg arg0, UArg arg1)
{
    uint8_t ch;

    while (1)
    {

        Task_sleep(1000);

// THE JUMP STOP WORKING WHEN THIS PART IS UNCOMMENTED
//        if(!UART_read(uart, &ch, 1))
//        {
//            // Do something
//        }
//        else
//        {
//            // Do something
//        }
    }
}

That is the only change from the working program to the one that doesn't work.

I don't know if it is relevant, but in both applications I commented:

/* ================ ROM configuration ================ */
/*
 * To use BIOS in flash, comment out the code block below.
 */
/*
var ROM = xdc.useModule('ti.sysbios.rom.ROM');
if (Program.cpu.deviceName.match(/CC26/)) {
    ROM.romName = ROM.CC2650;
}
else if (Program.cpu.deviceName.match(/CC13/)) {
    ROM.romName = ROM.CC1350;
}
*/

Can someone help me to understand why the jump stop working when I used the uart driver?

  • I solve the problem calling UART_close(uart); before jumping.
  • Hi Mad,

    I am assuming the main() function you are showing is the one for the first program. What do you do in the 2nd program in terms of initializing the UART driver? Also, it'd be a good idea to close the UART using UART_close() before jumping to the 2nd program, so that it can start from a clean slate.

    Best regards,
    Vincent
  • Never mind. It looks like you arrived to the same conclusion. Good job!
  • Vincent W. said:
    Hi Mad,

    I am assuming the main() function you are showing is the one for the first program. What do you do in the 2nd program in terms of initializing the UART driver? Also, it'd be a good idea to close the UART using UART_close() before jumping to the 2nd program, so that it can start from a clean slate.

    Best regards,
    Vincent

    Vincent W. said:

    Never mind. It looks like you arrived to the same conclusion. Good job!

    Thank you for your time anyway!

  • Vincent W. said:
    Never mind. It looks like you arrived to the same conclusion. Good job!

    Hi,

    I am still having problems to jump between two firmwares stored in the device flash memory.

    To give you some context again:

    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;

    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.

    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?

  • Hi Mad,

    Could you please start a new thread with your query?

    Thanks,

    Vincent