移植EKF代码后,仿真硬件错误中断

STM32在移植EKF代码后  ,编译没有问题,仿真的时候出现 硬件错误中断:

void HardFault_Handler(void)
{
  /* USER CODE BEGIN HardFault_IRQn 0 */

  /* USER CODE END HardFault_IRQn 0 */
  while (1)
  {
    /* USER CODE BEGIN W1_HardFault_IRQn 0 */
    /* USER CODE END W1_HardFault_IRQn 0 */
  }
}

查了网上的论坛,得到以下两个原因:STM32出现HardFault_Handler故障的原因主要有两个方面:

1、内存溢出或者访问越界。这个需要自己写程序的时候规范代码,遇到了需要慢慢排查。

2、堆栈溢出。增加堆栈的大小。

 

移植的EKF部分代码:

void attitudeKalmanfilter(const uint8_T updateVect[3], real32_T dt, const
  real32_T z[9], const real32_T x_aposteriori_k[12], const real32_T
  P_aposteriori_k[144], const real32_T q[12], real32_T r[9], real32_T
  eulerAngles[3], real32_T Rot_matrix[9], real32_T x_aposteriori[12], real32_T
  P_aposteriori[144])
{
	memset(wak,0,sizeof(wak));
	memset(b_A_lin,0,sizeof(b_A_lin));
	memset(b_q,0,sizeof(b_q));
	memset(c_A_lin,0,sizeof(c_A_lin));
	memset(d_A_lin,0,sizeof(d_A_lin));
	memset(e_A_lin,0,sizeof(e_A_lin));
	memset(b_P_apriori,0,sizeof(b_P_apriori));
	memset(K_k,0,sizeof(K_k));
	
  real32_T O[9];
  real_T dv0[9];
  real32_T a[9];
  int32_T i;
  real32_T b_a[9];
  real32_T x_n_b[3];
  real32_T b_x_aposteriori_k[3];
  real32_T z_n_b[3];
  real32_T c_a[3];
  real32_T d_a[3];
  int32_T i0;
  real32_T x_apriori[12];
  real_T dv1[144];
  real32_T A_lin[144];
  static const int8_T iv0[36] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0,
    0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

//  real32_T b_A_lin[144];
//  real32_T b_q[144];
//  real32_T c_A_lin[144];
//  real32_T d_A_lin[144];
//  real32_T e_A_lin[144];
  int32_T i1;
  real32_T P_apriori[144];
//  real32_T b_P_apriori[108];
  static const int8_T iv1[108] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };

//  real32_T K_k[108];
  real32_T fv0[81];
  static const int8_T iv2[108] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 };

  real32_T b_r[81];
  real32_T fv1[81];
  real32_T f0;
  real32_T c_P_apriori[36];
  static const int8_T iv3[36] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

  real32_T fv2[36];
  static const int8_T iv4[36] = { 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

  real32_T c_r[9];
  real32_T b_K_k[36];
  real32_T d_P_apriori[72];
  static const int8_T iv5[72] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    1, 0, 0, 0 };

  real32_T c_K_k[72];
  static const int8_T iv6[72] = { 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
    0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0 };

  real32_T b_z[6];
  static const int8_T iv7[72] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 1 };

  static const int8_T iv8[72] = { 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
    0, 0, 0, 1 };

  real32_T fv3[6];
  real32_T c_z[6];

  /*  Extended Attitude Kalmanfilter */
  /*  */
  /*  state vector x has the following entries [ax,ay,az||mx,my,mz||wox,woy,woz||wx,wy,wz]' */
  /*  measurement vector z has the following entries [ax,ay,az||mx,my,mz||wmx,wmy,wmz]' */
  /*  knownConst has the following entries [PrvaA,PrvarM,PrvarWO,PrvarW||MsvarA,MsvarM,MsvarW] */
  /*  */
  /*  [x_aposteriori,P_aposteriori] = AttKalman(dt,z_k,x_aposteriori_k,P_aposteriori_k,knownConst) */
  /*  */
  /*  Example.... */
  /*  */
  /*  $Author: Tobias Naegeli $    $Date: 2012 $    $Revision: 1 $ */
  /* coder.varsize('udpIndVect', [9,1], [1,0]) */
  /* udpIndVect=find(updVect); */
  /* process and measurement noise covariance matrix */
  /* Q = diag(q.^2*dt); */
  /* observation matrix */
  /* 'attitudeKalmanfilter:33' wx=  x_aposteriori_k(1); */
  /* 'attitudeKalmanfilter:34' wy=  x_aposteriori_k(2); */
  /* 'attitudeKalmanfilter:35' wz=  x_aposteriori_k(3); */
  /* 'attitudeKalmanfilter:37' wax=  x_aposteriori_k(4); */
  /* 'attitudeKalmanfilter:38' way=  x_aposteriori_k(5); */
  /* 'attitudeKalmanfilter:39' waz=  x_aposteriori_k(6); */
  /* 'attitudeKalmanfilter:41' zex=  x_aposteriori_k(7); */
  /* 'attitudeKalmanfilter:42' zey=  x_aposteriori_k(8); */
  /* 'attitudeKalmanfilter:43' zez=  x_aposteriori_k(9); */
  /* 'attitudeKalmanfilter:45' mux=  x_aposteriori_k(10); */
  /* 'attitudeKalmanfilter:46' muy=  x_aposteriori_k(11); */
  /* 'attitudeKalmanfilter:47' muz=  x_aposteriori_k(12); */
  /* % prediction section */
  /* body angular accelerations */
  /* 'attitudeKalmanfilter:51' wak =[wax;way;waz]; */
  wak[0] = x_aposteriori_k[3];
  wak[1] = x_aposteriori_k[4];
  wak[2] = x_aposteriori_k[5];
//  wak[0] = 0;
//  wak[1] = 0;
//  wak[2] = 0;
//return;

  /* body angular rates */
  /* 'attitudeKalmanfilter:54' wk =[wx;  wy; wz] + dt*wak; */
  /* derivative of the prediction rotation matrix */
  /* 'attitudeKalmanfilter:57' O=[0,-wz,wy;wz,0,-wx;-wy,wx,0]'; */
  O[0] = 0.0F;
  O[1] = -x_aposteriori_k[2];
  O[2] = x_aposteriori_k[1];
  O[3] = x_aposteriori_k[2];
  O[4] = 0.0F;
  O[5] = -x_aposteriori_k[0];
  O[6] = -x_aposteriori_k[1];
  O[7] = x_aposteriori_k[0];
  O[8] = 0.0F;

 

通过观察仿真时候的汇编代码,我发现每次都是在 执行下面的语句时候出现错误中断:

wak[0] = x_aposteriori_k[3];
  wak[1] = x_aposteriori_k[4];

对应的汇编代码:

汇编不是很熟悉,大致映像中的意识是:

0x08004F7E ED950A03  VLDR          s0,[r5,#0x0C]  //把r5寄存器中的地址加上0XC得到新的地址,将新的地址中的内容赋值给S0
0x08004F82 ED870A00  VSTR          s0,[r7,#0x00]  //把s0内容数据,放到   (r7+0x00)这个地址中,r7寄存器中放的是一个地址
   209:   wak[1] = x_aposteriori_k[4]; 
0x08004F86 ED950A04  VLDR          s0,[r5,#0x10]
0x08004F8A ED870A01  VSTR          s0,[r7,#0x04]

LDR :表示从存储器装入寄存器里面

STR:表示寄存器数据送入存储器

接下来,我把函数代码提前return,如下面。发现不再进入中断

  wak[0] = x_aposteriori_k[3];
  wak[1] = x_aposteriori_k[4];
  wak[2] = x_aposteriori_k[5];

//return;

这时候推测:堆栈溢出?通过将attitudeKalmanfilter函数中的局部变量提升为全局变量,发现也不会进入错误中断。因此,在STM32中写程序的时候,局部变量太大,可能会导致堆栈溢出

 

 

 

给自己留给作业。为什么会溢出呢?不应该在编译的时候,就会把堆栈空间大小准备好吗?还是只是给了一个地址而已呢?后面接着实验:

把局部变量全部初始化定义,再看会不会进入错误中断,如果进入,那么说明编译的时候给的堆栈空间确实就是一个指针,没有安排空间大小;如果没有出现中断,那就是给了大小

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值