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.
Hi,
I customized bootloader code for SD Card bootloader.Everything is fine but this code is not able to jump and execute the application file.Please check if i am missing something.
Attaching bootloader codeX24015_boot_loader_sd.rar
This is my bootloader code for bl_main.c
//*****************************************************************************
//
// bl_main.c - The file holds the main control loop of the boot loader.
//
// Copyright (c) 2006-2020 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.
//
// This is part of revision 2.2.0.295 of the Tiva Firmware Development Package.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>
#include <stdarg.h>
#include "inc/hw_gpio.h"
#include "inc/hw_flash.h"
#include "inc/hw_i2c.h"
#include "inc/hw_memmap.h"
#include "inc/hw_nvic.h"
#include "inc/hw_ssi.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "bl_config.h"
#include "bootloader/bl_flash.h"
#include "bootloader/bl_hooks.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/ssi.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/sysctl.h"
#include "Petit/pff.h"
#include "Petit/pffconf.h"
#include "custom.h"
//*****************************************************************************
// Specifies how many bytes read from file to write flash at one time
// if higher increase ram size decrease program load time
// else decrease ram size increase program load time
//*****************************************************************************
#define WRITE_DATA_PACKET_SIZE 128//128 --DEFAULT
static BYTE bWriteBuffer[WRITE_DATA_PACKET_SIZE];
static FATFS fatfs;
// Function Prototypes
void ConfigureSSIPort(uint32_t ui32Protocol, uint32_t ui32Mode,
uint32_t ui32BitRate, uint32_t ui32DataWidth);
//*****************************************************************************
//
// Make sure that the application start address falls on a flash page boundary
//
//*****************************************************************************
#if (APP_START_ADDRESS & (FLASH_PAGE_SIZE - 1))
#error ERROR: APP_START_ADDRESS must be a multiple of FLASH_PAGE_SIZE bytes!
#endif
//*****************************************************************************
//
// Make sure that the flash reserved space is a multiple of flash pages.
//
//*****************************************************************************
#if (FLASH_RSVD_SPACE & (FLASH_PAGE_SIZE - 1))
#error ERROR: FLASH_RSVD_SPACE must be a multiple of FLASH_PAGE_SIZE bytes!
#endif
//*****************************************************************************
//
//! \addtogroup bl_main_api
//! @{
//
//*****************************************************************************
//*****************************************************************************
//
// A prototype for the function (in the startup code) for calling the
// application.
//
//*****************************************************************************
extern void CallApplication(uint32_t ui32Base);
//*****************************************************************************
//
// A prototype for the function (in the startup code) for a predictable length
// delay.
//
//*****************************************************************************
extern void Delay(uint32_t ui32Count);
//*****************************************************************************
//
// Converts a word from big endian to little endian. This macro uses compiler-
// specific constructs to perform an inline insertion of the "rev" instruction,
// which performs the byte swap directly.
//
//*****************************************************************************
#if defined(ewarm)
#include <intrinsics.h>
#define SwapWord(x) __REV(x)
#endif
#if defined(codered) || defined(gcc) || defined(sourcerygxx)
#define SwapWord(x) __extension__ \
({ \
register uint32_t __ret, __inp = x; \
__asm__("rev %0, %1" : "=r" (__ret) : "r" (__inp)); \
__ret; \
})
#endif
#if defined(rvmdk) || defined(__ARMCC_VERSION)
#define SwapWord(x) __rev(x)
#endif
#if defined(ccs)
uint32_t
SwapWord(uint32_t x)
{
__asm(" rev r0, r0\n"
" bx lr\n"); // need this to make sure r0 is returned
return(x + 1); // return makes compiler happy - ignored
}
#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.
//
//*****************************************************************************
void ConfigureDevice(void)
{
#ifdef CRYSTAL_FREQ
//
// Since the crystal frequency was specified, enable the main oscillator
// and clock the processor from it.
//
#if defined(TARGET_IS_TM4C129_RA0) || \
defined(TARGET_IS_TM4C129_RA1) || \
defined(TARGET_IS_TM4C129_RA2)
//
// Since the crystal frequency was specified, enable the main oscillator
// and clock the processor from it. Check for whether the Oscillator range
// has to be set and wait states need to be updated
//
if(CRYSTAL_FREQ >= 10000000)
{
HWREG(SYSCTL_MOSCCTL) |= (SYSCTL_MOSCCTL_OSCRNG);
HWREG(SYSCTL_MOSCCTL) &= ~(SYSCTL_MOSCCTL_PWRDN |
SYSCTL_MOSCCTL_NOXTAL);
}
else
{
HWREG(SYSCTL_MOSCCTL) &= ~(SYSCTL_MOSCCTL_PWRDN |
SYSCTL_MOSCCTL_NOXTAL);
}
//
// Wait for the Oscillator to Stabilize
//
Delay(524288);
if(CRYSTAL_FREQ > 16000000)
{
HWREG(SYSCTL_MEMTIM0) = (SYSCTL_MEMTIM0_FBCHT_1_5 |
(1 << SYSCTL_MEMTIM0_FWS_S) |
SYSCTL_MEMTIM0_EBCHT_1_5 |
(1 << SYSCTL_MEMTIM0_EWS_S) |
SYSCTL_MEMTIM0_MB1);
HWREG(SYSCTL_RSCLKCFG) = (SYSCTL_RSCLKCFG_MEMTIMU |
SYSCTL_RSCLKCFG_OSCSRC_MOSC);
}
else
{
HWREG(SYSCTL_RSCLKCFG) = (SYSCTL_RSCLKCFG_OSCSRC_MOSC);
}
#else
HWREG(SYSCTL_RCC) &= ~(SYSCTL_RCC_MOSCDIS);
Delay(524288);
HWREG(SYSCTL_RCC) = ((HWREG(SYSCTL_RCC) & ~(SYSCTL_RCC_OSCSRC_M)) |
SYSCTL_RCC_OSCSRC_MAIN);
#endif
#endif
}
//*****************************************************************************
//
//! Configure the SSI port the SPI for the SD interface in SPI mode.
//
//*****************************************************************************
void ConfigureSSI(void)
{
/* Enable SD SSI peripherals */
ROM_SysCtlPeripheralEnable(SD_SYSCTL_PERIPH_SSI);
ROM_SysCtlPeripheralEnable(SD_SYSCTL_PERIPH_GPIO_SCLK);
ROM_SysCtlPeripheralEnable(SD_SYSCTL_PERIPH_GPIO_MOSI);
ROM_SysCtlPeripheralEnable(SD_SYSCTL_PERIPH_GPIO_MISO);
ROM_SysCtlPeripheralEnable(SD_SYSCTL_PERIPH_GPIO_FSS);
/* SSI-1 Configure Pins */
// Enable pin for SSI SSI1CLK
ROM_GPIOPinConfigure(SD_GPIO_SCLK_PINCFG);
ROM_GPIOPinTypeSSI(SD_GPIO_SCLK_BASE, SD_GPIO_SCLK_PIN);
// Enable pin for SSI SSI1XDAT0(MOSI)
ROM_GPIOPinConfigure(SD_GPIO_MOSI_PINCFG);
ROM_GPIOPinTypeSSI(SD_GPIO_MOSI_BASE, SD_GPIO_MOSI_PIN);
// Enable pin for SSI SSI1XDAT1(MISO)
ROM_GPIOPinConfigure(SD_GPIO_MISO_PINCFG);
ROM_GPIOPinTypeSSI(SD_GPIO_MISO_BASE, SD_GPIO_MISO_PIN);
// Enable pin PB4 for SSI1 SSI1FSS
//GPIOPinConfigure(SD_GPIO_FSS_PINCFG);
//GPIOPinTypeSSI(SD_GPIO_FSS_BASE, SD_GPIO_FSS_PIN);
// Enable pin PK7 for GPIOOutput (SSI1FSS_SD)
ROM_GPIOPinTypeGPIOOutput(SD_GPIO_FSS_BASE, SD_GPIO_FSS_PIN);
/* Configure pad settings */
/* SCLK (PD3) */
MAP_GPIOPadConfigSet(SD_GPIO_SCLK_BASE,
SD_GPIO_SCLK_PIN,
GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD);
/* MOSI (PD1) */
MAP_GPIOPadConfigSet(SD_GPIO_MOSI_BASE,
SD_GPIO_MOSI_PIN,
GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD);
/* MISO (PD0) */
MAP_GPIOPadConfigSet(SD_GPIO_MISO_BASE,
SD_GPIO_MISO_PIN,
GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD_WPU);
/* CS (PD2) */
MAP_GPIOPadConfigSet(SD_GPIO_FSS_BASE,
SD_GPIO_FSS_PIN,
GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD);
//
// Configure and enable the SSI port for SPI master mode. Use SSI1,
// system clock supply, idle clock level low and active low clock in
// Freescale SPI mode, master mode, 1MHz SSI frequency, and 8-bit data.
// For SPI mode, you can set the polarity of the SSI clock when the SSI
// unit is idle. You can also configure what clock edge you want to
// capture data on. Please reference the datasheet for more information on
// the different SPI modes.
//
uint32_t sysclock = 120000000;
ROM_SSIConfigSetExpClk(SD_SSI_BASE, sysclock, SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 400000, 8);
//
// Enable the SSI1 module.
//
ROM_SSIEnable(SD_SSI_BASE);
}
//*****************************************************************************
//
//! This function performs the update on the selected port.
//!
//! This function is called directly by the boot loader or it is called as a
//! result of an update request from the application.
//!
//! \return Never returns.
//
//*****************************************************************************
void Updater(void)
{
/*
uint32_t EraseSize=0;
uint32_t AppAddress=0;
uint32_t i,j,k,l;
uint32_t WriteDataPacketCount;
uint32_t WriteDataPacketRemainder;
FRESULT rc;
UINT br;
*/
uint32_t EraseSize=0;
uint32_t AppAddress=0;
uint32_t i,j;
uint32_t WriteDataPacketCount,WriteDataPacketRemainder;
FRESULT rc;
FATFS fatfs;
UINT br;
// Initialize UART for console messages
ConfigureUART();
// Initialize the SSI controller
ConfigureSSI();
// Led gpio pin settings
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
ROM_GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE, GPIO_PIN_1);
// Led blink
ROM_GPIOPinWrite(GPIO_PORTN_BASE,GPIO_PIN_1,GPIO_PIN_1);
for(i=0;i<100000;i++);
ROM_GPIOPinWrite(GPIO_PORTN_BASE,GPIO_PIN_1,!GPIO_PIN_1);
for(i=0;i<100000;i++);
// try 10 times to mounting sd card. Blink led on every try.
j=0;
do{
rc = pf_mount(&fatfs);
ROM_GPIOPinWrite(GPIO_PORTN_BASE,GPIO_PIN_1,GPIO_PIN_1);
for(i=0;i<100000;i++);
ROM_GPIOPinWrite(GPIO_PORTN_BASE,GPIO_PIN_1,!GPIO_PIN_1);
for(i=0;i<100000;i++);
j++;
}
while(rc && j<10);
// if fail sd card mounting exit otherwise continue
if(!rc){
// try 10 times to opening app.bin file which in sd card(if exist). Blink led on every try.
j=0;
do{
rc = pf_open("X24015.bin");
ROM_GPIOPinWrite(GPIO_PORTN_BASE,GPIO_PIN_1,GPIO_PIN_1);
for(i=0;i<100000;i++);
ROM_GPIOPinWrite(GPIO_PORTN_BASE,GPIO_PIN_1,!GPIO_PIN_1);
for(i=0;i<100000;i++);
j++;
}
while(rc && j<10);
// if fail app.bin file opening exit otherwise continue
if(!rc)
{
UARTprintf("fatfs.fsize %d \n" ,fatfs.fsize);
// if file size is not multiple of 4 exit otherwise continue
if((fatfs.fsize & 0x03)==0)
{
// Calculate page count that will erase according to app.bin file size
EraseSize = fatfs.fsize/FLASH_PAGE_SIZE;
if(fatfs.fsize%FLASH_PAGE_SIZE)
EraseSize++;
// Erase necessary pages
AppAddress=APP_START_ADDRESS;
for(i=0;i<EraseSize;i++)
{
ROM_FlashErase(AppAddress);
AppAddress += FLASH_PAGE_SIZE;
}
AppAddress=APP_START_ADDRESS; // Set app address to write
// Calculate packet count according to write data packet size that user defined
WriteDataPacketCount=fatfs.fsize/WRITE_DATA_PACKET_SIZE;
UARTprintf("WriteDataPacketCount %d \n" ,WriteDataPacketCount);
// Calculate remainder of division
WriteDataPacketRemainder=fatfs.fsize%WRITE_DATA_PACKET_SIZE;
UARTprintf("WriteDataPacketRemainder %d \n" ,WriteDataPacketRemainder);
// Read number of WRITE_DATA_PACKET_SIZE bytes from app.bin file and
// write it to the flash memory number of WriteDataPacketCount times.
for(i=0;i<WriteDataPacketCount;i++){
pf_read(bWriteBuffer,WRITE_DATA_PACKET_SIZE,&br);
ROM_FlashProgram((uint32_t*)bWriteBuffer,AppAddress,WRITE_DATA_PACKET_SIZE);
AppAddress += WRITE_DATA_PACKET_SIZE;
UARTPutch('.');
}
// Read 4 bytes from app.bin file and
// write it to the flash memory number of WriteDataPacketRemainder times.
for(i=0;i<WriteDataPacketRemainder/4;i++)
{
pf_read(bWriteBuffer,4,&br);
ROM_FlashProgram((uint32_t*)bWriteBuffer,AppAddress,4);
AppAddress += 4;
}
// If done blink led 2 times with long delay.
ROM_GPIOPinWrite(GPIO_PORTN_BASE,GPIO_PIN_1,GPIO_PIN_1);
for(i=0;i<1000000;i++);
ROM_GPIOPinWrite(GPIO_PORTN_BASE,GPIO_PIN_1,!GPIO_PIN_1);
for(i=0;i<1000000;i++);
ROM_GPIOPinWrite(GPIO_PORTN_BASE,GPIO_PIN_1,GPIO_PIN_1);
for(i=0;i<1000000;i++);
ROM_GPIOPinWrite(GPIO_PORTN_BASE,GPIO_PIN_1,!GPIO_PIN_1);
for(i=0;i<1000000;i++);
UARTprintf("Done1\n");
// Reset and disable the SSI peripherals used by the boot loader.
ROM_SysCtlPeripheralDisable(SD_SYSCTL_PERIPH_SSI);
ROM_SysCtlPeripheralReset(SD_SYSCTL_PERIPH_SSI);
ROM_SysCtlPeripheralDisable(SD_SYSCTL_PERIPH_GPIO_SCLK);
ROM_SysCtlPeripheralReset(SD_SYSCTL_PERIPH_GPIO_SCLK);
ROM_SysCtlPeripheralDisable(SD_SYSCTL_PERIPH_GPIO_MOSI);
ROM_SysCtlPeripheralReset(SD_SYSCTL_PERIPH_GPIO_MOSI);
ROM_SysCtlPeripheralDisable(SD_SYSCTL_PERIPH_GPIO_MISO);
ROM_SysCtlPeripheralReset(SD_SYSCTL_PERIPH_GPIO_MISO);
ROM_SysCtlPeripheralDisable(SD_SYSCTL_PERIPH_GPIO_FSS);
ROM_SysCtlPeripheralReset(SD_SYSCTL_PERIPH_GPIO_FSS);
for(i=0;i<1000000;i++);
UARTprintf("Done2\n");
for(i=0;i<1000000;i++);
((int (*)(void))APP_START_ADDRESS)();
HWREG(NVIC_APINT) = (NVIC_APINT_VECTKEY | NVIC_APINT_SYSRESETREQ);
while(1);
}
}
}
// for(i=0;i<1000000;i++);
// UARTprintf("Done11\n");
// for(i=0;i<1000000;i++);
// Reset
((int (*)(void))APP_START_ADDRESS)();
HWREG(NVIC_APINT) = (NVIC_APINT_VECTKEY | NVIC_APINT_SYSRESETREQ);
}
//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************
This is bl_config.h file
where start Address is #define APP_START_ADDRESS 0x00004000
//*****************************************************************************
//
// bl_config.h - The configurable parameters of the boot loader.
//
// Copyright (c) 2010-2017 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.
//
// This is part of revision 2.1.4.178 of the Tiva Firmware Development Package.
//
//*****************************************************************************
#ifndef __BL_CONFIG_H__
#define __BL_CONFIG_H__
#include "custom.h"
//*****************************************************************************
//
// The following defines are used to configure the operation of the boot
// loader. For each define, its interactions with other defines are described.
// First is the dependencies (i.e. the defines that must also be defined if it
// is defined), next are the exclusives (i.e. the defines that can not be
// defined if it is defined), and finally are the requirements (i.e. the
// defines that must be defined if it is defined).
//
// The following defines must be defined in order for the boot loader to
// operate:
//
// One of CAN_ENABLE_UPDATE, ENET_ENABLE_UPDATE, I2C_ENABLE_UPDATE,
// SSI_ENABLE_UPDATE, UART_ENABLE_UPDATE, or USB_ENABLE_UPDATE
// APP_START_ADDRESS
// STACK_SIZE
// BUFFER_SIZE
//
//*****************************************************************************
//*****************************************************************************
//
// The frequency of the crystal used to clock the microcontroller.
//
// This defines the crystal frequency used by the microcontroller running the
// boot loader. If this is unknown at the time of production, then use the
// UART_AUTOBAUD feature to properly configure the UART.
//
// Depends on: None
// Exclusive of: None
// Requires: None
//
//*****************************************************************************
#define CRYSTAL_FREQ 25000000
//*****************************************************************************
//
// This enables the boosting of the LDO voltage to 2.75V. For boot loader
// configurations that enable the PLL (for example, using the Ethernet port)
// on a part that has the PLL errata, this should be enabled. This applies to
// revision A2 of Fury-class devices.
//
// Depends on: None
// Exclusive of: None
// Requires: None
//
//*****************************************************************************
//#define BOOST_LDO_VOLTAGE
//*****************************************************************************
//
// The starting address of the application. This must be a multiple of 1024
// bytes (making it aligned to a page boundary). A vector table is expected at
// this location, and the perceived validity of the vector table (stack located
// in SRAM, reset vector located in flash) is used as an indication of the
// validity of the application image.
//
// The flash image of the boot loader must not be larger than this value.
//
// Depends on: None
// Exclusive of: None
// Requires: None
//
//*****************************************************************************
#define APP_START_ADDRESS 0x00004000
//*****************************************************************************
//
// The address at which the application locates its exception vector table.
// This must be a multiple of 1KB (making it aligned to a page boundary).
// Typically, an application will start with its vector table and this value
// will default to APP_START_ADDRESS. This option is provided to cater for
// applications which run from external memory which may not be accessible by
// the NVIC (the vector table offset register is only 30 bits long).
//
// Depends on: None
// Exclusive of: None
// Requires: None
//
//*****************************************************************************
#define VTABLE_START_ADDRESS 0x00004000
//*****************************************************************************
//
// The size of a single, erasable page in the flash. This must be a power
// of 2. The default value of 1KB represents the page size for the internal
// flash on all Tiva MCUs and this value should only be overridden if
// configuring a boot loader to access external flash devices with a page size
// different from this.
//
// Depends on: None
// Exclusive of: None
// Requires: None
//
//*****************************************************************************
#define FLASH_PAGE_SIZE 0x00004000
//*****************************************************************************
//
// The amount of space at the end of flash to reserved. This must be a
// multiple of 1024 bytes (making it aligned to a page boundary). This
// reserved space is not erased when the application is updated, providing
// non-volatile storage that can be used for parameters.
//
// Depends on: None
// Exclusive of: None
// Requires: None
//
//*****************************************************************************
//#define FLASH_RSVD_SPACE 0x00000800
//*****************************************************************************
//
// The number of words of stack space to reserve for the boot loader.
//
// Depends on: None
// Exclusive of: None
// Requires: None
//
//*****************************************************************************
#define STACK_SIZE 1024
//*****************************************************************************
//
// The number of words in the data buffer used for receiving packets. This
// value must be at least 3. If using autobauding on the UART, this must be at
// least 20. The maximum usable value is 65 (larger values will result in
// unused space in the buffer).
//
// Depends on: None
// Exclusive of: None
// Requires: None
//
//*****************************************************************************
#define BUFFER_SIZE 20
//*****************************************************************************
//
// Enables the pin-based forced update check. When enabled, the boot loader
// will go into update mode instead of calling the application if a pin is read
// at a particular polarity, forcing an update operation. In either case, the
// application is still able to return control to the boot loader in order to
// start an update.
//
// Depends on: None
// Exclusive of: None
// Requires: FORCED_UPDATE_PERIPH, FORCED_UPDATE_PORT, FORCED_UPDATE_PIN,
// FORCED_UPDATE_POLARITY
//
//*****************************************************************************
#define ENABLE_UPDATE_CHECK
//*****************************************************************************
//
// The GPIO module to enable in order to check for a forced update. This will
// be one of the SYSCTL_RCGCGPIO_Rx values, where Rx represnts the required
// GPIO port. This applies to Blizzard class and later devices for FORCED_UPDATE_PORT.
//
// Depends on: ENABLE_UPDATE_CHECK
// Exclusive of: None
// Requries: None
//
//*****************************************************************************
#define FORCED_UPDATE_PERIPH SYSCTL_RCGCGPIO_R5 /* Port-F */
//*****************************************************************************
//
// The GPIO port to check for a forced update. This will be one of the
// GPIO_PORTx_BASE values, where "x" is replaced with the port name (such as
// B). The value of "x" should match the value of "x" for
// FORCED_UPDATE_PERIPH.
//
// Depends on: ENABLE_UPDATE_CHECK
// Exclusive of: None
// Requries: None
//
//*****************************************************************************
#define FORCED_UPDATE_PORT GPIO_PORTF_BASE
//*****************************************************************************
//
// The pin to check for a forced update. This is a value between 0 and 7.
//
// Depends on: ENABLE_UPDATE_CHECK
// Exclusive of: None
// Requries: None
//
//*****************************************************************************
#define FORCED_UPDATE_PIN 4 // PF4 connected to BOOT switch
//*****************************************************************************
//
// The polarity of the GPIO pin that results in a forced update. This value
// should be 0 if the pin should be low and 1 if the pin should be high.
//
// Depends on: ENABLE_UPDATE_CHECK
// Exclusive of: None
// Requries: None
//
//*****************************************************************************
#define FORCED_UPDATE_POLARITY 0 // PF0 = 0 triggers boot loader update
//*****************************************************************************
//
// This enables a weak pull up for the GPIO pin used in a forced update. This
// value should be 0 if the pin should be have an internal weak pull down and
// 1 if the pin should have an interal weak pull up.
// Only FORCED_UPDATE_WPU or FORCED_UPDATE_WPD or neither should be defined.
//
// Depends on: ENABLE_UPDATE_CHECK
// Exclusive of: None
// Requries: None
//
//*****************************************************************************
//#define FORCED_UPDATE_WPU
//#define FORCED_UPDATE_WPD
//*****************************************************************************
//
// This enables the use of the GPIO_LOCK mechanism for configuration of
// protected GPIO pins (for example JTAG pins). If this value is not defined,
// the locking mechanism will not be used. The only legal values for this
// feature are GPIO_LOCK_KEY for Fury devices and GPIO_LOCK_KEY_DD for all
// other devices except Sandstorm devices, which do not support this feature.
//
// Depends on: ENABLE_UPDATE_CHECK
// Exclusive of: None
// Requries: None
//
//*****************************************************************************
//#define FORCED_UPDATE_KEY GPIO_LOCK_KEY
//#define FORCED_UPDATE_KEY GPIO_LOCK_KEY_DD
//*****************************************************************************
//
// Boot loader hook functions.
//
// The following defines allow you to add application-specific function which
// are called at various points during boot loader execution.
//
//*****************************************************************************
//*****************************************************************************
//
// Performs application-specific low level hardware initialization on system
// reset.
//
// If hooked, this function will be called immediately after the boot loader
// code relocation completes. An application may perform any required low
// hardware initialization during this function. Note that the system clock
// has not been set when this function is called. Initialization that assumes
// the system clock is set may be performed in the BL_INIT_FN_HOOK function
// instead.
//
// void MyHwInitFunc(void);
//
//*****************************************************************************
//#define BL_HW_INIT_FN_HOOK MyHwInitFunc
//*****************************************************************************
//
// Performs application-specific initialization on system reset.
//
// If hooked, this function will be called immediately after the boot loader
// sets the system clock. An application may perform any additional
// initialization during this function.
//
// void MyInitFunc(void);
//
//*****************************************************************************
#define BL_INIT_FN_HOOK MyInitFunc
//*****************************************************************************
//
// Performs application-specific reinitialization on boot loader entry via SVC.
//
// If hooked, this function will be called immediately after the boot loader
// reinitializes the system clock when it is entered from an application
// via the SVC mechanism rather than as a result of a system reset. An
// application may perform any additional reinitialization in this function.
//
// void MyReinitFunc(void);
//
//*****************************************************************************
//#define BL_REINIT_FN_HOOK MyReinitFunc
//*****************************************************************************
//
// Informs an application that a download is starting.
//
// If hooked, this function will be called when a new firmware download is
// about to start. The application may use this signal to initialize any
// progress display.
//
// void MyStartFunc(void);
//
//*****************************************************************************
#define BL_START_FN_HOOK MyStartFunc
//*****************************************************************************
//
// Informs an application of the SD drive mount status
//
// If hooked, this function will be called when loader mounts the SD drive.
//
// void MyMountFunc(uint32_t error);
//
//*****************************************************************************
#define BL_MOUNT_FN_HOOK MyMountFunc
//*****************************************************************************
//
// Informs an application of the SD drive image file open status.
//
// If hooked, this function will be called when loader opens the SD drive.
//
// void MyOpenFunc(uint32_t error);
//
//*****************************************************************************
#define BL_OPEN_FN_HOOK MyOpenFunc
//*****************************************************************************
//
// Informs an application that the flash memory process has started.
//
// If hooked, this function will be called when loader begins the firmware
// flash process.
//
// void MyBeginFunc(uint32_t error);
//
//*****************************************************************************
#define BL_BEGIN_FN_HOOK MyBeginFunc
//*****************************************************************************
//
// Informs an application that the flash memory process has completed.
//
// If hooked, this function will be called when loader completes the firmware
// flash process.
//
// void MyEndFunc(uint32_t error);
//
//*****************************************************************************
#define BL_END_FN_HOOK MyEndFunc
//*****************************************************************************
//
// Informs an application of download progress.
//
// If hooked, this function will be called periodically during firmware
// download. The application may use this to update its user interface.
// When using a protocol which does not inform the client of the final size of
// the download in advance (e.g. TFTP), the ulTotal parameter will be 0,
// otherwise it indicates the expected size of the complete download.
//
// void MyProgressFunc(unsigned long ulCompleted, unsigned long ulTotal);
//
// where:
//
// - ulCompleted indicates the number of bytes already downloaded.
// - ulTotal indicates the number of bytes expected or 0 if this is not known.
//
//*****************************************************************************
#define BL_PROGRESS_FN_HOOK MyProgressFunc
//*****************************************************************************
//
// Informs application that the flash memory process is exiting the bootloader.
//
// If hooked, this function will be called when loader completes the firmware
// flash process.
//
// void MyExitFunc(uint32_t error);
//
//*****************************************************************************
#define BL_EXIT_FN_HOOK MyExitFunc
//*****************************************************************************
//
// Defines the application bin image filename to look for on the SD drive.
// The boot loader will attempt to mount and open this file ten times. If
// successful, it will flash the contents of the file into program
// memory space.
//
//*****************************************************************************
#define BL_IMAGE_FILENAME "X24015.bin"
//*****************************************************************************
//
// X24015 SD Card Socket SPI Pin Assignments
//
// .baseAddr = SSI1_BASE, /* SPI base address */
// .portSCK = GPIO_PORTB_BASE, /* SPI SCK PORT */
// .pinSCK = GPIO_PIN_5, /* SCK PIN (PB5) */
// .portMISO = GPIO_PORTE_BASE, /* SPI MISO PORT */
// .pinMISO = GPIO_PIN_5, /* MISO PIN (PE5) */
// .portMOSI = GPIO_PORTE_BASE, /* SPI MOSI PORT */
// .pinMOSI = GPIO_PIN_4, /* MOSI PIN (PE4) */
// .portCS = GPIO_PORTK_BASE, /* GPIO CS PORT */
// .pinCS = GPIO_PIN_7 /* CS PIN (PK7) */
//
//*****************************************************************************
// Peripherals used by SD drive
#define SD_SYSCTL_PERIPH_SSI SYSCTL_PERIPH_SSI2
#define SD_SYSCTL_PERIPH_GPIO_SCLK SYSCTL_PERIPH_GPIOD // PD3 -- CLK
#define SD_SYSCTL_PERIPH_GPIO_MOSI SYSCTL_PERIPH_GPIOD // PD1 -- DAT0
#define SD_SYSCTL_PERIPH_GPIO_MISO SYSCTL_PERIPH_GPIOD // PD0 -- DAT1
#define SD_SYSCTL_PERIPH_GPIO_FSS SYSCTL_PERIPH_GPIOD // PD2 -- FSS
/* Base port for SD SSI */
#define SD_SSI_BASE SSI2_BASE
/* SD Drive SCLK port/pin definitions */
#define SD_GPIO_SCLK_BASE GPIO_PORTD_BASE
#define SD_GPIO_SCLK_PINCFG GPIO_PD3_SSI2CLK
#define SD_GPIO_SCLK_PIN GPIO_PIN_3
/* SD Drive MOSI port/pin definitions */
#define SD_GPIO_MOSI_BASE GPIO_PORTD_BASE
#define SD_GPIO_MOSI_PINCFG GPIO_PD1_SSI2XDAT0
#define SD_GPIO_MOSI_PIN GPIO_PIN_1
/* SD Drive MISO port/pin definitions */
#define SD_GPIO_MISO_BASE GPIO_PORTD_BASE
#define SD_GPIO_MISO_PINCFG GPIO_PD0_SSI2XDAT1
#define SD_GPIO_MISO_PIN GPIO_PIN_0
/* SD Drive FSS port/pin definitions */
#define SD_GPIO_FSS_BASE GPIO_PORTD_BASE
#define SD_GPIO_FSS_PIN GPIO_PIN_2
//*****************************************************************************
// THE UART IS AVAILABLE FOR DEBUG OUTPUT MESSAGE SUPPORT
//*****************************************************************************
//*****************************************************************************
//
// Selects the baud rate to be used for the UART.
//
// Depends on: UART_ENABLE_UPDATE, CRYSTAL_FREQ
// Exclusive of: UART_AUTOBAUD
// Requires: None
//
//*****************************************************************************
#define UART_FIXED_BAUDRATE 115200
//*****************************************************************************
//
// Selects the clock enable for the UART peripheral module
//
// Depends on: UART_ENABLE_UPDATE
// Exclusive of: None
// Requires: UARTx_BASE
//
//*****************************************************************************
#define UART_CLOCK_ENABLE SYSCTL_RCGCUART_R0
//*****************************************************************************
//
// Selects the base address of the UART peripheral module
//
// Depends on: UART_ENABLE_UPDATE
// Exclusive of: None
// Requires: UART_CLOCK_ENABLE
//
//*****************************************************************************
#define UARTx_BASE UART0_BASE
//*****************************************************************************
//
// Selects the clock enable for the GPIO corresponding to UART RX pin
//
// Depends on: UART_ENABLE_UPDATE
// Exclusive of: None
// Requires: UART_RXPIN_BASE, UART_RXPIN_PCTL and UART_RXPIN_POS
//
//*****************************************************************************
#define UART_RXPIN_CLOCK_ENABLE SYSCTL_RCGCGPIO_R0
//*****************************************************************************
//
// Selects the base address for the GPIO corresponding to UART RX pin
//
// Depends on: UART_ENABLE_UPDATE
// Exclusive of: None
// Requires: UART_RXPIN_CLOCK_ENABLE, UART_RXPIN_PCTL and UART_RXPIN_POS
//
//*****************************************************************************
#define UART_RXPIN_BASE GPIO_PORTA_BASE
//*****************************************************************************
//
// Selects the port control value for the GPIO corresponding to UART RX pin
//
// Depends on: UART_ENABLE_UPDATE
// Exclusive of: None
// Requires: UART_RXPIN_CLOCK_ENABLE, UART_RXPIN_BASE and UART_RXPIN_POS
//
//*****************************************************************************
#define UART_RXPIN_PCTL 0x1
//*****************************************************************************
//
// Selects the pin number for the GPIO corresponding to UART RX pin
//
// Depends on: UART_ENABLE_UPDATE
// Exclusive of: None
// Requires: UART_RXPIN_CLOCK_ENABLE, UART_RXPIN_BASE and UART_RXPIN_PCTL
//
//*****************************************************************************
#define UART_RXPIN_POS 0
//*****************************************************************************
//
// Selects the clock enable for the GPIO corresponding to UART TX pin
//
// Depends on: UART_ENABLE_UPDATE
// Exclusive of: None
// Requires: UART_TXPIN_BASE, UART_TXPIN_PCTL and UART_TXPIN_POS
//
//*****************************************************************************
#define UART_TXPIN_CLOCK_ENABLE SYSCTL_RCGCGPIO_R0
//*****************************************************************************
//
// Selects the base address for the GPIO corresponding to UART TX pin
//
// Depends on: UART_ENABLE_UPDATE
// Exclusive of: None
// Requires: UART_TXPIN_CLOCK_ENABLE, UART_TXPIN_PCTL and UART_TXPIN_POS
//
//*****************************************************************************
#define UART_TXPIN_BASE GPIO_PORTA_BASE
//*****************************************************************************
//
// Selects the port control value for the GPIO corresponding to UART TX pin
//
// Depends on: UART_ENABLE_UPDATE
// Exclusive of: None
// Requires: UART_TXPIN_CLOCK_ENABLE, UART_TXPIN_BASE and UART_TXPIN_POS
//
//*****************************************************************************
#define UART_TXPIN_PCTL 0x1
//*****************************************************************************
//
// Selects the pin number for the GPIO corresponding to UART TX pin
//
// Depends on: UART_ENABLE_UPDATE
// Exclusive of: None
// Requires: UART_TXPIN_CLOCK_ENABLE, UART_TXPIN_BASE and UART_TXPIN_PCTL
//
//*****************************************************************************
#define UART_TXPIN_POS 1
#endif // __BL_CONFIG_H__
This is the .cmd file of the main application which need to run by bootloader.
/******************************************************************************
*
* enet_weather_ccs.cmd - CCS linker configuration file for enet_weather.
*
* Copyright (c) 2013-2017 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.
*
* This is part of revision 2.1.4.178 of the EK-TM4C1294XL Firmware Package.
*
*****************************************************************************/
--retain=g_pfnVectors
/* The following command line options are set as part of the CCS project. */
/* If you are building using the command line, or for some reason want to */
/* define them here, you can uncomment and modify these lines as needed. */
/* If you are using CCS for building, it is probably better to make any such */
/* modifications in your CCS project and leave this file alone. */
/* */
/* --heap_size=0 */
/* --stack_size=256 */
/* --library=rtsv7M3_T_le_eabi.lib */
/* The starting address of the application. Normally the interrupt vectors */
/* must be located at the beginning of the application. */
#define APP_BASE 0x00004000 //0x00004000[for bootloader]//0x00000000[for normal]
#define RAM_BASE 0x20000000
/* System memory map */
MEMORY
{
/* Application stored in and executes from internal flash */
FLASH (RX) : origin = APP_BASE, length = 0x000FC000 //// 0x000FC000[for bootloader]// 0x00100000[for normal]
/* Application uses internal RAM for data */
SRAM (RWX) : origin = 0x20000000, length = 0x00040000
}
/* Section allocation in memory */
SECTIONS
{
.intvecs: > APP_BASE
.text : > FLASH
.const : > FLASH
.cinit : > FLASH
.pinit : > FLASH
.init_array : > FLASH
.vtable : > RAM_BASE
.data : > SRAM
.bss : > SRAM
.sysmem : > SRAM
.stack : > SRAM
}
//__STACK_TOP = __stack + 2048; ORIGINAL
__STACK_TOP = __stack + 2048;
SD Card read and data is also fine from SD Card.
Below Are the logs i have taken from Serial port
fatfs.fsize 185360 <CR><LF>
WriteDataPacketCount 1448 <CR><LF>
WriteDataPacketRemainder 16 <CR><LF>
........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................Done1<CR><LF>
Done2<CR><LF>
Hi,
If you look at the bootloader startup file bl_startup_ccs.s, it will check if there is a forced update before jumping to the application. CheckForceUpdate is in the file bl_check.c. It will check if the first two locations of APP_START_ADDRESS = 0x4000 are all 0xFFFFFFFF. It will check if the CRC of the program image is correct. It will check if bootloading is forced by a pin. If any one of these is true then it will not jump to the application and instead it will jump to the Updater. Therefore, you need to check if any of these conditions is true in your case.
;;*****************************************************************************
;;
;; The reset handler, which gets called when the processor starts.
;;
;;*****************************************************************************
.thumbfunc ResetISR
ResetISR: .asmfunc
;;
;; Enable the floating-point unit. This must be done here in case any
;; later C functions use floating point. Note that some toolchains will
;; use the FPU registers for general workspace even if no explicit floating
;; point data types are in use.
;;
movw r0, #0xED88
movt r0, #0xE000
ldr r1, [r0]
orr r1, r1, #0x00F00000
str r1, [r0]
;;
;; Initialize the processor.
;;
bl ProcessorInit
;;
;; Call the user-supplied low level hardware initialization function
;; if provided.
;;
.if $$defined(BL_HW_INIT_FN_HOOK)
.ref BL_HW_INIT_FN_HOOK
bl BL_HW_INIT_FN_HOOK
.endif
;;
;; See if an update should be performed.
;;
.ref CheckForceUpdate
bl CheckForceUpdate
cbz r0, CallApplication
;;
;; Configure the microcontroller.
;;
.thumbfunc EnterBootLoader
EnterBootLoader:
.if $$defined(ENET_ENABLE_UPDATE)
.ref ConfigureEnet
bl ConfigureEnet
.elseif $$defined(CAN_ENABLE_UPDATE)
.ref ConfigureCAN
bl ConfigureCAN
.elseif $$defined(USB_ENABLE_UPDATE)
.ref ConfigureUSB
bl ConfigureUSB
.else
.ref ConfigureDevice
bl ConfigureDevice
.endif
;;
;; Call the user-supplied initialization function if provided.
;;
.if $$defined(BL_INIT_FN_HOOK)
.ref BL_INIT_FN_HOOK
bl BL_INIT_FN_HOOK
.endif
;;
;; Branch to the update handler.
;;
.if $$defined(ENET_ENABLE_UPDATE)
.ref UpdateBOOTP
b UpdateBOOTP
.elseif $$defined(CAN_ENABLE_UPDATE)
.ref UpdaterCAN
b UpdaterCAN
.elseif $$defined(USB_ENABLE_UPDATE)
.ref UpdaterUSB
b UpdaterUSB
.else
.ref Updater
b Updater
.endif
.endasmfunc
uint32_t CheckForceUpdate(void) { #ifdef CHECK_CRC uint32_t ui32Retcode; #endif #ifdef BL_CHECK_UPDATE_FN_HOOK // // If the update check function is hooked, call the application to determine // how to proceed. // return(BL_CHECK_UPDATE_FN_HOOK()); #else uint32_t *pui32App; #ifdef ENABLE_UPDATE_CHECK g_ui32Forced = 0; #endif // // See if the first location is 0xfffffffff or something that does not // look like a stack pointer, or if the second location is 0xffffffff or // something that does not look like a reset vector. // pui32App = (uint32_t *)APP_START_ADDRESS; if((pui32App[0] == 0xffffffff) || ((pui32App[0] & 0xfff00000) != 0x20000000) || (pui32App[1] == 0xffffffff) || ((pui32App[1] & 0xfff00001) != 0x00000001)) { return(1); } // // If required, scan the image for an embedded CRC and ensure that it // matches the current CRC of the image. // #ifdef CHECK_CRC InitCRC32Table(); ui32Retcode = CheckImageCRC32(pui32App); // // If ENFORCE_CRC is defined, we only boot the image if the CRC is // present in the image information header and the value calculated // matches the value in the header. If ENFORCE_CRC is not defined, we // the image if the CRC is good but also if the length field of the header // is zero (which typically indicates that the post-build step of running // binpack to add the length and CRC to the header was not run). // #ifdef ENFORCE_CRC if(ui32Retcode != CHECK_CRC_OK) #else if((ui32Retcode != CHECK_CRC_OK) && (ui32Retcode != CHECK_CRC_NO_LENGTH)) #endif { // // The CRC32 image check failed indicating that the image is // corrupt (or doesn't have the CRC embedded correctly). Either way, // fail the update check and force the boot loader to retain control. // return(2); } #endif #ifdef ENABLE_UPDATE_CHECK // // If simple GPIO checking is configured, determine whether or not to force // an update. // return(CheckGPIOForceUpdate()); #else // // GPIO checking is not required so, if we get here, a valid image exists // and no update is needed. // return(0); #endif #endif }
Hi Charles ,Now i am unable to jump to bootloader from main Application.
I am using the following function.
void JumpToBootLoader(void)
{
//
// Disable all processor interrupts. Instead of disabling them
// one at a time, a direct write to NVIC is done to disable all
// peripheral interrupts.
//
HWREG(NVIC_DIS0) = 0xffffffff;
HWREG(NVIC_DIS1) = 0xffffffff;
//
// Return control to the boot loader. This is a call to the SVC
// handler in the boot loader.
//
(*((void (*)(void))(*(uint32_t *)0x2c)))();
}
I even tried the below but bootloader is not able to rum from main application, please suggest.
ROM_SysCtlPeripheralDisable(SYSCTL_PERIPH_SSI2);
ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_SSI2);
ROM_SysCtlPeripheralDisable(SYSCTL_PERIPH_GPIOD);
ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOD);
ROM_SysCtlPeripheralDisable(SYSCTL_PERIPH_GPIOD);
ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOD);
ROM_SysCtlPeripheralDisable(SYSCTL_PERIPH_GPIOD);
ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOD);
ROM_SysCtlPeripheralDisable(SYSCTL_PERIPH_GPIOD);
ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOD);
HWREG(NVIC_DIS0) = 0xffffffff;
HWREG(NVIC_DIS1) = 0xffffffff;
HWREG(NVIC_DIS2) = 0xffffffff;
HWREG(NVIC_DIS3) = 0xffffffff;
HWREG(NVIC_DIS4) = 0xffffffff;
// Also disable the SysTick interrupt.
ROM_SysTickIntDisable();
ROM_SysTickDisable();
(*((void (*)(void))(*(uint32_t *)0x2c)))();
Hi,
Not sure what happened. How do you know it didn't jump to the bootloader after executing (*((void (*)(void))(*(uint32_t *)0x2c)))()?
If you look at bl_startup_ccs.s the processor should jump to 0x2C for the SVC call. As you can see it will then jump to the vector at UpdateHandler.
.word 0 ;; Offset 24: Reserved .word 0 ;; Offset 28: Reserved .word UpdateHandler - 0x20000000 ;; Offset 2C: SVCall handler .word IntDefaultHandler ;; Offset 30: Debug monitor handler
UpdateHandler: .asmfunc ;; ;; Initialize the processor. ;; bl ProcessorInit ;; ;; Load the stack pointer from the vector table. ;; movs r0, #0x0000 ldr sp, [r0] ;; ;; Call the user-supplied low level hardware initialization function ;; if provided. ;; .if $$defined(BL_HW_INIT_FN_HOOK) bl BL_HW_INIT_FN_HOOK .endif ;; ;; Call the user-supplied re-initialization function if provided. ;; .if $$defined(BL_REINIT_FN_HOOK) .ref BL_REINIT_FN_HOOK bl BL_REINIT_FN_HOOK .endif ;; ;; Branch to the update handler. ;; .if $$defined(ENET_ENABLE_UPDATE) b UpdateBOOTP .elseif $$defined(CAN_ENABLE_UPDATE) .ref AppUpdaterCAN b AppUpdaterCAN .elseif $$defined(USB_ENABLE_UPDATE) .ref AppUpdaterUSB b AppUpdaterUSB .else b Updater .endif .endasmfunc