Dynamic Modules
In traditional desktop operating systems, user space and kernel space are separate. Applications run in user space, while kernels and kernel modules run in kernel space. Kernel modules can be dynamically loaded and deleted to extend kernel functions. dlmodule
Under RT-Thread, it is a software component that provides a dynamic module loading mechanism in kernel space. In versions before RT-Thread v3.1.0, this is also called an application module. In RT-Thread v3.1.0 and later, it returns to tradition and is named as a dynamic module.
dlmodule
The component is more of an ELF format loader, which loads the code segment and data segment of a separately compiled elf file into memory, parses the symbols in it, and binds them to the API address exported by the kernel. The dynamic module elf file is mainly placed on the file system under RT-Thread.
Dynamic modules provide RT-Thread with a mechanism for dynamically loading program modules. Since they are also independent of kernel compilation, they are more flexible to use. In terms of implementation, this is a mechanism that separates the kernel and dynamic modules. Through this mechanism, the kernel and dynamic modules can be compiled separately, and the compiled dynamic modules can be loaded into the kernel through the module loader in the kernel at runtime.
In RT-Thread's dynamic modules, two formats are currently supported:
.mo.mo
It is an executable dynamic module with the suffix of as compiled ; it can be loaded, and the system will automatically create a main thread to executemain
the function in this dynamic module; at the same time, thismain(int argc, char**argv)
function can also accept parameters on the command line..so.so
It is a dynamic library with as the suffix when compiled ; it can be loaded and reside in the memory, and provides some function sets to be used by other programs (code in the kernel or dynamic modules).
Currently, RT-Thread supports dynamic modules for architectures such as ARM and x86, and will be extended to MIPS and RISC-V in the future. The RT-Thread kernel firmware can use a variety of compiler tool chains, such as GCC, ARMCC, IAR, etc., but the dynamic module part currently only supports GNU GCC tool chain compilation. Therefore, to compile the RT-Thread module, you need to download the GCC tool, such as CodeSourcery's arm-none-eabi tool chain. In general, it is best to compile the kernel and dynamic modules with the same tool chain (so that inconsistent behavior will not occur on libc). In addition, dynamic modules can generally only be loaded into RAM for use, and symbol resolution is performed and bound to the API address exported by the kernel, and they cannot be run directly in XIP mode based on Flash (because the code segments in Flash cannot be modified anymore).
When you want to test and use dynamic modules in the system, you need to compile a firmware that supports dynamic modules and the dynamic modules that need to be run. The following describes the compilation methods of firmware and dynamic modules in two parts.
When you want to use dynamic modules, you need to open the corresponding options in the firmware configuration. Use menuconfig to open the following configuration:
Also open the file system configuration options:
In rtconfig.py corresponding to bsp, set the configuration parameters needed for dynamic module compilation:
The relevant explanations are as follows:
M_CFLAGS - C code compilation parameters used when compiling dynamic modules. Generally, it is compiled in PIC mode (that is, the code address supports floating mode execution);
M_CXXFLAGS - C++ code compilation parameters used when compiling dynamic modules. The parameters
M_CFLAGS
are similar to those above;M_LFLAGS - parameters for dynamic modules when linking. Also PIC mode, and linking as a shared library (partial link);
M_POST_ACTIOn - the action to be performed after the dynamic module is compiled. Here, the elf file will be stripped to reduce the size of the elf file;
M_BIN_PATH - when the dynamic module is compiled successfully, whether the corresponding dynamic module file needs to be copied to a unified place;
Basically, these compilation configuration parameters for ARM9, Cortex-A, and Cortex-M series are the same.
The kernel firmware will also RTM(function)
export some function APIs for dynamic modules to use. These exported symbols can be used in msh through the command:
list_symbols
List all exported symbol information in the firmware. dlmodule
The loader also parses the symbols that need to be parsed in the dynamic module according to the symbol table exported here to complete the final binding action.
This symbol table will be placed in a special section named RTMSymTab, so the corresponding firmware link script also needs to retain this area and will not be removed by linker optimization. You can add the corresponding information in the link script:
Then scons
execute the following command in the BSP project directory:
scons --target=ua -s
To generate the kernel header file search path and global macro definitions that need to be included when compiling dynamic modules.
There is an independent repository on github: rtthread-apps , which contains some examples related to dynamic modules and dynamic libraries.
The directory structure is as follows:
You can clone this git repository locally, and then compile it using the scons tool in the command line. If you are using a Windows platform, it is recommended to use the RT-Thread/ENV tool.
After entering the console command line, go to the directory where the rtthread-apps repo is located (again, please ensure that the full path of this directory does not contain spaces, Chinese characters, etc.) and set two variables:
RTT_ROOT - points to the root directory of RT-Thread code;
BSP_ROOT - points to the BSP project directory;
It can be used under Windows (assuming the BSP used is qemu-vexpress-a9):
To set the corresponding environment variables. Then use the following command to compile the dynamic module, such as the hello example:
scons --app=hello
After successful compilation, it will generate hello.mo file in rtthread-apps/hello directory.
You can also compile dynamic libraries, such as lib:
scons --lib=lib
After successful compilation, it will generate lib.so file in rtthread-apps/lib directory.
We can put these mo and so files into the RT-Thread file system. In msh, we can simply hello
execute hello.mo
the dynamic module in command mode:
After calling hello, the main function in hello.mo will be executed, and the corresponding dynamic module will be exited after the execution is completed. hello/main.c
The code is as follows:
In addition to directly loading and executing dynamic modules through msh, you can also use the dynamic module API provided by RT-Thread in the main program to load or unload dynamic modules.
This function loads a dynamic module from the file system into memory and returns a pointer to the module if it is loaded correctly. This function does not create a thread to execute the dynamic module, but only loads the module into memory and resolves the symbol address.
This function pgname
loads the dynamic module according to the path and starts a thread to execute main
the function of this dynamic module. At the same time, cmd
it is passed as a command line parameter to main
the function entry of the dynamic module.
This function is called by the module runtime to set the module's exit return value ret_code
and then exit from the module.
This function name
checks whether there is a dynamic module already loaded in the system.
This function returns a pointer to the dynamic module in the calling context.
This function returns the address of a symbol given its name.
The POSIX standard libdl API is also supported in RT-Thread dlmodule, which is similar to loading a dynamic library into memory (and parsing some symbol information in it), and the dynamic library provides the corresponding function operation set. The header files that libdl API needs to include are:
#include <dlfcn.h>
This function is similar to dlmodule_load
, which will load the dynamic library from the file system and return the handle pointer of the dynamic library.
This function handle
searches for symbol
the symbol of in the dynamic library and returns its address if it exists.
This function will close handle
the dynamic library pointed to by and unload it from the memory. It should be noted that when the dynamic library is closed, dlsym
the symbol address originally returned by will no longer be available. If you still try to access it, it may cause a fault error.
A: Please update the RT-Thread source code to version 3.1.0 or above.
A: Please refer to the GCC link script file link.lds of the qemu-vexpress-a9 BSP and add the following content to the TEXT section of the GCC link script of the project.
Last updated