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.
Related
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.
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!
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.
Can code written for an Cortex A5 built by one company be ported to a Cortex A9 made by another company without too much difficulty?
I want to write some bare metal C code that runs on Atmel's SAMA5D4 (Cortex A5) that takes video from a CMOS camera with a parallel interface and encodes it to H.264. That chip can hardware encode at 720p.
Later, I may want to build a similar setup that can encode at 1080p, so I would want to upgrade to a more expensive chip, NXP i.MX 6Solo (Cortex A9).
So I want to know if I would encounter major headaches or if it would be rather easy to port later. My gut tells me it should be easy but I thought I'd better ask the experts first. If it's a huge headache though I may start with the more expensive chip first.
I'm new to this and not at all experienced with ARM chips or even much C but am willing to learn :-)
As captured in the comments, this task can be made easier if the code is initially written to attempt to clearly abstract the platform specific detail from the application code. This is not as simple as simply replacing the boot.s and isn't something that you can really claim to have done until you've tested the porting.
Much of the architectural behaviour between the two processors will be unchanged, and the C-compiler ought to be able to take advantage of micro-architectural optimisations. This optimisation may not be the best that you could achieve with some manual effort.
Where you are likely to see hard problems is any points in your code that are sensitive to memory ordering or potentially interactions between code and exceptions. The Cortex-A9 is significantly more out-of-order than the Cortex-A5, and the migration may expose bugs in your code. Libraries ought to be stable now, but there is still a risk to be aware of. Anticipating this sort of problem is quite hard and if you are writing the majority of the code yourself you probably need to build in some contingency for the porting task. Once the code is stable on A9, issues of this sort are less likely to show up on either A5 (to give a lower cost production option), or more recent high performance cores.
If I cut and paste a chapter of my math textbook into a my biology text book will that make sense? They both are written using the english language.
No that makes no sense. Assuming you are sticking to common ARM instructions for the code (english), the code isnt going to work from one chip (math book) to another (biology). The majority of the difference is between the vendors logic which is outside the ARM core, no reason whatsoever to assume that two vendors have the same peripherals at the same addresses that work exactly the same bit for bit, gate for gate.
So in general baremetal will NOT work and does NOT work like this. A very high level printf this or that C program, sure because you have many layers of abstraction including the target, doesnt even have to be arm to arm. Now saying that it is certainly possible for you to make or maybe if very lucky find a hardware abstraction layer that hides the differences between the chips, at that layer then you can ideally write that portion of the project and port it. As far as the arm vs arm the differences should be handled by the compiler and again dont even have to be arm to arm could be arm to mips. Any assembly language you may have or any core specific accesses/instructions would need to be checked against the two technical reference manuals to insure they are compatible. Probably not at the cortex-a level but for cortex-ms there are some address space core specific items that can affect high level language code, but for something like this to work you would have to hide that in the abstraction layer.
Generally NO, ARM is the underlying core, the chip differences have nothing to do with ARM so its like cutting and pasting a chapter from a mystery novel you are writing in english into a biography you are also writing in english and hoping that chapter makes sense in the latter book.
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.