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.

TMS570LS3137: Bootloader FreeRTOS program

Part Number: TMS570LS3137

Hello Jagadish, sorry for my delay. I tried your solution on the link TMS570LS3137: Bootloader FreeRTOS program, but it didn't work for me. Pensive

I attached my complete code:

V2.2_Firmware_Boot.zip

When the bootloader had finished, I noticed that the FreeRTOS didn't run (It had to power on the LEDs). So I clicked on 'pause', and I observed that the program showed the following:

I attached my code. Let me know if you want to see a particular piece of code.

sys_main.c

/* Include Files */
#include "sys_common.h"
#include "system.h"
#include "stdio.h"
#include "esm.h"
#include "sys_mpu.h"


#include "FreeRTOS.h"
#include "os_task.h"
#include "os_semphr.h"

#include "het.h"
#include "gio.h"
#include "can.h"
#include "sci.h"
#include "adc.h"
#include "sys_vim.h"
#include "sys_core.h"

#include "bootloader.h"
#include "bl_can.h"

#include "includes.h"

#include "bl_check.h"
#include "bl_led_demo.h"

#include "bl_config.h"
#include "sci_common.h"


void initFunction()
{
    _enable_interrupt_();
    gioSetDirection(hetPORT1, 0xFFFFFFFF);
    canInit();
  //  sciInit();
    adcInit();
    vimInit();
}



/*
*********************************************************************************************************
*                                                 MAIN
*********************************************************************************************************
*/
void main(void){

    /* USER CODE BEGIN (22) */
        systemInit();
        _coreEnableIrqVicOffset_();
        initFunction();
        esmInit();

    /* USER CODE END */

        _mpuInit_();



    RTOSFunction();
}

includes.c


/* Define Task Handles */
xTaskHandle xTask1Handle;
xTaskHandle xTask2Handle;
xTaskHandle xTask3Handle;
xTaskHandle xTask4Handle;
xTaskHandle xTask5Handle;

xQueueHandle xMainQ = NULL;
xQueueHandle xErrQ  = NULL;
xQueueHandle xComQ  = NULL;
xQueueHandle xComRx  = NULL;
xQueueHandle xComIn = NULL;
xQueueHandle xSense = NULL;
xQueueHandle xTimer = NULL;

xSemaphoreHandle xSemaphoreTime = NULL;

void vApp(void *pvParameters);
void vTimer(void *pvParameters);
void vTaskIDLE(void *pvParameters);
void vSense(void *pvParameters);

void RTOSFunction()
{
      vSemaphoreCreateBinary(xSemaphoreTime);

      /*Create Queues*/
      xMainQ  = xQueueCreate(10, sizeof (struct xMessage));
      xSense  = xQueueCreate(10, sizeof (struct xMessage));
      xErrQ   = xQueueCreate(10, sizeof (struct xMessage));
      xComIn  = xQueueCreate(10, sizeof(int));
      xComRx  = xQueueCreate(10, sizeof(int));

      /* Create Tasks */
      xTaskCreate(vTimer,            "TIMER", configMINIMAL_STACK_SIZE, NULL, 5, &xTask1Handle);
      xTaskCreate(vApp,              "APP",   configMINIMAL_STACK_SIZE, NULL, 5, &xTask1Handle);
      xTaskCreate(vTaskIDLE,         "IDLE",  configMINIMAL_STACK_SIZE, NULL, 4, &xTask1Handle);
      /*Create Aperiodic Tasks*/
      xTaskCreate(vSense,            "HK",    configMINIMAL_STACK_SIZE, NULL, 4 , &xTask5Handle);
      xTaskCreate(vTCP,              "TCP",   configMINIMAL_STACK_SIZE, NULL, 4, &xTask4Handle);

      //_mpuInit_();


      /* Start Scheduler */
      vTaskStartScheduler();
      /* Run forever */
      while(1);
}

sys_link.cmd

MEMORY
{

    /* PARA GRABAR*/

    VECTORS (X)  : origin=0x00020020 length=0x00000020
    FLASH_CODE  (RX) : origin=0x00020040 length=0x008000-0x40 fill=0xFFFFFFFF
    FLASH0  (RX) : origin=0x00028000 length=0x0014FFC0
    FLASH1  (RX) : origin=0x00180000 length=0x00180000
    STACKS  (RW) : origin=0x08000000 length=0x00000800
    KRAM    (RW) : origin=0x08000800 length=0x00000800
    RAM     (RW) : origin=(0x08000800+0x00000800) length=(0x0003F800 - 0x00000800)


/* USER CODE BEGIN (2) */
/* USER CODE END */
}

/* USER CODE BEGIN (3) */
/* USER CODE END */

/*----------------------------------------------------------------------------*/
/* Section Configuration                                                      */

SECTIONS
{

    .intvecs : {} > VECTORS
    /* FreeRTOS Kernel in protected region of Flash */
    .kernelTEXT   : {} > FLASH0 | FLASH1
    .cinit        : {} > FLASH0 | FLASH1
    .pinit        : {} > FLASH0 | FLASH1
    /* Rest of code to user mode flash region */
    .text         : {} > FLASH0 | FLASH1
    .const        : {} > FLASH0 | FLASH1
    /* FreeRTOS Kernel data in protected region of RAM */
    .kernelBSS    : {} > KRAM
    .kernelHEAP   : {} > RAM
    .bss          : {} > RAM
    .data         : {} > RAM


/* USER CODE BEGIN (4) */
/* USER CODE END */
}

Thank you in advance. I'll wait for any suggestions. Smile

  • Hi ,

    Which bootloader code you are using?

    UART or CAN or Ethernet or any other?

    Is it possible to share Bootloader code as well?

    --

    Thanks & regards,
    Jagadish.

  • Hello Jagadish, thank you for your reply.

    Yes, of course. I'm using the bootloader through CAN. I checked it with another project (without RTOS), and the bootloader is working (records and rounds it correctly)

    I downloaded the Bootloader project from the TI webpage.

    UPGRADE2.zip

     I made small changes, but the code is working I checked this project, and the bootloader is working.

    6064.TMS570LSx_rtiBlinky_BL_APP20020.zip

    Thank you so much for your help!

    Kind regards,

    Federico.

  • Hi Federico,

    I don't have TMS570LS3137 board with me now. I will get it in two days. So please give me some time for testing.

    --

    Thanks & regards,
    Jagadish.

  • Hello Jagadish,

    Thank you so much for your help. 

    Please, let me know if you could test the bootloader.

    Kind regards.

  • Hi Federico,

    My LS3137 HDK board is not working so i am reassigning this thread to my colleague for help.

  • Hi Federico,

    The purpose of a bootloader is to update the firmware located in the flash. After the firmware is updated, a software reset should be issued, so the code execution will jump to the new firmware properly. My suggestion is not to use freeRTOS for bootloader.

  • The F021 Flash APIs must be run in a priviledged mode (a mode other than user mode) to allow access to the Flash memory controller registers. The tasks in freeRTOS is configured as user mode by default. You need to switch to a privileged mode before starting the bootloader, then switch it back to user mode after the firmware has been programmed to flash.

    void vTask_bootloader(void *pvParameters)
    {
         portENTER_PRIVILEG_MODE();

         bootloader code ...

         portSWITCH_TO_USER_MODE();

         for(;;)   {
              vTaskDelay(1000);
         }
    }

    The Software interrupt handler is defined in os_portasm.asm

    You can add the following code to your includes.c file:

  • Hello QJ Wang! Thank you very much for your help.

    I tried your suggestions, but it doesn't work yet.

    On the other hand, I tried another solution because I think the issue could be more general. Following the steps given by Jagadish in the following link:R TI E2E support forums I tried recording the App in the 0x20020 position with the CCS.

    I did the following steps:

    1 - Erase the total Flash (with UnityFlash)

    2- Load the Bootloader program (called UPGRADE2)

    3- With the target connected, I load the Application (at the 0x20020 position) (No erase Flash, so there is the Bootloader program at the beginning of the memory).

    This is the sys_link.cmd of the Application program: 

    VECTORS (X) : origin=0x00020020 length=0x00000020
    FLASH_CODE (RX) : origin=0x00020040 length=0x008000-0x40 fill=0xFFFFFFFF
    FLASH0 (RX) : origin=0x00028000 length=0x0014FFC0
    FLASH1 (RX) : origin=0x00180000 length=0x00180000
    STACKS (RW) : origin=0x08000000 length=0x00000800
    KRAM (RW) : origin=0x08000800 length=0x00000800
    RAM (RW) : origin=(0x08000800+0x00000800) length=(0x0003F800 - 0x00000800)

    So, at the beginning of the memory there is the Bootloader program, and a the 0x20020 it's the Application program

    4- Did click on 'RUN', and the CCS starts to run the Application program, but it is blocked (or anything similar). Because I didn't see that the tasks were running.

    5- Did click on 'Pause', and I saw the following message:

    0x00004E44 (no symbols are defined)

    But in that position there is information

    6- I set a while(1) in the sys_main.c on my Application program (before the RTOS Scheduler), and I did the same steps again. And works (I see the LEDs power ON).

    But the issue is when I want to run the RTOSFunctions (where the FreeRTOS should start to run).

    7- In order to make sure that the Application works, I load the App only (in the 0x0 position), and works. For this, I changed the sys_link.cmd with the following lines and executed it:

    VECTORS (X) : origin=0x00000000 length=0x00000020
    KERNEL (RX) : origin=0x00000020 length=0x00008000
    FLASH0 (RX) : origin=0x00008020 length=0x00177FE0
    FLASH1 (RX) : origin=0x00180000 length=0x00180000
    STACKS (RW) : origin=0x08000000 length=0x00000800
    KRAM (RW) : origin=0x08000800 length=0x00000800
    RAM (RW) : origin=(0x08000800+0x00000800) length=(0x0003F800 - 0x00000800)

    I am not sure about how to solve this issue. It's some strange. I really appreciate it if you could make anything suggestions about it.

    Thank you so much.

    Kind Regards,

    Federico.

  • 5- Did click on 'Pause', and I saw the following message:

    0x00004E44 (no symbols are defined)

    Your bootloader is located at 0x00000000, and your application is programmed to the flash starting from 0x20020. The address 0x4E44 is not part of your application. It might be abort handler of your bootloader.

    The bootloader has small size, and it is hard to make it bug-free. Please modify the sys_intvecs.asm of bootloader to jump to your abort handler in your application in case there is a data abort.


    resetEntry
    b _c_int00
    undefEntry
    b #0x20020 ;undefEntry
    svcEntry
    b #0x20020 ;svcEntry
    prefetchEntry
    b #0x20020 ;prefetchEntry
    b #0x20020 ;;_dabort
    b #0x20020  ;;phantomInterrupt
    ldr pc,[pc,#-0x1b0]
    ldr pc,[pc,#-0x1b0]

  • Hello QJ Wang. Thank you for your fast reply.

    I performed your suggestion, but when I loaded the Bootloader, the board stayed with the Res Led On.

    If I don't change the _dabort, I can load the Bootloader, but I have the same result as before Disappointed

    Could it be strange, that once you started running the application at position 20020, it has to go back to previous positions? Since the error continues to be marked at position 0x00004E44.

    Thank you very much for your help

  • the board stayed with the Res Led On

    In your bootloader, do you perform any selftest which generates data abort intentionally? For example 2-bit ECC error forcing test. You can use polling mode in bootloader to check the error flag and clear the error flag manually in your bootloader.

    Could it be strange, that once you started running the application at position 20020

    The 20020 in your sys_intvecs.asm should be in hexadecimal format 0x20020

  • Hello QJ Wang,

    Yes, the position is in hexadecimal format.

    And no, I didn't perform the selftest to generate data abort internally. How can I do that? 

    I checked the step-by-step with another Application program, it has only 2 tasks and turns on and off 2 LEDs, and the results it's the same as before.

    The issue is when the App program is creating the tasks. In this point, I don't know why but jump to another position (at the beginning) when entering this line:

    xTaskCreate(vTaskIDLE, "IDLE", configMINIMAL_STACK_SIZE, 0, 1, &xTask1Handle);

    (I commented the rest of the tasks, but the issue is the same with everywhere FreeRTOS program).

    And the program jumps to these lines:

    Break at address "0x10" with no debug information available, or outside of program code.

    Break at address "0x85e8" with no debug information available, or outside of program code.

    Break at address "0x85dc" with no debug information available, or outside of program code.

    And there is info in these positions.

    I have tried with other application programs without RTOS, and it works fine. Sorry, but I really need the RTOS to work with the Bootloader. Or maybe there is another solution to save the RTOS App in a memory location, and then jump to that location from the Bootloader? I mean, as long as I can have different programs in different memory locations, and jump from one to another, it would work for me. And I would use the Bootloader to record programs without RTOS, in case it is not possible to use the bootloader with RTOS.

  • Sorry, but I really need the RTOS to work with the Bootloader

    My understanding is that you need the freeRTOS for your application, but not for bootloader. You don't use RTOS for bootloader.

    I checked the step-by-step with another Application program, it has only 2 tasks and turns on and off 2 LEDs, and the results it's the same as before.

    It looks like the 2 red LEDs are turned on by the code in your application rather the bootloader.

    Can you please check the value of ESM status registers? and CP15 data abort status register?

    Yes, the position is in hexadecimal format.

    But your code shows a decimal number (20020) is used 

    Did you use the updated bootloader sys_intvecs.asm? 

    resetEntry
    b _c_int00
    undefEntry
    b #0x20020 ;undefEntry
    svcEntry
    b #0x20020 ;svcEntry
    prefetchEntry
    b #0x20020 ;prefetchEntry
    #0x20020 ;;_dabort
    #0x20020  ;;phantomInterrupt
    ldr pc,[pc,#-0x1b0]
    ldr pc,[pc,#-0x1b0]

  • Thank you for your help QJ Wang.

    Yes sorry, I updated the sys_intvecs.asm as your suggestions.

    But I cannot update the _dabort, because when I change the instruction as b #0x20020 ;;_dabort , the bootloader program doesn't load to the board (It stays with the RED LED On).

    I update the  sys_intvecs.asm as:

    Is there any solution to change the _dabort? And do I need to update the sys_intvecs.asm on my RTOS App too?

    In my App I have:

    ESM status

    cp15:

    I recorded a video when it was running the App.

    Let me know if you need anything else, please. Thank you very much.

  • Hi,

    But I cannot update the _dabort, because when I change the instruction as b #0x20020 ;;_dabort , the bootloader program doesn't load to the board

    Do you mean you can not load the application using the bootloader? or the bootloader can not be loaded to MCU flash through CCS?

    And do I need to update the sys_intvecs.asm on my RTOS App too?

    No, you don't need to change sys_intvecs.asm in your application (RTOS App).

    The value of ESM status registers is zero which means no ESM flag is set. 

    The data abort fault status is: 0x80D --> MPU permission fault. 

    If you run the bootloader only (boot + load the application using CAN or UART + program application to flash (from 0x20020), but don't jump to application), can you get a data abort?

  • Hello QJ Wang,

    Sorry for not expressing myself correctly. When I make the change in the Bootloader program in the sys_intvecs.asm and then load the Bootloader on the board with the CCS, the board stays with the Red LED (17) ON. So, I made the changes you mentioned above except for the _dabort. And it was like:

    ;-------------------------------------------------------------------------------
    ; import reference for interrupt routines

    .ref _c_int00
    .ref _dabort
    .ref phantomInterrupt
    .def resetEntry

    ;-------------------------------------------------------------------------------
    ; interrupt vectors

    resetEntry
    b _c_int00
    undefEntry
    b #0x20020 ;undefEntry
    svcEntry
    b #0x20020 ;svcEntry
    prefetchEntry
    b #0x20020 ;prefetchEntry
    b _dabort
    b #0x20020 ;phantomInterrupt
    ldr pc,[pc,#-0x1b0]
    ldr pc,[pc,#-0x1b0]

    • If you run the bootloader only (boot + load the application using CAN or UART + program application to flash (from 0x20020), but don't jump to application), can you get a data abort?

    I ran the Bootloader, and then loaded the Application using CAN (at location 0x20020). If I don't jump to the Application, it doesn't generate the data abort. It only does it when I jump to the Application, and at the part that wants to create the task.

    The sys_intvecs.asm of my Application is:


    .ref _c_int00
    .ref vPortSWI
    .ref _dabort
    .ref phantomInterrupt
    .def resetEntry

    ;-------------------------------------------------------------------------------
    ; interrupt vectors

    resetEntry
    b _c_int00
    undefEntry
    b undefEntry
    b vPortSWI
    prefetchEntry
    b prefetchEntry
    b _dabort
    b phantomInterrupt
    ldr pc,[pc,#-0x1b0]
    ldr pc,[pc,#-0x1b0]

    Do I need to make any further changes? When I jump into the application and try to create the tasks, it's like it doesn't find the functions and jumps to the first memory locations.

    Thanks in advance

  • You don't need to change the sys_intvec.asm of your application. As mentioned before, the _dabort in your bootloader sys_intvecs.asm should be changed to #0x20020. 

    1. _dabort in your sys_intvecs.asm is not changed: the data abort in your application will cause the SW jump to wrong location for abort handler

    2. If you change _dabort to #0x20020, the data abort from your bootloader will not be handled properly. So you need to make sure that there is no data abort happened in your bootloader. Add a breakpoint at a instruction in dabort handler, then run your bootloader to make sure there is no data abort happened.

  • Hello QJ Wang.Sorry for my delay.

    I have a good news. I found the solution!

    I tried with the following vectors:

    ;-------------------------------------------------------------------------------
    ; interrupt vectors
    
    resetEntry:
        b    _c_int00        ; Reset
        b    #0x20018        ; Undefined instruction
        b    #0x20018        ; Software interrupt (SWI / SVC)
        b    #0x20018        ; Abort (prefetch)
        b    _dabort         ; Abort (data)
        b    #0x20018        ; phantomInterrupt
        ldr  pc,[pc,#-0x1b0] ; IRQ
        ldr  pc,[pc,#-0x1b0] ; FIRQ
    

    The theory being the offset is always 0x20020 to the same position in the application vector table. And the PC always has instr+8 to begin with.

    And now it's working !! I did the following steps:

    1 - Erase the total Flash (with UnityFlash)

    2- Load the Bootloader program (called UPGRADE2)

    3- With the target connected, I load the Application (at the 0x20020 position) (No erase Flash)

    4- Did click on 'RUN', and the CCS starts to run the Application program, create the tasks and running the scheduler.

    5- Did click on 'Reset' button, and the board starts to run the Bootaloader.

    And well, I have only one question more. I have the following code on my Bootloader.

    If I send the CAN_APP command, the Application program doesn't work.(I can see the " JUMP " on the terminal)

    void main(void)
    
    {
    
        g_pulUpdateSuccess[3] = 0x30002019;  /*version number, 03.00, in 2019*/
        uint32_t ID, Bytes, ulCmd, fnRetValue = 0;
        uint8_t ucUpdateStatus, ucStatus;
        /* Initialize SCI Routines to receive Command and transmit data */
        sciInit();
    
        canInit();
    
        sciSend(scilinREG, 14, " MODE: SYSTEM ");
    
    
        do{
    
            ID = PacketRead(CAN_PORT, CommandBuffer, &Bytes);
    
    
            switch (ID)
            {
    
            case CAN_ALIVE:
                sciSend(scilinREG, 7, " ALIVE ");
            PacketWrite(CAN_PORT, CAN_ACK, &ucStatus, 1);
            break;
    
            case Bootloader:
                sciSend(scilinREG, 7, " BOOT ");
    
                /* Copy the flash APIs to SRAM*/
                //_copyAPI2RAM_(&apiLoadStart, &apiRunStart, &apiLoadSize);
                memcpy(&apiRunStart, &apiLoadStart, (uint32)&apiLoadSize);
    
                /* Copy the .const section */
                //_copyAPI2RAM_(&constLoadStart, &constRunStart, &constLoadSize);
                memcpy(&constRunStart, &constLoadStart, (uint32)&constLoadSize);
    
                UpdaterCAN(CAN_PORT);
    
                break;
    
            case CAN_APP:
            /*SALTO DE SYSTEM A LA APP NUEVA*/
                sciSend(scilinREG, 6, " JUMP ");
    
                 g_ulTransferAddress = (uint32_t)APP_START_ADDRESS;     //here doesnt work
                 ((void (*)(void))g_ulTransferAddress)();
    
                break;
    
            case RESET:
                sciSend(scilinREG, 7, " RESET ");
            PacketWrite(CAN_PORT, CAN_ACK, &ucStatus, 1);
    
            //
            // Perform a software reset request.  This will cause the
            // microcontroller to reset; no further code will be executed.
            //
            // Use the reset in SYSECR register.
            //
            systemREG1->SYSECR = (0x10) << 14;
            break;
    
            default:
                sciSend(scilinREG, 11, " FUNC DEFA ");
    
              //  PacketWrite(canREG1, CAN_PING, &status, 1);
                break;
    
    
            }
        }while((ID!=CAN_APP) || (ID!=Bootloader));
    
    }
    

    But, if I write the jumps lines at the beginning of the code, the Applications program works fine!!!

    void main(void)
    
    {
    
        g_pulUpdateSuccess[3] = 0x30002019;  /*version number, 03.00, in 2019*/
        uint32_t ID, Bytes, ulCmd, fnRetValue = 0;
        uint8_t ucUpdateStatus, ucStatus;
        /* Initialize SCI Routines to receive Command and transmit data */
        sciInit();
    
        canInit();
    
        sciSend(scilinREG, 14, " MODE: SYSTEM ");
    
     //   sciSend(scilinREG, 5, " APP ");
               g_ulTransferAddress = (uint32_t)APP_START_ADDRESS;
               ((void (*)(void))g_ulTransferAddress)();             //HERE WORKS
    
    
        do{
    
            ID = PacketRead(CAN_PORT, CommandBuffer, &Bytes);
    
    
            switch (ID)
            {
    
            case CAN_ALIVE:
                sciSend(scilinREG, 7, " ALIVE ");
            PacketWrite(CAN_PORT, CAN_ACK, &ucStatus, 1);
            break;
            ...............
            etc...
            
    

    Well this is the last hehe. Thank you !!

  • Good to know it. Thanks