I build a simple “Blink” application, which does not work. Upon inspection, I found that there’s ELF file in the flash memory of my STM32. Here’s build log which confirms this:
Building in release mode
Checking size .pio\build\bluepill_f103c8_128k\firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM: [== ] 21.1% (used 4312 bytes from 20480 bytes)
Flash: [= ] 14.8% (used 19448 bytes from 131072 bytes)
Configuring upload protocol...
AVAILABLE: blackmagic, cmsis-dap, dfu, jlink, stlink
CURRENT: upload_protocol = stlink
Uploading .pio\build\bluepill_f103c8_128k\firmware.elf
Do you really see the ELF header in flash? If that was the case the devs should have catched tha a long time ago. With upload_protocol = stlink (and no offset_address) it passes the ELF file to OpenOCD, which it handles perfectly fine per doc. You can see the verbose flashing command with the project task Advanced → Verbose Upload.
Uploading .pio\build\bluepill_f103c8_128k\firmware.bin
xPack OpenOCD x86_64 Open On-Chip Debugger 0.11.0+dev (2021-10-16-21:19)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
debug_level: 1
hla_swd
none separate
target halted due to debug-request, current mode: Thread
xPSR: 0x01000000 pc: 0xfffffffe msp: 0xfffffffc
** Programming Started **
Warn : no flash bank found for address 0x00000000
** Programming Finished **
** Verify Started **
Error: checksum mismatch - attempting binary compare
embedded:startup.tcl:1070: Error: ** Verify Failed **
in procedure 'program'
in procedure 'program_error' called at file "embedded:startup.tcl", line 1131
at file "embedded:startup.tcl", line 1070
*** [upload] Error 1
and the flash memory contents are unchanged (I performed full chip erase before programming).
If you have local changes that are save-worthy, I’d recommend removing C:\Users\.platformio\packages\framework-arduinoststm32-maple and ``C:\Users.platformio.cacheand rebuilding and uploading without anyoffset_address. Double check that .text is at 0x8000000 then.
The linker script in verbose build output is set to flash.ld.
Its contents:
INCLUDE mem-flash.inc
/* Provide memory region aliases for common.inc */
REGION_ALIAS("REGION_TEXT", rom);
REGION_ALIAS("REGION_DATA", ram);
REGION_ALIAS("REGION_BSS", ram);
REGION_ALIAS("REGION_RODATA", rom);
/* Let common.inc handle the real work. */
INCLUDE common.inc
I just got used to that core. In the regular core I’m not sure how to set custom RCC PLL multiplier. In Maple core, it’s achieved by adding a single #define:-DBOARD_RCC_PLLMUL=RCC_PLLMUL_6.
For STM32Duino, you override the whole _weak clock init method with your own and have your settings directly in there, i.e. in your regular firmware code somewhere you add
extern "C" void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {};
/* Initializes the CPU, AHB and APB busses clocks */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL6; // was: RCC_PLL_MUL9
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
Error_Handler();
}
/* Initializes the CPU, AHB and APB busses clocks */
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) {
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_USB;
PeriphClkInit.AdcClockSelection = RCC_ADCPCLK2_DIV6;
// this likely needs adjusting too to hit 48MHz when USB is needed!!
PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV1_5;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
Error_Handler();
}
}