About STM32 HAL quality and performance [closed] - arm

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
I'm about to start a new project on a classical STM32L4 based product.
I have a good experience in ARM developpement but not in STM32 specifically.
I am wondering what is the quality and performance of the STM32 HAL and low level drivers provided by STmicro (in the package STM32Cube).
I'd like to gather developpers experience and feedback on the topic.
Basically I'd like to know if you are happy with this code or on the contrary if you encounter some issues, if some of you developped their own drivers for some reasons, etc...
Thank you !

I do not like HAL for many reasons:
It gives pseudo developers false feeling that they do not have to know how their hardware works.
Time spent learning HAL may be longer (and usually is) than needed to understand how the hardware works.
Horrible overhead
Many errors.
But on the other hand I use HAL (actually deeply modified by me) to control two peripherals USB & Ethernet as writing could take too much time. But as I wrote before I know how does it work on the hardware/low level and modified it for my liking.

After the transition from smaller 8-bit microcontrollers to ARM, I've started to use the HAL library on STM32 right away and had a more or less satisfying experience. But it comes with an overhead like already stated and a quite large set of poorly documented functionality. That can lead to some confusion.
However, the big advantage of using the HAL over hand-written-code-from-scratch was the level of abstraction it provides. That came in handy when I needed switch from one type of STM32 to another; and also when I needed to get things up and running quickly. - I've used quite similar code on a couple of very different types / families of STM32 micros (L0, L1, F1, F4, F7); it actually worked most of the time. Using the HAL library made the transition much less painful, than when you need to know the exact memory map and register layout of the specific micro...
With that said, I need to admit that I'm still a newbie when it comes to modern embedded software and I'm still learning, after about 2 years of prototyping work on different STM32 based projects (hobby and professional). I still need to learn more about the provided LL code, for example.
Entering the embedded field with a different software background, using HAL level code instead of twiddeling single bits of different registers in the right sequence, and taking all the different restrictions into account to get for example basic UART / SPI / I2C communication working, eased things up quite a bit for me. IMHO, the STM32 HAL lies in a middleground between pure hand written code and what mbed does for example (C++ / vender-agnostic abstraction (as far as I know)). - It tames the complex beast to an acceptable level, so that an average software developer like me can handle it. That comes with some trade-offs, like already mentioned by others...
After all, the STM32 HAL also kind of serves as a boiler plate code repository, that can sometimes be easier to read/understand than the cryptic reference manual in some cases. - Using HAL code generated by STM32CubeMX always gave me a much smoother start at bring-up time, when I needed quickly test a new board. It can also help to experiment and test things out. And when a performance critical part needs to be hand-optimized later on, then that will still be possible after setting up a project, or even incrementally adjusting it with STM32CubeMX. You can mix handwritten code with HAL code.
Some problems recognized since 2016:
Some constants, structs and function signatures changed when new code updates were released by ST. Things seem to be in constant development.
Lack of good documentation (comments in code files) and clean example code (too specific, also not well documented).
Convoluted, sometimes inefficient code.
Spelling errors.

I personally do not like HAL library for following reasons.
It takes up much memory in my controller, I really do not have space where i would fit in Bootloader and Application and here i need to add 2 HAL overheads as well ( one in Bootloader and another in Application).
It internally uses interrupts ( i am pretty sure it does)
It is not bug free , i once tried version 1.0 and failed horribly.
Debugging is pain , You never know where the bug is, in your application or in HAL.
What I liked by ST was Standard Peripheral Library, it was just assembly to C converter and very easy to use.

I love the HAL and Cube, but you have to read the drivers and be prepared to suffer.
I used to wiggle bits like the naysayers, you can pick your poison.
In my situation, if I use the HAL, I can sucker a real programmer into maintaining my code. Say no more, I'm in on the HAL. Be forewarned, the Cube simply creates an approximation of something that works.

Related

Question to any embedded systems engineers out there using STM32 NUCLEO

I have recently bought an STM32 NUCLEO Dev Kit and wondered if this what an actual Embedded Systems Engineer would use in the industry when developing a product?
I'm using Kiel Uvision 5, STMCubeMX and STM32 ST-LINK Utility to develop certain projects. As I am used to using PIC and using registers like PORTA, OSCCON, TIMER0 etc, I see that Kiel Uvision 5 uses ready made functions like HAL_GPIO_TogglePin(.........) etc. Is this the usual way they do this in industry or work more directly with the registers?
It's heavily opinion based and I wouldn't get surprised if this question got closed for this reason. This answer only touches on few aspects of what you're asking about. It's a very broad topic and it's going to be hard - if not impossible - to include everything in one post which wouldn't end up being several pages long. However to give you my perspective on the topic, while trying to remain unbiased, the short answer is.. it depends.
If you're asking about what is used in most common cases, it's likely going to be the HAL (previously StdPeriph) functions you've mentioned. The reason is - they get the job done in most common cases. After all it always comes down to what the cost of creating a product is going to be. If HAL functions are "good enough" for the purpose, they're going to be used simply because they're faster to develop with. The higher the development cost, the more you'll want to cut it (or move it elsewhere) and using abstractions is one way of doing so.
However, even though I think it's safe to assume that HAL / Std Periph / any other (including proprietary) abstraction layer is generally used, it's not always the case for at least two reasons I can think of:
Existing functions may not be suitable for your purpose. Giving HAL as an example, it works pretty well for most common cases, but sometimes your needs may be so specific that you'll have to go and mess "under the hood", often ending up either writing your own variation of the functions of building something new on top of HAL. Personally I can think of at least few examples where HAL functions weren't exactly what I needed. It doesn't necessarily mean that the library is bad, it's just sometimes the requirements are very specific.
Messing with registers directly may sometimes be required for performance reasons. HAL and similar are an abstraction layer and as any abstraction, they take more time to execute than using the registers directly. If you're trying to squeeze absolute maximum out of given peripheral, you'll sometimes have to go down to register level.
Now to a more biased portion of my answer.. I can see why you ask this question. Coming from PIC world where Flash or CPU clocks were more precious, it does make sense to use registers directly there. In case of STM32, it's not as critical anymore. Having said that, you'll sometimes stumble upon opinions that "using registers is the only true way", but personally I find such discussions ending up being purely academic. I see registers or any abstraction built on top of it as tools and you should use the right tools for the right job. Two examples of NOT using the right tools:
You use only registers as "the only right way" either because you believe it yourself or you've been told so. Your products take twice (if not more) time to develop, your code takes less space in flash (so now you use 46% of 1MB flash instead of 48%). Code that is performance-critical meets its goals. Code that has relaxed execution time constraints is also super efficient, but it doesn't affect the end customer much, if at all. Your code is also less reusable - you find yourself rewriting same portions of code over and over every time you release new product for a new MCU family.
You only use HAL / any other similar abstraction because "you didn't pick so powerful MCU to have to go down to register level", or because you're told you should never ever touch registers. You develop much faster and you're able to release two products instead of just one using registers. However when there are execution time constraints / transmission speeds you have to hit, you find yourself picking MCUs more powerful than should theoretically be needed. Sometimes you find yourself writing wrappers around HAL because they don't give you exactly the functionality you need - it feels like making it more complicated than it should be.
So after all, if there was anything to take out of what I'm trying to say is that you should use what is suitable for the job on a case-by-case basis. In case of STM32, you nowadays have 3 options: HAL (top abstraction level), HAL LL (Low Level abstraction - often simple wrapper functions around register acceses) or using registers directly. Which one you choose should come from what your requirements are.
I use Nucleo boards all the time. It allows me to start write software before I have the actual hardware ready.
HAL & register way is rather the programmer choice than the "industry standard". I personally use HAL drivers when program more complicated peripherals like USB and Ethernet to avoid wiring the full stacks from the scratch.
I have just finished my degree and we heavily used the STM32 platform with CMSIS and HAL.
It is a matter of preference. The HAL libraries offer higher abstraction but come with some quirks that are not very intuitive. The HAL (was/)is buggy sometimes. We have encountered SPI transfer bugs which made the higher transfer rates of SPI unusable because of a delay in the per byte transfer.
CMSIS offers lower level access but still abstracts away from simple bit manipulation. I don't think that direct register access is a great way to program anymore and at least CMSIS should be used. But it still a matter of opinion, preference and what is right for the job at hand. If you need something quick: HAL. If you need really fine control: CMSIS.
(sidenote I believe that CMSIS has been phased out in favor of HAL but it is still usable at this time)
All of the other answers are valid.
Just wanted to chime in and say I used STM32 regularly at my job (and at two different companies). We used the HAL drivers at both companies. There are obviously some issues with them, but used regularly enough by others that you can easily find support online. Additionally CubeMx does a decent job with them, at least enough to get you started on using the peripherals. So the 0->something step feel smaller. But getting really optimized code and design, you may want to dive deeper to really understand what each of the HAL drivers are doing and decide which method works for your project, goals, and requirements.

Which ARM Cortex M product line to use?

I am trying to select a particular companies line of ARM Cortex M microprocessors to work with for a project I want to do. Since all the companies license the architecture from ARM Holdings I am wondering how much difference there can be in the hardware between brands? I am thinking the documentation and software productivity and overall experience may be the deciding factor?
I have tried one company and their documentation was lacking! Thousands of pages of fluff about what wonderful stuff they make but very little info on how to use the things.
Mostly I am looking for good documentation. I don't need endless obsolete sample programs that don't compile and use mystery macros and functions! A line that includes a microprocessor with 2 ADC not just multiplexing channels to 1 ADC would be good but I may end up using external ADC.
Would anybody care to say what they recommend and why.
BTW: My history is programming C++, C# in MS Visual Studio for machine tool HMI as well as motion controllers.
Thanks In Advance
Chris
Most of your application has nothing to do with ARM and the cortex-m. Each chip vendor adds its own peripherals (or sometimes purchased) around the arm core. Most of your code is talking to peripherals. The processor core doesnt make the chip, the things other than the processor core make the chip.
You need to go do your research, stackoverflow is not about doing it for you. You should be able to find a list of parts with the number of peripherals you want, independent of processor core used. While a particular chip vendor may have different uarts across their product line or different gpios, adcs, etc, you can still get a feel for a vendor without having to look at every part on that list as you narrow in.
No vendor has great docs, some do have bad docs, that is part of the exercise. All of them provide libraries, same deal nobody has great libraries, some have bad ones, but the point of the libraries is to hide the details. You need to do your homework and look at the docs, look at that code, can you live with it can you replace it or repair it, or is it better to move on to another vendor or same vendor and an alternate library.
1% of the job is writing the application the other 99% is reading docs and doing experiments to make the peripherals do what you want them to do.
Same brand or different brands with the same name of processor core doesnt mean anything with respect to portability. If you read the arm docs as you should read any of the processor core docs for whatever parts you are evaluating or choosing, you will see that even if 7 vendors have products with the cortex-m0, that core has compile time and runtime options that each vendor could choose from making either the code or the performance incompatible with other chips using a cortex-m0. But the amount of code that would port anyway is a very very small percentage of your project. Most of your project is the not-processor-core stuff.
Note ARM makes a number of cortex-m cores that are not 100% compatible with each other. If you feel the need to go with an ARM core, then narrow in on the one you want, that will narrow your choices as far as available chips goes.
Built in ADCs are there to save on chips, depending on the specs you want, accuracy or performance, you may very well end up with an external ADC which makes the specific microcontroller less important if the ADC and its specs are your primary requirement.
Software productivity, also has little to nothing to do with the processor core. The vendors are going to cobble together an IDE with a compiler and libraries because folks expect that, doesnt make any of them any good nor productive. The text editor alone goes the way of religion and politics with developers, there is no single editor or environment that is perfect for every developer, developers have their ways of doing things and some are compatible and some are not. Some developers can bend some cant. Very rarely do you have to use the tools they provide.
It is not possible for us to choose your part for you nor is it possible for us to choose your development environment. That is not the purpose of stackoverflow.
The time it took to write your question and wait for an answer thus far you could have looked at all the major vendors docs several times over. I hope you didnt stop after the first one.

how to code for an arm processor

Hey I'm fairly new to coding, I joined a coding club because I have an interest for the growing world of technology. The topics lately have been about computer architecture and in the group we have been talking about ARM processor.
Our club captain notified us of the following:
"Develop a software product for an ARM processor to do a task of your choice. However, before you start the task, you need to send me a paragraph to let me know what you are trying to solve."
Does anyone know of any reference or code examples I could look up? Or any other helpful links
The question does not make a lot of sense. The Arm architecture spans a wide range from fairly small microcontrollers aimed at low power or fast response tasks, mid range devices which are good for set-top-box, camera or router embedded applications, smartphones, right up to server class products.
There are also variants which are designed for safety critical systems, or high reliability.
Each specific application will require different features, but at the level that you are writing code, you are unlikely to appreciate the factors which would help you to chose a device. Is it something portable, or needing a long battery life, or providing secure communication? If you had a specific device which you needed to use, the application would be more obvious (but still very wide).
I am going to give an answer to a generic question- How to code for an arm processor/any processor-
So, the first step is to understand what ISA is! ISA is a manual(for beginners) which the company releases which acts an information source for those who wish to code for their specific processor.(In architecture world, ISA has lot more implications. What I have given is somewhat an oversimplification). Now, I would recommend that you start looking at the ARM ISA. Go through the instructions that ARM supports, understand all the features in ARM, understand the state of the machine,registers, addressing modes, etc. Get a good understanding of what your version of ARM specifically supports(NEON, Thumb, Vectors(?)).
Once you have a hang of the ISA, the next step is to decide what you want to build since now you are aware what all your processor is capable of doing. You know your limitations as well. So, now will be a good time to come up with an idea.
Now, the next step is setting up your environment. Read the specs of the board which you will be using. Set up the environment. Know the compilers/assembler. Know what flags they support.
Finally, write a simple basic assembly code. Write a code to add two numbers. I usually follow this convention- For Assembly, I write addition of two numbers as my first code. For High Level(C,C++, Java), I write HelloWorld. Execute your code and observe the output. I recommend that for the first code, you step into your debugger and observe the state of the machine after every instruction. (Keep the ISA handy).
Slowly, up your game. Write codes with functions, strings,etc. Finally, get yourself some fun stuff and learn to interface them.(LEDs, LCDs, Sensors, Camera).
Cheers!

Place to get software for embedded components?

I'm wondering if anyone knows of a place on the web that I can purchase or download software modules, written in C or C++, for the interaction between microprocessors and other components, like DACs, ADCs, or UARTs. Sort of like a git-hub for embedded C software. Does this place exist?
You're possibly looking for something called a 'board support package' or BSP. For a given operating system it will have a collection of drivers / libraries to help you communicate with the hardware component.
Saying that, some standard hardware interfaces for e.g. 16550 Uart might have drivers that come with the OS.
You might also want to take a look at Jean Labrosse's "Embedded Systems Building Blocks" book. It has some straight C libraries for dealing with UARTs, Analog I/O, timers, etc.
Of course, you do still need to wire them up to the actual chip's hardware implementation (as other answers have indicated, you can usually get libs to help with that from the chip vendors), but they can be a convenient wrapper to let you more easily move your higher level software from one device to another. There's no earth-shattering stuff that would be particularly difficult to do on your own, but it's there for the taking, so why not? Even if it's not exactly what you might want, it's a leg up.
Normally the device manufacturer will supply you with a libc that you can use for all the low-level stuff.
first, decide which chip manufacturer to go for... next, go to their official site or contact them, you would get the libs for the supported IO's and other communication stuffs.
Ok what about for TI? BSPs are something I'm aware of, but they dont' really exist for software that exists below the O/S level.
2nd, lets say I wanted to wanted software to make the TI MSP430 Microcontroller talk to DAC7565. I realy can't find software that relates those two in any reliable way.
I'm talking about a complete software package, something equivalent to a gem in Ruby, where I could call functions like "OutputVoltage(unsigned int voltage, unsinged int channel)" and be oblivious to the hardware implementation.
#nobugz Yes, I agree, but that is awfully restraining. C should be like Ruby where you can only focus on what you want to do, not having to spend time restricting yourself because of the availability of software...
#Shaihi
I'm not, I am a software engineer with an engineering firm who custom design their own boards. I just can't believe that across the entire world and the entire history of software engineering that I am the first person who needs to interface this microcontroller and this DAC. SO therefore it must exist someplace. Maybe I can't get my hands on it but someone, somewhere has done it before.
I'm a very young engineer, but it just seems like there are hundreds or thousands of guys who end up writing the same software again and again. And on top of that, since there are plenty of software engineers who are terribly good at abstraction and reuse, I'm willing to bet there are plenty of engineers who end up re-writing the same software time and time again because the software they write is way too tightly coupled to that specific application.
Just seems like a giant waste of engineering hours.
Did you check the application notes on the A/D vendor's web site? They very often have C code. The problem with assembly language code is that there are so many different ADC and microprocessor vendors and so many different ways to wire up the chip that they can't provide a general purpose library. Also, a programmer may want to poll the end-of-conversion flag or allow the chip to interrupt when the conversion is complete. It is very application specific. Your best hope is that the vendor has some example code that will serve as a guide for how to use the chip. The good news is that user's manuals for these peripherals are a lot better than they were 20 years ago.
Also, the vendor probably has application engineers who will help you with your design.

Developing a non-x86 Operating system [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 7 years ago.
Improve this question
I have to choose a thesis topic soon and I was considering implementing an operating system for an architecture that is not x86 (I'm leaning towards ARM or AVR). The reason I am avoiding x86 is because I would like to gain some experience with embedded platforms and I (possibly incorrectly) believe that the task may be easier when carried out on a smaller scale. Does anyone have any pointers to websites or resources where there are some examples of this. I have read through most if not all of the OSDev questions on stack overflow, and I am also aware of AvrFreaks and OSDev. Additionally if anyone has had experience in this area and wanted to offer some advice in regards to approach or platform it would be much appreciated.
Thanks
Developing an (RT)OS is not a trivial task. It is very educational though. My advice to you is to start hardware independent. PC is a good starting point as it comes with plenty of I/O possibilities and good debugging. If you create a kind-of-virtual machine application, you can create something with simple platform capabilities (console output, some buttons/indicators are a good start). Also, you can use files for instance, to output timing (schedules) If you start on 'bare metal' you'll have to start from scratch. Debugging on a LED (on/off/blinking) is very hard and time consuming. My second advice is to define your scope early: is it the scheduler, the communication mechanisms or the file systems you're interested at... ? Doing all can easily end up in a life long project.
Samek, Miro, Practical UML Statecharts in C/C++ contains some interesting sections on a microkernel. It's one of my favorite books.
Advanced PIC Microcontroller Projects in C: From USB to RTOS with the PIC 18F Series
seems to cover some of your interests; I haven't read it yet though. Operating Systems: Internals and Design Principles may also bring good insights. It covers all aspects from scheduler to network stack. Good luck!
Seems like you should get a copy of Jean Labrosse's book MicroC/OS.
It looks like he may have just updated it too.
http://micrium.com/page/press_room/news/id:40
http://micrium.com/page/home
This is a well documented book describing the inner workings of an RTOS written in C and ported to many embedded processors. You could also run it on a x86, and then cross compile to another processor.
Contiki might be a good thing to research. It's very small, runs on microcontrollers, and is open source. It has a heavy bias towards networking and communications, but perhaps you can skip those parts and focus on the kernel.
If you choose ARM, pick up a copy of the ARM System Developer's Guide (Sloss, Symes, Wright). Link to Amazon
Chapter 11 discusses the implementation of a simple embedded operating system, with great explanations and sample code.
ARM and AVR are chalk and cheese - you've scoped this very wide!
You could produce a very different and more sophisticated OS for ARM than AVR (unless you are talking about AVR32 perhaps - which is a completely different architecture?).
AVR would be far more constraining to the point that the task may be just to trivial for the scope of your thesis. Even specifying ARM does not narrow it down much; low-end ARM parts have small on-chip memories, no MMU and simple peripherals; higher end parts have an MMU, data/instruction caches, often a GPU, sometimes an FPU, hardware Java bytecode execution, and many other complex peripherals. The term 'ARM' covers ARM7, ARM9, ARM11, Cortex M3, Cortex M8, plus a number of architectures intended for use on ASICs and FPGAs - so you need to narrow it down a bit perhaps?
If you choose ARM, take a look at these resources. Especially the Insider's Guides from Hitex, and the "Building bare-metal ARM with GNU", they will help you get your board 'up' and form starting point for your OS.
Silly as it may sound, I was recently interested in the Arduino platform to learn some hacking tricks with the help of more experienced friends. There was also this thread for a guy interested in writing an OS for it (although not his primary intention).
I think the Arduino is very basic and straightforward as an educational tool for such endeavors. It may worth the try checking it out if it fits the bill.
The first thing I recommend is to narrow your thesis topic considerably. OSs are ubiquitous, well researched and developed. What novel idea do you hope to pursue?
That said, the AvrX is a very small microkernel that I've used professionally on AVR microcontrollers. It is written in assembly. One person started to port it to C, but hasn't finished the port. Either finalizing the port to C and/or making a C port to the AVR32 architecture would be valuable.
An OS shall not be tightly coupled to any processor so ARM or x86 doesn't matter.
It will be a bigger topic, if we start discussing if ARM is embedded and x86 is not. Anyway, there are many many places in which x86 processors are used for embedded software development.
I guess most of the kernel code will be just plain C lanugage. There are many free OS that are already available, like for example, embedded linux, Free version of Itron, minix, etc ... It will be a daunting task.
But on the other hand, what you can try is, port embedded linux to platforms in which it is not yet working. This will be really useful to the world.
An RTOS is almost never architecture specific. Refer to any RTOS architecture available on the net and you will notice that a CPU/Hardware abstraction layer abstracts out the CPU. The board specific portions (that deal with peripherals such as com ports, timers etc.) are abstracted by a board support package.
To begin with, get an understanding of how multi-threading works in a RTOS try implementing a simple context switch code for the CPU of your choice; this will involve code for creating a thread context, saving a context and restoring a saved context. This code will form the basis of your hardware abstraction layer. The initial development can easily be accomplished using a software simulator for the selected CPU.
I agree with the poster who suggested reading the book, uCOS-II by Jean Labrosse. Samples of context switch code, especially for x86, should be just a google search away!
http://www.amazon.com/Operating-Systems-Design-Implementation-3rd/dp/0131429388
Pretty solid stuff.

Resources