
Quadcopter Programming Part 2: Using the CMSIS Library and First Takeoff - timakro
https://timakro.de/blog/quadcopter-programming-part-2/
======
sgtnoodle
The article's Delay function unfortunately has a rollover bug. If the counter
rolls over in the middle of a delay, the delay will return early. It's a
nefarious bug because it only occurs every 50 days, and only if the program is
delaying. Also, while it's probably ok in this usage since it's a 32-bit cpu,
it would be better to use atomic access intrinsics or a critical section and
memory barriers rather than volatile to make the counter variable "ISR safe".

Embedded code is a lot of fun, but if you want to safely work on the "really
fun" stuff it's important to maintain a high level of quality and correctness
for fundamental but lame utility functions like this. Otherwise you could
literally build a ticking time bomb!

~~~
emilfihlman
>Also, while it's probably ok in this usage since it's a 32-bit cpu, it would
be better to use atomic access intrinsics or a critical section and memory
barriers rather than volatile to make the counter variable "ISR safe".

The dislike for volatile coming from people in higher systems is pretty tiring
and unwarranted.

Volatile is a perfectly fine tool on low level mcus.

~~~
fhars
No, it is not, it will just work most of the time in low level MCUs because
compilers support this abuse for lack of clearly better options. C and C++
have no support whatsoever for dealing with interrupts: volatile does not
introduce any memory fences, atomics are for sharing data between threads
which you do not have in many embedded systems, and sig_atomic_t is only
defined for situations where you have a posix-like runtime environment. So
sharing data between an ISR and the main program is undefined in C, and the
compilers are free to compile „volatile“ the way most people expect, but the
language does not guarantee that it works.

It can be argued that the only kind of variable that can be shared safely
between an ISR and the rest of the code is a volatile sig_atomic_t, but that
is an argument from analogy and not from first principles, as the C abstract
machine has no concept of ISR. The same goes for the argument that you should
use atomic intrinsics, plausible, but still just an analogy.

(Just in case anyone was wondering if C as a language is close to the metal:
no, it is not.)

------
JoshMcguigan
I found quadcopters to be a great way to get into embedded development. There
are a couple posts on my blog [0] [1] related to getting Rust running on a
quadcopter controller, although I never actually got my code controlling the
drone in flight. The lesson I learned was that if I was going to do it again
I'd definitely choose a board with an exposed debugger port, as I spent a lot
of time repurposing one of the motor outputs into a serial transmit port just
to do some "println debugging".

Not sure if OP is here, but I'd be interested in hearing about which debug
options are easily exposed on that board. Can you use the port you are
flashing the drone with as a standard serial port after your code is loaded?
Looking forward to the future post about SWD that is introduced at the end of
this post as well.

[0]: [https://www.joshmcguigan.com/blog/betafpv-drone-flight-
contr...](https://www.joshmcguigan.com/blog/betafpv-drone-flight-controller-
hello-rust/)

[1]: [https://www.joshmcguigan.com/blog/betafpv-drone-flight-
contr...](https://www.joshmcguigan.com/blog/betafpv-drone-flight-controller-
board-support-crate/)

~~~
timakro
SWD is purposefully exposed on that board and instead of flashing via the
bootloader I got flashing with gdb via SWD with the `load` command working. I
just use a male header with some jumper wires for the connection. It seems
stable enough. Some pictures of the debug port here:

[https://files.timakro.de/IMG_20191201_142259.jpg](https://files.timakro.de/IMG_20191201_142259.jpg)

[https://files.timakro.de/IMG_20191201_142246.jpg](https://files.timakro.de/IMG_20191201_142246.jpg)

------
hexo
CMSIS is the most bizarre API i've ever seen. This kind of mixing
ALLCAPS_WithUnderscores_AndCamelCase is like criminal. Also _Min_Heap_Size.
And that is the reason i would never use it and i've always looked for
alternatives. Now i've ended up using Ivory/Tower eDSL framework where just
about everything is equally complicated - as building a spaceshuttle.

~~~
leggomylibro
On the bright side, the core CMSIS headers should work with all ARM Cortex-M
cores, so you don't get locked into one vendor's HAL to do things like setup
interrupts or interact with registers that are common to ARM cores. It also
has something approaching first-party support with a permissive license.

I think that the ALLCAPS parts come from acronyms in most cases. Like, NVIC =
Nested Vector Interrupt Controller. The naming can get a little bit confusing,
but it seems fairly consistent.

------
sansnomme
What does this line of code mean?

    
    
        *(volatile uint32_t *)0x40021018 = 0x00000004;
    

Why is a pointer being created and dereferenced at the same time?

~~~
chli
It's how you access memory mapped registers in C. It's writing the value 0x04
at that address using a 32-bit memory write. There is a peripheral register at
that location.

------
prudhvis
I thought, the Peripheral library is deprecated for STM32. Is there any reason
to use it besides the STM32 CUBE framework?. Because, the later seems to
support more STM32 product lines.

~~~
roland35
Stm32 cube mx is the newest version of the framework, but the old peripheral
driver library is a bit simpler and easier to use! It is more low level and a
light layer over the hardware.

The new cube library can be more complex.

~~~
leggomylibro
The new cube libraries do include two abstraction layers, though. I agree that
the "HAL" libraries can be very confusing because they try to do everything
for you with endlessly nesting functions and macros, but the "LL" (Low-Level)
ones are closer to the old peripheral driver libraries.

------
mips_avatar
Just ordered one myself after reading your post, look forward to working on
this platform!

~~~
timakro
Great! Be sure to check out the first part if you have trouble getting
started. Best of luck :)

