Using HAL libraries without uncommenting HAL_conf.h specific library - c

I want to use uart without uncommenting stm32****_HAL_conf.h:
#define HAL_UART_MODULE_ENABLED
I've tried to add it on main.h and/or including manually:
#include "stm32h7xx_hal_uart.h"
but these adding causes to cubeIDE to tell: Undefined reference to.
I wonder why uncommenting that define solve all errors (Note: thos only causes uart header to being included in HAL_conf.h) but customly adding them to main.h will giving us error. Since by every cubeMX refresh the HAL_conf.h resets to it's default. Also I've seen this usefull question undefined reference when including a header file .
It seems the defenition in the code changes linker behaviour, doesn't it? But how?
What I've done?
1.Added required file to the project uart header and source.
2.including the header file in program
3.defining the flag to let #ifdef's to doing their job
But no work is done.

Each HAL driver's source file checks to see if its HAL_FOO_MODULE_ENABLED symbol is defined. If it is not, the driver still compiles and generates a .o file, but this will contain no functions. This will lead to linker errors if those driver functions are referenced in other code.
Therefore, HAL_FOO_MODULE_ENABLED must be defined in a file that the driver #includes. The drivers do not #include "main.h", so you cannot add the definition there.
CubeMX will automatically define symbols for used drivers in stm32xxx_hal_conf.h. Note that this is an autogenerated file, and will be overwritten anytime CubeMX deems it necessary to change anything. So while it is possible to manually edit that file, you'd need to be aware that it could revert later.
There is probably not a safe place you can manually add these defines, that will not be reverted by CubeMX at a later time. They could probably be added to your compiler flags, e.g. -DHAL_UART_MODULE_ENABLED if you really needed to do it this way.

Related

Where are the header functions defined? [duplicate]

When I include some function from a header file in a C++ program, does the entire header file code get copied to the final executable or only the machine code for the specific function is generated. For example, if I call std::sort from the <algorithm> header in C++, is the machine code generated only for the sort() function or for the entire <algorithm> header file.
I think that a similar question exists somewhere on Stack Overflow, but I have tried my best to find it (I glanced over it once, but lost the link). If you can point me to that, it would be wonderful.
You're mixing two distinct issues here:
Header files, handled by the preprocessor
Selective linking of code by the C++ linker
Header files
These are simply copied verbatim by the preprocessor into the place that includes them. All the code of algorithm is copied into the .cpp file when you #include <algorithm>.
Selective linking
Most modern linkers won't link in functions that aren't getting called in your application. I.e. write a function foo and never call it - its code won't get into the executable. So if you #include <algorithm> and only use sort here's what happens:
The preprocessor shoves the whole algorithm file into your source file
You call only sort
The linked analyzes this and only adds the source of sort (and functions it calls, if any) to the executable. The other algorithms' code isn't getting added
That said, C++ templates complicate the matter a bit further. It's a complex issue to explain here, but in a nutshell - templates get expanded by the compiler for all the types that you're actually using. So if have a vector of int and a vector of string, the compiler will generate two copies of the whole code for the vector class in your code. Since you are using it (otherwise the compiler wouldn't generate it), the linker also places it into the executable.
In fact, the entire file is copied into .cpp file, and it depends on compiler/linker, if it picks up only 'needed' functions, or all of them.
In general, simplified summary:
debug configuration means compiling in all of non-template functions,
release configuration strips all unneeded functions.
Plus it depends on attributes -> function declared for export will be never stripped.
On the other side, template function variants are 'generated' when used, so only the ones you explicitly use are compiled in.
EDIT: header file code isn't generated, but in most cases hand-written.
If you #include a header file in your source code, it acts as if the text in that header was written in place of the #include preprocessor directive.
Generally headers contain declarations, i.e. information about what's inside a library. This way the compiler allows you to call things for which the code exists outside the current compilation unit (e.g. the .cpp file you are including the header from). When the program is linked into an executable that you can run, the linker decides what to include, usually based on what your program actually uses. Libraries may also be linked dynamically, meaning that the executable file does not actually include the library code but the library is linked at runtime.
It depends on the compiler. Most compilers today do flow analysis to prune out uncalled functions. http://en.wikipedia.org/wiki/Data-flow_analysis

GCC - How to stop malloc being linked?

I am struggling to get my code down to minimal bare bones size! I am using a STM32F0 with only 32k flash and need a good part of the flash for data storage. My code is already at approx 20k flash size! Some of this is due to use of the STM32 HAL functions which I can account for and optimise later if needed.
However, my biggest consumer of flash is all the implicitly included library routines. I can not seem to remove these functions. They are not called anywhere in my code or any HAL code. Functions such as _malloc_r (1.3k Bytes), and __vfiprintf_r (3kB) and many others are using a large part of my flash. I think these are all the libc functions. I do not use these and would like them gone!
Does anybody know how to remove these?
I have tried different optimisation levels and linker options but no luck so far. I have tried -nostdlib and --specs=nosys.specs with no change. If I remove my file with definitions for functions such as _exit I get a linker error suggesting that the library is still included and needs these. Also linker map confirms presence of a lot of unwanted functions!
Any suggestions?
When you are wondering about what takes space, or why functions and libraries have been linked in, generate a map file with cross references - something like "-Wl,-Map=program.map,--cref". Look at the file with a text editor, and you can see why a function like malloc has been included.
Solved... Some of my code included and called assert. The moment I removed assert calls my code size more than halved! I instead used the STM32 HALs assert_param macro that is a light weight assert that just redirects to a user defined function.
It would be helpful if someone could explain to me how gcc decides to include library functions when assert is called? I see that assert.h declares an external function __assert_func. How does the linker know to reference it from a library rather than just say "undefined reference to __asert_func"?

Qt Creator ClangCodeModel can't parse or autocomplete conditional nested includes?

I'm starting an embedded AVR project in C with QtCreator.
I believe I have everything setup and working correctly; I can write code that #include's headers from avr-libc, build with a custom makefile, and the binary is automatically flashed onto the chip for me. Unfortunately, even though my code compiles without any warnings from avr-gcc, QtCreator's ClangCodeModel plugin does not recognize a subset of the #define'd port and register names--it claims that there are errors, and autocompletion does not work.
I think I've identified the problem:
The boilerplate #include in avr projects is #include <avr/io.h>. io.h itself #include's a number of other headers unconditionally, no-matter-what, such as headers that define register names common to all AVR devices. And code completion does work correctly with the names defined in those headers. However, it also conditionally includes one other header based on which specific AVR device you are targetting. There are many hundreds of AVR devices out there, each one having its own header file that defines port and register names. io.h determines which one to include like this:
#if defined (__AVR_AT94K__)
# include <avr/ioat94k.h>
#elif defined (__AVR_AT43USB320__)
# include <avr/io43u32x.h>
#elif defined (__AVR_AT43USB355__)
# include <avr/io43u35x.h>
#elif defined (__AVR_AT76C711__)
# include <avr/io76c711.h>
.
.
.
and so on. I reason that the correct header must actually be included since compiling throws no errors, even though ClangCodeModel does show error tags. By that I mean, I can write code that references a device-specific register name and compile without problems, but ClangCodeModel does not recognize that register name.
EDIT: Note that if I actually directly #include <avr/iom328p.h> at the top of main.c, ClangCodeModel parses the header just fine and autocompletion works. Unfortunately, I can't actually leave it like that. From <avr/io.h>:
This header file includes the apropriate IO definitions for the
device that has been specified by the -mmcu= compiler
command-line switch. This is done by diverting to the appropriate
file <avr/ioXXXX.h> which should
never be included directly. Some register names common to all
AVR devices are defined directly within <avr/common.h>,
which is included in <avr/io.h>,
but most of the details come from the respective include file.
and from <avr/iom328p.h>:
/* This file should only be included from <avr/io.h>, never directly. */
From the ClangCodeModel documentation:
The feedback you get through warning and error markers is the same as
a compiler will give you, not an incomplete set or a close
approximation, as when using the built-in Qt Creator code model.
That doesn't seem to be the case. To me, that claim implies ClangCodeModel would go ahead and evaluate the #if defined (__MY_AVR__), and parse the correct device-specific header, which isn't happening here.
It is essential to me that code completion works since embedded projects require typing esoteric register and port name macros all day long.
What am I missing?
makefile, and the makefile referenced at the bottom include.
The general <avr/io.h>.
The device-specific header <avr/iom328p.h> which has all the names I need, and ClangCodeModel is failing to parse.
Contents of QtCreator's MyProjectName.includes (I added these lines manually).
You should add
#define __AVR_ATmega328__
to your MyProjectName.config file.
QtCreator's code model cannot get all compiler defines, because your Makefile is not generated by qmake, cmake, or qbs.

Compile-time test if function is optimized out

I'm writing a small operating system for microcontrollers in C (not C++, so I can't use templates). It makes heavy use of some gcc features, one of the most important being the removal of unused code. The OS doesn't load anything at runtime; the user's program and the OS source are compiled together to form a single binary.
This design allows gcc to include only the OS functions that the program actually uses. So if the program never uses i2c or USB, support for those won't be included in the binary.
The problem is when I want to include optional support for those features without introducing a dependency. For example, a debug console should provide functions to debug i2c if it's being used, but including the debug console shouldn't also pull in i2c if the program isn't using it.
The methods that come to mind to achieve this aren't ideal:
Have the user explicitly enable the modules they need (using #define), and use #if to only include support for them in the debug console if enabled. I don't like this method, because currently the user doesn't have to do this, and I'd prefer to keep it that way.
Have the modules register function pointers with the debug module at startup. This isn't ideal, because it adds some runtime overhead and means the debug code is split up over several files.
Do the same as above, but using weak symbols instead of pointers. But I'm still not sure how to actually accomplish this.
Do a compile-time test in the debug code, like:
if(i2cInit is used) {
debugShowi2cStatus();
}
The last method seems ideal, but is it possible?
This seems like an interesting problem. Here's an idea, although it's not perfect:
Two-pass compile.
What you can do is first, compile the program with a flag like FINDING_DEPENDENCIES=1. Surround all the dependency checks with #ifs for this (I'm assuming you're not as concerned about adding extra ifs there.)
Then, when the compile is done (without any optional features), use nm or similar to detect the usage of functions/features in the program (such as i2cInit), and format this information into a .h file.
#ifndef FINDING_DEPENDENCIES
#include "dependency_info.h"
#endif
Now the optional dependencies are known.
This still doesn't seem like a perfect solution, but ultimately, it's mostly a chicken-and-the-egg problem. When compiling, the compiler doesn't know what symbols are going to be gc'd out. You basically need to get this information from the linker stage and feed it back to the compilation stage.
Theoretically, this might not increase build times much, especially if you used a temp file for the generated h, and then only replaced it if it was different. You'd need to use different object dirs, though.
Also this might help (pre-strip, of course):
How can I view function names and parameters contained in an ELF file?

what is the difference between uio.h and io.h?

Sometimes I see compiler complaining about this line
#include <sys/io.h>
with
fatal error: sys/io.h: No such file or directory
If I simply change it to
#include <sys/uio.h>
It will magically work. Can someone explain to me the difference? Why do some OSes have one but not the other?
Edit: This issue happens on a Linux, not just OS X.
Generally speaking, it is not safe or even sensible to simply change the name of a header file being included when the compiler cannot find that header. Headers with similar names do not necessarily have anything to do with each other.
That appears to be the case here: the GLIBC header file sys/io.h does not declare the vectored I/O functions of the POSIX-specified header sys/uio.h, at least not directly. In fact, GLIBC also provides sys/uio.h. They're different. Neither C nor POSIX provides any reason to believe that sys/uio.h on one system would provide any declarations that are provided by a header named sys/io.h on that or any other system.
If you are trying to build C code and some header cannot be found, then the first thing to consider is the include search path, and whether the header name needs a path segments added or removed. The next thing to consider is whether that header is needed at all in the build environment. If it is not, then changing the header to name some other header that is actually present will fix the build, but so would deleting the include directive altogether.
I'd rate it better, in fact, to remove or comment out such a failing include directive, make sure warnings are cranked up, and see what, if any, missing declarations the compiler then complains about. That will give you a handle with which to determine what header, if any, you should include in place of the missing one.

Resources