RT1052 rtthread 报错"FPU active!" "UNALIGNED"

2020-3-27 10:44 [复制链接] 6 36

本帖最后由 parkin 于 2020-3-27 10:49 编辑
7 f0 N' f4 ~, W; e9 J6 `( g, R3 d
问题:. ?/ [+ m$ J$ ]/ W& x& i
    RT1052 rtthread 报错"FPU active!" "UNALIGNED"
3 O. Z, ?3 t: J. d( G/ ~+ ~. E- _; w9 L4 Z2 ?4 ~3 k3 w
开发环境:6 G# k7 Z8 x* B; S' k8 |! |
    RT-Thread: v4.0.2(master)
( V  g7 {6 }9 j    SOC: i.MX RT1050
) I# f' ~: q  u; @: ~! L9 Q& s    Board: 野火 RT1052
* A7 w  `, ?3 A& d
问题背景:
' d$ ], f% f0 e0 |3 v    我创建了一个线程去解析UDP数据, 而数据形式是我定义好的一个结构体的形式, 我使用结构体指针去取对应的值, 取前面的值都可以, 但取到float类型的成员时, 程序崩溃, 报如下错误:7 w1 K1 j3 F( M$ u& ~( e1 m

error

error
使用到的结构体:
  1. typedef struct
    " V9 a% C' N- M. _- v- A: z
  2. {7 l) s6 N' N; n0 [# ^
  3.     unsigned char protocol_flag;
    7 |3 o) m; [) K( c1 R9 t: \
  4.     unsigned char protocol_version;
      L( Y' U5 z3 p( t/ z2 ~' _
  5.     unsigned char direction;0 L! Z6 W+ g9 y6 P! i- L
  6.     unsigned char cmd;7 e) Y+ P( k( V/ X+ X
  7.     unsigned int len;
    ) [  i+ C2 |) P, R) F
  8. } UdpProtocolHead;6 i2 E  t* n1 p$ |3 M3 E. A7 o% P
  9. % i8 ?( k: b- s! I7 O: q
  10. typedef struct+ U1 ]  a7 B* Q; F7 k
  11. {4 d- T6 I' a1 u- S' r
  12.     UdpProtocolHead head;  r5 T0 h# d4 {9 }' E3 b1 R
  13.     unsigned int data1;
    2 ^/ Y1 W6 r) l; P8 F" e
  14.     unsigned int data2;
    8 q' x- ~. `  w  q2 p8 |
  15.     unsigned int data3;
      j+ U% E, r; O8 b% D" @$ A: U
  16.     unsigned int data4;8 ^+ i; R, }4 V. V, O
  17.     float data5;7 H# v: J8 ?, K' J' b
  18.     float data6;& i5 M% a3 S  L1 h+ T0 Y* k
  19. } UdpProtocolData;
复制代码
0 @6 e% E% k5 ~. M& X
9 y  H" |. O" n: |" m
问题代码:
1 G, l, `. K: B& U, }, Z% t% S
  1. int8_t handle_data_tophalf(uint8_t* data, uint32_t len, struct sockaddr_in* client_addr){* K+ j  \( n& a4 U6 g  i; [
  2.     UdpProtocolData* data = (UdpProtocolData*)data;
      W' t, @5 }6 g# B) d8 I
  3.    
    ) O6 d. c' [3 @$ X' X
  4.     uint8_t* p = (uint8_t*)&data->data5;
    - m( }! M9 S% O
  5.     printf("data5: %x %x %x %x\r\n", p[0], p[1], p[2], p[3]);
    . ]( q0 j  a2 K* s$ A
  6.     printf("data5: %f\r\n", data->data5);
    3 V; ~# E6 i* @+ o; c* g7 l  O) F1 v
  7.     p = (uint8_t*)&data->fy;
    ' l6 R& d4 v, d$ |6 f6 x
  8.     printf("data6: %x %x %x %x\r\n", p[0], p[1], p[2], p[3]);1 t% l* X9 d( D* p" y9 l
  9.     printf("data6: %f\r\n", data->data6);1 i' Z2 Q! r6 h5 G5 C- O
  10. }
复制代码
% C4 }3 l9 N  e/ a3 E

$ X( r+ s# `: y2 m
问题自测:

$ z& N, N1 G% q5 k& h5 e
    我在main中编写了自测代码来模拟现场, 运行正常, 代码如下:
char data2[] = {0xff, 0x01, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
                    , 0x00, 0x00, 0x00, 0x20, 0x10, 0x20, 0x2d, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x3f};
uint8_t* p2 = rt_malloc(sizeof(data2));
memcpy(p2, data2, sizeof(data2));
UdpProtocolData* pdata = (UdpProtocolData*)p2;
printf("head: %x %x %x %x %d\r\n", pdata->head.protocol_flag, pdata->head.protocol_version
                                 , pdata->head.direction, pdata->head.cmd, pdata->head.len);
printf("head: %x %x %x %x\r\n", pdata->data_type, pdata->data_index, pdata->timestamp_s, pdata->timestamp_ns);
printf("data: %f %f\r\n", pdata->fy, pdata->fx);
4 e$ c7 k! m, ^' @, R
(提供一个网站错误: 以上代码无法插入为代码格式)
运行结果如下:
( M, t8 y, X; M% |
  1. head: ff 1 0 10 32
    . ]* N2 X2 g! p; l, g8 o
  2. head: 0 0 0 2d2010205 D- \9 a$ @( ?+ |4 z
  3. data: 2.000000 1.000000
复制代码

' z$ s" P2 s' C9 v) c+ |/ ]$ {
4 W0 U/ f6 h# q9 o+ @" `2 p8 |

2 M) U0 G% [6 m. T
% h; L5 m/ J# r0 r
使用道具 举报 显示全部楼层 回复
最新评论 | 正序浏览
显示全部楼层 |楼层直达:
发表于 2020-3-27 11:26:50 | 显示全部楼层
自顶, 勿沉
使用道具 举报 回复
发表于 2020-3-27 11:49:00 | 显示全部楼层
类型强转必然出错,还要留意对齐和填充问题。
使用道具 举报 回复
发表于 2020-3-27 14:08:23 | 显示全部楼层
aozima 发表于 2020-3-27 11:49
9 \( I  N7 f: K- @$ \$ Q类型强转必然出错,还要留意对齐和填充问题。

6 d/ l" ?1 \: J; v& A上面的类型强转是能够输出的, 反而是本来类型是float, 而无法使用和输出
使用道具 举报 回复
发表于 2020-3-27 14:30:20 | 显示全部楼层
本帖最后由 aozima 于 2020-3-27 14:32 编辑
0 w' K! L% b& [( O8 [+ t$ @& O1 P9 T  g& ~
data地址是多少?
8 D! \& X, E5 T# g1 @data->data6 地址多少?' Q# g: @# ?: {5 P% l

: k8 S! h+ ^1 `6 }5 K7 efloat 要求地址对齐到4字节。* ~1 q  z5 L8 T( y# F% r
使用道具 举报 回复
发表于 2020-3-27 15:43:19 | 显示全部楼层
aozima 发表于 2020-3-27 14:30
6 U' L$ _6 a0 j  b: S( W( ^data地址是多少?& o7 W1 o3 t9 h, ]3 A
data->data6 地址多少?
5 L( _+ O$ m; v3 l& i
你好, 谢谢你提示, 正是你说的字节对齐问题, 这个问题是因为全局变量定义的是 uint32_t 的数据类型, 而该数组地址非四字节对齐, 在使用中强转为结构体指针, 再引用float成员导致字节未对齐问题, 打印查看到 float成员地址也非四字节对齐. 在此感谢你的回复. 同时又产生了新的疑问:
/ g$ J1 t' _0 @) P, ^; O   int 类型为什么没有出错, 而float却出错了呢? 是float有什么特殊要求吗?能否给出具体的依据.谢谢!
使用道具 举报 回复
发表于 2020-3-27 16:16:03 | 显示全部楼层
去看反汇编指令,/ l5 Y2 {1 [: x1 t1 I! K: p  A0 d2 K3 L
去单步调试,看地址,看寄存器。
  ?2 O4 r1 R- ]去查arm手册(M系列支持一定程度的非对齐访问,但STM/LDM不能)
使用道具 举报 回复
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  1. 4 主题
  2. 74 帖子
  3. 74 积分

Ta的主页 发消息

Archiver|手机版|小黑屋|RT-Thread开发者社区 ( 沪ICP备13014002号-1

有害信息举报电话:021-31165890 手机:18930558079

© 2006-2019 上海睿赛德电子科技有限公司

Powered by RT-Thread

快速回复 返回顶部 返回列表