I'm using
STM32F103ZE recently, it has 512KB flash and 64KB RAM, for a small
program, the 64K RAM is big enough to hold both the code and the
data. If we can debug codes in RAM, then there's no need to write the
flash every time, so you don't have to worry about the life of the
flash.
STM32F10X chips have
3 boot mode: flash, bootloader and RAM, depends on the levels on
Boot0 and Boot1 pins. But the Boot From RAM mode is actually not very
useful, because there's no mapping mechanism in the chip to let to
CPU to access RAM area at reset. We know that in STM32F10x chips,
flash memory starts from address 0x800 0000, and bootloader resides
from 0x1FFF B000 or 0x1FFF F000, and in the respective boot mode,
both of the addresses are mapped to 0x0000 0000, so the CPU can get
the right place (the CPU loads stack pointer SP and program pointer
PC from address 0x0000 0000 and 0x0000 0004 at reset).
But for RAM, it can
not be mapped to address 0, so there's no strait way to get the CPU
to boot from RAM. We need the help from the debugger to load the SP
and PC, later in this article I will show you how to do it.
I wrote a simple
program to do the RAM demo, it just flashes a LED at PB0:
#define LED1
0x0001 // PB0
int main(void)
{
volatile
unsigned long i;
RCC->APB2ENR
|= RCC_APB2ENR_IOPBEN;
GPIOB->CRL =
0x44444442;
while(1)
{
GPIOB->ODR
^= LED1;
for (i=0;
i<0x100000; i++);
}
return 0;
}
To let the code
loaded in RAM, we need to do some modifications with the project
options.
First, In the Keil uVision IDE, select the project settings from Project →Options for Target 'Target1' :
The high-lighted
area are the settings need to be modified. We change to IROM1 address
to start from the RAM base address, and divide the whole RAM in 2
parts, half for code, and half for data.
Step 2, we go to the 'Debug' tab and make the following changes:
You probably have
already noticed the RAM.ini file. What is this? This is the most
important part in this project to make the RAM debugging successful.
The Initialisation File is a command set for the debugger hardware,
these commands are executed at the beginning of debug. Keil provided
it with it's MDK package, you can find it here:
\ARM\Boards\ST\STM3210E-EVAL\Blinky\Dbg_RAM.ini
The file is short
and the code is strati forward, it basically just load the SP and PC
from the start of the RAM and setup the vector table:
FUNC void Setup
(void) {
SP =
_RDWORD(0x20000000); // Setup Stack Pointer
PC =
_RDWORD(0x20000004); // Setup Program Counter
_WDWORD(0xE000ED08, 0x20000000); // Setup Vector Table Offset
Register
}
load %L incremental
Setup();
// Setup for Running
g, main
Final step, to modify the programming algorithm. Hit the “settings” in the “Debug” tab, then select “Flash Download” tab.
First of all, select
the “Do not Erase” option, as we are using RAM, then change the
address range to the RAM area, otherwise you will be prompted a “no
algorithm for address xxxxxxxxx” error when downloading the code.
Finally, don't forget to change the “RAM for Algorithm” to avoid
overlaps with the code area.
Now we are all set
to run our code in RAM! Make the project and then enter the debug
widow, and hit 'Run'. Yeah, the LED is flashing, our code is running
in RAM! The BOOT0 and BOOT1 pins are actually not having effect on
the running, you can have any settings on these 2 pins when
debugging.
Some issues with the RAM debugging:
1. Code and Data
size are limited.
2. If you reset the
chip, you have to run the Setup() function in the debugger
initialization file manually, otherwise the CPU will not get the
correct SP and PC. To do so, in the command window, type “Setup()”
in the command line and press ENTRE.
No comments:
Post a Comment