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.

TMS570LS0714: Read emulated EEPROM from Bootloader with FEE driver, undefEntry reset

Part Number: TMS570LS0714
Other Parts Discussed in Thread: HALCOGEN

Hello,

I've successfully implemented a CAN Bootloader on TMS570LS0714 based on SPNA241 application report: I can get the Bootloader answering to CAN commands, flashing the binary application file and running the application.

Unfortunately, our design doesn't allow GPIO to be checked for application update, so the idea is that our application is writing on a specific FEE block when it needs to be updated.

The Bootloader then reads this FEE block to now if needs to flash new application or jump to the application directly.

Read/Write operations on FEE from application are working fine.

In the Bootloader, I enabled the FEE driver from HALCOgen, and I changed the linker file to:

/*----------------------------------------------------------------------------*/
/* Linker Settings */

--retain="*(.intvecs)"

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

/*----------------------------------------------------------------------------*/
/* Memory Map */

MEMORY
{
VECTORS (X) : origin=0x00000000 length=0x00000020 vfill = 0xffffffff
FLASH0 (RX) : origin=0x00000020 length=0x000BFFE0 vfill = 0xffffffff
SRAM (RW) : origin=0x08002000 length=0x0001EB00
STACK (RW) : origin=0x08000000 length=0x00001500
/* USER CODE BEGIN (2) */
#if 1
ECC_VEC (R) : origin=(0xf0400000 + (start(VECTORS) >> 3))
length=(size(VECTORS) >> 3)
ECC={algorithm=algoL2R4F021, input_range=VECTORS}

ECC_FLA0 (R) : origin=(0xf0400000 + (start(FLASH0) >> 3))
length=(size(FLASH0) >> 3)
ECC={algorithm=algoL2R4F021, input_range=FLASH0 }
#endif
/* USER CODE END */
}

/* USER CODE BEGIN (3) */
ECC
{
algoL2R4F021 : address_mask = 0xfffffff8 /* Address Bits 31:3 */
hamming_mask = R4 /* Use R4/R5 build in Mask */
parity_mask = 0x0c /* Set which ECC bits are Even and Odd parity */
mirroring = F021 /* RM57Lx and TMS570LCx are build in F021 */
}
/* USER CODE END */

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


SECTIONS
{
.intvecs : {} > VECTORS

flashAPI:
{
.\TMS570LS07x\source\Fapi_UserDefinedFunctions.obj (.text)
.\source\bl_flash.obj (.text)
--library= "c:\ti\Hercules\F021 Flash API\02.01.01\F021_API_CortexR4_BE.lib" (.text)
} palign=8 load = FLASH0, run = SRAM, LOAD_START(apiLoadStart), RUN_START(apiRunStart), SIZE(apiLoadSize)

.text : {} > FLASH0
.const : {} palign=8 load=FLASH0, run = SRAM, LOAD_START(constLoadStart), RUN_START(constRunStart), SIZE(constLoadSize)
.cinit : {} > FLASH0
.pinit : {} > FLASH0
.data : {} > SRAM
.bss : {} > SRAM
.sysmem : {} > SRAM

/* USER CODE BEGIN (4) */
FEE_TEXT_SECTION : {} > FLASH0
FEE_CONST_SECTION : {} > FLASH0
FEE_DATA_SECTION : {} > SRAM
/* USER CODE END */
}

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

 to add FEE sections.

In the Bootloader main file, I initialize the FEE with :

TI_FeeModuleStatusType Status;

TI_Fee_Init();
do
{
TI_Fee_MainFunction();
fee_delay();
Status=TI_Fee_GetStatus(0 );
}
while(Status!= IDLE);

and I run the rest of the CAN Bootloader (copy the flash APIs to SRAM, ConfigureCANDevice and run UpdaterCAN).

With this configuration, the Bootloader doesn't answer anymore to ping commands and when I break the execution, the program is stuck in undefEntry reset.

I cannot determine exactly what causes the program to reset by stepping with the debugger.

Can someone please help me to read EEPROM  from Bootloader, whether with FEE driver or directly with F021 API?

Thank you

  • Hello Olivier,

    You can use FEE driver in bootloader and in application. The bootloader should use the same FEE configuration used in your application code.

  • Dear QJ,

    Thank you for your answer, but can you please have a look at the project attached?

    I've check that Bootloader and Application HALCOgen  FEE configurations are identical.

    If I run the TI_Fee_Init() function before the copy of flash API and const sections to to SRAM, the sofware will reset to undefEntry within TI_Fee_Init().

    If I run the TI_Fee_Init() after the copy to SRAM, the progran will run and respond to ping commands, but will reset within Fapi_BlockProgram() when trying to flash with CAN_COMMAND_GET_DATA  command.

    If I don't run TI_Fee_Init() at all, the bootloader will run correctly.CMU_BL - TMS570LS0714.zip

    Thank you for your help.

  • I will take a look. 

  • Hello QJ,

    I made some more debugging and it seems that after the TI_Fee_MainFunction() is executed in 

    TI_Fee_Init();
    do
    {
    TI_Fee_MainFunction();
    fee_delay();
    Status=TI_Fee_GetStatus(0 );
    }
    while(Status!= IDLE);

    I get a reset when calling any BL function that resides in SRAM.

    Regards,

    Olivier

  • Hi Olivier,

    I don't have USB-CAN adaptor at home, so I will do test in office tomorrow.

  • Hi Olivier,

    I enabled FEE driver in bootloader, and I got a similar issue. The bootloader code gets stuck when performing flash operation (erase or program). I will investigate this problem further.

  • Hi Olivier,

    I found the issue in my project. In my first test, the application is located at 0x10000. But I noticed this morning that the size of bootloader is larger than 0x10000 since the FEE is used in bootloader. I changed the application start address to 0x40000, everything works fine.

    BTW, I use UART bootloader for testing.

    Attached is the my test code in main()

    /********************************************************************************************************
    *
    * bl_main.c      : The main filefor the boot loader.
    * Author         : QJ Wang. qjwang@ti.com
    * Date           : 2-18-2016
    *
    * Copyright (c) 2006-2011 Texas Instruments Incorporated.  All rights reserved.
    * Software License Agreement
    *
    * Texas Instruments (TI) is supplying this software for use solely and
    * exclusively on TI's microcontroller products. The software is owned by
    * TI and/or its suppliers, and is protected under applicable copyright
    * laws. You may not combine this software with "viral" open-source
    * software in order to form a larger program.
    *
    * THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
    * NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
    * NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    * A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
    * CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
    * DAMAGES, FOR ANY REASON WHATSOEVER.
    *
    * Author:  Qingjun Wang  (qjwang@ti.com)
    *---------------------------------------------------------------------------------------------------------------------
    * Revision History
    *---------------------------------------------------------------------------------------------------------------------
    * Version          Date        Author         Description
    *---------------------------------------------------------------------------------------------------------------------
    * 00.10.00       19/09/2012    QJ Wang        1. Initial Version
    * 00.10.01       10/01/2014    QJ Wang        1. Changes for Rev2.01.00 F021 Flash API
    * 00.10.02       11/12/2014    QJ Wang        1. Changes for Rev2.01.01 F021 Flash API
    * 00.20.00       18/02/2016    QJ Wang        1. Rewrote code for y-modem protocol, and CRC16
    *                                             2. Changes in bl_flash.c, bl_link.cmd
    *                                             3. Changed App start address to 0x10100, The 0x10000~0x10100 is left for
    *                                                application update status
    *                                             4. Added TMS570LS0714 devices
    ***********************************************************************************************************/
    
    #include "bl_config.h"
    
    #if defined (CAN_ENABLE_UPDATE)
    	#include "bl_can.h"
    	#include "can.h"
    #endif
    
    #if defined (SPI_ENABLE_UPDATE)
    	#include "bl_spi.h"
    	#include "spi.h"
    #endif
    
    #if defined (UART_ENABLE_UPDATE)
    	#include "bl_uart.h"
    #endif
    
    #include "system.h"
    #include "bl_check.h"
    #include "sci_common.h"
    #include "rti.h"
    #include "gio.h"
    
    #include "ti_fee.h"
    
    /*****************************************************************************
    * bl_main
    ******************************************************************************/
    #if defined (SPI_ENABLE_UPDATE) || defined(UART_ENABLE_UPDATE) || defined(CAN_ENABLE_UPDATE)
    
    /*****************************************************************************
    *
    * This holds the current remaining size in bytes to be downloaded.
    *
    ******************************************************************************/
    uint32_t g_ulTransferSize;
    
    /*****************************************************************************
    *
    * This holds the current address that is being written to during a download
    * command.
    *
    ******************************************************************************/
    uint32_t g_ulTransferAddress;
    
    /*****************************************************************************
    *
    * This is the data buffer used during transfers to the boot loader.
    *
    ******************************************************************************/
    uint32_t g_pulDataBuffer[BUFFER_SIZE];
    
    /*****************************************************************************
    *
    * This is the data buffer used for update status.
    *
    * g_pulUpdateSuccess[] are used to store application update status and application
    * image's version etc
    ******************************************************************************/
    
    uint32_t g_pulUpdateSuccess[] = {0x5A5A5A5A, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
    uint32_t g_ulUpdateStatusAddr = APP_STATUS_ADDRESS;
    
    uint32_t g_ulUpdateBufferSize = 32; /*32 bytes or 8 32-bit words*/
    
    #define E_PASS     		0
    #define E_FAIL     		0x1U
    #define E_TIMEOUT  		0x2U
    
    /*****************************************************************************
    *
    * This is an specially aligned buffer pointer to g_pulDataBuffer to make
    * copying to the buffer simpler.  It must be offset to end on an address that
    * ends with 3.
    *
    ******************************************************************************/
    uint8_t *g_pucDataBuffer;
    
    extern unsigned int apiLoadStart;
    extern unsigned int apiLoadSize;
    extern unsigned int apiRunStart;
    
    
    extern unsigned int constLoadStart;
    extern unsigned int constLoadSize;
    extern unsigned int constRunStart;
    
    uint16 u16JobResult,Status;
    Std_ReturnType oResult=E_OK;
    unsigned char read_data[100]={0};
    
    uint8 SpecialRamBlock[100];
    
    /*****************************************************************************
    *
    * This holds the current address that is being written to during a download
    * command.
    *
    ******************************************************************************/
    void delay(unsigned int delayval)
    {
    	while (delayval--);
    }
    
    
    void main(void)
    {
    	uint32_t fnRetValue;
    
    	unsigned int BlockNumber;
        unsigned int loop;
    
        /* Initialize FEE. This will create Virtual sectors, initialize global variables etc.*/
    
        /* Copy the flash APIs to SRAM*/
        memcpy(&apiRunStart, &apiLoadStart, (uint32)&apiLoadSize);
        /* Copy the .const section */
        memcpy(&constRunStart, &constLoadStart, (uint32)&constLoadSize);
    
    	/* Initialize RTI driver */
    	gioInit();
    	gioSetDirection(gioPORTB, 0xFFFF);
    
        /* Initialize RAM array.*/
        for(loop=0;loop<100;loop++) SpecialRamBlock[loop] = loop;
    
        TI_Fee_Init();
        do
        {
            TI_Fee_MainFunction();
            delay(0x100);
            Status=TI_Fee_GetStatus(0 );
        }
        while(Status!= IDLE);
    
        BlockNumber=0x1;
        TI_Fee_WriteAsync(BlockNumber, &SpecialRamBlock[0]);
        do
        {
            TI_Fee_MainFunction();
            delay(0x100);
            Status=TI_Fee_GetStatus(0);
        }
        while(Status!=IDLE);
    
    
    	/*Enable RTI to check if interrupt affect flash erase/program*/
    	rtiInit();
    	/* Enable RTI Compare 0 interrupt notification */
    	rtiEnableNotification(rtiNOTIFICATION_COMPARE0);
    
    	/* Enable IRQ - Clear I flag in CPS register */
    	/* Note: This is usually done by the OS or in an svc dispatcher */
    	_enable_IRQ();
    
    	/* Start RTI Counter Block 0 */
    	rtiStartCounter(rtiCOUNTER_BLOCK0);
    
    	/* Initialize SCI Routines to receive Command and transmit data */
    	sciInit();
    
    	#if defined (SPI_ENABLE_UPDATE)
    	UART_putString(UART, "\r Hercules MCU SPI BootLoader ");
    	#endif
    	#if defined (CAN_ENABLE_UPDATE)
    	UART_putString(UART, "\r Hercules MCU CAN BootLoader ");
    	#endif
    	#if defined (UART_ENABLE_UPDATE)
    	UART_putString(UART, "\r Hercules MCU UART BootLoader ");
    	#endif
    
    	UART_putString(UART, "\r TI Safety MCU Application Team, qjwang@ti.com \r\r");
    
    	//
    	//  See if an update should be performed.
    	//
    	fnRetValue = CheckForceUpdate();
    
    	//fnRetValue = 0;
    	if (!fnRetValue)
    	{
    		#ifdef DEBUG_MSG
    		UART_putString(UART, "\r Jump to application...  ");
    		#endif
    		g_ulTransferAddress = (uint32_t)APP_START_ADDRESS;
    		((void (*)(void))g_ulTransferAddress)();
    	}
    
    	//
    	//  Configure the microcontroller.
    	//
    	//EnterBootLoader
    	#ifdef CAN_ENABLE_UPDATE
    	ConfigureCANDevice(CAN_PORT);
    	#endif
    	#ifdef SPI_ENABLE_UPDATE
    	ConfigureSPIDevice(SPI_PORT);
    	#endif
    	#ifdef UART_ENABLE_UPDATE
    	ConfigureUartDevice();
    	#endif
    
    	//
    	// Branch to the update handler. Use can1
    	//
    	#ifdef CAN_ENABLE_UPDATE
    	UpdaterCAN(CAN_PORT);
    	#endif
    
    	#ifdef UART_ENABLE_UPDATE
    	UpdaterUART();
    	#endif
    	#ifdef SPI_ENABLE_UPDATE
    	UpdaterSPI(SPI_PORT);
    	#endif
    
    }
    
    
    /******************************************************************************
    *
    * Configures the microcontroller.
    *
    * This function configures the peripherals and GPIOs of the microcontroller,
    * preparing it for use by the boot loader.  The interface that has been
    * selected as the update port will be configured, and auto-baud will be
    * performed if required.
    *
    * \return None.
    *
    ******************************************************************************/
    #ifdef SPI_ENABLE_UPDATE
    void ConfigureSPIDevice(spiBASE_t *node)
    {
    	//
    	// Initialize the SPI1 as slave mode
    	// Enable the SPI interface in slave mode.
    	// Set the SPI protocol to Motorola with default clock high and data valid on the rising edge.
    	//
    	spiInit();
    }
    #endif
    
    #ifdef UART_ENABLE_UPDATE
    void ConfigureUartDevice(void)
    {
    	//
    	// Enable the the clocks to the UART and GPIO modules.
    	//
    	sciInit();
    }
    #endif
    
    
    void rtiNotification(uint32 notification)
    {
    	/*  enter user code between the USER CODE BEGIN and USER CODE END. */
    	gioSetBit(gioPORTB, 7, gioGetBit(gioPORTB, 7) ^ 1);
    }
    
    #endif
    
    

  • Hi QJ,

    I did not think about the size of the bootloader. That was indeed the issue.

    It works now, thank you for your support.

    Best regards,

    Olivier