免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2221 | 回复: 6
打印 上一主题 下一主题

[C++] 嵌入式平台c++比较棘手的问题!请各位大虾赐教! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-09-08 01:40 |只看该作者 |倒序浏览
个人状况:熟悉c语言,还算精通,c++大学学过,有一些基本概念,但是工作一年多没有使用过;

目前正在支援客户,开发中遇到如下问题:

1、客户的代码(middleware+app)全使用c++开发,我们自己的platform的代码(driver)使用c语言开发,c++&c编译及链接问题早已搞定。

2、大家知道elf格式,对嵌入式平台来说,elf格式的目标文件太大,我们必须通过
1)、使用objcopy部分section(比如.text,.rodata,)出来使用压缩工具(我们使用7-zip)压缩;
2)、ld里面写死某一部分库使用压缩工具压缩;
来构建flash image。

3、嵌入式系统一般都有bootloader,我们把整个flash image分为bootloader和system两部分,bootloader负责跳转到sdram或者jump到flash指定位置;

4、system中这部分压缩之后的code必须由bootloader解压缩到内存,或者先bootloader jump到系统的某一小段指定代码,让这部分代码去解压缩system中压缩的部分code;

因为一些历史原因,我们的做法是:
1、把客户的提供的所有库(middleware+app)全使用7-zip压缩;

2、system部分的code一部分未压缩(包括一部分汇编代码及main函数),一部分压缩;

3、bootloader jump到flash指定位置,该位置也即system部分的第一条指令位置;

4、platform上电后bootloader执行完自己的工作,然后jump到system部分位于flash第一条指令处,然后执行到main函数,在该函数里调用7-zip把压缩的部分代码(这部分代码是客户的c++编译后的代码)解压缩到sdram


碰见如下问题:
如果使用该方式,发现c++里面的构造函数没用。。。
MyObj::MyObj(int x, int y)
: m_x(x)
, m_y(y)
{
}

const MyObj my_obj(4,5);

总结问题:c++部分的代码全压缩,然后在系统上电后(这时候嵌入式操作系统已经跑进main函数)由main函数调用7-zip把c++部分解压缩到sdram。这时候class里面的构造函数没用(my_obj(4,5)并没有初始化m_x = 4; m_y = 5,而是m_x = 0; m_y = 0)
请问,问题出现在哪里?

[ 本帖最后由 dodolo0k 于 2009-9-8 01:50 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2009-09-08 08:54 |只看该作者
我只好像听说,在底层的开发(驱动),有很多C++的特性是不被支持的~~~~ 具体什么不是很清楚,也许LZ可以自己实现~~

论坛徽章:
0
3 [报告]
发表于 2009-09-08 13:17 |只看该作者
没看清楚你说的“跑到main函数再7zip解码”这个main函数到底是哪个main函数。

从一般的程序而言,main函数不是程序的起点,前面还有一堆crt的东东,负责调用c++的全局变量和静态变量的构造函数。

最好不要使用全局变量或者静态变量。或者变通一下,将全局变量和静态变量改成指针,
然后增加一个初始化函数和结束函数,在main()最开始和结束时调用,负责给各个全局指针new对象。

或者将程序改成动态链接库,然后模拟动态装载的方式,先调用_init()函数,然后再调用所需的入口函数。

论坛徽章:
0
4 [报告]
发表于 2009-09-08 14:53 |只看该作者

回复 #3 drangon 的帖子

我们使用eCos,在cyg_user_start()里面调用7zip解压缩c++的压缩代码到sdram
估计就是你说的这原因,因为c++的构造函数调用在cyg_user_start()之前,而c++部分的代码载入到SDRAM在cyg_user_start()之内

但又有一原因搞不懂:我们是把c++库的所有section都压缩了的(包括.ctors==>构造函数section),所有section都是在cyg_user_start()之内一起解压缩到SDRAM

论坛徽章:
0
5 [报告]
发表于 2009-09-08 17:00 |只看该作者
看不懂说的什么,但是如果正常的ram初始化好了,在跑这个程序,不会有任何问题的。

论坛徽章:
0
6 [报告]
发表于 2009-09-08 21:59 |只看该作者

回复 #4 dodolo0k 的帖子

不清楚cyg_user_start()的具体流程,感觉问题在于解压缩后,如何去启动程序,如果直接调用main()函数,估计是不行的,能否直接跳到_start标号那边执行?或者其他方法能够先执行一下各个全局变量的构造函数,具体可以看看crt里面相关函数。

论坛徽章:
0
7 [报告]
发表于 2009-09-08 23:41 |只看该作者
原帖由 drangon 于 2009-9-8 21:59 发表
不清楚cyg_user_start()的具体流程,感觉问题在于解压缩后,如何去启动程序,如果直接调用main()函数,估计是不行的,能否直接跳到_start标号那边执行?或者其他方法能够先执行一下各个全局变量的构造函数,具体 ...

不知道红色部分怎么去做。。。
现在总结原因估计是:eCos本生都是由c++写的,ecos的cyg_user_start()函数可以理解为我们在pc上写程序的main(),实际上是在进入cyg_user_start()时候,那些全局class的构造函数都已经被执行,不然eCos内核都跑不起来!而我们在cyg_user_start()之中才去把客户的c++库(.ctors也在压缩包内)解压到SDRAM中,已经错过了c++调用构造函数初始化全局class的时间!!!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP