Kernel 配置
20 Dec 2024
Read time: 3 minute(s)
如需使用 Dynamic Module 功能,需要在内核中打开以下配置:
- 启用 POSIX 文件系统和
I/O:
Rt-Thread options ---> RT-Thread Components ---> C/C++ and POSIX layer ---> POSIX (Portable Operating System Interface) layer ---> [*] Enable POSIX file system and I/O
- 启用动态模块
API:
Rt-Thread options ---> RT-Thread Components ---> C/C++ and POSIX layer ---> POSIX (Portable Operating System Interface) layer ---> [*] Enable dynamic module APIs, dlopen()/dlsym()/dlclose() etc
-
如有需要,可以选择 dm-app 动态加载时使用的内存堆 (heap),否则可跳过此步。
具体的可选堆会随不同平台的配置有所不同:Rt-Thread options ---> RT-Thread Components ---> C/C++ and POSIX layer ---> POSIX (Portable Operating System Interface) layer ---> [*] Enable dynamic module APIs, dlopen()/dlsym()/dlclose() etc Select dynamic module use mem (Prsam CMA heap) ---> (X) Sys Heap ( ) Prsam CMA heap
符号导出
Kernel 中被 dm-app 访问到的符号需要使用 RTM_EXPORT() 宏来进行声明,类似 Linux 中的 EXPORT_SYMBOL() 宏。
- 对于一些标准的 C 库函数,dm-app 可以直接使用 Kernel 中已经定义好的 RTM_EXPORT()
声明,例如
luban-lite/kernel/rt-thread/components/libc/posix/libdl/dlsyms.c。
RTM_EXPORT(strcpy); RTM_EXPORT(strncpy); RTM_EXPORT(strlen); RTM_EXPORT(strcat); RTM_EXPORT(strstr); RTM_EXPORT(strchr); RTM_EXPORT(strcmp); RTM_EXPORT(strtol); RTM_EXPORT(strtoul); RTM_EXPORT(strncmp); ...
- 对于 RT-Thread API 函数,dm-app 可以直接使用 Kernel 中已经定义好的
RTM_EXPORT() 声明,例如
luban-lite/kernel/rt-thread/src/thread.c
RTM_EXPORT(rt_thread_create); RTM_EXPORT(rt_thread_yield); RTM_EXPORT(rt_thread_startup); RTM_EXPORT(rt_thread_detach); ...
-
用户可以使用下列命令查看当前系统中使用 RTM_EXPORT() 声明的符号:
list_symbols
系统输出结果示例如下:rt_critical_level=> 0x40013cc0 rt_exit_critical=> 0x40014090 rt_enter_critical=> 0x40013ce0 rt_device_set_tx_complete=> 0x40014220 rt_device_set_rx_indicate=> 0x40014200 rt_device_control=> 0x400141f0 rt_device_write=> 0x40014370 rt_device_read=> 0x40014330 rt_device_close=> 0x400143b0
重要:未使用 RTM_EXPORT() 声明的 Kernel 函数无法在 dm-app 中使用。如需在 dm-app 中使用自定义的 Kernel 函数,必须使用 RTM_EXPORT() 声明。
GCC low-level 函数的符号导出
在加载 dm-app 时,可能会遇到找不到某些 GCC low-level runtime library 中的函数符号的情况,如 __floatdidf 、 __umoddi3、__udivdi3、__fixdfdi。这些函数是 GCC 基础运算库的一部分,用于实现 CPU 原生硬件指令无法完成的操作。例如,在 32bit 系统中实现 64bit (long long) 类型数据的除法,GCC 就会自动调用软件函数 __umoddi3 来实现。具体原理可以参考The GCC low-level runtime library。
执行以下操作步骤,可解决这种问题:
-
使用以下命令,在工具链中找出函数的原型声明:
grep -r -A1 __umoddi3 luban-lite/toolchain/
toolchain/share/info/gccint.info: -- Runtime Function: unsigned long __umoddi3 (unsigned long A, toolchain/share/info/gccint.info- unsigned long B)
-
在 Kernel 中使用 RTM_EXPORT() 给函数加上符号导出声明:
extern unsigned long __umoddi3 (unsigned long a, unsigned long b); RTM_EXPORT(__umoddi3); extern unsigned long __udivdi3 (unsigned long a, unsigned long b); RTM_EXPORT(__udivdi3); extern double __floatdidf (long i); RTM_EXPORT(__floatdidf); extern long __fixdfdi (double a); RTM_EXPORT(__fixdfdi);