Author Topic: Getting Started with STM32 (ARM CORTEX)  (Read 5785 times)

0 Members and 1 Guest are viewing this topic.

Offline Glenn0010Topic starter

  • Regular Contributor
  • *
  • Posts: 225
  • Country: mt
Getting Started with STM32 (ARM CORTEX)
« on: June 29, 2018, 03:46:41 pm »
Hi

So I have worked previously briefly with the STM for some small projects but want to get into it more now. However what I have noticed is that it is quite convoluted or at least for me especially since I worked with ARM7 mcu before and they are really easy to work with.

I would like to work with the standard peripheral library, however for example using keil it takes about half an hour setting up a project which does not really make sense for me the amount of steps that are required. Furthermore I cannot for the life of me find where to change the clock speed and PLL etc.

I know there is the ST CUBE system but I would like to work with the peripheral library. Can some one point me to a good source of getting started since there is a lot of info but I don't really know where to start from.  Also with the projects that I worked with before I could not debug properly for example I could not see the ADC value in the IDE and I',m sure cause I did not configure something correctly.

Thanks!
 

Offline martinayotte

  • Regular Contributor
  • *
  • Posts: 64
 

Offline pyroesp

  • Regular Contributor
  • *
  • Posts: 180
  • Country: be
    • Nicolas Electronics
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #2 on: June 29, 2018, 09:14:02 pm »
I'm using Atollis TrueStudio to program on STM32, just got back into it.
I'd recommend going on ST's website and checking the application notes for your device, and obviously checking the datasheet for the clock and PLL registers.

STM32CubeMX let's you configure everything you want. You should be able to find the clock and PLL, change it to your liking and generate C code.
Import that to a C project in Keil and you should be fine... I guess.

Haven't tried using STM32CubeMX with TrueStudio yet.
 

Offline Glenn0010Topic starter

  • Regular Contributor
  • *
  • Posts: 225
  • Country: mt
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #3 on: June 30, 2018, 08:02:16 am »
The main issue upon doing some research is that the HAL Library is a bit more complex (buggy sometimes) and more high level. While with the standard peripheral library it seems you get more of an understating of what is going on at the chip level.

Basically my issue is to find and easy way to create a project and set up the clocks using the std library. I looked for example how to change the internal clocks etc but different sources quoted different header files etc and I could not figure it out.

I do agree with you that the with the cube it is very easy to use. Is the cube (HAL) used in industry or do they stick with the STD library?
 

Offline MosherIV

  • Super Contributor
  • ***
  • Posts: 1530
  • Country: gb
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #4 on: June 30, 2018, 10:19:30 am »
ST no longer support the standard peripheral library, ie they no long do bug fixes or answer questions or do new versions. This is because they replaced it with the ST CUBE which generates the code that the library code use to be.

NONE of the library or cube code is a Hardware Abstraction Layer, it is simpley driver code for the ST peripherals. It is up to you the developer to put a HAL layer on top of the driver code.

Some of the ST peripherals are difficult to understand from the programmers reference manual, they have application notes for guiding you through using the peripheral for certain application eg timer modual for pwm.

Edit: I believe yes it is used in industry now, ST no longer support the peripheral library so companies have no choice but to use the ST CUBE. It has been 5 years since I have worked with STM32s, I now work on Infineon ARMs

I did not have much problems with the internal PLL clocks with the peripheral library, there are 2 defines in a header file somewhere. You define the clock speed you want and the crystal clock speed and the library code works out what the values should be to put into the PLL registers. Note, not all clock freq are possible and sometime it is dictated by one of the peripherals eg the USB peripheral must have the PLL clock set to certain freq.

« Last Edit: June 30, 2018, 10:36:21 am by MosherIV »
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8714
  • Country: fi
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #5 on: June 30, 2018, 11:53:33 am »
During the 5 years I have spent with STM32 series, the "trend tool of the year", and the supposedly "correct way of doing things" has changed about... 5 times?

During this time, I have seen people come and go, always instructing beginners to learn a different toolset each year, then these toolsets get obsolete or simply non-trendy after a few succesful LED blinker projects. I have seen very little success doing anything actually - but countless of threads like this, asking "how to get started".

It's not about how to get started - it's should be about how to do something useful, in a sustainable manner.

The coding style taught using these libraries and toolsets is pure horror - typically 20-30 lines of code is either copypasted or autogenerated to change an IO pin as an output and turn an LED on. Projects are autogenerated without any clue what's happening on the background. We just need to admit ourselves this is totally unsustainable and stop doing that.

I understand the Arduino way of hiding ugly things like #includes to make it easier to just blink a LED for an artist/beginner, using about two lines of code. And it really works easily with simple digitalWrite(). And I understand people want to use integrated tools and as much libraries as possible to make the same experience happen on STM32. But now, you have a much more capable and powerful MCU which can do anything you want (and there probably is a reason why you picked a more powerful ARM instead of the AVR or PIC), but instead, you are led to fear that it's "too complex to understand", necessitating "abstraction". A nice goal, on paper.

But, the fact is that all implementations I've seen to provide this generic abstaction on STM32 are totally failed beyond unusable, most notably the STM32 HAL and Standard Peripheral Library. You are still exposed to all ugly internal details, but added with an extra layer of complexity how to control these partially-exposed low-level details through elaborate higher-level details - which are very buggy as well.

Needless to say, you don't need to go this route. You can do it much easier, like you traditionally do with any microcontroller - follow the reference manual for guidance how to work with the peripherals, and write to the registers as you wish. This is because, despite all the fear-mongering, these devices are not that much more complex compared to an AVR or PIC. The reference manuals are long, but only because they offer so many peripherals. You only use what you need.

The CMSIS and standard peripheral library header files contain useful definitions, similar to any old traditional PIC or AVR, to make register access easy. You don't need to use the "whole package", such as the initialization structs and buggy, bloated functions.

But, the biggest issue is the lack of documentation and proper tutorials - a horrible signal-to-noise ratio in available information. And, due to the lack of sane tools, you do need to understand the concepts of linker scripts and startup code to get started, which has a steep learning curve for a beginner, perhaps someone who's accustomed in the transparent it-just-works autogeneration in AVRGCC. In the end, it pays back extremely well, since the alternative way of following the trend packages and horribly autogenerated and copypasted code is a total and utter dead end.
« Last Edit: June 30, 2018, 12:08:13 pm by Siwastaja »
 
The following users thanked this post: rfspezi, asmfan

Offline Dubbie

  • Supporter
  • ****
  • Posts: 1115
  • Country: nz
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #6 on: June 30, 2018, 12:20:08 pm »
Personally I don’t really get all the hate for the Cube. I find it super useful for planning projects. When it comes to figuring out what peripherals you are going to use on what pins, it’s really quick and easy. Clocks are super easy to set up. I haven’t had any trouble with using any of the peripherals. I have done half a dozen projects with it now and it’s been extremely straightforward. I use VisualGDB which has nice debugging and means I can use visual studio which I like.

My last project, I wrote the firmware while I waited for my boards to arrive, and was very surprised and pleased that it worked first time I flashed it. It had a statemachine, spi drivers for a peripheral chip, and lcd display drivers. And a couple of quadrature decoders using hardware timers. So more complex than an LED blinking!

I am not a professional programmer, so take my opinion with a grain of salt. But don’t discount the cube without trying it.
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8714
  • Country: fi
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #7 on: June 30, 2018, 12:36:22 pm »
Oh, let's talk about Cube.

It's well possible that the Cube's way of generating peripheral code is way better than the "old" standard peripheral library way. It probably is, since the old way totally sucked beyond unusable. So it's easy to improve on that, and it's no surprise seeing them discontinue it.

I like the idea of the Cube's ability to quickly map pins on a large pin count device and thus help in HW design, so I tried to download and install it to map a 176-pin STM32H7 device I'm now working with. Even finding the download link was difficult enough; following the download links led to an infinite loop of getting to the same download page. Then, I accidentally downloaded some device packages that were lacking the software itself. Then it occured to me it requires installing an obsolete, security-problematic, nowadays often blocked and mostly unsupported framework called "Java" no one uses anymore for any other purpose, so it's not worth installing anymore because the Cube is the only software that would need it. And then it occured to me that the Cube is not a standalone software at all, but a plugin for another IDE software behemoth I don't want to install. After trying to get Cube running in a Windows machine for about 2-3 hours, I gave up in a "I don't need this 'helper tool'" fashion and planned the pins manually in an Altium schematic using text annotations, tables and colors to help the process, which took about the same time. Now, this manual way has another added benefit: since Cube will not exist anymore in 1-2 years (let's come back to this, I'm happy to admit I'm wrong if it still maintained in 2020), now I have avoided learning another temporary and useless skill.

I'm sure all the "hate" against Cube is not in the software itself, but it's all about the volatility of such tools and the terrible track record of ST's software tools and support. People just don't want to use such software - even without trying, and I understand that very well.

Helper software is great, but it needs to be trustable; if not, the "help" you get from it needs to be quite significant in order it to override more manual methods.

It works when there is no other way. For example, the FPGA vendor tools such as Quartus are horrible pieces of bloated shit, but they simply cannot be replaced with anything else since they incorporate the completely proprietary and super complex place&route algorithm.

On the other hand, the time I have spent learning gcc, make, ld and binutils has been very widely usable. I have no barriers whatsoever to pick any other ARM Cortex microcontroller from any other manufacturer. Also, since these tools have not changed or broken in several decades, I have a great trust they can be used in similar manner after another two decades.

The BEST thing in ARM microcontrollers is that they finally brought standard toolsets to the MCU world so that you are no longer in that much vendor lock-in due to development software, and can jump between the MCU families much easier. Manufacturer-specific toolsets try to actively prevent this - and this is understandably favorable from the MCU manufacturers' point of view, so it's no wonder they support this way so visibly.

The biggest fear is that MCU manufacturers stop producing documentation and force the users that way in constructing the programs using their closed libraries. So far, there is not much sign of that happening - the ones who do this have always done this.
« Last Edit: June 30, 2018, 12:53:24 pm by Siwastaja »
 

Offline Glenn0010Topic starter

  • Regular Contributor
  • *
  • Posts: 225
  • Country: mt
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #8 on: June 30, 2018, 04:32:43 pm »
If I am honest I totally agree with you I prefer setting the registers myself, first off you know what exactly is going on, further it reduces the likelihood of bugs as well. Having woorked with ARM7 UCs before (LPC2119), I programmed them using the register and it was very easy and you know exactly what is happening.

However the Cortex cores are a different beast and much more complex. I would like to try to set the registers manually as you say but what exactly do I need to download etc? I am using Keil 5. Are there any software packs/compilers I need to download, since most of the documentation I find is using some sort of library.

Thanks so much
 

Offline MosherIV

  • Super Contributor
  • ***
  • Posts: 1530
  • Country: gb
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #9 on: June 30, 2018, 05:01:34 pm »
The Cortex-M cores are very similar. They are identicle (software wise) no matter which manufacturer you go to. The CMSYS is the standardised interface for the ARM core no matter who's microcontroller you use. The Cortex-M cores are ARMs evolution of the ARM7.

The ST CUBE generates the initial/boot code, adds the CMSYS code and then adds the peripheral driver code for the STM32 specific microcontroller that you have.

You are completely free to ignore all of this IF YOU WANT TO. You will have to read the programmers reference manual and figure out how the peripheral works and what the register do yourself.

As a professional embedded developer, I do not have time to do this. Any help the silicone vendor can give is welcome.

So long as Keil supports the ARM Core you are using, it has the debugger support, you should be good. You need the CMSYS code to support the set up of the ARM Core, some example boot code might help. As you have found, STM32 have their own peripheral for managing the clock. You can try the old peripheral library code, be sure to get the right code for the STM32 that you have, they all look similar but there are enough differences that may cause strange thing to happen if you have the wrong one. If you want to write the driver code yourself, you can, it will just take you longer before you get round to coding your application. The advantage of writing the driver code is that you will know the ST peripherals very well!
 

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 895
  • Country: us
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #10 on: June 30, 2018, 05:14:30 pm »
CubeMX is pretty good for dealing with GPIO planning and setting up the various clocks in the system. Both of those things can be complicated in the STM32 world. [You wouldn't think that GPIO stuff is difficult, but it actually impacts your DMA ability on STM32.]

The main thing I don't like about the cube is that it depends on code generation. I.e., it spits out some (usually nasty) source code that you're expected to edit and fill in with useful calls. Machine generating source code that someone else is expected to edit is a *TERRIBLE* idea. STM isn't the only offender, however.

ST's HAL library is (in some ways) more complicated than simply dealing with the registers directly. Some folks like it, but I prefer the LL "library" which is mostly a bunch of macro definitions.
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8714
  • Country: fi
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #11 on: June 30, 2018, 08:37:39 pm »
If I am honest I totally agree with you I prefer setting the registers myself, first off you know what exactly is going on, further it reduces the likelihood of bugs as well. Having woorked with ARM7 UCs before (LPC2119), I programmed them using the register and it was very easy and you know exactly what is happening.

However the Cortex cores are a different beast and much more complex. I would like to try to set the registers manually as you say but what exactly do I need to download etc? I am using Keil 5. Are there any software packs/compilers I need to download, since most of the documentation I find is using some sort of library.

It seems you have the skills and you are good to go. I can assure you it will go well if you keep up with the way of doing like in the past.

For STM32, I Google for, download and include just the header files, such as:
stm32f2xx.h
system_stm32f2xx.h
core_cm3.h
core_cmFunc.h
core_cmInstr.h

Exact files depend on the MCU.

Then I copy over my own linker script and startup code templates from the previous project, and modify as needed. It's nice to have your own linker and startup scripts, and know how they work, because these MCUs often have special features such as fast core-coupled memories, and you may want to control how you map flash pages for non-volatile storage. These files tend to look at bit ugly, but oh well... You don't need to modify them all the time, so it's not that critical. For an example:
https://github.com/siwastaja/rn1-brain/blob/master/stm32.ld
https://github.com/siwastaja/rn1-brain/blob/master/stm32init.c

... and, that's about it! Now you can just follow the reference manual. All the information is really there (+ the datasheet, of course). I just compile with gcc, using a makefile such as this:
https://github.com/siwastaja/rn1-brain/blob/master/makefile

I didn't need to even look at the ARM Cortex-M core reference manual for years, since it just works and gcc handles all the basic stuff. But you may want to get the STM32 Programming Manual (device specific) for some extra info not available in the reference manual.

The basic compiler tools are available at https://launchpad.net/gcc-arm-embedded


BTW, I did this as a rather quick "fix":
https://github.com/siwastaja/pulutof1-fw/blob/master/stm32_cmsis_extension.h
Even though using these macros will have some performance and code size penalty compared to configuring all bits in one register in one go, it's usually not an issue, and these are still blazing fast compared to the CMSIS/standard peripheral library bloat functions. You may or may not like this style, but it may be worth looking at.
« Last Edit: June 30, 2018, 08:51:55 pm by Siwastaja »
 

Offline Glenn0010Topic starter

  • Regular Contributor
  • *
  • Posts: 225
  • Country: mt
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #12 on: July 01, 2018, 07:34:21 am »
Thank for the pointers!

Hopefully I get my laptop from repair tomorrow and I can get started again. Having learned a lot from my thesis project (BLDC motor controller Hardware design), oh and thanks for your help in that. (If you have not yet, take a look at that thread again got loads of results including thermal tests.... https://www.eevblog.com/forum/projects/bldc-motor-controller-rc-snubber-design-waveforms/msg1540880/#msg1540880), I got a job as a graduate power electronics design engineering in MOTOR CONTROL  ;D ;D and I look forward to keep learning on the hardware side of things.

In my own time I would like to improve my "software" skills and implement FOC now that I have relatively "OK" hardware layout and I kinda know what i going on.

Thanks!!
 

Offline luiHS

  • Frequent Contributor
  • **
  • Posts: 602
  • Country: es
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #13 on: July 01, 2018, 08:44:48 am »
 
You should use Cubemx to configure the entire periphery in the STM32, it is the easiest and fastest way to do it.

All manufacturers offer tools for a simple and graphic configuration of the entire periphery, preventing the user from having to spend time writing the necessary source code. ST offers Cubemx for its STM32, Microchip offers Harmony for its PIC, NXP offers MCUXpresso with the Cofig Tools for its Kinetis, LPC and iMX (the missing Freescale, offered KDS with Processor Expert for the Kinetis).

Because you do not want to use Cubemx, and you prefer to do everything manually?, That approach does not make sense.

As for a good source of information to learn to program the STM32, it is the book MASTERING STM32 by Noviello, it is the bible of the STM32, a very cheap PDF book (874 pages), which explains practically everything you need.

https://leanpub.com/mastering-stm32

Hopefully one day someone will do something as good as Noviello's book, but for Kinetis or better yet for the iXM RT series from NXP. I miss a detailed and practical explanation of things like the DMA in the Kinetis and now the new RT1020 from NXP.
« Last Edit: July 01, 2018, 08:51:16 am by luiHS »
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8714
  • Country: fi
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #14 on: July 01, 2018, 08:50:15 am »
I'm not an "user". I'm a programmer, and I have no issues whatsoever "having to spend time writing the necessary source code". It's exactly what I do, and need to do. Having 1-2% of it autogenerated by a tool I need to learn first, and which has a lifespan of a maybe three years, and requires a book to be understood - sorry, nope.

After autogenerating that pile of code, what next? You still can't program, are even more afraid of writing "the necessary source code". How are you going to do your "own things"? How are you going to debug the thing?

I have noticed one interesting thing as well: the peripherals are not just "init to something and forget". No, usually I need to do something specific, and in order to do that, I need to understand the peripherals, and how to control them to do what I want.

If they spent even 5% of the time and resources they now spend in making tools into making the existing documentation easier to read (just by hiring someone to proofread it would be a good start!), that would be an optimal solution. I find about 50% of the time working with peripherals is simply lost by deciphering cryptic documentation, which could be fixed by using a single good technical writer. Additional effort could go into streamlining the peripheral design so that they would be easier to configure.

Fixing the problem of hard-to-use-peripherals by building code generation tools is simply totally wrong place to do it.

This being said, I don't feel like the peripherals are hard to use. They are quite OK; no code generation helpers needed. But I admit they could be much better still.
« Last Edit: July 01, 2018, 08:54:27 am by Siwastaja »
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4288
  • Country: us
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #15 on: July 01, 2018, 08:53:28 am »
Quote
The ST CUBE generates the initial/boot code, adds the CMSYS code and then adds the peripheral driver code for the STM32 specific microcontroller that you have.

You are completely free to ignore all of this IF YOU WANT TO. You will have to read the programmers reference manual and figure out how the peripheral works and what the register do yourself.

As a professional embedded developer, I do not have time to do this.

One hopes that "professionals" only have to struggle through the complex initialization stuff once, after which they 1) understand it a lot better, so it isn't so complex, and 2) have reusable code that can easily be adapted to later projects.
It's a pretty ambiguous situation.  The same engineers that will swear up and down that you should do your own clock initialization and uart code from scratch will equally vehemently swear  that you should never write your own network stack or floating point math libraries...
 

Offline luiHS

  • Frequent Contributor
  • **
  • Posts: 602
  • Country: es
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #16 on: July 01, 2018, 09:05:39 am »
I'm not an "user". I'm a programmer, and I have no issues whatsoever "having to spend time writing the necessary source code". It's exactly what I do, and need to do. Having 1-2% of it autogenerated by a tool I need to learn first, and which has a lifespan of a maybe three years, and requires a book to be understood - sorry, nope.

After autogenerating that pile of code, what next? You still can't program, are even more afraid of writing "the necessary source code". How are you going to do your "own things"? How are you going to debug the thing?

I have noticed one interesting thing as well: the peripherals are not just "init to something and forget". No, usually I need to do something specific, and in order to do that, I need to understand the peripherals, and how to control them to do what I want.

If they spent even 5% of the time and resources they now spend in making tools into making the existing documentation easier to read (just by hiring someone to proofread it would be a good start!), that would be an optimal solution. I find about 50% of the time working with peripherals is simply lost by deciphering cryptic documentation, which could be fixed by using a single good technical writer. Additional effort could go into streamlining the peripheral design so that they would be easier to configure.

Fixing the problem of hard-to-use-peripherals by building code generation tools is simply totally wrong place to do it.

This being said, I don't feel like the peripherals are hard to use. They are quite OK; no code generation helpers needed. But I admit they could be much better still.


Then you should start with the assembler language and books on ARM Cortex, to understand in detail how everything works.

Is it really worth it to waste so much time studying these things in detail? That depends on each one, for me clearly NO.

That's why there are tools like Cubemx, and all the manufacturers of microcontrollers offer that type of assistants, so that the "programmer" can dedicate himself to what is really important, without losing so much time.

I am an engineer, I design hardware and program software, I am a programmer, user, human and inhabitant of the earth and the solar system. That does not change anything, so try to optimize my time in the development and future maintenance of a product, otherwise, I would be reading books on how to program a microcontroller in asssembler language, to understand in detail how a microcontroller is made (something that I also know).
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8714
  • Country: fi
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #17 on: July 01, 2018, 09:07:52 am »
Let's see... Clock initialization on the most complex, top-of-the-line STM32F7 device, in the most complex case (Vreg overdrive config for maximum frequency): 10 lines of code. Took about 10 minutes to write with the refman. Worked on the first try. Never did the same before. It's not that complex.

It's not about writing super complex code once, then copypasting it to the next project. That's almost as bad as autogenerating it, hence I understand people's need of automating the process of writing excessive amount of poor code, since it totally sucks to do it manually!

But the right thing to do is: don't write excessive amount of poor code manually, or automatically.

If your init code is super complex, the chances are, you are doing something wrong (such as use the STM32 peripheral library structs and functions, which easily bloat a 200-line init into 2000 lines).

This is not rocket science: the same principles that apply to the programming in general, apply to peripheral control as well. Write readable, maintainable code, divide it to functions, suspect and rethink long and unclear constructs, question everything that looks complex or generates a lot of lines you don't understand.

Now, code autogeneration just makes this worse. Now you are accepting the fact you have a lot of code you don't understand, can't write or maintain, code that you just place there once and forget. You are just automating the horrible task of generating it. The actual problem is that you didn't need to build that mess to begin with.

Doing bad things suck. So don't automate doing bad things. Simply don't do bad things. Automate doing bad things only when it's really inevitable. Then you need to be questioned, and you need to be ready to prove why you did it that way. "That's how it's done" is a fairly weak argument.

It's sometimes inevitable - for example, when creating long mathematical lookup tables - but for the actual code, no way!

And yes, initializing peripherals is just normal code, and part of normal programming. It interacts with everything else. It's not a separate thing from your "user code".

If you have an issue with that, you are doing completely wrong things. I recommend one of the following:

1) Use an OS, and write software in userland, preferably in higher-level language
2) Don't program at all., or...
3) Keep doing what you are doing, but get off the high horse. What you are doing is not "the correct way", nor the "easy way". It's the "short-run lazy way", as well as the "trendy" way. You are going to get more likes than me on this if we vote; but I have never done these things for popularity.
« Last Edit: July 01, 2018, 09:50:15 am by Siwastaja »
 
The following users thanked this post: nugglix

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8714
  • Country: fi
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #18 on: July 01, 2018, 09:26:01 am »
Then you should start with the assembler language and books on ARM Cortex, to understand in detail how everything works.

No, you don't. Even though learning the core and assembler is a useful skill, you don't need to understand everything in detail.  I don't suggest starting from there if you already have a project you need to get started with. gcc-arm is easy and works well. Start looking at the assembler when you first time need it.

By all means optimize your time usage by leaving "waste" and "manual work" out. I do exactly that, and I have been able to create such complex systems in such little time that this clearly works out for me. And I'm sure it works for many others, as well. Maybe not you, but we need to share the information of different ways of doing things, to enable different people to find the way suiting them best.

We are also responsible on how we teach others, and we are responsible for this planet. Wasted resources and wasted skills due to super-short-term greediness is a real pity. Software bloat and security is a serious concern.

I have not wasted any time in learning STM32 peripherals. I did have a steep learning curve in STM32, wasting time in not getting things work right first, but that was 100% due to broken toolsets. Cube didn't exist. Something else was trending (with the same arguments, "this is so easy, why waste time learning things when you can use this?"), and now it is discontinued. Documentation about practical tools didn't exist. Good examples didn't exist - they are still scarce. I used a broken linker script I found online, which plagued me for almost a year with subtle issues. I sidestepped these issues the wrong way, because I was feared about the details, so instead I worked around the issue of not understanding enough.

The problems are almost always in tools, libraries and documentation. By adding more tools on the top of bad tools is not going to be sustainable. Similarly, working around bad documentation with autogeneration tools is not sustainable.

The key is, understand enough of everything so that you survive, don't waste time going too much into details, but go enough into details so that you survive. Without needing to come up with bad excuses for generating total unreadable crap code. Question everything - if a trend library works like shit or generates code you don't like, it probably is shit. OTOH, some non-trendy libraries can be very good. Use good libraries; such that help you instead of slowing you down. But you need to have a point of comparison. If all you do is use code written by others, you never know, and you may have the false notion that everything is so complex because you don't understand it, because you haven't tried.

Sometimes you need to just spend an extra week or month in learning some basic thing, and that will pay itself back later. You need to be able to identify which skills are like that, and which are wasted time. This is the hardest part. For me, it's clear that learning to use CubeMX is wasted time. I am 100% sure it's discontinued fairly soon, this happens with everyone, especially with ST. I also don't want to have a vendor lock-in in STM32 parts. I need the skills to read through reference manuals, which stays the only universal format, and use the common tools for compiling. ARM is a great thing since you only need one set of tools!

CubeMX - I'm just not interested! Feel free to use it, but don't tell me I "should" use it.

Now, I don't have any issues just picking up an MCU, reading through the documentation and building whatever I want, and do that quickly. The skill of reading through documentation and writing my own code with brain switched on isn't a magical gift - it's because of I wanted to learn, and invested my time in it. It has already paid back very well, and I'm still just 33.

For me, learning how to use a tool that is in the backend of every freaking IDE out there, and that has existed for 30 years, is such a skill. For you, it might be learning to use the trend wrapper tool of the year, which may seem quicker at first, but it probably isn't even in the short run (they have a lot of details, too, and learning them is totally wasted time!), let alone in the long run.

But I think we need to just disagree here. I think you need to understand the code you write and run, each and every line. I don't see this as a "wasteful detail". If you don't understand it, the chances are, you are copypasting and autogenerating much more code than necessary, increasing the "surface area" of the code so much that now you are having wasteful details there all the time.
Minimalizing, OTOH, exactly reduces the level of detail.
« Last Edit: July 01, 2018, 09:56:51 am by Siwastaja »
 
The following users thanked this post: nugglix, Joeri_VH

Offline Doctorandus_P

  • Super Contributor
  • ***
  • Posts: 3800
  • Country: nl
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #19 on: July 01, 2018, 02:28:50 pm »
I am interested in this thread becuase I am in very much the same boat as OP.
Started dabbling with STM32 a few years ago, but haven't done a real project yet.
My interest in STM32 mainly comes from the use of this processor family in a lot of Chinese products and its price/performance ratio.

In total I bought from Ali:
- 3x Maple Mini.
- 10x "Blue Pill"
- 20x STM32F103C8T6 loose chips.
- 1x FX2N Mitsubishi PLC clone. (Decent power supply, common mode filter, smps, hardened I/O)
- 4x DPS5005 ( Alternative software "opendps")
- 1x DP30V5A-L (USD 11 programmable power supply).
- 1x DSO138 ("oscilloscope" development board with TFT LCD).
- 1x DSO150 ("oscilloscope" development board with TFT LCD).
- 3x ST-Link V2 (I have some spares :).

I have been endlessly wanderig about where and how to start, which is complicated a bit extra because I use linux exclusively and a lot of stuff is windows oriented.
One of the first really usefull things I found was the tutorial from Pandafruits.
It is a very short ( 20 minutes to read, afternoon to understand) introduction in linker scripts and startup code targeted to STM32. It also helps with makefiles, programming, and a short intro to debugging. If you want to know these low level basics, it is an excellent read:
http://pandafruits.com/stm32_primer/stm32_primer_hardware.php

Then I installed an enoumous amount of ST stuff, among which the SPL. I was sort of disgusted by the bloatware. For changing a single bit in some register, you have to:
1). Declare some structure (of which the name you don't know).
2). Modify that sturcture.
3). Give that structure to some initialisation function (of which you also don't know the name).

After getting a blinking led project going I wanted to look a bit into what the startup code does. With a decent IDE (I use Qt Creator) it is of course easy to follow program execution / function calls through multiple files. Then I found stuff that after 3 function calls deep it did nothing. It went to a line of comment where you might someday want to enter some code ??? Yuch.

But at least that stuff from ST has linker scripts for gcc-none-eabi, but they do not use that name, but hide them in templates for IDE's that use the GCC compiler. Sigh.
Talking about linker scripts: I believe STM32 has no separate built-in "EEPROM", but instead you can reserve a piece of FLASH in a linker script to emulate "EEPROM". Is this correct? What is the endurance of the FLASH? Every little bit of info costs me hours and hours to find, untill I loose concentration and get stuck.

I've dabbled a bit with Platformio. Platformio is really handy for installing a recent compiler, and initializing projects (MBED, Arduino, SPL, and more) and at least getting something to compile.
PlatformIO uses "SCONS" as a build environment. It seems to work and is not too complicated, and it works together with Qt Creator, which I already used for AVR projects (not arduino).
PlatformIO is a plus. As a "safety" you could analyze the command lines it spits out and cobble together a simple makefile which does the same. Learning from (working) examples works better with me than learning from an overwhelming amount of spread out documentation.

In PlatfomIO I build a little project. Just read the ADC, scale it a bit and output PWM to a RC servo.
This "worked" in a few minutes. The servo sort of followed the potentiometer. However, every time the duty cycle is written to the timer it generates a glitch on the PWM output pin. So I had a look through the mbed platform. The code of which was neatly pulled from Internet by Platformio. First thing I noticed is that the mbed code was build on top of another lib (I think STL). So then you have the situation that in order to debug your own 3 line program ( read adc, output pwm, repeat) you are confronted with 2 apparently buggy frameworks on top of each other.
Not my cup of tea, so I abandoned that pretty fast.
A nice thing of MBED is the overview of development boards on their site. 100+ different boards from a handfull of manufacturers. If you're not fully committed to STM32 yet, then try to form an opinion on the quality of the development tools for those boards. STM32 is "not the best" in development tools.

Arduino...
I also did a blinking led with STM32duino (Fork of the Maple Mini) for the "blue pill" board.
I'm a bit confused why this fork exists. The "blue pill" and the "maple mini" are both readily available from Ali / Ebay, and the price for both is in a range that it does not matter. The Maple may be 20ct less cheap, but you get twice the memory for that. I think that RogerClarckeMelbourne made the fork for the "blue pill" boards before he realized that the Maple Mini was also available for very similar pricing.
Arduino does a lot horribly wrong (such as the java contaption which they call "IDE", and the redicilous connector pinout and the lack of a SMPS on their boards)
On the software side it seems to be a mixed bag. The "digitalWrite()" is attrocious and I very much dislike the random mix of C and C++ (which they give some other name to).
Another thing I dislike very much about the "arduino" stuff is all the pre-instantiated objects. First time I wanted to use "arduino" I wanted to use my self written RS485 library for the uart, but the USART was "occupied" by some pre-instantiated object hidden in the library code somewhere.
But "arduino" also seems to do some things right. It has a somwhat consistent API to get things done.
I might be tempted to pull parts out of the arduino framework, modify it to only instantiate the objects I need for a project and take it from there. Doing this might make it easier to take some leverage from the thousands of little libraries that can be installed with PlatformIO. On the other hand, I think it is also build upon a very old version of the SPL and I 'm not sure I want to put time in that.

I also played a bit with stmCUBE. It "works" under Linux (surprisingly) and it seems to be a nice way to do the initial project setup with hardly any learning curve. PLL settings and the whole clock distribution can be set up and experimented with, with just a few mouse clicks in a gui.
stmCUBE also seems to help a lot in assigning pins to peripherals. Almost all peripherals can be routed to 2 (or 3?) different locations on the chip and there are lot of opportunities for pin conflicts. StmCube keeps track of those and you can point and click in gui to find a working combination.
Just knowing which pins to use for which peripheral is a plus. It also copies template code into a new project, and adds your custom I/O configuration, and it also generates a fairly readable makefile. After the project is set up it is not dependent anymore on stmCUBE. I think stmCUBE is a plus for beginners to ease the learning curve a bit, even though the generated code is not of the highest quality. At least having some code with the right register names and bits in your created template gets you familiar with those names.

LL
I think LL has existed for some time but is being "revived" by ST because the rest sucks so much.
I have not tried it yet, but if you have written code for any uC before and are familiar with directly working with registers for initializing peripherals then you probably also dislike the bloatware of the frameworks stacked on top of each other, and you just want a header file with register and bit names to address registers, and then get on with it to write your own application.

Templates:
I've seen a few projects for intialisation of I/O registers which are template based. C++ templates are very powerful and have very little run time overhead. Downside is that they are a bitch to write and debug. If these were more widely accepted I might be very tempted to use them, but I already have my hands and head more than full with all the other stuff I'm overwhelmed with.
If you are interested in this then search for "Kvasir" " XPCC" "bmtk"
The small Davy Jones has also written his own template lib, and compares it with the ST stuff in:


Compatibility:
I have a bunch of self written libraries for hardware to control with my AVR's (doing that for 20 years). I would like to have some compatibility layer to be able to use these libraries also for STM32 but the differences seem to be too big to make this worthwile.
I also had some peeks at datasheets of processors of the same class as the STM32. (ATSAM3, Freescale, LPC). They may use the same processor core and instruction set, but peripherals are implemented in completely different ways. Timers and USARTs have different bits in different registers and different functionalities. The only road for a "common framework" for such processors would be ... just as worse as arduino or mbed I'm afraid.

I think I agree with posts in this thread before me.
Learning to wade through documentation efficiently is a valuable skill to learn.
Writing C / C++ in a "clean" way also a valuable skill to learn.
If I take the USART as an example, then the code for basic USART operations is probably 50 to 100 lines of code. If these are wrapped in readable / logical functions then your code will be relatively easy to maintain (and possibly port) to other micro controllors without touching the bulk of your application code.
 
The following users thanked this post: asmfan

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8714
  • Country: fi
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #20 on: July 01, 2018, 03:38:39 pm »
Then I installed an enoumous amount of ST stuff, among which the SPL. I was sort of disgusted by the bloatware. For changing a single bit in some register, you have to:
1). Declare some structure (of which the name you don't know).
2). Modify that sturcture.
3). Give that structure to some initialisation function (of which you also don't know the name).

As we heard earlier, these libraries are now "discontinued". Good riddance. No one could even theoretically write code with these - they were always copypasted or autogenerated. And they were horribly bloat, most of the functions weren't even inlined. Most examples on the web are polluted by this coding style, which makes googling for advice harder.

Quote
Talking about linker scripts: I believe STM32 has no separate built-in "EEPROM", but instead you can reserve a piece of FLASH in a linker script to emulate "EEPROM". Is this correct? What is the endurance of the FLASH?

Indeed, no EEPROM. Linker script can be used to define the addresses in an easy manner, and reading the flash works out-of-box like reading any other memory addresses, but writing requires actual code, no compiler can generate it for you. For an example with a full reflash-the-chip-on-the-fly + EEPROM-like variable storage system, see for example this: https://github.com/siwastaja/pulutof1-fw/blob/master/flash.c

Endurance is in the range of about 10000 cycles or so. It is problematic if you need to rewrite frequently. In this case, you should implement some kind of wear leveling. Libraries exist for this, but haven't tried them.

Quote
through the mbed platform. The code of which was neatly pulled from Internet by Platformio. First thing I noticed is that the mbed code was build on top of another lib (I think STL). So then you have the situation that in order to debug your own 3 line program ( read adc, output pwm, repeat) you are confronted with 2 apparently buggy frameworks on top of each other.
Not my cup of tea, so I abandoned that pretty fast.

Yeah, nope. This kind of development style is unmaintainable. Aim for a small number of short, simple files, all under your control. Most MCU projects are simple enough that they are a few thousands of lines with no library or "framework" dependencies expect the standard libraries.

Quote
Arduino...
... is unusable for serious, large projects, but it's never even meant for that. It's at least useful to get that simple LED blinker work quickly, and connect designed-for-arduino modules, which are already complete finished SW/HW designs, together.

Quote
Compatibility:
I have a bunch of self written libraries for hardware to control with my AVR's (doing that for 20 years). I would like to have some compatibility layer to be able to use these libraries also for STM32 but the differences seem to be too big to make this worthwile.

The STM32 peripherals are quite often incompatible between device families or even devices. That's sad. Luckily, they are often quite similar, so often it's just doing some tiny little detail in a different way.

Compatibility layer is likely quite difficult to do.

The reason is, we tend to use these powerful MCUs in a way where everything mixes together: DMA's, peripherals and IRQs form a nice little application-specific mess which is usually impossible to generalize as a library.

The best course of action, hence, is to try to keep the coding style as simple and minimalistic as possible, and add generalization through minimalistic helpers that hide the most ugly things and most of all, makes writing code faster, reducing number of lines.

Quote
I also had some peeks at datasheets of processors of the same class as the STM32. (ATSAM3, Freescale, LPC). They may use the same processor core and instruction set, but peripherals are implemented in completely different ways. Timers and USARTs have different bits in different registers and different functionalities. The only road for a "common framework" for such processors would be ... just as worse as arduino or mbed I'm afraid.

Yeah... OTOH, after you have have used 5 different STM32 MCUs, and every one of them had a different UART, it's no more difficult to go to Freescale or LPC :P.

They are almost the same. Write the baudrate register, some RXEN and TXEN, DMA and IRQ enable flags...

Quote
If I take the USART as an example, then the code for basic USART operations is probably 50 to 100 lines of code.

Possibly much less, even.

Init is about 5 lines and if you send and receive text, it's a few lines more. DMA is about 10-15 lines extra.
« Last Edit: July 01, 2018, 03:45:17 pm by Siwastaja »
 

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 895
  • Country: us
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #21 on: July 01, 2018, 07:55:07 pm »
@Siwastaja

I see you also use your own C code in the reset handler to initialize memory (looking at stm32init.c).  :-+

Me too. It surprises me that most Cortex-M firmware projects (every OEM example I've seen) still resort to assembly code for the vector table and the stuff that runs before main. Do people think that the compiler can't optimize a simple loop?  |O

One of the goals of the Cortex-M design was to be able to use straight C code for interrupt handlers. And if you allow for compiler-specific attributes for weak symbols, it's easy to do the vector table itself as a C struct or array. A side effect is that then you don't have to remember the difference between .s and .S  ::)
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4288
  • Country: us
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #22 on: July 01, 2018, 11:27:39 pm »
Quote
It surprises me that most Cortex-M firmware projects (every OEM example I've seen) still resort to assembly code for the vector table and the stuff that runs before main.
OTOH, it's not very complex assembly code, and while it's "clever" that asm isn't needed, it's not clear to me that it's really that much of an advantage, either.
Atmel ARMs have C code for startup and vector code.
OTOH, their concept of "easy clock initialization" in ASF is a joke, IMO.  And results in over 1k of code aimed at clock-related things.

 

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 895
  • Country: us
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #23 on: July 02, 2018, 01:14:32 am »
Quote
It surprises me that most Cortex-M firmware projects (every OEM example I've seen) still resort to assembly code for the vector table and the stuff that runs before main.
OTOH, it's not very complex assembly code, and while it's "clever" that asm isn't needed, it's not clear to me that it's really that much of an advantage, either.
Atmel ARMs have C code for startup and vector code.
OTOH, their concept of "easy clock initialization" in ASF is a joke, IMO.  And results in over 1k of code aimed at clock-related things.
Well, most firmware engineers are used to looking at C code. Maybe some are fine with assembly, but I think most look at it as some kind of black magic. Like when you're trying to figure out what the actual name of some interrupt vector is. You can grep *.h and *.c all you want, but if it's in an assembly file, you might not see it.

What's goofy is when those same projects use arcane inline assembly with a .c file for the really tricky stuff like moving values to/from special registers (while using assembly source files for "boring" things like initialization).
 

Offline xaxaxa

  • Regular Contributor
  • *
  • Posts: 248
  • Country: ca
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #24 on: July 02, 2018, 04:26:25 am »
I have always used libopencm3 which is a thin wrapper around the hardware registers and can definitely recommend it. It doesn't try to be a "framework" but rather a helper library so that you can e.g. call a function to start an adc conversion (which is usually more readable) instead of setting a bit in a strangely-named register.
 
The following users thanked this post: nugglix

Offline Gibson486

  • Frequent Contributor
  • **
  • Posts: 324
  • Country: us
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #25 on: July 02, 2018, 01:16:18 pm »
My advice would be just to get something working. The SPL is no longer supported and it looks like cube is here to stay. You will see a bunch of people who says learn SPL because it is better...well, they need to to learn to get with the times. Part of being an engineer is learning new tools, whether you like them or not.

I understand that there is a sense of pride in getting stuff working from the ground up, but you will find that once your start with the HAL, there will be something you do not like and you will have to change it anyways. Yeah, there is some crappy code in the HAL, but I work with a bunch firmware people who have the mentality of hating the HAL and well, debugging there code is no better than debugging the HAL.

As for being too upper level? Not really. So instead of pushing bits directly to registers, now you have a function (that is well used by other places) that now pushes bits into registers. I can see why people do not like the I2C library (yeah, that one sucks), but everything else is not bad at all.
« Last Edit: July 02, 2018, 01:17:53 pm by Gibson486 »
 

Offline Dubbie

  • Supporter
  • ****
  • Posts: 1115
  • Country: nz
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #26 on: July 02, 2018, 08:59:38 pm »
Thanks for your thoughts Gibson486.

Sometimes I think that I must be the only person in the world who doesn't have a big problem with the cube HAL.
It's nice to hear that I'm not crazy. (well for that reason anyway)
 

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 895
  • Country: us
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #27 on: July 02, 2018, 10:53:53 pm »
Sometimes I think that I must be the only person in the world who doesn't have a big problem with the cube HAL.
You and the guy who wrote it.

 :-DD


PS. sorry  :-X
 
The following users thanked this post: Dubbie

Offline apblog

  • Regular Contributor
  • *
  • Posts: 108
  • Country: us
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #28 on: July 03, 2018, 02:14:41 am »
I love CubeMX.  I use it to plan pinouts and to generate clock tree and system setup code.

Then I see what it did, copy the register setups to my code, and throw out the cube code. Best of both worlds.

Of course I read the bits and make the effort to understand what is being done.  But starting with generated code as an example is a lot easier and faster than trying to understand every nuance of features that
I do and don’t need before I can start writing code
 

Offline Doctorandus_P

  • Super Contributor
  • ***
  • Posts: 3800
  • Country: nl
Re: Getting Started with STM32 (ARM CORTEX)
« Reply #29 on: July 03, 2018, 07:59:02 pm »
Just curious, what do you think about CMSIS?
I sort of like the idea of a vendor independent framework. There seems to be some support from ARM, TI, ST, NXP, Keil, Atmel/Microchip and others. But somehow I get the idea that a lot of stuff is old and/or deprecated.

For the moment I think I'll start with MBED.
Platformio supports the MBED platform for the "Blue Pill" board and there seem to be lots of libraries for external chips, for example TFT controllers.
[ Rant]
I've always disliked the "arduino" stuff. The java contraption they use an "IDE" is easy to avoid with platformio, and the horrible pinout also if you buy something that fits on a breadboard. What is still annoying is the "digitalWrite()" which is sprinkled everywhere ( 45% speed penalty for already slow TFT library (Adafruit / AVR)) and the mixed bag with C and C++ and all kinds of pre intstantiated objects for hardware I want to use differently.
[ /Rant]

In mbed you have to declare objects yourself, so you only declare the objects you need, and this also makes it easy to plug in a homebrew alternative class if needed.
This example looks pretty clean:
Code: [Select]
#include "mbed.h"

Serial pc(USBTX, USBRX); // tx, rx

int main() {
    pc.printf("Hello World!\n\r");
    while(1) {
        pc.putc(pc.getc() + 1); // echo input back to terminal
    }
}

Most important is probably to "just start somewhere", as said before in this post. With platformio & mbed I can postpone having to dive into the low level stuff and get some fun projects going and gradually build knowledge of the peripherals I find interesting.
I by no means see mbed as the platform I want to use for the next 10 years, but just a starting point to ease the learning curve a bit and that is something I need badly because I've been skidding down that curve for more then a year.

Just a thought:
Another way to start / pick a framework is to find a project you are intersted in on github / gitlab / elsewhere and that compiles cleanly. (inclusive project / makefile / schematic etc), and then adopt whatever is used in that project and build from there.


 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf