开发指导
接口说明
表 1 功能列表
开发流程
- 利用arm-none-eabi-gcc交叉编译器编译共享库并制作FAT或LittleFS文件系统格式镜像烧写至flash中;
- 在target_config.h文件中定义宏LOSCFG_DYNLINK为1使能动态加载模块;
- 调用LOS_SoLoad接口加载指定路径下的共享库;
- 调用LOS_FindSym接口查找指定符号,获取符号地址;
- 调用LOS_SoUnload卸载指定共享库句柄。
说明:
- 利用交叉编译器编译共享库所需要的编译选项参考ELF支持规格一节。
- 制作文件系统镜像之前需要对特定单板适配FAT或LittleFS文件系统。
- 共享库不依赖编译器中的libc库,不支持c++。
- 共享库只能依赖内核提供的接口,不能依赖其他共享库。
编程实例
实例以cortex-m4单板为例。
-
共享库示例代码及编译
示例代码主要测试全局符号间的调用功能以及对内核接口maloc、free、memset接口的调用功能。
#include <stdlib.h> #include <string.h> int g_param = 10; int callee(int a, int b) { char *addr = malloc(g_param); if (addr == NULL) { return 0; } memset(addr, '1', g_param); free(addr); return a + b + g_param; } int caller(int a, int b) { return callee(a, b); }
$ arm-none-eabi-gcc -fPIC -shared -mcpu=cortex-m4 -nostdlib -nostartfiles -z max-page-size=4 -o test.so test.c
-
导出共享库中使用到的malloc、free、memset符号,下述代码单独编写成一个.c文件,参与OS编译即可。
#include "stdlib.h" #include "string.h" SYM_EXPORT(malloc); SYM_EXPORT(free); SYM_EXPORT(memset);
-
确定内核的编译环境,在对应编译器的编译链接脚本中添加如下语句,保证符号表信息在编译链接的时候输出到指定的段。
在IAR编译器.icf链接脚本中添加如下语句:
keep {section .TABLE.START}; keep {section .sym.*}; keep {section .table.end}; define block SYMBOL_TABLE with fixed order { section .TABLE.START, section .sym.*, section .table.end }; place in ROM_region {readonly, block SYMBOL_TABLE};
在gcc编译器的.ld链接脚本中添加如下语句:
__sym_table_start = .; KEEP(*( SORT (.sym.*))); __sym_table_end = .;
-
共享库加载链接、执行与卸载
示例代码主要测试LOS_SoLoad、LOS_FindSym、LOS_SoUnload接口的功能是否正常以及通过LOS_FindSym查找到的符号的调用是否正常。
#include "los_dynlink.h" VOID DynlinkTest(VOID) { VOID *handle = NULL; INT32 (*func)(INT32, INT32) = NULL; CHAR *symbolName = "caller"; CHAR *dsoName = "/lib/test.so"; INT32 ret; handle = (VOID *)LOS_SoLoad(dsoName, NULL); if (handle == NULL) { printf("Failed to load so\n"); return; } func = (INT32 (*)(INT32, INT32))LOS_FindSym(handle, symbolName); if (func == NULL) { printf("Failed to find symbol\n"); LOS_SoUnload(handle); return; } ret = func(1, 1); if (ret != 12) { printf("Failed to execute function\n"); LOS_SoUnload(handle); return; } ret = LOS_SoUnload(handle); if (ret != 0) { printf("Failed to unload so\n"); } printf("Success!\n"); }
-
结果验证
Success!
说明: 用例中文件系统路径为/lib/test.so; 可以创建一个任务,在任务中调用DynlinkTest接口进行测试;