I have an IAR STM32 project where I am need to wrap a library function with some custom logic. I do not have the ability to recompile the library itself, so what I would like to do is create a function libfunction_shim that calls into the original libfunction. Using the --redirect linker option (--redirect libfunction=libfunction_shim), I can redirect calls to the original function to the shim, including calls inside the library itself. However, I need to call the original function from the shim.
If I add another redirect (--redirect libfunction_original=libfunction), it ends up redirecting libfunction_original to libfunction_shim, rather than the original libfunction. I've tried reordering the redirects, but it does the same thing regardless of order.
The linker log demonstrates this:
Symbol Redirected to Reason
------------- ------ ------
...
libfunction libfunction_shim command line
libfunction_original libfunction_shim command line
What I would like this:
Symbol Redirected to Reason
------------- ------ ------
...
libfunction libfunction_shim command line
libfunction_original libfunction command line
Is it possible to do this using the linker?
This is not possible using linker redirects, you have to write your shim function in a specific way. A complete description is available in the manual (pg 225 in the 8.40.1 version) but to summarize: First you name the shim $sub$$libfunction, where libfunction is the name of the function to shadow. From inside the shim you can use $super$$libfunction to call the original version of libfunction. A minimal example is shown below.
extern void $Super$$foo(void);
void $Sub$$foo(void)
{
$Super$$foo(); /* calls the original foo() function */
}
Related
I feel like I'm missing some key idea with this one.
I have a library that I'd like to create a CMakeLists.txt file for. I want to link against it with different applications.
This library expects a conf.h file to be defined. The application has to provide this. The library expects it. What is this relationship called?
My current solution in CMakeLists.txt is to have a variable like:
...
target_include_directories(lib PUBLIC
${CONF_DIR}
)
And then have CONF_DIR be defined by the application. This is uncool, because I can't have multiple applications linking against it.
The only other alternative is to keep a copy of the entire source library inside the application folder, which is also uncool.
I'm looking to maximize reusability. How do I approach this?
Side note: For anyone who's familiar, the library in question is STM32Cube's HAL library, and the pesky file is stm32h7xx_hal_conf.h.
This is a very common approach, when a library requires configuration. FreeRTOS would be another example.
I don't see the issue with modifying the target_include_directories for the library from the App's CMakeLists.txt.
Usually, I create a function to handle the library set-up. The call site would look something like this:
add_stm32_hal_lib(
PATH drivers/STM32H7xx_HAL_Driver
EXTRA_INCLUDES path/to/config
)
# ...
target_link_libraries(app PUBLIC stm32_hal)
The contents of the EXTRA_INCLUDES parameter get shoved into target_include_directories of the static library.
You can't do anything about this, so you'll have to copy the library code.
The header file is used during library compilation stage, so its code ends up being hardwired into the final binary. Because of this, if you want to change some parameters from the header, you need to recompile the library from scratch.
Ideally, the library should be rewritten in such way, that all parameters that are contained in the header can be set up dynamically, during the runtime, using some additional configuration API.
I did setup a C project with Eclipse Photon (4.8.0) for developing a program for the ESP-32. I did configure the IDE according to this official setup instructions.
Flashing the ESP-32 works fine. But as soon as I try to include header files from a sub folder, I run into troubles. I have set up a very simple project to illustrate the issue. The project consists of main.c, base/test.h and base/test.c, whereas the test.h and test.c files only contain one function with the signature void function1(void);.
When I try to call function1() in main.c, I get this error in main.c:
Undefined reference to function1()
Please compare to the attached screenshot, where everything is depicted.
How to solve this issue?
This is not a compiler, but rather a linker error.
Note, with #includeing a header file, you only make the external function known to the compiler. You also need to link to the external function during the linking stage. Make sure you include the compiled object file that contains function1 into the link.
Seems like you need to do proper linking.
If you are linking with a library, you need to specify:
The name of the library: Project\Settings\C C++ General\Paths and Symbols\Libraries
Location where the linker should search for this library:
Project\Settings\C C++ General\Paths and Symbols\Library Paths
Important: see Note.
If you are linking with object files, add those to:
Project\Settings\C C++ Build\Settings\Linker\Miscellaneous\Other objects
Note:
If your library name is, for example, libsomething.a, than you need to specify only something as the name; so omit lib prefix and .a suffix.
If your library is not prefixed with lib, then you need to add its name prefixed with :. For example, something.a should be added as :something.a.
The point is to generate a hex without main function using IAR linker - xlink?
This code should be loaded into the RAM of RL78 MCU.
A quick Google search of iar generate hex from library brought me to this document, "Creating an Absolutely Placed Library", as a first result. It has all the information you need, plus some information on using a CRC for consistency checking. The document is for the IAR EWRX variant, but the concepts should all be the same.
The basic process is to compile your library as an executable, but without a main() function in it. You'll need to set your library configuration under General -> Library Options to None. You can also setup your file conversion settings at this point.
Since you don't have a main() function for a program entry point, you will need to create an entry function to call the IAR C runtime initialization function, __iar_data_init2(), and then set the linker to use this function as the entry point (which can be found under Linker Options -> Library Options).
When building a library, all the symbols will be preserved until the final link step for the application using it, but since you are building this as an executable, it is important that the symbols you want to keep have the __root keyword, or under Linker -> Extra Options you can specify --no-remove to keep all symbols.
In the next step, you need to use isymexport to export the symbols that you want. You will need a file to direct the tool what to export. In the example, they have a file that just contains the following:
show lib_*
show __checksum*
This will direct the tool to export all symbols beginning with lib_ and all symbols beginning with __checksum. They note that __iar_data_init2() should not be exported, as this would cause conflicts with the application that ultimately will use this code. You invoke the tool like so:
isymexport <path to .out file> <path to output from tool> --edit <path to file created above>
Now you should have the output from isymexport and the library file that you were looking for. For the application using this library, you'll need to add the output from isymexport as a library under Linker -> Library, and in your application, you'll need to call your entry function in the library before you attempt to use any of the library's symbols.
This should be the information you need to generate a library that lives in a hex file and can be loaded separately, as well as how to use that library. The referenced document has a lot more detail, so if it is available at that link (or can be found elsewhere by title) it will be a better reference than my summary here.
I have two C source files. A comment to a function bar()in file A needs to refer to a function foo() in file B. How can I make this link?
I tried:
Writing something like: B.c::foo() hoping that doxygen would go to file B and find function foo there.
Also tried simply ::foo() but that did not help.
Then I tried giving file B.c a special tagname as in doing //! #file specialtag on first line of B.c and then doing specialtag::foo() in my comment but not much has changed.
I tried to force the link with \ref and \link but even that did not help.
The //! #file line is present in both A.c and B.c so doxygen should be aware of the code.
EDIT
I tried what #doxygen suggested but with no luck. I made an example project to show where I am running into problems, its here: http://www.filedropper.com/testdoxygen2tar
I used the default setup file, made with doxygen -g.
The output I am getting:
You can see that the foobar function is not being linked to.
EDIT 2
Found the problem. Function foo was undocumented and so no page for it was generated, so of course doxygen had no page to link to. (I was generating documentation with the SOURCE_BROWSER option enabled and hoping that a link to function definition would be generated)
This is pretty straightforward. Here's a minimal example that works with a default configuration file (doxygen -g):
First create file foo.c with the following contents:
/** #file */
/** Function foo, see also bar(). */
void foo()
{
}
then create file bar.c with the following contents:
/** #file */
/** Function bar, see also foo(). */
void bar()
{
}
Run doxygen and observe in the HTML output that both functions will have a link to the other function.
I am trying to use Eclipse and NetBeans for programming in C (not C++). Is there a feature/plugin for them which automatically keeps the source and header files in sync?
As in, when I implement a function in the source file, does it automatically insert the correct lines in the header file?
I did look at solutions like lzz, but they are not what I am looking for.
Eclipse CDT allows you to write a prototype in the header file, and automatically add it to the C file.
Instructions
Add function prototype to .h file void foobar()
Select the function name "foobar" (try double clicking)
In the toolbar click Source -> Implement Method
Wizard it up
Thats probably the best you're gonna get out of the box
Agree with approach proposed by Ryu. In C, I would not automatically create declarations in headers. This should be an explicit action making public some symbol from the C module.
However if declaration/implementation are already setup and you want to modify any of them, I imagine that with Eclipse you may want to use Toggle Function Definition in a possible workflow where you copy in clipboard intermediate toggling results and paste them later over the changed declaration or implementation declaration.
Also use rename refactoring intensively when you change things.