Use QEMU to run RT-Thread dynamic module on Windows platform

Summary

This application note describes the use of QEMU to run the RT-Thread dynamic module on the Windows platform.

The purpose and structure of this article

The purpose and background of this article

The RT-Thread dynamic module component dlmodule provides a mechanism for dynamically loading program modules. The dlmodule component is more of an ELF format loader, which loads the separately compiled code segment and data segment of an elf file into memory, analyzes the symbols in it, and binds it to the API address exported by the kernel. The dynamic module elf file is mainly placed on the file system under RT-Thread.

RT-Thread's dynamic module component currently supports two formats:

.mo is an executable dynamic module with a suffix of .mo when compiled. It can be loaded, and the system will automatically create a main thread to execute the main function in this dynamic module; at the same time, the main(int argc, char** argv) function can also accept parameters on the command line.

.so is a dynamic library with .so as the suffix when compiled. It can be loaded, and reside in memory, and provide some function set to be used by other programs (code in the kernel or dynamic modules).

This article mainly explains the use of QEMU to run the RT-Thread dynamic module on the Windows platform.

Structure of this article

This article first explains how to enable RT-Thread dynamic module components, and then explains how to run dynamic modules and dynamic libraries based on QEMU.

Ready to work

Download the RT-Thread source code. It is recommended to download version 3.1.0 and above.

Download RT-Thread Env tool, it is recommended to download version 1.0.0 and above.

Download the rtthread-apps source code.

Download link:

https://github.com/RT-Thread/rtthread-apps (please copy to an external browser to open)

Enable dynamic module components

Configuration project

Switch to the qemu-vexpress-a9 BSP root directory in the Env console, and then enter the menuconfig command to open the configuration menu.

Enter the "RT-Thread Components → POSIX layer and C standard library" menu, and open the configuration options of libc and dynamic modules as shown by the arrow in the figure below.

Enter the "RT-Thread Components → Device virtual file system" menu to open the configuration options of the file system. Exit menuconfig and save the configuration.

Compile the project

Use the scons command to compile the project.

Run dynamic module commands

After the compilation is complete, use the qemu.bat command to run the project. Press Tab to view all commands. You can see the two commands list_module and list_symbols of the dynamic module, indicating that the dynamic module component is successfully configured.

The list_module command can view the dynamic modules currently running.

The list_symbols command can view the functions that can be used by the dynamic module and their corresponding memory addresses. When the dynamic module is loaded, the symbols in it will be parsed and bound to the corresponding function address.

Generate dynamic module compilation dependency environment

Close the running program and use the scons --target=ua -s command in the Env console to generate the kernel header file search path and global macro definitions that need to be included when compiling the dynamic module.

Run dynamic module

Run the simplest dynamic module

Create dynamic modules

Get an example

Download the RT-Thread dynamic module tool library rtthread-apps. The tools directory of rtthread-apps contains the Python and SConscript scripts needed to compile the dynamic module. main.c in the hello directory is a simple example of dynamic module usage. The source code is shown below.

#include int main(int argc, char *argv[]) {printf("Hello, world"); return 0;}

This code implements the simplest main function that prints the string "Hello world".

Set environment variables

Switch to the root directory of rtthread-apps on the Env console (the full path of the directory does not contain spaces and Chinese characters), and then set the environment variables through the following two commands.

set RTT_ROOT=d:epositoryt-thread, set RTT_ROOT as the root directory of RT-Thread source code.

set BSP_ROOT=d:epositoryt-thread\bsp\qemu-vexpress-a9, set BSP_ROOT to qemu-vexpress-a9 BSP root directory.

Compile dynamic modules

Use the scons --app=hello command to compile the dynamic module.

The dynamic module file hello.mo will be generated under the rtthread-apps/hello directory.

Put the dynamic module into the file system

The compiled dynamic module hello.mo needs to be placed in the file system. qemu-vexpress-a9 BSP will use a virtual SD card device sd.bin, we need to put the dynamic module in this virtual SD card. For physical devices, you can directly add the dynamic module to the storage device managed by the file system. Here you need to use a small tool fatdisk in the Env tool, which is located in the tools directory of Env, which also provides a fatdisk usage instruction. Fatdisk is used here to convert a local directory on the PC into an image file of sd.bin, which exists as a fat file system.

New directory

Create a new sd directory under the fatdisk directory, and copy the dynamic module hello.mo file just compiled to the sd directory.

Modify the configuration file

Modify the configuration file fatdisk.xml in the fatdisk directory according to the following configuration.

The image file space size disk_size is configured to 5120Kbytes (the size can be configured as needed).

The sector size of the image file sector_size needs to be configured to 512 KBytes.

To convert the directory name root_dir configuration to sd, it means the sd directory under the current directory.

Specify the generated image file name output and configure it as sd.bin.

strip needs to be configured as 0.

5120512sdsd.bin0

Generate image file

Switch to the root directory of fatdisk in the Env console, and run the fatdisk command to convert the specified directory into a flash image file according to the configuration in the configuration file fatdisk.xml.

A successful operation will generate a sd.bin file in the fatdisk directory with a size of 5MB.

The generated image file sd.bin needs to be copied to the qemu-vexpress-a9 BSP directory.

Run dynamic module

Switch to the root directory of qemu-vexpress-a9 BSP in the Env console and enter the qemu.bat command to run the project.

After the system is running, you will see the file system initialization successful message "file system initialization done!".

Use the ls command to see the dynamic module file hello.mo in the root directory.

Enter the hello command to run the dynamic module hello.mo. You can see the string "Hello, world" printed by the main function of the dynamic module

The main principle of using dynamic module components to run dynamic modules is shown in the figure below:

Initialization and cleanup functions of dynamic modules

The dynamic module component provides two extended functions for users to use, namely module_init() and module_cleanup().

The module_init() function will be executed before the dynamic module runs, and the user can do some initialization work as needed.

The module_cleanup() function will call back once in the idle thread after the dynamic module runs to perform the cleaning work set by the user.

The RT-Thread system will automatically create a thread to execute the main function in the dynamic module, and the main(int argc, char* argv[]) function can also accept parameters on the command line. The default priority of this thread is equal to the priority of the idle thread, and the thread stack defaults to 2048 bytes. The user can modify the priority and stack of this thread in the module_init() function.

Sample code

Based on the previous simple dynamic module sample code main.c, add the use of module_init() and module_cleanup() functions. The sample code is shown below.

#include #include /* Dynamic module initialization function*/ void module_init(struct rt_dlmodule *module) {module->priority = 8; module->stack_size = 4096; printf("this is module %s initial function!",module ->parent.name);} /* Dynamic module cleanup function*/ void module_cleanup(struct rt_dlmodule *module) {printf("this is module %s cleanup function!",module->parent.name);} int main (int argc, char *argv[]) {int i; printf("hello world from RTT::dynamic module!"); /* Print command line parameters*/ for(i = 0;i

The sample code mainly implements the following functions:

The priority and stack of this thread can be set in the initialization function of the dynamic module.

The cleanup function simply prints information.

The main function parses the command line parameters and prints them out.

Please refer to the previous section to put the dynamic module file generated by this sample code into the file system, and copy the generated image file sd.bin to the qemu-vexpress-a9 BSP directory.

operation result

Switch to the root directory of qemu-vexpress-a9 BSP in the Env console and enter the qemu.bat command to run the project.

After the system is running, you will see the file system initialization successful message "file system initialization done!".

Use the ls command to see the dynamic module file hello.mo in the root directory.

Enter the hello this is rt-thread! command to run the dynamic module hello.mo. The string after hello is the parameter.

When the dynamic module initialization function module_init is executed, the string "this is module hello initial function!" will be printed.

When the main function of the dynamic module is executed, the string "hello world from RTT::dynamic module!" is printed, and the command line parameters are also printed out in turn.

After the dynamic module runs, the cleanup function module_cleanup is executed, and the string "this is module hello cleanup function!" is printed.

Run dynamic library

Create dynamic library

Get an example

Download the RT-Thread dynamic module tool library rtthread-apps. There is a simple dynamic library example lib.c in the lib directory of rtthread-apps. The source code is shown below, which implements 2 simple functions for use.

#include int lib_func(void) {printf("hello world from RTT::dynamic library!"); return 0;} int add_func(int a, int b) {return (a + b);}

Compile dynamic library

Environment variables need to be set before compiling the dynamic library. Then use the scons --lib=lib command to compile the dynamic library.

The dynamic library file lib.so will be generated in the rtthread-apps/lib directory.

Please refer to the previous section to put the dynamic library file lib.so in the file system, and copy the generated image file sd.bin to the qemu-vexpress-a9 BSP directory.

Run dynamic library

Add sample code

Add the following sample code to main.c in the qemu-vexpress-a9 BSP applications directory.

#include #include #include /* Dynamic library file path*/ #define APP_PATH "/lib.so" /* Function pointer type*/ typedef int (*add_func_t)(int, int); typedef void (*lib_func_t)(void ); int dlmodule_sample(void) {void* handle; lib_func_t lib_function; add_func_t add_function; /* Open the dynamic library file in RTLD_LAZY mode and obtain the dynamic library operation handle */ handle = dlopen(APP_PATH,RTLD_LAZY); if(!handle) {printf("dlopen %s failed!",APP_PATH); return -1;} /* According to the dynamic library operation handle, return the address corresponding to the dynamic library function lib_func()*/ lib_function = (lib_func_t)dlsym(handle," lib_func"); if(!lib_function) {printf("dlsym %p failed!",handle); return -1;} /* Run dynamic library function*/ lib_function(); /* According to dynamic library operation handle, return The address corresponding to the dynamic library function add_func()*/ add_function = (add_func_t)dlsym(handle,"add_func"); if(!add_function) {printf("dlsym %p failed!",handle); return -1;} / * Run the dynamic library function to calculate 3+4 and print the result*/ printf("add_function result is:%d",add_function(3,4)); /* After running, close the dynamic library according to the operation handle*/ dlclose(handle) ; return 0;} MSH_CMD_EXPORT(dlmodule_sample, dlmodule sample); int main(void) {printf("hello rt-thread!"); return 0;}

The RT-Thread dynamic module component also supports the POSIX standard libdl API. This sample code calls the libdl API to run the dynamic library. The sample code first opens the dynamic library file lib.so according to the path of the dynamic library, and then obtains the address of the lib_func() function of the dynamic library and runs this function. Then get the address of the add_func() function of the dynamic library, and pass in the parameters 3 and 4 to run the function calculation result. Finally, close the dynamic library.

Run dynamic library

Switch to the root directory of qemu-vexpress-a9 BSP in the Env console, and enter the scons command to recompile the project. After the compilation is complete, enter the qemu.bat command to run the project. Press Tab to see the newly added sample code command dlmodule_Sample.

Use the ls command to see the dynamic library file lib.so in the root directory, and enter the dlmodule_sample command to run the dynamic library sample code.

The first line runs the lib_func() function and prints the string "hello world from RTT::dynamic library!"

The second line runs the add_func() function to calculate 3+4 and prints the addition result 7.

FC Optical Fiber Adapter

FC Optical Fiber Adapter,Sc Optical Fiber Adapter,Short Ear Sc Adapter

ShenZhen JunJin Technology Co.,Ltd , https://www.jjtcl.com