你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

SWstm32 转换c项目到c++,补遗

[复制链接]
hi201803 发布时间:2018-3-14 00:57
本帖最后由 hi201803 于 2018-3-19 21:44 编辑 " w8 Z" N9 J* b1 ^7 n

" m' j: E( D/ E: S, n& I6 w- i7 e版本:   SWstm32 V2.4* z9 z( b4 B0 @3 E& ?" z; ~
现象: 使用stm32cubeMX 生成 代码, 然后再 SWstm32 中转换成 c++ 项目。 c++虚函数执行 出错。
3 y. ]7 b: b% q/ g9 ?* o8 j7 ^4 M1 z       下面的代码,  无法正确运行:( 在keil 中可正确运行 ). 代码只是示例,非实际项目中遇错代码.
" F2 R% V& D1 i* V' ^9 y
% u# @. U# ^" a3 E* A. fclass  class_11 G$ @. e1 B- T# D
{' F/ K% j; P: T, [  [9 L- o
public:/ q& l% }% U( H( h# z
    int a, b;8 v* ]( X0 f" v; j: ~
     virtual void send ( int , char*) =0;
& Y+ f0 J% D8 |$ Q( I8 ^     void fun( int  i1 , char* cs1) {  send (i1,cs1); };8 E) i3 K4 t0 \9 p0 N4 F) P
};
# A! c& ?$ f1 f" ]5 @# eclass  class_2 :  public class_1
0 V0 B( f# M# I# l5 r{8 Q% ^" L  t! m- o& \5 }
public:
7 X* V; u  O. x$ o+ H/ C* ^/ B: ^    int a1, b1;3 u. g5 C- Y2 G0 `4 k- I
     virtual void send ( int , char*)  {     } ;
+ @  p( r4 @0 H1 R' t. V}  aclass;
9 V% h$ s3 x0 [
/ B4 g' H' k% u; q- V1 Jextern "C" void fun1(void);" l6 g" n" {3 l6 `( f7 p3 A/ v% b! P
void fun1(void)
  |' Z9 l# D. ^  a. }( u0 n{
6 |. S0 U* X6 o2 O6 s+ @$ X' y    int i=1;
+ `9 F4 d0 `5 d    char cs[8];* P0 N7 ^1 K7 D5 U* y: s' J1 h: G9 n
   aclass.fun( 1, cs);   //  函数fun  调用class_1::send , 应该变成调用 class_2:: send。 但调用一个莫名其妙的地址了.最后导致异常中断.+ h0 z. i6 C2 B$ y0 Y) L6 P5 a/ R
}   8 ?$ g; a! q, C* y. `
====2018/03/14  增加:   测试以上代码  ==================================
: |8 x2 o' Z* Q' C# o' `2 }2 ]
/ g1 f) I# q& M1 B: t// 上面橙黄色代码是添加的,为了使编译通过. 不影响测试.# N3 q* M  h, X
// 然后再 main 函数中调用 fun1.
* b) }; p% |' |# P% }2 I" o- Cextern void fun1(void);
) w2 D! k; w3 V' P2 w. L0 B: bvoid main(void)9 q6 L  K3 j1 x4 R" N5 D
{( L0 ?& W0 N7 ]% ]
   fun1( );
: \8 y5 `) Q# p" C: o3 T3 G1 R  while(1);
1 {8 v4 L( O8 ?5 g; c}. k* ^/ w8 k# j& t/ a: }
测试结果:  
; u* N+ s5 n# E  B* s9 l  I   1.  使用stm32cubeMX 生成 代码, 然后再 SWstm32 中转换成 c++ 项目,添加以上代码, 测试不通过 !!!! 。. N" \0 I& [0 r* [2 Y. }0 X# v
   2.  如果直接使用 swstm32 生成 C++ 程序, 添加以上代码, 测试通过 !!!!!! 。-: h* M4 ^' a5 x5 x7 E; D
-
) P- e, m) l6 r8 A* v" @====2018/03/15  增加:  原因  ===================================8 C* X) B7 w6 T9 @$ P* n
原因:      SWstm32 把 c 项目转化为 c++ 时, 没有修改启动代码,全局变量 的类实例 没有初始化,类实例指向虚表的指针不正确。 ' ^" R* L3 E6 f5 C* c6 e
解决办法 1 :  在初始化代码中, 调用 main 函数之前, 执行:  bl __libc_init_array' j! O: M6 c4 N7 g
解决办法 2 : 直接拷贝 使用 swstm32 生成 C++ 项目的初始化代码, 替换原启动代码。
2 f1 }8 i$ M9 j; `. c* K
: O$ d+ K5 j( q! H1 ~# m+ {
: [6 Z* \* D+ `; i, Y' H' E$ O* ~
, h- ]* i& j, A8 V8 d! u
. p* A+ e2 I# p* Z8 [
( g, i' ]4 B$ @* C/ n
* b7 b& ]6 H4 K+ f
ac6版本.jpg
赞 收藏 1 评论7 发布时间:2018-3-14 00:57

举报

7个回答
maxtch 回答时间:2018-3-14 05:51:42
vtable 在数据段里面吗?
Mandelbrot_Set 回答时间:2018-3-14 09:26:08
示例代码vs2015编译不过。。。
hi201803 回答时间:2018-3-14 16:05:37
本帖最后由 hi201803 于 2018-3-20 13:54 编辑 * b' U+ y5 X& x+ T
Mandelbrot_Set 发表于 2018-3-14 09:26) g& y) ~8 w: b& r- O: ]$ I
示例代码vs2015编译不过。。。

/ B% Q8 @, p; K! I+ k7 Z我又测试了代码, 在swstm32 的开发环境中测试的。
0 }5 f( t4 |' R0 u8 b# w在一楼中添加了测试结果。
hi201803 回答时间:2018-3-14 17:14:50
maxtch 发表于 2018-3-14 05:51- f  S' Z* A( U- [$ q- x
vtable 在数据段里面吗?
+ g9 k+ Q# L1 G9 i. ~. ~) u
奇怪,
4 J1 p9 O3 H. H' x+ Ac转换成c++项目中, 在map文件里面只看到 class_2 的虚表, 没有class_1的虚表。 运行不正常.
1 r& ^0 r0 k. D5 T+ B" z3 z' ~) S但  直接使用SWStm32 生成的项目中, map文件里面看到 class_1, 和class_2 的虚表, 运行正常.
7 Z$ f* N( E# ]% {* I1 e1 _) `5 Z/ t, ]- w/ E
我对比两项目的c++ 编译,连接,及 链接文件, 居然没发现明显的不一样。 真是奇怪。
maxtch 回答时间:2018-3-14 21:00:51
hi201803 发表于 2018-3-14 17:14
0 V$ t& A1 |- Z# V6 K) o3 y4 u( q奇怪,
) t/ y5 ]- N- nc转换成c++项目中, 在map文件里面只看到 class_2 的虚表, 没有class_1的虚表。 运行不正常.
) ]( L9 g4 o7 _但  ...

& B# z9 k) n0 E. l3 b6 L+ a! W8 ~把两个链接脚本文件 diff 一下,某处细节肯定有差异。还有,可以尝试一下替换 GCC,用 Arm 打包的 GCC 7.2 换下 Ac6 的版本。
hi201803 回答时间:2018-3-14 22:33:26
maxtch 发表于 2018-3-14 21:00# B- s' A% w( {1 D) R7 C
把两个链接脚本文件 diff 一下,某处细节肯定有差异。还有,可以尝试一下替换 GCC,用 Arm 打包的 GCC 7. ...

( P3 v6 e/ V- \* ^2 o. ~' N7 s
" V& I' G( w9 Z" c把链接脚本文件 都弄成一样的了,还是不行。 " P2 t- |2 A2 H$ y' O  ~
hi201803 回答时间:2018-3-15 22:46:00
maxtch 发表于 2018-3-14 21:00
& S! z$ @3 t4 z5 v$ x把两个链接脚本文件 diff 一下,某处细节肯定有差异。还有,可以尝试一下替换 GCC,用 Arm 打包的 GCC 7. ...

) p. D0 N; k9 v9 j5 D) T/ k. N' I原因找到了:  
1 p; Y2 m0 n) O% P7 m7 S% O启动代码没有调用 全局变量 类实例 的初始化函数,造成类实例指向虚表的指针不正确.
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版