cancel
Showing results for 
Search instead for 
Did you mean: 

Boot mode Flash Program won't run

eva
Associate II
Posted on October 20, 2009 at 11:53

Boot mode Flash Program won't run

12 REPLIES 12
eva
Associate II
Posted on May 17, 2011 at 13:23

Hey,

We designed a new prototype for one of our products, using an STM32F103 6C6 CPU, connected to a LIS3LV02DQ accelerometer in SPI mode, SPI Eeprom, and another SPI sensor,exclusivly made for our company. I use the Rhide IDE and ST renaissance Programmer using JTAG with GPIO_Remap_SWJ_NoJTRST.

I can get everything working in Boot Mode RAM, I had my hardware designer

mount little jumpers on the BOOT0 BOOT1 lines so I can easily switch the prototypes boot mode. Now the code is getting to big to debug in RAM mode,

so I switched to Flash mode, the jumpers on my board, the Boot Mode to Flash in the Processor options and I commented the line saying:

//#define VECT_TAB_RAM

I also tried explicitly defining VECT_TAB_FLASH instead, but I can't get the code to run. Whenever I switch the jumpers on the board and don't switch the option in Rhide I get the Error Wrong Boot mode detected. So the software does detect the selected Boot mode correctly.

If I turn everthing back to RAM mode the code runs fine.

'Edited''

I got the testprogram running in Flash mode, I have to manually reset the Target board by powering it down/up. Then the led flashes.

So I switched back to my main Program, using the same 'trick'

It still wouldn't run, after commenting out blocks and lines

I found out wich line (the commented sqrt) is the problem.

sX=ReadX_GSensor();

sY=ReadY_GSensor();

sZ=ReadZ_GSensor();

dX=(double)sX / 2048 * 6;

dY=(double)sY / 2048 * 6;

dZ=(double)sZ / 2048 * 6;

// Calculate Vector Resultant

dX=dX*dX;

dY=dY*dY;

dZ=dZ*dZ;

dX=dX+dY+dZ;

// dG=sqrt(dX); WONT RUN IN FLASH!!!!!

uG=dG*100;

In the original RAM project I had the following equivalent,

I just stripped it down in the snippet above to find the exact cause of the problem.

dX=(double)sX / 2048 * 6;

dY=(double)sY / 2048 * 6;

dZ=(double)sZ / 2048 * 6;

// Calculate Vector Resultant

dG=sqrt(dX*dX + dY*dY + dZ*dZ);

uG=dG*100;

And that ran fine in RAM mode.

Then I added an sprintf of uG in u8 Buffer[5] to send it to a serial LCD connected, that gave the code size error, making me switch to Flash mode and making the sqrt function stop the program from executing.

Isn't the Flash memory suposed to be larger than the RAM?

Regards,

Eva

[ This message was edited by: eva.dvd on 09-09-2009 16:35 ]

eva
Associate II
Posted on May 17, 2011 at 13:23

I change the Linker Script to:

Files\Raisonance\Ride\Lib\ARM\STM32F103_32K_10K_FLASH.ld

but I still can't get it to run from flash.

If I use STM32F103_32K_10K_RAM.ld and Boot Mode RAM and set my jumpers BOOT0 BOOT1 to RAM on the target board it works.

[ This message was edited by: eva.dvd on 08-10-2009 14:38 ]

tomas23
Associate II
Posted on May 17, 2011 at 13:23

Hi Eva, in STM32 every FLASH is bigger than RAM. Don't you forget to change the linker file --or-- don't you reach the RIDE demo version limit?

Give us the error msgs from RIDE, it shall help.

Btw. how the program ''fails'' if you call the SQRT? Is it some trouble during compilation or in run-time?

eva
Associate II
Posted on May 17, 2011 at 13:23

The program compiles in RAM mode without warnings or errors.

If I start debug, the programs works, serial communication with PC,

SPI communication with Sensors, ...

I set the Processor Boot Mode in Settings window to Flash, I remove the #define VECT_TABLE_RAM, it compiles without warnings or errors.

I click on RLINK Configuration Advanced options, Erase the Flash, select the hex file for upload, I reset the target board (Power off Power on) but the Program doesn't respond to serial communication from my PC anymore.

I don't know what you mean by changing the linker file?

regards,

Eva

clive2
Associate II
Posted on May 17, 2011 at 13:23

Make sure that the flash controller (clocks, wait-states, buffer, etc) is set up correctly. If you haven't correctly initialized the environment in which the code is running this would be a problem, the RAM runs without configuration, whereas the flash will need to be configured before changing clock settings.

a) Use an example program that runs in flash as the starting basis for your code, or as a test case.

b) Use the default speed/memory settings for the buses, cpu and flash at boot and don't reprogram them. Comment out code changing clock, pll settings, if the code functions at the slower speed you need to review the clock settings and wait state configurations.

c) Analyze carefully the start up code (the assembler stuff executed before main()). Look at your code, compare it to other samples.

If this is not helping then you need to break out your JTAG debugger and start tracing through the code from startup to identify where your problem is.

-Clive

eva
Associate II
Posted on May 17, 2011 at 13:23

''the flash will need to be configured before changing clock settings.''

I don't really know what you mean by this. Are you referring to the STARTUP section in the Linker Options? That is still set to default startup.

Here is my RCC Config:

RCC_DeInit(); // RCC system reset(for debug purpose)

RCC_HSEConfig(RCC_HSE_ON); // Enable HSE

HSEStartUpStatus = RCC_WaitForHSEStartUp(); // Wait till HSE is ready

if(HSEStartUpStatus == SUCCESS)

{

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); // Enable Prefetch Buffer

FLASH_SetLatency(FLASH_Latency_2); // Flash 2 wait state

RCC_HCLKConfig(RCC_SYSCLK_Div1); // HCLK = SYSCLK/1

RCC_PCLK2Config(RCC_HCLK_Div1); // PCLK2 = HCLK

RCC_PCLK1Config(RCC_HCLK_Div2); // PCLK1 = HCLK/2

*RCC_ADCCLKConfig(RCC_PCLK2_Div4);

*RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_2); // PLLCLK = 4MHz / 1 * 2 = 8 MHz

RCC_PLLCmd(ENABLE); // Enable PLL

while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) // Wait till PLL is ready

{

}

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); // Select PLL as system clock source

while(RCC_GetSYSCLKSource() != 0x08) // Wait till PLL is used as system clock source

{

}

}

// Enable peripheral clocks ----------------

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | // GPIOA, GPIOB and SPI1 USART1 clock enable

RCC_APB2Periph_SPI1 | RCC_APB2Periph_USART1, ENABLE);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE); // SPI2 Periph clock enable

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE); // Enable ADC and GPIOC

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); // Enable PB4 AF Clock

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // TIM2 clock enable

}

It basically comes from one of the examples, the lines starting with

a * I added or modified. There is a 4 Mhz crystal connected and 2 load capacitors.

[ This message was edited by: eva.dvd on 09-10-2009 14:25 ]

eva
Associate II
Posted on May 17, 2011 at 13:23

I can get the code to work from flash if I disable big parts of it.

for example this function:

void PT_ProcessPressure(void)

{double dSensorTemp;

double ddT;

double dOFF;

double dSENS;

double dSensorPressure;

double dX;

double fd1,fd2;

double UT1;

double tmp;

PT_Reset_Sensor();

D1=PT_Sensor_Read_Data(1);

D2=PT_Sensor_Read_Data(2);

// fd1=(double)D1;

// fd2=(double)D2;

// UT1 = 8 * C5 + 20224;

// ddT = fd2 - UT1;

// tmp = (200+ddT*(C6+50)/1024);

// Temp=(int)tmp;

// dOFF = C2*4+((C4-512)*ddT)/4096;

// dSENS = C1 + (C3*ddT)/1024 + 24576;

// dX = (dSENS * (fd1-7168))/16384 - dOFF;

// tmp= (dX*10/32+2500);

Press=(unsigned int) tmp;

}

It reads an Intersema pressure sensor. The entire program runs perfect in RAM mode. When I switch to FLASH, it works as shown here with the calculations commented out, as soon as I enable those lines the program doesn't do anything anymore in Flash mode.

I assume the compiling bit is exactly the same in flash or ram mode??

So I assume its a linking problem?? Where can I adjust things like Stack and Heap options with Ride+Gcc ?

thanks....

clive2
Associate II
Posted on May 17, 2011 at 13:23

I'm using Keil, the stack size is set up in STM32F10x.s (Startup Code). The default one in most of the STM32 projects is woefully small, and insufficient to use printf/scanf libraries, especially with floating point support.

From a linker perspective you'd have to ensure it knows where the RAM and FLASH are located, and their size. The C startup has to clear it's BSS segment (uninitialized variables) in RAM, and copy initialize variables from FLASH into RAM. Once this is done it will execute main()

Like I said, you need to connect the JTAG debugger, add some breakpoints, and step through the offending code to understand *WHY* it is failing. I would hazard that you are touching the wrong memory addresses, writing into FLASH, or otherwise generating a fault condition. Until you figure out how it fails, you are not in a good position to change random settings.

You have confined the problem by commenting out sections, now you know a good place to put the breakpoint and start debugging.

-Clive

clive2
Associate II
Posted on May 17, 2011 at 13:23

I think the demo compilers come with a pretty short shelf life, regardless of your distributor/vendor. Not sure if ST has there own download (LM does), Keil's is here

http://www.keil.com/demo/

Perhaps you should look at single stepping the assembler code preceding the entry into main(). If a system debugs in RAM, it should debug in FLASH. If the initial stack pointer is in FLASH that would be problematic.

My dev boards all expose JTAG, BOOTx pins, and at least one UART specifically for debug (monitor/instrumentation) and in-system programming. A bunch of test point pads in the current iteration. If you don't have unfettered access to these you are in somewhat of a bind.

I'd suggest you back-track, try putting the bulk of your code, or a test harness for it, on to the MCBSTM32. Verify the code runs on a known-to-work platform, if it still breaks your are in a position to debug it. If it works, you'll have to evaluate how your platform differs, or if there are critical differences in your project files.

-Clive