Vector Table dla STM32 bazujących na Cortex M3/4/7
Info LINK
When you apply power to board (or reset) the PC of the processor is loaded with the value 0x0000_0000.
step 1 )Then the processor reads the value from this adress. (in Cortex value = 0x0800_0000 ) in to MSP
( MSP - Main Stack Pointer register )
So, MSP is the main stack pointer ARM Cortex micro-controller. And that means, the processor first actually initializes the stack pointer register Initial SP Value
step 2) So, after that, processor reads the value of @ memory location 0x0000_0004 into PC.
( PC - points to the (next) instruction to be fetched, not the current instruction being executed ! )
That value is actually the address of the reset handler.(Reset, adres is 0x0800_0004 )
So, now then PC jumps to the reset handler.
(zamiana 0c0000_0000 na 0x0800_0000 to memory aliasing robiona przez MCU
Pamięć jest zmapowana na flash memory. tak jest tylko w produktach ST w Texas intrument (TI) flash jest od 0x0000_0000 więc nie ma potrzeby mapowania)
Now the reset handler is just a C or assembly function written by you to carry out some of the initialization required for your application.
And from the reset handler you call your main() function of the application. So, control comes to the main()
Boot Configuration of STM32
piny odczytywane podczas resetu.
BOOT0 configuration:
BOOT0 is at level “0” through a pull-down R28. If you want to set BOOT0 at level “1”, it can
be configured by setting a jumper between P2.21 (BOOT0) and P2.22 (VDD).
Note:If you need to set BOOT0 at level "1" continuously, then open SB19 solder bridge to avoid a consumption of 6 mA, while connecting pin P2.21 and P2.22 with a jumper or with a wire.
BOOT1 configuration:
BOOT1 ((PB2) jump withGND
embedded SRAM adres is 0x2000_0000, czyli w trzeciej opcji adres 0x0000_0000 będzie zmapowany na podany adres SRAM a nie na flash (0x0800_0000)
Drivery (film rozdzial 4)
Driver do link/debugera pasuje do obu płytek
https://www.st.com/en/development-tools/stsw-link009.html
ST-Link firmware Upgrade
https://www.st.com/en/development-tools/stsw-link007.html
LINK z Driver+CubeMX+Flasher my Dysk
ST-Link Utility
KEIL MDK 5 software instalation (film rozdział 5)
https://www2.keil.com/mdk5LINK my dysk
film rozdział 6. Installing OpenSTM32 System-Workbench
(jeśli nie windows i nie możesz KEIL )
film rozdział 7. STM32CubeMX
(sysem generujący kod)LINK z Driver+CubeMX+Flasher my Dysk
film rozdział 8. Exploring STM32 Native Bootloader
1-lokalizacja pinów do botowania i ich ustawienie2-dokument an2606 LINK
3-uzycie dodatkowego USART-USB do wgrania bootloadera (po podłączonym USB nie pojdzie)
4-program do flashowania
https://www.st.com/en/development-tools/flasher-stm32.html
LINK z Driver+CubeMX+Flasher my Dysk
tworzenie pliku hex i wgrywanie wlasnego bootloadera
przykładowy link:
https://scienceprog.com/flashing-programs-to-stm32-embedded-bootloader/
płytka discovery STM32F407/446
- ustaw BOOT0 i BOOT1
- podłącz do serial3 (RX - PB11 , TX- PB10 )
płytka discovery STM32F411
- ustaw BOOT0 i BOOT1
- podłącz do serial2 (RX - PD6 , TX- PD5 ewentualnie RX - PA3 , TX- PA2)
- ustaw poprawną prędkość com na managerze urządzen windowsa i w programie oraz Parity = Even
mała płytka i jej podłączenie do flasher:
STM32F103C8T6
- ustaw BOOT0 jako 1
- podłącz do serial1 (TX - pin A9 , RX - pin A10 + GND)
- ustaw poprawną prędkość com na managerze urządzen comX i w programie oraz Parity = Even
film rozdział 9. Custom Bootloader Communication with HOST
Nucleo64:
1-wyjasnienie: USART2(przez wbudowane usb stlinka ) do wysyłania polecen i otrzymywania odpowiedzi z bootloadera - tu nie potrzebny dodatkowy usb-usart jak w rozdziale 8,
USART3 (przez dodatkowy usb-uart do pin B10 i B11) do wyswietlania komunikatow debugowych bootloaderai i wgrania go.
(generalnie w sprzęcie ST bootloader wspiera protokoły komunikacji usb,SPI,I2c itp. )
DISCO:
nie ma dostępu do USARTA przez ust stlinka (jest przez mikro usb wpne na płytce)
STM32F411 nie ma USARTA3 ale USART2 umożliwia wgranie bootloadera przez usart
2-Code Placement in Flash
uzyjemy pierwszych 32 kilobajtów naszej pamięci flash żeby wgrać tam bootloader, kolejne sektory flash będą dla kodu naszego programu.
Wbudowany w rom bootloader ST jest pod adresem: System memory. Jeśli wgramy go do Sectora 0 fash to będzie pod adresem 0x800_0000 a kod programu zacznie się od sektora drugiego czyli 0x800_8000
3-Supportet Commands
Bootloader Commands.pdf + prezentacja
pliki LINK
4-Bootloader communication HOST(PeCet)- Bootloader(MCU)
host wysyła komende. bootloader sprawdza crc i odpowiada 2 bajtami (pierwszy ACK lub NACK zależy czy crc ok, i drugi długość nadchodzącej odpowiedzi, następnie wysyła odpowiedz o podanej długości.
film rozdział 10. Boot-Loader Project Creation
1- uzycie STM32CubeMX do generowanie kodu dla uVision
Nowy Projekt/ w zakładce Board Selector wybraC Vendora STMelectronic, typo of Board
poprawka, zamiast board selector lepiej wybrać sam mikrokontroler np stm32F411VE a nie płytkę !
czysta konfiguracja bez potencjalnych konfliktów
w ProjecrSettings w zakładce Project:
ustaw project location w KeilWorkspace
Toolchain/IDE ustaw MDK-ARM V5
w zakładce Code Generator ustaw Copy only the necessary library files
po stworzeniu projektu w programie:
zakładka Pinout (zakładki parz góra)
Nucleo64:
.wybrac USART2 (wbudowane usb(virtual com) - do wysyłania comand bootloadera) ustawic Asynchroniczny tryb
.wybrac USART3 (przez usb-usart dongle) ustawic asynchroniczne , klikając z Ctrl w zazielenione piny pokazuje piny zastępcze (można dać drag and drop na nie)
DISCO411:
aktywować dwa usarty przez wewnętrzne dongle uart ?
dostępne usarty to 1,2,6 ale do wyświetlania działać będzie 2 i 6 (przez 1 wgrywa stlink)
.wybrac CRC i dac activated
.wybrac RCC i sprawdzic czy HSE jest disable - external clock
zakładka ClockConfiguration
na wykresie SYSCLK - podaje zegar
menu Project
.wybrac Generate Code
wybrać OpenProject wtedy otwiera uVision z gotowym projektem:
w uVision:
w folderze Drivers/CMSIS mamy pliki systemowe
w folderze Drivers/STM321xxHAL_Driver mamy drivery
w Application/MDK-ARM mamy plik startup
w folderze Application/User mamy plik main.c gdzie piszemy KOD bootloadera
w uVision
klikamy "Options for Target" (symbol magicznej rozdzki ) zakladka Debug , wybieramy USE: ST-Link Debugger, kliknąć obok "Settings"
otworzy okno i w Download Option (po prawej na dole) wybrać
"Verify Code Download", "Download to Flash"
OK
OK
w uVision
klikamy "build" (ikonka 2 w kolejnosci od lewej F7)
następnie "Load" (ikonka 6 w kolejnosci , Download Code to Flash memory)
Jeśli OK, sprawdzamy, czy możemy debugować ikonka
Start/Stop debug sesion (Ctrl + F5)
2-analiza wygenerowanego kodu plik main (w uVision w folderze Application/User)
znajdują się w nim różne funkcje inicjalizujące
HAL_Init
MX_GPIO_Init
MX_USART2_UART_Init
MX_USART3_UART_Init
MX_CR_Init
SystemClock_config
(prawy klik/ Go to definition )
film rozdział 11. Boot-Loader UART Testing
1-przy otwartym projekcie w uVision, przełączyć zakładki pod projektem, na "functions" po rozwinięciu "+"
po wybraniu funkcji stm..._hal_uart.c szukamy metody HAL_UART_Transmit, klikamy, otwiera plik, nie zmieniamy go! ale możemy podejrzeć jakie argumenty przyjmuje funkcja
możemy użyć w main
HAL_UART_Transmit(&huart2,(uint8_t*)somedata, sizeof(somedata), HAL_MAX_DELAY);
gdzie somedata to wczesniej zadeklarowana tablica charow
char somedata[]="Hello \n"
huart2 to wczesniej zadeklarowany handler do UARTA;
UART_HandleTypeDef huart2;
piszemy pętle opozniajaca:
uint32_t=HAL_Gettick();
while(HAL_GetTick() < (current_tick+500) );
albo
HAL_Delay(1000);
teraz za pomocą putty sprawdzamy na COM na którym jest UART2 czy przychodzi wiadomosc.
(ustawic w putty poprawna wartosc predkosci 115200, w menagerze urzadzen windows tez tak ustawic prędkosc COM uarta)
2-wysyłka za pomocą USART3
ta sama funkcja jak powyżej tylko zamieniamy na uart3
przykład własnej funkcji do wysyłania message na console (4 minuta filmu) printmsg(...)
film rozdział 12. Boot-loader Jumping to User Code
1-Bootloader code flow chart
w zależności czy podczas resetu jest wybrany user button(making that GPIA to ground on nucleo) mamy 2 ścieżki
implementacja:
/* Lets check whether button is pressed or not, if not pressed jump to user application */ if ( HAL_GPIO_ReadPin(B1_GPIO_Port,B1_Pin) == GPIO_PIN_RESET ) { printmsg("BL_DEBUG_MSG:Button is pressed .. going to BL mode\n\r"); //we should continue in bootloader mode bootloader_uart_read_data(); } else { printmsg("BL_DEBUG_MSG:Button is not pressed .. executing user app\n"); //jump to user application bootloader_jump_to_user_app(); }
przykład dodania breakpointów i debugowania
2- kod powyzej uzytych funkcji:
void bootloader_uart_read_data(void) { uint8_t rcv_len=0; while(1) { memset(bl_rx_buffer,0,200); //here we will read and decode the commands coming from host //first read only one byte from the host , which is the "length" field of the command packet HAL_UART_Receive(C_UART,bl_rx_buffer,1,HAL_MAX_DELAY); rcv_len= bl_rx_buffer[0]; HAL_UART_Receive(C_UART,&bl_rx_buffer[1],rcv_len,HAL_MAX_DELAY); switch(bl_rx_buffer[1]) { case BL_GET_VER: bootloader_handle_getver_cmd(bl_rx_buffer); break; case BL_GET_HELP: bootloader_handle_gethelp_cmd(bl_rx_buffer); break; case BL_GET_CID: bootloader_handle_getcid_cmd(bl_rx_buffer); break; case BL_GET_RDP_STATUS: bootloader_handle_getrdp_cmd(bl_rx_buffer); break; case BL_GO_TO_ADDR: bootloader_handle_go_cmd(bl_rx_buffer); break; case BL_FLASH_ERASE: bootloader_handle_flash_erase_cmd(bl_rx_buffer); break; case BL_MEM_WRITE: bootloader_handle_mem_write_cmd(bl_rx_buffer); break; case BL_EN_RW_PROTECT: bootloader_handle_en_rw_protect(bl_rx_buffer); break; case BL_MEM_READ: bootloader_handle_mem_read(bl_rx_buffer); break; case BL_READ_SECTOR_P_STATUS: bootloader_handle_read_sector_protection_status(bl_rx_buffer); break; case BL_OTP_READ: bootloader_handle_read_otp(bl_rx_buffer); break; case BL_DIS_R_W_PROTECT: bootloader_handle_dis_rw_protect(bl_rx_buffer); break; default: printmsg("BL_DEBUG_MSG:Invalid command code received from host \n"); break; } } } /*code to jump to user application *Here we are assuming FLASH_SECTOR2_BASE_ADDRESS *is where the user application is stored */ void bootloader_jump_to_user_app(void) { //just a function pointer to hold the address of the reset handler of the user app. void (*app_reset_handler)(void); printmsg("BL_DEBUG_MSG:bootloader_jump_to_user_app\n"); // 1. configure the MSP by reading the value from the base address of the sector 2 uint32_t msp_value = *(volatile uint32_t *)FLASH_SECTOR2_BASE_ADDRESS; printmsg("BL_DEBUG_MSG:MSP value : %#x\n",msp_value); //This function comes from CMSIS. __set_MSP(msp_value); //SCB->VTOR = FLASH_SECTOR1_BASE_ADDRESS; /* 2. Now fetch the reset handler address of the user application * from the location FLASH_SECTOR2_BASE_ADDRESS+4 */ uint32_t resethandler_address = *(volatile uint32_t *) (FLASH_SECTOR2_BASE_ADDRESS + 4); app_reset_handler = (void*) resethandler_address; printmsg("BL_DEBUG_MSG: app reset handler addr : %#x\n",app_reset_handler); //3. jump to reset handler of the user application app_reset_handler(); } /* prints formatted string to console over UART */ void printmsg(char *format,...) { #ifdef BL_DEBUG_MSG_EN char str[80]; /*Extract the the argument list using VA apis */ va_list args; va_start(args, format); vsprintf(str, format,args); HAL_UART_Transmit(D_UART,(uint8_t *)str, strlen(str),HAL_MAX_DELAY); va_end(args); #endif }
VTOR - Vector Table Offset Register
The VTOR indicates the offset of the vector table base address from memory address 0x00000000.
na dole w obszarze BL adresy zaczynają się od 0x0800 0000 i tam na samym początku mamy Vector Table boot loadera.
Powyżej (od sektora 2) zaczyna się pamięć user aplication od adresu 0x0800 8000. żeby przeskoczyć z adresu BL na User-apl trzeba wpisać do VTOR wartość 0x0800 8000
rozdz 13
..........................................
Na podstawie kursu LINK
repo kursu
Plik z repo LINK
LINK uproszczona instrukacja STM32F411
LINK implementacja Bootloadera
KursSTM32F411 a Forbot
Płytki:
STM32 Nucleo and STM32 Discovery boards:
Of course they use the same processor, so it is a good question.
The Nucleo boards are designed to help engineers design and prototype ideas very quickly. You use the online mbed compiler and the wide range of APIs that are part of that community. They also have the standard Arduino connectors which allows you to use the wide range of modules that have been developed. I believe they are also aimed at hobbyist and the education market due to their simplicity and that the USB connection can be treated as a serial device for outputting to a terminal on the PC.
Discovery boards are now starting to support mbed so the line is blurring, but they are designed for Engineers looking to do a more detailed evaluation of the STM32 MCUs. To support this they include the necessary components, like MEMS, microphones, sensors, and LCD displays to demonstrate specific device features and an integrated debugger. They’re great for prototyping the MCU before you include it in your final product design.
The step above that is the full evaluation boards, which gives you access to each of the MCUs pins for a full characterisation.
Sklep:
STM32 Nucleo Botland LINK
STM32 Discovery Botland LINK
wersje STM32F Discovery Link
Dokumentacja STM32F411VE
Kurs
Forbot Kurs dla Nucleo
Forbot Kurs dla Discovery
Zestawy do kursu:
Discovery
Nucleo Podstawowy
Nucleo Rozszerzony
Inne kursy Udemy:
beg::
https://www.udemy.com/course/stm32f4-programming-course-for-beginners/
https://www.udemy.com/course/microcontroller-embedded-c-programming/
adv:
https://www.udemy.com/course/mastering-microcontroller-with-peripheral-driver-development/
https://www.udemy.com/course/embedded-system-programming-on-arm-cortex-m3m4/
https://www.udemy.com/course/microcontroller-programming-stm32-timers-pwm-can-bus-protocol/
GynvaelColdwind-jak działą bootloader Arduino link








