2019-03-17 01:57 PM
Hi,
today I stumbled across a problem, where I wanted to assign around 50k of RAM to FreeRTOS and I immediately got a linker error, because target ran out of RAM.
I had a look at the datasheet and this says 48k RAM. I've been using a self-hacked-together linkerscript for very long now, that has 64k set.
For a long time now I was thinking it has 64k, because my flash programming utilities report it every time I program this chip.
I am using a ST-LinkV2, host-OS is linux and I use texane's stlink utility. I also tried with stm32flash and stm32loader.py.
This is what they report:
st-info from texane's st-link utility reports 64k RAM, 256k flash
$ st-info --probe
Found 1 stlink programmers
serial: 513f6f06503f55493945093f
openocd: "\x51\x3f\x6f\x06\x50\x3f\x55\x49\x39\x45\x09\x3f"
flash: 262144 (pagesize: 2048)
sram: 65536
chipid: 0x0414
descr: F1 High-density device
stm32flash reports 64k RAM and 512k FLASH:
$ stm32flash /dev/ttyUSB0
stm32flash 0.5
http://stm32flash.sourceforge.net/
Interface serial_posix: 57600 8E1
Version : 0x22
Option 1 : 0x00
Option 2 : 0x00
Device ID : 0x0414 (STM32F10xxx High-density)
- RAM : 64KiB (512b reserved by bootloader)
- Flash : 512KiB (size first sector: 2x2048)
- Option RAM : 16b
- System RAM : 2KiB
stm32loader.py does not report sizes:
$ sudo ./stm32loader.py -V -p /dev/ttyUSB0
Open port /dev/ttyUSB0, baud 115200
*** Get command
Bootloader version: 0x22
Available commands: 0x0, 0x1, 0x2, 0x11, 0x21, 0x31, 0x43, 0x63, 0x73, 0x82, 0x92
Bootloader version 22
*** GetID command
Chip id: 0x414 (STM32 High-density)
Is this a false report? I assume the serial bootloader (in case of stm32flash) reports the memory sizes to the tool. Also I assume ST wouldn't program wrong memory sizes to the bootloader. Does this mean my device has 64k/512k?
Does the internal bootloader scan flash for availability or does it work with pre-programmed flash/ram-size values?
How does the ST-LinkV2 (swdio/swdclk connection) work? It detects 256k flash (as this device is supposed to have), but it detects 64k RAM (16k more than supposed).
How would I test for this? Writing an application, that writes and reads back RAM above 48k and same for the flash?
I already heard about the 128k STM32F103C8T6 (blue pills etc) that have 128k flash. Maybe it is the same with these..,
Thanks in advance,
Doss
2019-03-17 03:38 PM
Depends on the die, ST has a handful of die covering all F1 series parts. Smaller memory ones typically targeting smaller packages, as the RAM/FLASH are physically quite large in area.
ST test a portion on some parts, depending on pricing structure, and encode that size in the OTP. For 0x414 die this would be the 16-bit word at 0x1FFFF7E0
2019-03-18 11:37 AM
0x1FFFF7E0 says 0x0100. I haven't found a description of this word yet. Could you please point me to the document where I can find more about this memory location?
I've been playing around with openocd and set flashsize to 0 (probe instead of predefined) and tried to write a 512k file with just 0xA5A5.... in it. It stops with a error (something like "bank not supported" or similar) when it reaches 256k+1b.
The same if I tell openocd it has 512k instead of probing.
With RAM I had success.
I wrote a test-program that writes+reads this 16k chunk of memory.
Official RAM is at 0x20000000-0x2000BFFF (48k). The rest up to 0x2000FFFF is (almost) working RAM.
The test program freezes whenever I try to read or write above 0x2000FFFC. Up to and including 0x2000FFFC I have usable RAM.
This is my test code:
int main(void) {
char buffer[81];
uint32_t address, misses = 0;
volatile uint32_t *dptr;
rcc_clock_setup_in_hse_8mhz_out_72mhz();
init_usart1();
usart1_puts("\e[2J\e[0;0H"); // clear screen + home cursor on terminal
usart1_puts(" testing address 0x");
usart1_puts("\e[s"); // tell terminal to save cursor position
for(address = 0x2000C000; address <= 0x2000FFFC; address++) {
snprintf(buffer, 81, "%08lX", address);
usart1_puts(buffer);
usart1_puts("\e[u"); // go to saved cursor position for next address to print
dptr = (volatile uint32_t *)address;
*dptr = 0xA5A5A5A5;
if(*dptr != 0xA5A5A5A5)
misses++;
}
snprintf(buffer, 81, "\r\n\r\n [ misses = %lu ] \r\n", misses);
usart1_puts(buffer);
while(1) { }
return 0;
}
2019-03-18 11:42 AM
It would be in the Reference Manual RM0008, search "F7E0" or "Flash Size Register"
0x100 256KB
2019-03-18 11:51 AM
Thank you!