Test RT thread dynamic module

Keywords: C++ Linux

      It is said that RT thread OS developed by Chinese people has been for some time and has not been tried. After all, learning a new platform takes a lot of time and energy. The main purpose of testing RT thread this time is to use its dynamic library function. Now the Cortex-M series Arm processor is very powerful. However, because Cortex-M does not have a memory manager. The program lacks relocation function. Therefore, it is difficult to implement a shared library (lib.so) similar to linux OS  ). The shared library is very important for the function expansion of the system. For example, in the controller, the function blocks need to be imported dynamically. If there is no shared library function, the newly added program library must be recompiled and downloaded together with the kernel and OS. It is more troublesome to add and update the function blocks remotely. Therefore, the shared library is very important for the embedded software controlling the device of

Getting to know RT thread

The RT thread Studio development environment is very convenient

      RT thread has provided an integrated development environment RT thread studio. It is very convenient to use. In order to reduce the trouble of setting at the beginning, I purchased an Art PI development board. Developing a flashing program is very fast and smooth.

Dependency of RT thread

  RT thread uses ST link as the program download tool. It needs to download and install STlink. At the same time, Python 2.7 needs to be installed

msh of RT thread

      Different from other embedded OS, RT thread provides a command tool similar to Linux shell, formerly called msh. It is linked to PC through USB on the development board. You can use a serial port software. It used to be called Finsh. I don't know why it's not called shell directly?

ENV tool that can't get rid of RT thread

    In the past, RT thread was developed using ENV tool. At present, it seems that the ENV tool is still indispensable for developing dynamic modules. It is used under windows cmd. Right click in the relevant directory and select conEMU Here to enter.

Make complaints about

      Maybe it's some historical baggage. Some concepts, naming and usage of RT thread are a little strange, which is different from linux or other development environments. It's a little confusing for beginners. As I pointed out, when developing software, you should be very careful in naming and terminology. Try to conform to social semantics (that is, people's habits).

    Another problem with RT thread is that there is a common problem with software developed by Chinese people. It is not the poor technology of the software itself, but the poor community. It is difficult to find answers to problems on the Internet. On the Internet, except for the original documents, there are few questions to answer, discuss with each other and share experience. Most articles are forwarded to each other or their own learning notes, Or the training teacher's copy. What you say is the same. If you make mistakes in one place, many places are wrong. This is the biggest confusion in using domestic software.

Using dynamic modules

Main reference [STM32H750] play art PI (VIII) -- add dynamic module   This blog post doesn't seem to have encountered too many problems.

  Source code from   rtthread-apps   It includes two programs, one is the library lib and the other is the main program hello

lib.c

#include <stdio.h>

int lib_func(void)
{
    printf("hello world from RTT::dynamic library!\n");

    return 0;
}

int add_func(int a, int b)
{
    return (a + b);
}

main.c in the hello directory

#include <stdio.h>
 #include <dlfcn.h>
 #include <rtthread.h> 
 
 #define APP_PATH "/sdcard/lib.so"
 
 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; 
      
       handle = dlopen(APP_PATH,RTLD_LAZY);
        if(!handle) {
             printf("dlopen %s failed!\n",APP_PATH); return -1;
              } 
         
         
              lib_function = 
              (lib_func_t)dlsym(handle,"lib_func");
               if(!lib_function) { 
                   printf("dlsym %p failed!\n",handle); return -1; } 
                  
                   lib_function(); 
               
               
                    add_function = (add_func_t)dlsym(handle,"add_func");
                     if(!add_function) { printf("dlsym %p failed!\n",handle); return -1; }                         
                     printf("add_function result is:%d\n",add_function(3,4));
 dlclose(handle); return 0; }
   MSH_CMD_EXPORT(dlmodule_sample, dlmodule sample);
   int main(void) { 
       printf("rt-thread dynamic module Test!\n");
        return 0; 
}

By careful comparison, we have made a little change.

The original #define APP_PATH "/lib.so" is changed to

 # define APP_PATH "/sdcard/lib.so". Maybe you can set it somewhere and use / lib.so.

Besides, I don't know why

MSH_CMD_EXPORT(dlmodule_sample, dlmodule sample);     It doesn't work. This statement can transform the dlmount_sample program into a msh command. Run the program under msh. I later called dlmount_sample program directly in main.

Compiled commands

 set RTT_ROOT=C:\RT-ThreadStudio\workspace\art_pi_module\rt-thread
 set BSP_ROOT=C:\RT-ThreadStudio\workspace\art_pi_module
 scons --target=ua -s
 scons --lib=lib
 scons --app=hello

Further testing

[STM32H750] play art PI (VIII) -- add dynamic module   This is the end of the article, but there seems to be some things to do to really use dynamic modules

Calling lib.so Library in studio project file

This seems relatively simple. Copy dlmount_sample to the main of the project.

/*
 * Copyright (c) 2006-2020, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2020-09-02     RT-Thread    first version
 */

#include <rtthread.h>
#include <rtdevice.h>
#include "drv_common.h"
#include <stdio.h>
 #include <dlfcn.h>
#define LED_PIN GET_PIN(I, 8)
#define APP_PATH "/sdcard/lib.so"

 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;
       handle = dlopen(APP_PATH,RTLD_LAZY);
        if(!handle) {
             printf("dlopen %s failed!\n",APP_PATH); return -1;
              }


              lib_function =
              (lib_func_t)dlsym(handle,"lib_func");
               if(!lib_function) {
                   printf("dlsym %p failed!\n",handle); return -1; }

                   lib_function();

                 //add function
                    add_function = (add_func_t)dlsym(handle,"add_func");
                     if(!add_function) { printf("dlsym %p failed!\n",handle); return -1; }
                     printf("add_function result is:%d\n",add_function(3,4));
           
 dlclose(handle);
 return 0;
  }
int main(void)
{
    rt_uint32_t count = 1;
    printf("rt-thread dynamic module Test!\n");
    rt_thread_mdelay(500);
    dlmodule_sample();
    rt_pin_mode(LED_PIN, PIN_MODE_OUTPUT);

    while(count++)
    {
        rt_thread_mdelay(500);
        rt_pin_write(LED_PIN, PIN_HIGH);
        rt_thread_mdelay(500);
        rt_pin_write(LED_PIN, PIN_LOW);
    }
    return RT_EOK;
}

#include "stm32h7xx.h"
static int vtor_config(void)
{
    /* Vector Table Relocation in Internal QSPI_FLASH */
    SCB->VTOR = QSPI_BASE;
    return 0;
}
INIT_BOARD_EXPORT(vtor_config);

      The only problem here is that when the main thread is run, the sdcard cannot be found when the lib.so file is opened at the beginning of mount sdcard. Therefore, I added one before calling dlmount_sample

 rt_thread_mdelay(500);

Ensure that the sdcard mount is successful.

lib calls external functions  

      How to call back the main function in the lib program. Here we use the C language callback method. It is feasible after testing.

lib.c

#include <stdio.h>

int lib_func(void)
{
    printf("hello world from RTT::dynamic library!\n");

    return 0;
}

int add_func(int a, int b)
{
    return (a + b);
}
int handle(int y, int (*Callback)(int)){
    printf("Entering Handle Function. \n");
        Callback(y);
        printf("Leaving Handle Function. \n");
        return 0;
}

dlmodule_sample subroutine

#include <rtdevice.h>
#include "drv_common.h"
#include <stdio.h>
 #include <dlfcn.h>
#define LED_PIN GET_PIN(I, 8)
#define APP_PATH "/sdcard/lib.so"

 typedef int (*add_func_t)(int, int);
 typedef void (*lib_func_t)(void);
 typedef void (*handle_func_t)(int,int (*Callback)(int));
 int Callback(int x) // Callback Function 1
 {
     printf("Hello, this is Callback_1: x = %d ", x);
     return 0;
 }

  int dlmodule_sample(void)
  {
      void* handle;
      lib_func_t lib_function;
      add_func_t add_function;
      handle_func_t handle_function;
       handle = dlopen(APP_PATH,RTLD_LAZY);
        if(!handle) {
             printf("dlopen %s failed!\n",APP_PATH); return -1;
              }


              lib_function =
              (lib_func_t)dlsym(handle,"lib_func");
               if(!lib_function) {
                   printf("dlsym %p failed!\n",handle); return -1; }

                   lib_function();

                 //add function
                    add_function = (add_func_t)dlsym(handle,"add_func");
                     if(!add_function) { printf("dlsym %p failed!\n",handle); return -1; }
                     printf("add_function result is:%d\n",add_function(3,4));
                 // callback
                     handle_function = (handle_func_t)dlsym(handle,"handle");
                                         if(!handle_function) { printf("dlsym %p failed!\n",handle); return -1; }
                  handle_function(100,&Callback);
 dlclose(handle);
 return 0;
  }

Conclusion

        Completed the preliminary test of RT thread OS external module call. External module call is very useful for embedded programs, perhaps because the external module function of RT thread makes me fall in love with RT thread.

Posted by Jay_Seagrave on Wed, 24 Nov 2021 08:19:01 -0800