-
STM32 Programming Toolset + dependencies
sudo apt-get install git make cmake libusb-1.0-0-dev sudo apt-get install gcc build-essential wget https://github.com/stlink-org/stlink/releases/download/v1.8.0/stlink_1.8.0-1_amd64.deb -q --show-progress sudo dpkg -i stlink_1.8.0-1_amd64.deb
Connect the board to an USB port and to test its connectivity you can execute the followind command:
lsusb | grep STM Expected output: STMicroelectronics ST-LINK/V2.1
The COM LED should also be green. A problem with USB enumeration is indicated by a blinking red COM LED.
To see more specific information about the board you can execute the following command:
st-info --probe Found 1 stlink programmers version: V2J37S27 serial: 066BFF373146363143223537 flash: 524288 (pagesize: 2048) (512KB) sram: 147456 (144KB) chipid: 0x467 dev-type: STM32G0Bx_G0Cx
The Cortex-M0+ has the following reset behavior according to this well documented presentation here:
- Reads the Initial SP, also called the MSP (Main Stack Pointer)
- Reads the reset vector
- Branches to the starting of the program execution address (reset handler)
- Subsequently executes program instructions (TBD in the
Reset_Handler
function)
A strong reference point was this forum post and also this implementation for the STM32H7xx series.
- Define the interrupt vector table for the NVIC according to the Cortex-M0+ Manual and STM32G0x1xx series reference Manual.
void (* g_pfnVectors[])(void) __attribute__((section (".isr_vector"))) = {...}
- Move the MSP to the SP (Stack Pointer) using inline assembly and
LDR
instruction (see page 141 from ARMv6-m Architecture Manual). It uses the_estack
symbol defined in the linker script.
__asm (
"LDR R0, =_estack \n\t"
"MOV SP, R0 \n\t"
);
- Initialize the
.data
section. In order to use symbols from the.data
section, the startup code needs to copy the data fromLMA (Flash)
toVMA (SRAM)
to make sure that all C code can access the initialized data. It uses the_data_start
,data_end
symbols for the virtual adresses and_sidata
symbol for the start address of the LMA of the.data
section.
uint32_t *dataSrc = &_sidata, *dataDest = &_data_start;
while (dataDest < &_data_end) {
*dataDest++ = *dataSrc++;
}
- Initialize the
.bss
section to zero using inline assembly. It uses the_bss_start
and_bss_end
symbols defined in the linker script.
__asm (
"LDR R0, =_bss_start \n\t"
"LDR R1, =_bss_end \n\t"
"MOV R2, #0 \n\t"
"loop_zero: \n\t"
" CMP R0, R1 \n\t"
" BGE end_loop \n\t"
" STR R2, [R0] \n\t"
" ADD R0, R0, #4 \n\t"
" B loop_zero \n\t"
"end_loop: \n\t"
);
The purpose of this function is to configure the PLL Block
of the Clock tree
with a frequency of 64 MHz and to select PLLRCLK
as the SYSCLK
source.
The formula by which the output fPLLR is calculated is the following:
fPLLR = ((fPLLIN / M) * N) / R, where: - fPLLIN is the frequency of HSI16 clock source of 16 MHz - M, N and R are configurable parameters using PLLCFGR register
- STM32G0x1xx Reference Manual
- Memory Organization (Chapter 2.2.2 Memory map and register boundary addresses - pg. 62)
- System Clock Selection (Chapter 5. Reset and clock control (RCC) - pg. 155)
- STM32 Cortex-M0/M0+ Programming Manual
- ARMv6-M Architecture Reference Manual
KEYWORD | DESCRIPTION |
---|---|
SECTIONS |
Defines the mapping between the sections of the input object files to the sections of the linker's output file, by specifying the memory layout of each output section. |
KEEP |
Tells the linker to not remove the section wrapped by this command. Important when working with ARM microprocessors because the interrupt vector table must be in a predefined memory location and is not referenced directly by code. |
LMA |
Load Memory Address. |
VMA |
Virtual Memory Address. |
. |
Location Counter. |
ALIGN |
Introduces the required amount of padding to align the location counter. |
To be able to run the rules inside the provided Makefile
you are required to also install the ARM GNU Toolchain:
sudo apt-get install gcc-arm-none-eabi
- Create
.hex
file using the Makefile rule:
make all
- Flash the device
st-flash --format ihex write program.hex
2024-12-22T16:36:26 INFO common.c: STM32G0Bx_G0Cx: 144 KiB SRAM, 512 KiB flash in at least 2 KiB pages.
2024-12-22T16:36:26 WARN common_flash.c: Flash base use default L0 address
2024-12-22T16:36:26 INFO common_flash.c: Attempting to write 508 (0x1fc) bytes to stm32 address: 134217728 (0x8000000)
-> Flash page at 0x8000000 erased (size: 0x800)
2024-12-22T16:36:26 INFO flash_loader.c: Starting Flash write for WB/G0/G4/L5/U5/H5/C0
2024-12-22T16:36:26 INFO common_flash.c: Starting verification of write complete
2024-12-22T16:36:26 INFO common_flash.c: Flash written and verified! jolly good!
2024-12-22T16:36:26 INFO common.c: Go to Thumb mode
(OPTIONAL) 3. Start a gdb
connection using st-util
and connect locally using gdb-multiarch
sudo apt-get install gdb-multiarch
# Inside the first terminal window
st-util
# Inside the second terminal window
gdb-multiarch
(gdb) file program.hex
(gdb) target remote localhost:4242
(gdb) ...