Hello
I have spent couple of long days playing around with the bootloader before I posted this question (memory model, arm instructions etc). The idea seems to be simple, I would like to have the small piece of code that will perform jump into the flash memory location when it can run the application.
I am not going to describe in details what is not working trying to save the time of the audience, I will describe the easiest test case I'm trying to make to work.
My test example is trying to get to work an existing example:
http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908/t/317657.aspx?pi307171=3
1. I have written a simple app in ccs that blink LED1 using delay in the loop + fire timer interrupt that blink LED2 (to see is the interrupt vector table being looked after). After playing a lot with the linker script I keep it simple for now. Blinking app is starting at 0x00000000 in flash. It works perfectly, using LMFlash I can save bin on the HDD, erase and upload back again it is working fine every time. I have stored offseted version of the blinking led program 0x00 to 0xC00, and again I can erase, upload and run.
2. I cloned LED test program, removed everything in main and copy/paste code from the link example:
HWREG(NVIC_VTABLE) = 0x00002800;
__asm(" ldr r1, [r0]\n"
" mov sp, r1");
__asm(" ldr r0, [r0, #4]\n"
" bx r0\n");
3. I have uploaded offseted version of the blinking led program (0x00 to 0xC00) into flash location 0x00002800 (I have verified that by reading all flash memory into a file)
My problem is that nothing happens, led is not blinking, I would like to get confidence that I can upload the application into any location of the flash with the same result. Ideally I want to keep two different apps in the flash and decide which one I jump upon start.
I have attached source of the app + linker that two examples are based on:
App:
unsigned int isrcounter;
unsigned int test;
//---------------------------------------------------------------------------
// delay()
//
// Creates a 500ms delay via TivaWare fxn
//---------------------------------------------------------------------------
void delay(void)
{
SysCtlDelay(6700000); // creates ~500ms delay - TivaWare fxn
}
int main(void) {
// if it is 0x31 0x31 0x31 0x31 then Block 1 switch to Vector 0x2800
if(1)
{
HWREG(NVIC_VTABLE) = 0x00002800;
__asm(" ldr r1, [r0]\n"
" mov sp, r1");
__asm(" ldr r0, [r0, #4]\n"
" bx r0\n");
}
/*
//HWREG(NVIC_VTABLE) = (unsigned long)0x00001800;
//Set CPU Clock to 40MHz. 400MHz PLL/2 = 200 DIV 5 = 40MHz
SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
// ADD Tiva-C GPIO setup - enables port, sets pins 1-3 (RGB) pins for output
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4);
// Turn on the LED
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 4);
uint32_t ui32Period;
//to get the timer interrupt working
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
TimerConfigure(TIMER1_BASE, TIMER_CFG_PERIODIC);
//ROM_TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
int tmp=SysCtlClockGet();
TimerPrescaleSet(TIMER1_BASE, TIMER_A, 50000);
ui32Period = SysCtlClockGet()/1000;//devide by 1000 to get one ms interval
TimerLoadSet(TIMER1_BASE, TIMER_A, 900000);
IntEnable(INT_TIMER1A);
TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
IntMasterEnable();
TimerEnable(TIMER1_BASE, TIMER_A);
while(1)
{
test++;
// LED values - 2=RED, 4=BLUE, 8=GREEN
if(GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_4))
{
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4, 0);
}
else
{
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4, 16);
}
delay();
}
*/}
void ledToggle(void)
{
// LED values - 2=RED, 4=BLUE, 8=GREEN
if(GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_2))
{
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0);
}
else
{
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 4);
}
}
void TimerIntHandler(void)
{
isrcounter++;
// Clear the timer interrupt
TimerIntClear(TIMER1_BASE, TIMER_TIMA_TIMEOUT);
ledToggle(); // toggle LED
}
LINKER FILE
#define APP_BASE 0x00000000 //0x00002800
#define RAM_BASE 0x20000000
--retain=g_pfnVectors
MEMORY
{
FLASH (RX) : origin = 0x00000000, length = 0x00030000
SRAM (RWX) : origin = 0x20000000, length = 0x00008000
}
/* 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=rtsv7M4_T_le_eabi.lib */
/* Section allocation in memory */
SECTIONS
{
.intvecs: > 0x00000000
.text : > FLASH
.const : > FLASH
.cinit : > FLASH
.pinit : > FLASH
.init_array : > FLASH
.vtable : > 0x20000000
.data : > SRAM
.bss : > SRAM
.sysmem : > SRAM
.stack : > SRAM
}
__STACK_TOP = __stack + 512;
Thanks
Patrick