cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103VCT6 more RAM+Flash than datasheet says?

doss
Associate II

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

4 REPLIES 4

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

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
doss
Associate II

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;
}

It would be in the Reference Manual RM0008, search "F7E0" or "Flash Size Register"

https://www.st.com/content/ccc/resource/technical/document/reference_manual/59/b9/ba/7f/11/af/43/d5/CD00171190.pdf/files/CD00171190.pdf/jcr:content/translations/en.CD00171190.pdf

0x100 256KB

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
doss
Associate II

Thank you!