stm32f1xx
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
stm32f1xx [2016/02/13 18:17] – [in-application programming] kingkevin | stm32f1xx [2017/07/24 10:54] – [maple mini] typo kingkevin | ||
---|---|---|---|
Line 72: | Line 72: | ||
* proper USB disconnect circuit (useful for using the DFU bootloader it comes with) | * proper USB disconnect circuit (useful for using the DFU bootloader it comes with) | ||
* small | * small | ||
- | * good analogue | + | * good analog |
* more flash (128 vs 64 kB) | * more flash (128 vs 64 kB) | ||
* small, fits breadboard (600 mil wide) | * small, fits breadboard (600 mil wide) | ||
Line 79: | Line 79: | ||
* no additional connections (SWD, power, GND) | * no additional connections (SWD, power, GND) | ||
* the pin silkscreen are not the chip pins (you always need the schematic at hand) | * the pin silkscreen are not the chip pins (you always need the schematic at hand) | ||
- | * the clones don't provide a second voltage regulator for the analague | + | * the clones don't provide a second voltage regulator for the analogue |
===== blue pill ===== | ===== blue pill ===== | ||
- | {{ : | + | {{ : |
+ | {{ : | ||
This cheap board is often referred as blue pill in forums and sold under $2.50 as [[http:// | This cheap board is often referred as blue pill in forums and sold under $2.50 as [[http:// | ||
Line 96: | Line 97: | ||
* 6: -40 to 85 °C | * 6: -40 to 85 °C | ||
* peripherals: | * peripherals: | ||
- | * 2x20 GPIO pins on the side (most MCU pins are accessible) | + | * two 1x20 GPIO pins headers |
* USB micro-B | * USB micro-B | ||
* SWD on the top | * SWD on the top | ||
* boot select | * boot select | ||
* power LED | * power LED | ||
- | * user LED, on P13 | + | * user LED, on PC13 (warning: switching this LED heavily affects the RTC) |
* reset button (NRST) | * reset button (NRST) | ||
* 32.768 kHz real time clock (RTC) | * 32.768 kHz real time clock (RTC) | ||
Line 117: | Line 118: | ||
Mine for example has a 10 kΩ pull-up (to 3.3 V) resistor on USB D+/PA12 instead if a 4.7kΩ (to 5 V), although USB devices use a 1.5 kΩ resistor to pull up (to 3.3 V) usually. | Mine for example has a 10 kΩ pull-up (to 3.3 V) resistor on USB D+/PA12 instead if a 4.7kΩ (to 5 V), although USB devices use a 1.5 kΩ resistor to pull up (to 3.3 V) usually. | ||
+ | ===== core board ===== | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | You can often find this versatile board for $6 by searching for "51 core board" | ||
+ | |||
+ | It has: | ||
+ | * [[http:// | ||
+ | * STM32: 32-bit ARM | ||
+ | * F: general purpose | ||
+ | * 103: medium density (performance line) | ||
+ | * C: 48 pins | ||
+ | * 8: 64 kB flash | ||
+ | * T: LQFP | ||
+ | * 6: -40 to 85 °C | ||
+ | * peripherals: | ||
+ | * two 2x10 GPIO pin headers on the side (most MCU pins are accessible) | ||
+ | * USB micro-B | ||
+ | * 2x3 SWD+UART port | ||
+ | * boot select | ||
+ | * power LED | ||
+ | * user LED, on PA1 | ||
+ | * reset button (NRST) | ||
+ | * user button (PA8) | ||
+ | * 32.768 kHz real time clock (RTC) | ||
+ | |||
+ | {{ : | ||
+ | |||
+ | It offers quite a lot of peripheral options: | ||
+ | * 2x4 header for the ESP-01 WiFi module (base on the ESP8266) | ||
+ | * 2x4 header for the nRF24L01 transceiver module | ||
+ | * 1x4 header for a Bluetooth module (using as UART port) | ||
+ | * 1x8 header for an OLED/TFT screen | ||
+ | * 2x5 header for a VS1053/ | ||
+ | * space and pads for a CR1220 coin cell (with knife pins) connected to VBAT (for the the RTC circuit of the micro-controller), | ||
+ | * footprint for a flash chip (W25xxx, SOP-8) connected to an SPI port (SPI1) | ||
+ | * footprint for a EEPROM chip (24Cxx, SOP-8) connected to an I2C port (I2C1), but don't forget to add the pull-up resistors (R12 and R13) | ||
+ | * footprint for a [[https:// | ||
+ | |||
+ | advantages: | ||
+ | * user LED and button | ||
+ | * large AMS1117 voltage regulator | ||
+ | * fuse on USB 5V | ||
+ | * separate 5V connection | ||
+ | * SWD+UART header (ideal for the black magic probe) | ||
+ | * RTC oscillator included | ||
+ | * compact (42x53 mm) | ||
+ | * M3 mounting holes | ||
+ | drawbacks: | ||
+ | * very few power pins | ||
+ | |||
+ | **warning**: | ||
====== flashing ====== | ====== flashing ====== | ||
Flashing refers to programming your application into flash, so the micro-controller can run it. | Flashing refers to programming your application into flash, so the micro-controller can run it. | ||
There are several ways to program the flash, as explained in [[http:// | There are several ways to program the flash, as explained in [[http:// | ||
- | * In-Circuit Programming (ICP): using SWJ (serial wire and JTAG) or the built-in boot loader. This mechanism is provided natively by the micro-controller | + | * [[#ICP|In-Circuit Programming (ICP)]]: using SWJ (serial wire and JTAG) or the embedded bootloader. This mechanism is provided natively by the micro-controller |
- | * In-Application Programming (IAP): using a custom application which can write into flash. But for that you first need to flash this application (often called boot loader) using an ICP method | + | * [[#IAP|In-Application Programming (IAP)]]: using a custom application which can write into flash. But for that you first need to flash this application (often called boot loader) using an ICP method |
It's also possible to program it into RAM and run it from there, but this is not the focus here. | It's also possible to program it into RAM and run it from there, but this is not the focus here. | ||
Line 129: | Line 182: | ||
But if you are interested, the documents referred in this section provide the information you need. | But if you are interested, the documents referred in this section provide the information you need. | ||
- | ===== in-circuit programming | + | ===== ICP ===== |
+ | |||
+ | In-Circuit Programming methods: | ||
+ | * [[#embedded bootloader]]: | ||
+ | * [[#SWJ]]: complex but fast, and allows debugging | ||
- | ==== built-in | + | ==== embedded |
- | The STM32 micro-controller come with a built-in boot loader | + | The STM32 micro-controller come with a embedded bootloader |
How to start this bootloader is described in [[http:// | How to start this bootloader is described in [[http:// | ||
Line 149: | Line 206: | ||
* ST provides a [[http:// | * ST provides a [[http:// | ||
* [[https:// | * [[https:// | ||
- | * I use [[https:// | + | * I use [[https:// |
./ | ./ | ||
</ | </ | ||
Line 165: | Line 222: | ||
You first need a SWD or JTAG adapter. | You first need a SWD or JTAG adapter. | ||
I am using a [[jtag# | I am using a [[jtag# | ||
- | + | Don't forget to add a udev rule to allow the user to access the SWD adapter: < | |
- | To control the SWD adapter several software are available: | + | |
- | * [[https:// | + | |
- | * but I am using [[http:// | + | |
- | + | ||
- | Using OpenOCD: | + | |
- | - install PpenOCD: < | + | |
- | sudo apt-get install openocd | + | |
- | </ | + | |
- | - add a udev rule to allow the user to access the SWD adapter: < | + | |
sudo tee / | sudo tee / | ||
# STMicroelectronics ST-LINK/V2 | # STMicroelectronics ST-LINK/V2 | ||
Line 181: | Line 229: | ||
sudo service udev reload | sudo service udev reload | ||
</ | </ | ||
- | | + | |
- | - start openOCD: < | + | To control the SWD adapter several software are available: |
+ | * the dedicated [[#st-link]] tool | ||
+ | * but I am using [[# | ||
+ | |||
+ | === st-link === | ||
+ | |||
+ | [[https:// | ||
+ | |||
+ | To install st-link: | ||
+ | <code bash> | ||
+ | git clone https:// | ||
+ | cd stlink/ | ||
+ | ./ | ||
+ | ./ | ||
+ | make | ||
+ | </ | ||
+ | |||
+ | To write the firmware at 0x0800 0000 (the flash memory start address) you can simply use: | ||
+ | <code bash> | ||
+ | ./st-flash write firmware.bin 0x08000000 | ||
+ | |||
+ | 2016-02-14T10: | ||
+ | 2016-02-14T10: | ||
+ | 2016-02-14T10: | ||
+ | 2016-02-14T10: | ||
+ | Flash page at addr: 0x08001800 erased | ||
+ | 2016-02-14T10: | ||
+ | 2016-02-14T10: | ||
+ | 2016-02-14T10: | ||
+ | 6/6 pages written | ||
+ | 2016-02-14T10: | ||
+ | 2016-02-14T10: | ||
+ | </ | ||
+ | |||
+ | What is useful is that it show some information about the chip at the beginning. | ||
+ | You can also get this information using '' | ||
+ | |||
+ | You can also use it combination with [[#GDB]] to [[# | ||
+ | - start the st-util server: <code bash> | ||
+ | ./st-util | ||
+ | |||
+ | INFO src/ | ||
+ | INFO src/ | ||
+ | INFO src/ | ||
+ | INFO gdbserver/ | ||
+ | INFO gdbserver/ | ||
+ | INFO gdbserver/ | ||
+ | </ | ||
+ | - start GDB with the firmware to flash/ | ||
+ | arm-none-eabi-gdb firmware.elf | ||
+ | |||
+ | ... | ||
+ | Reading symbols from firmware.elf...done. | ||
+ | (gdb) tar extended-remote :4242 | ||
+ | Remote debugging using :4242 | ||
+ | 0x0800016c in ?? () | ||
+ | (gdb) load | ||
+ | Loading section .text, size 0x85d8 lma 0x8002000 | ||
+ | Loading section .ARM.exidx, size 0x8 lma 0x800a5d8 | ||
+ | Loading section .data, size 0x8b4 lma 0x800a5e0 | ||
+ | Start address 0x80043fc, load size 36500 | ||
+ | Transfer rate: 9 KB/sec, 7300 bytes/ | ||
+ | </ | ||
+ | |||
+ | === OpenOCD === | ||
+ | |||
+ | [[http:// | ||
+ | It supports numerous adapters and micro-controllers (targets). | ||
+ | You just have to specify what you are using. | ||
+ | |||
+ | To use OpenOCD: | ||
+ | - install OpenOCD: <code bash> | ||
+ | sudo apt-get install openocd | ||
+ | </ | ||
+ | - start openOCD | ||
openocd --file interface/ | openocd --file interface/ | ||
</ | </ | ||
- | - connect to openOCD to open a session: < | + | - connect to openOCD to open a session: < |
telnet localhost 4444 | telnet localhost 4444 | ||
</ | </ | ||
- | - in this session reset and halt the MCU: < | + | - in this session reset and halt the MCU: < |
reset halt | reset halt | ||
</ | </ | ||
- | - you can dump the current flash content (from 0x0800 0000 to 0x0801 ffff): < | + | - you can dump the current flash content (from 0x0800 0000 to 0x0801 ffff): < |
dump_image dump.bin 0x08000000 0x1ffff | dump_image dump.bin 0x08000000 0x1ffff | ||
</ | </ | ||
- | - and write to flash a new firmware at 0x0800 0000 (the flash memory address). firmware.bin must be in the working directory where you started openOCD: < | + | - and write the firmware at 0x0800 0000 (the flash memory |
flash write_image erase firmware.bin 0x08000000 | flash write_image erase firmware.bin 0x08000000 | ||
</ | </ | ||
You can also use this openOCD one-liner to flash a firmware: | You can also use this openOCD one-liner to flash a firmware: | ||
- | < | + | < |
openocd --file interface/ | openocd --file interface/ | ||
Line 230: | Line 352: | ||
</ | </ | ||
+ | Like with [[# | ||
===== IAP ===== | ===== IAP ===== | ||
Line 245: | Line 368: | ||
It works well on most generic boards and is small (8kB). | It works well on most generic boards and is small (8kB). | ||
- | To flash using the bootloader: | + | If you want to make use of USB in your actual application after the bootloader started it, don't forget to force re-enumerating USB so the host computer sees the new interface: |
+ | * you can do this on the board by signalling a USB reset. On the [[#maple mini]] there is a dedicated circuit. On generic boards you can pull USB D+/PA12 low for a short time | ||
+ | * you can also force this on the host using [[https:// | ||
+ | sudo ./usb-reset "/ | ||
+ | </ | ||
+ | |||
+ | To flash using the USB DFU bootloader: | ||
- download the [[https:// | - download the [[https:// | ||
* [[https:// | * [[https:// | ||
- | * [[https:// | + | * [[https:// |
* [[https:// | * [[https:// | ||
- flash bootloader (at 0x0800 0000) using [[#ICP]] | - flash bootloader (at 0x0800 0000) using [[#ICP]] | ||
- | - install DFU-util (>=0.8): < | + | - install DFU-util (>=0.8): < |
sudo apt-get install dfu-util | sudo apt-get install dfu-util | ||
</ | </ | ||
- | - install the rules to allow users to use the DFU devices: < | + | - install the rules to allow users to use the DFU devices: < |
sudo tee / | sudo tee / | ||
# LeafLabs STM32 DFU USB | # LeafLabs STM32 DFU USB | ||
Line 265: | Line 394: | ||
- remove flashing device | - remove flashing device | ||
- re-plug USB | - re-plug USB | ||
- | - the board should enumerate as DFU device. verify in the logs: < | + | - the board should enumerate as DFU device. verify in the logs: < |
tail -f / | tail -f / | ||
Line 277: | Line 406: | ||
... | ... | ||
</ | </ | ||
- | - check the available DFU profiles: < | + | - check the available DFU profiles: < |
dfu-util --list | dfu-util --list | ||
Line 291: | Line 420: | ||
Found DFU: [1eaf:0003] ver=0201, devnum=4, cfg=1, intf=0, alt=0, name=" | Found DFU: [1eaf:0003] ver=0201, devnum=4, cfg=1, intf=0, alt=0, name=" | ||
</ | </ | ||
- | - you can flash the firmware (at 0x800 2000): < | + | - you can flash the firmware (at 0x800 2000): < |
dfu-util --verbose --device 1eaf:0003 --cfg 1 --intf 0 --alt 2 --download firmware.bin | dfu-util --verbose --device 1eaf:0003 --cfg 1 --intf 0 --alt 2 --download firmware.bin | ||
Line 320: | Line 449: | ||
</ | </ | ||
- after the device is powered you have 0.5 seconds to flash the firmware before if starts the main firmware | - after the device is powered you have 0.5 seconds to flash the firmware before if starts the main firmware | ||
- | - on [[https:// | ||
- | sudo ./usb-reset "/ | ||
- | </ | ||
====== developing ====== | ====== developing ====== | ||
Line 337: | Line 463: | ||
I am using [[http:// | I am using [[http:// | ||
I still keep the [[http:// | I still keep the [[http:// | ||
+ | |||
+ | ====== debugging ====== | ||
+ | |||
+ | Here are methods I use to debug my firmware, in increasing order of difficulty and power. | ||
+ | |||
+ | ===== LED ===== | ||
+ | |||
+ | Most of the development boards come with a user LED connected to a GPIO. | ||
+ | Switching it on an off is pretty easy. | ||
+ | I use it to show a current state (on/off) or activity (toggling). | ||
+ | |||
+ | The advantage is that you can also use it in interrupt service routines, or see the signal on the oscilloscope (to measure the speed, frequency, or use it as trigger). | ||
+ | |||
+ | ===== prinft ===== | ||
+ | |||
+ | The LED is pretty simple but also very limited. | ||
+ | The next step is printing messages on the console about what is being done. | ||
+ | For the communication I use a USART port. | ||
+ | They are easy to configure and run, reliable, and simple to connect to. | ||
+ | It's also fast enough to send debug messages. | ||
+ | |||
+ | With these messages I can show multiple states, the history of events, and ongoing actions. | ||
+ | But don't use USART in interrupt service routines. | ||
+ | That just creates a mess. | ||
+ | |||
+ | ===== GDB ===== | ||
+ | |||
+ | The [[https:// | ||
+ | |||
+ | Often it's used to debug local computer software, but it can also be used to debug software running on a remote micro-controller. | ||
+ | For that you just need as [[#SWJ]] adapter to be able to control the hardware, and software making use of this adapter such as [[# | ||
+ | Then tell GDB to connect to this remote target, through this SWJ software. | ||
+ | |||
+ | Here a quick example using [[# | ||
+ | arm-none-eabi-gdb --eval-command=" | ||
+ | |||
+ | ... | ||
+ | Reading symbols from firmware.elf...done. | ||
+ | Remote debugging using | openocd --file interface/ | ||
+ | Open On-Chip Debugger 0.10.0-dev-00189-g554313b (2016-01-12-16: | ||
+ | ... | ||
+ | Info : STLINK v2 JTAG v17 API v2 SWIM v4 VID 0x0483 PID 0x3748 | ||
+ | Info : using stlink api v2 | ||
+ | Info : Target voltage: 3.286573 | ||
+ | Info : stm32f1x.cpu: | ||
+ | Info : accepting ' | ||
+ | Info : device id = 0x20036410 | ||
+ | Info : flash size = 128kbytes | ||
+ | undefined debug reason 7 - target needs reset | ||
+ | 0x00000000 in ?? () | ||
+ | |||
+ | (gdb) monitor halt | ||
+ | stm32f1x.cpu: | ||
+ | target halted due to debug-request, | ||
+ | xPSR: 0x21000000 pc: 0x08002314 msp: 0x20004f80 | ||
+ | stm32f1x.cpu: | ||
+ | target halted due to debug-request, | ||
+ | xPSR: 0x21000000 pc: 0x08002314 msp: 0x20004f80 | ||
+ | |||
+ | (gdb) backtrace | ||
+ | #0 0x08002314 in main () at main.c:193 | ||
+ | |||
+ | (gdb) frame | ||
+ | #0 0x08002314 in main () at main.c:193 | ||
+ | 193 __WFI(); | ||
+ | </ | ||
+ | |||
+ | This is pretty useful to check the state (to figure out where the code runs havoc) and control the flow, even in interrupt service routines. | ||
+ | |||
+ | ===== SWO ===== | ||
+ | |||
+ | TODO |
stm32f1xx.txt · Last modified: 2024/01/07 17:49 by 127.0.0.1