打印

如何在芯片内做一个动态库?

[复制链接]
3906|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
feifan570|  楼主 | 2009-4-20 10:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
需求是这样的:
    使用256K片内flash的ARM芯片,0-128K用于存放应用程序,打算在200K的地方存放一个动态库(实际上就是几个函数),并且这个动态库在应用中是需要修改。在应用程序中使用函数指针的形式来调用这个动态库的函数。
    现在有两个问题:
    1.我怎么知道这个动态库的每个函数的地址是多少?
    2.以后这个动态库每次修改重新编译,怎么确保这些动态库的每个函数地址都不变呢?
沙发
armecos| | 2009-4-21 10:10 | 只看该作者

《增值包》支持动态链接库,www.armecos.com

动态链接库的地址是浮动的,函数库一般是只读的,不能在运行过程中修改,如果要改变功能,你可以实现多个库,需要哪个加载哪个就成了。

1、通过函数名查找地址
2、地址肯定要变化,每次加载位置不同,修改后偏移也不同,不能假定地址不变,变是一定的。

****************************
* 嵌入式动态链接库技术浅谈 *
****************************
    2009/04/21  asdjf@163.com  www.armecos.com

    在VB、VC程序里使用DLL动态链接库,用户不必看到源码或者链接整个库就可以进行二次开发,现在,我想在嵌入式系统里实现类似功能,也能用DLL库的方式为我的用户提供二次开发产品,比如:在EASTARM2200/SMARTARM2200上能实现吗?

    很多《增值包》用户希望在自己的产品中实现动态链接库,动态地加载函数库,在运行时刻链接,方便用户二次开发,不用重新编译整个程序,只需编译改动部分,就能升级系统。如此美妙的功能,《增值包》可以实现吗?当然没有问题了!有了此项功能,你就可以象在Linux里那样,在命令行输入“./myprog”运行你硬盘上的应用程序了,输入不同的文件名运行不同的程序,支持多个程序并发哦。

----------------
动态链接库的好处
----------------
    动态链接库的好处可多了,例如:当你升级一个系统的时候,可以只升级一个模块,而不必升级整个系统。你可以把不同的模块放在不同的介质上,并实施不同等级的保护,例如存放在flash里进行写保护。

    有些系统允许用户进行二次开发,这个时候几乎一定是需要动态链接库的,因为你不希望用户需要链接整个系统才能够进行二次开发,而且你可能希望支持多个用户模块,彼此不相互依赖,彼此不相互干扰。用户程序和DLL库可以分别开发,运行时刻才链接到一起,修改更新升级DLL库,不用重新编译用户应用程序。其实,这样已经有组件化开发的雏形了,如果再符合接口调用标准,那就真的很象COM(组件对象模型)了。使用组件开发软件产品具有很多优点:
    1、组件易替换------在庞大复杂的企业级应用程序中,如果使用组件技术将程序分成一个个组件模块,在进行程序修改或版本升级时,就可以只修改或替换相关的组件,而不影响其他众多的程序组件。
    
    2、适应业务需求更改------软件的业务需求通常象流水一样不确定,开发期间和软件配置之后,新的需求会不断涌现。在组件软件中,可以将业务规则放在少数几个组件中。当业务规则发生改变时,只需要修改原组件或重建并发布新组件即可。更新是局部的,程序中出错的机会也就限制在这个局部,使程序的调试和测试更为方便。
    
    3、可实现二进制代码重用------组件之间可以在二进制级别上进行集成和重用,这样一来只需一次编写代码就可以到处使用(类似java)。例如:可以建立一个处理所有字符串函数的组件,任何应用程序都可以使用这个字符串处理组件。以后对这个组件进行任何纠正和修改,也不必改变使用这个组件的应用程序。
    
    4、有助于并行开发------一个大应用系统由许多组件组成,这些组件的实现可以并列进行。比如:应用可能包含一个字符串处理组件、一个计算组件和一个数据读取组件,这些组件可以同时建立,只要接口设计正确,则建立这些组件之后他们将能顺利配合。
    
    可以实现类似DOS/Linux那种命令行启动程序功能,在命令行输入“./myprog”就可以运行硬盘根目录上的myprog应用程序。
    
    动态链接库只在用到时才加载到内存,不需要时可以卸载,节省内存资源。
    
--------------------
动态链接库的使用方法
--------------------
    假设开发了一个动态链接库mylib,里面有一个foo函数,现在要求动态加载函数库mylib,并找到foo函数的地址,然后执行此函数。

    //从存储介质(硬盘/CF卡/SD卡/flash)上读取动态链接库文件
    err = mount( "", "/", "ramfs" );//挂装根目录到flash介质上
    fd = open("./mylib",O_RDONLY);//只读方式打开动态链接库文件mylib
    len = read(fd, libfoo, len);//读取动态链接库至内存,只有用到的库才加载到内存,以便节省资源。

    void *fooh = dlopenmem( libfoo, len, RTLD_NOW );//打开动态链接库libfoo

    vfn *foo = (vfn *)dlsym( fooh, "foo" );//从动态链接库里找到foo函数的地址
    
    if( foo )
    {
        CYG_TEST_INFO( "LoadFoo: foo() call" );
        
        foo();    //执行动态链接库里的foo函数
        
        CYG_TEST_INFO( "LoadFoo: foo() returned" );
    }
    else
    {
        CYG_TEST_FAIL_FINISH( "LoadFoo: foo() NULL!!!" );
    }
    
    现在你就可以用《增值包》开发动态链接库了,很简单吧!
    
    你可以一次开发若干版本的库,用户需要哪个版本就加载哪个版本,如果需要升级更新,只要向用户提供新的替代库即可,用户应用程序不必做任何改变。可以把库保存到各种介质上,如:硬盘、CF卡、SD卡、flash等,保存到flash上的库自然就有写保护功能喽。你可以把需要不同权限的库保存到不同介质上。用户不必看到源码或者链接整个库就可以进行二次开发,太方便了不是吗!

使用特权

评论回复
板凳
highend| | 2009-4-21 11:33 | 只看该作者

固定位置,放几个跳转

库改变后,修改这几个位置,就行了。

好像单片机的中断一样。

使用特权

评论回复
地板
armecos| | 2009-4-21 12:08 | 只看该作者

固定位置跳转是不成的,

    因为DLL库里的函数也调用了用户程序里的函数,比如:printf打印函数,而printf函数在系统库中实现,系统库和用户应用程序静态链接(即:在编译时链接),所以,DLL中的函数也需要知道用户程序中printf函数的地址。不光是用户程序调用DLL库中的函数,DLL库中的函数也需要调用用户程序中的函数,因此,调用是双向的,DLL库中的函数地址和用户程序中函数的地址都必须已知。
    
    使用软中断方式或者固定位置跳转只能实现用户程序调用DLL库中的函数,但是无法实现反向调用(DLL库中的函数调用用户程序中的函数)。

使用特权

评论回复
5
McuPlayer| | 2009-4-21 21:29 | 只看该作者

DLL要Relocation一下才行

使用特权

评论回复
6
highend| | 2009-4-22 09:35 | 只看该作者

DLL库中的函数调用用户程序中的函数

同样在固定位置,放一个列表。

使用特权

评论回复
7
feifan570|  楼主 | 2009-4-24 12:38 | 只看该作者

没想到这么复杂

我原以为直接用函数指针调用就可以了,没有想到动态库也需要调用应用程序。其实我需要做的这个动态库需要调用一些c库函数,例如:memcmp等等。
    那么我是否可以这样:我在编译动态库的时候,我把它需要的C库函数全部自己重写一下,并编译进这个动态库就可以解决了呢?
    采用动态库的目的就是想把经常需要更改动态库和应用分开,面对不同客户需求时,我只要烧写不同的库就可以了,而不需要重新编译整个程序。
    目前我用的uc/os的操作系统,如果更换ecos,那软件平台变化太大,很多东西要重新开始,所以不敢想。只能等以后有机会再使用了

使用特权

评论回复
8
lr2131| | 2018-5-21 09:23 | 只看该作者
没想到早就有人研究过这个,单片机的动态链接技术,确实是可以实现的。
1.需要知道动态链接库中每个函数的地址,只需要在生成的map文件中找到对应的函数首地址即可。
2.以后这个动态库每次修改重新编译,如果对代码不做任何限定,这些函数的新编译的首地址将有可能和之前的不一样。那么简单的方法,就是加上IDE提供的限制字,强制要求函数编译到某个固定地方。
但这一招并不总能解决问题,比如说,之前写的一个函数,变长了,你即使加限定字,它之后紧紧挨着的函数,首地址也一定要往后挪动。
真正彻底解决这个问题的方法是,需要借鉴windows/linux这种操作系统上dll/so文件的机制,说白了,就是在动态库的首部加上函数名和函数地址的列表信息,相当于做个二次映射。
原理我觉得这样一定是通的,但目前我也没有做动态库函数首地址变化的功能,基本上一开始做好了动态库,就不会再怎么去动它。业余试试再试试吧

使用特权

评论回复
9
sqqdfny| | 2018-6-5 21:40 | 只看该作者
没这么复杂,你想一下有些芯片带片上IAP库的,是怎么让你去调用的

使用特权

评论回复
10
qiledexin| | 2018-6-12 15:39 | 只看该作者
用函数指针来实现,如果还是不知道怎么解决的话,付费咨询

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

92

主题

195

帖子

1

粉丝