
Bare Metal STM32 Programming and a Quadcopters Awakening - timakro
https://timakro.de/blog/bare-metal-stm32-programming/
======
dbolgheroni
Hi, interesting article, but I would like to suggest you something. While it's
OK to do bare metal just using the memory locations like you did:

    
    
        *(uint32_t *)0x40021018 = 0x00000004;
    

after a few days, it will become tiresome to read and to remember all those
addresses. I suggest you to use the header [0] that the ST provides for
STM32F1, which is included in packages such as STMCubeF1 [1], STMCubeF0, etc.

For instance, instead of using the memory address directly, you could just do

    
    
        RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
    

so it's easier to remember what is what. STMCubeF1 is a big package, but you
won't be using the API/drivers ST provides (such as HAL and LL), just the
header. As I understand, the STM32 community kind of rejects this API as
"bloated".

I have some examples here if you would like to take a look:

[https://github.com/dbolgheroni/arm-
makefile/blob/master/drv/...](https://github.com/dbolgheroni/arm-
makefile/blob/master/drv/gpio.c#L29)

Cheers,

[0] [https://github.com/dbolgheroni/arm-
makefile/blob/master/stm3...](https://github.com/dbolgheroni/arm-
makefile/blob/master/stm32cubef1/cmsis/include/stm32/stm32f103xb.h) [1]
[https://www.st.com/en/embedded-
software/stm32cubef1.html](https://www.st.com/en/embedded-
software/stm32cubef1.html)

~~~
dmitrygr

        *(uint32_t *)0x40021018 = 0x00000004;
    
    

Actually that line is not ok. But for another reason. Without "volatile" in
there, the compiler may reorder this access with others, or remove it, or
combine it with others. None of that is good.

~~~
arcticbull
That's a very important call-out. This is the kind of tear-your-hair-out stuff
that's going to be very difficult to track down unless you get it exactly
right. I echo that using the definitions makes the code infinitely more
readable and writeable, and makes zero difference in terms of performance.

------
ChuckMcM
Ok, this drives me nuts

ARGH! Seriously? The STM32F103? Crazy (or should that be Craze) hobbyists
using "blue pill" boards because they are cheap (and they are, like $3 on
ebay) which use this bastard chip of the ST Cortex-M line and they say "gee,
its a really simple circuit and since they sell for so cheap on ebay it should
be a good idea to use this chip!" BZZZZZZT!

ST Micro makes _much better_ CPUs that would be ideal for this application,
they have things like on board DSP instructions in their _floating point_
units, and can run at internal clock rates of _180_ MHz with a megabyte of
Flash and 384K of RAM, some of it very high performance (core coupled memory).
These CPUs are no harder to put onto a PCB than the STM32F103 and they are _so
much more capable_. And sure, they are $10 apiece instead of $1 apiece which
is fine if you're making BILLIONS of these things, but a bespoke quadcopter?

Oh but its Open Source, cool, except I can't find the PCB files anywhere, if I
could I could pull out that crap chip and put in a real CPU and have OSHPark
make me a few. I did find the software repo :
[https://github.com/Crazepony](https://github.com/Crazepony) and yeah, another
budget quadcopter maker with a bunch of things they want to sell and an "open
source" tag to try to get people to come and look. Fair enough, it made me
look. It is sort of the 'freemium' hardware company model.

Sigh. I'd love something bigger than the Crazflie[1] which is like real open
source (PCB and everything) and smaller than a DJI Phantom that I could play
around with.

~~~
jononor
Shoot the Crazepony people an email and ask about the PCB design files for
their 'open source' quadcopter?

~~~
ChuckMcM
I did one better than that, I shot my ST Micro rep an email and asked them if
they would like a open source design on the web that showcased their new
STM32F4 series with built in Wireless support and their new STSPIN BLDC
controllers with built in Cortex-M0s. He was quite taken with the idea :-)

~~~
halbritt
Quadcopter pilots have been using STM32F3 for years. Check out:
[https://github.com/betaflight/betaflight](https://github.com/betaflight/betaflight)
one of the more popular flight control projects. They've been supporting
STM32F4 and STM32F7 for quite some time.

A typical quad flight controller with an STM32F4 and a decent MPU will set you
back less than $30.

------
rofo1
Little bit off topic, but if anyone is on the fence about STM32, I strongly
suggest trying out STM32 Black pill 3.3V version
([https://wiki.stm32duino.com/images/5/52/Black_Pill_Schematic...](https://wiki.stm32duino.com/images/5/52/Black_Pill_Schematic.pdf)).
It's an _amazing_ board, Arduino-compatible, 72MHz, i/o, adc and pwm pins,
uart and i2c.

You can get it cheaper and just solder the header yourself. Even has a micro
USB support.

Truly remarkable board.

~~~
j1elo
I'm not an expert wrt. the clocking of these boards, how does it achieve the
72MHz? In that datasheet it looks like the onboard crystal is just 8MHz.

Does it use some kind of internal clock multiplier to achieve 72MHz? Would
such a magnified 8MHz to 72MHz provide a good stable clock?

~~~
neetdeth
The clock source is typically generated by a phase locked loop from the
external crystal oscillator. There's a PLL multiplier and divider value that
you can set obtain the desired frequency.

I _think_ the MCU starts running at a low speed from an internal RC
oscillator, and then setting up the high speed clock source happens early in
the initialization code. This code can be generated by ST's STM32Cube
software, which is useful as a reference implementation even if you don't use
the generated code in your project.

------
leggomylibro
Looks like a nice write-up!

ST actually sells an evaluation board for learning about drone control; it has
a BTLE module, four small FETs, sensors for pressure and a 9-axis IMU, a 1S
battery charging circuit, and source code for some example firmware on Github.
Search for 'STEVAL-FCU001V1'.

I've also seen a lot of cheap STM32-based FCU boards from the same places
you'd get one of these 'blue pill' boards.

These are very useful chips to learn about, because they come in all shapes
and sizes. Some focus on power efficiency, others on speed, others on
connectivity or signal processing, and there aren't too many differences that
you need to account for in your code.

Also, you can program and debug these using OpenOCD with a generic "ST-Link"
module; they only cost a few bucks from cheap sources, or many of ST's
evaluation boards have a built-in STLink probe which you can use. That lets
you connect to the chip from GDB and step through your code like a normal C
program, which is often a lifesaver.

~~~
timakro
On-chip debugging with OpenOCD was actually one of the next things I wanted to
try out with my drone. I need to get an ST-Link dongle because the drone
doesn't have one on board.

I'm not sure if JTAG will even work or if they connected a pin to some sensor
or similar on the board. SWD will work for sure, I saw the two SWCLK and SWDIO
connectors on the board.

~~~
leggomylibro
Cool, good luck! If you end up wanting a more 'official' STLink probe which is
still pretty cheap, the ones on their 'discovery kit' and larger 'nucleo'
boards can be disconnected from the main board and used with other targets.

They're a little bulky, but if you're interested in bare-metal programming,
the embedded Rust ebook[1] currently uses an STM32F3 discovery kit[2] as a
target, and that board's user manual has instructions for using its ST-Link to
program/debug an external application[3] like your drone.

[1]: [https://rust-embedded.github.io/book/](https://rust-
embedded.github.io/book/)

[2]: [https://octopart.com/stm32f3discovery-
stmicroelectronics-241...](https://octopart.com/stm32f3discovery-
stmicroelectronics-24148288)

[3]:
[https://www.st.com/resource/en/user_manual/dm00063382.pdf](https://www.st.com/resource/en/user_manual/dm00063382.pdf)
(PDF, see section 6.2 for STLink info)

------
snazz
I have no idea about the load carrying capacity of the drone, but it would be
an awfully cool project to add an ultrasound sensor(s) and write a program for
flying it around randomly indoors without hitting walls. A fancy feature might
be to solve a real-life maze by flying through it. Would such a thing be
possible?

~~~
msadowski
Not ultrasound but at one point in my life I made this:
[https://www.youtube.com/watch?v=ig8IRTejn8A](https://www.youtube.com/watch?v=ig8IRTejn8A)

(I'm even piloting in this video)

~~~
snazz
Very cool. Thank you for sharing!

------
ansible
Just FYI, I don't recommend charging LiIon or LiPo batteries in parallel, as
shown in one of the pictures.

There's a greater risk of fire or just general damage to the capacity of the
batteries.

~~~
kawsper
For the small 1S batteries you can get this style of charger for $16 that will
charge in parallel: [https://www.amazon.com/Happymodel-Battery-Charger-
Mobula7-Qu...](https://www.amazon.com/Happymodel-Battery-Charger-
Mobula7-Quadcopter/dp/B07K7H5H6C)

But for bigger batteries I recommend buying a charger that can handle 4 or
more separate batteries at a time like the SkyRC Q200 or the Turnigy TQ4, or
just do like me, charge each battery individually.

------
jburgess777
STM32 chips are used on a lot of quadcopter flight controllers, often using
open source firmware like Betaflight

[https://github.com/betaflight/betaflight/wiki](https://github.com/betaflight/betaflight/wiki)

~~~
kawsper
I am tracking this issue:
[https://github.com/betaflight/betaflight/issues/5516](https://github.com/betaflight/betaflight/issues/5516)

I can't wait to see how a STM32H7 will perform on a quadcopter, and what it
will allow for :)

------
swamp40
Keil has a completely free version of their compiler for STM32F0, STM32G0, and
STM32L0 micros: [https://www2.keil.com/stmicroelectronics-
stm32/mdk](https://www2.keil.com/stmicroelectronics-stm32/mdk)

~~~
hak8or
I cannot reccomend against Kiel, iar, and atollic enough. They are garbage
ide's (can only do string based auto complete, no dark theme, very poor window
management), yet still cost a small fortune if you want to go above 32KB of
flash usage or whatever other the free versions do. They also have their
version of a linker script which is even worse than normal linker scripts, and
if you are forced to use their compiler then often it doesn't even handle
c++11. Or if it does have c++, the auto complete doesn't.

Go for gcc or clang with cmake (or even just make) and use qt creator or
visual studio code or others. You will get cmake based auto complete, access
to a proper IDE color scheme of your choice, get to use your own compiler
(clang, gcc, etc), and it's much more flexible. And for debugging be able to
use a much more capable ozone from segger, or even gdb enabled backend in qt
creator or clion.

My work flow for example is cmake and gcc regarding tooling, qt creator or
visual studio code which works with cmake to give me proper context aware auto
complete, and clang-tidy as a linter running in the background. I am
incredibly productive with this, and am able to make use of c++17's features
to go for true zero cost abstractions, while shifting checks from runtime to
the compiler via types and static asserts and whatnot.

Plus, this is far more portable. No longer having to worry about project files
working across diffirent versions of keil (this bit me in the ass at my last
company). It's just a simple text file.

~~~
rct42
Unfortunately, iffy IDEs are pretty common in the embedded world. I too
dislike Keil's uVision IDE, but sometimes you need to take the bad with the
good. At work I use Keil + MDK-Pro and now and again also use ETM trace for
debugging really tricky problems. AFAIK armcc also produces higher performing
binaries than arm gcc (but this probably irrelevant in a lot of use cases).

------
cproctor
I can't help but wonder whether quadcopters will be where governments finally
legislate control over general computation. Having access to bare metal means
nobody can stop inexpensive and socially-disruptive quadcopter applications.
How many years before quadcopters join rats and pigeons as the scourge of
urban life, always on the prowl for unguarded power outlets or perches on
power lines?

Governments and/or corporations have control of the bottom layer of cell
phones and TCP/IP networking. Not so for firmware and cryptography, though not
for lack of trying.

------
msadowski
Thanks for sharing the article! I think it would make a good addition to my
WeeklyRobotics[1] series. Would you mind if I reshare it there?

[1] [http://weeklyrobotics.com/](http://weeklyrobotics.com/)

~~~
timakro
Nice series you got there, I just took a look and found some really
interesting projects. I would be honored for my article to be featured there!

~~~
msadowski
I'm glad you found some interesting projects, it means I'm doing some things
right!

I'll most probably feature your article in the issue coming out this Sunday or
a week after.

Thanks!

------
Warwolt
What tools did you use to make the drawings in the post? They look great!

