打印
[STM32F1]

使用stm32 classb库时遇到的问题

[复制链接]
1075|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
whong0951|  楼主 | 2020-4-17 11:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 whong0951 于 2020-4-17 11:19 编辑

因为产品需要通过classb安全认证,所以这两天在把st的 X-CUBE-CLASSB库往工程里添加,因为我们产品使用的是stm105芯片,按照官网说明的
X-CUBE-CLASSB version 2.2.0 supports the STM32L0, STM32L1, STM32L4, STM32L4+, STM32F0, STM32F1, STM32F2, STM32F3, STM32F4 and STM32F7 Series

下载了2.2.0版本的库,移植后进行调试时遇到了一些奇怪的问题,我在这里汇总一下:
1.代码优化问题
我把库的源代码抽出有影响部分的放在下面
#define init_control_flow() CtrlFlowCntInv = ~(CtrlFlowCnt = 0uL)
#define control_flow_call(a) CtrlFlowCnt += (a)
#define control_flow_resume(a) CtrlFlowCntInv -= (a)

  /*--------------------------------------------------------------------------*/
  /*------------------- CPU registers and flags self test --------------------*/
  /*--------------------------------------------------------------------------*/

  /* Initialization of counters for control flow monitoring */
  init_control_flow();

control_flow_call(CPU_TEST_CALLER);
  /* WARNING: all registers destroyed when exiting this function (including
  preserved registers R4 to R11) while excluding stack pointer R13) */
  if (STL_StartUpCPUTest() != CPUTEST_SUCCESS)
  {
    #ifdef STL_VERBOSE_POR
      printf("Start-up CPU Test Failure\n\r");
    #endif /* STL_VERBOSE_POR */
   
    FailSafePOR();
  }
  else  /* CPU Test OK */
  {
   control_flow_resume(CPU_TEST_CALLER);
   
    #ifdef STL_VERBOSE_POR
      printf(" Start-up CPU Test OK\n\r");
    #endif /* STL_VERBOSE_POR */
  }
  
函数STL_StartUpCPUTest() 功能是直接对r0~r12寄存器赋值0~12再读回,确认寄存器没有问题,但是在函数返回时却没有将寄存器的值还原。在-O3优化下,在执行control_flow_call(CPU_TEST_CALLER);时会将CtrlFlowCntInv 的地址存入r4寄存器中,但是r4寄存器的值会在执行STL_StartUpCPUTest() 后发生改变,导致执行到control_flow_resume(CPU_TEST_CALLER);时会直接对地址0x0000 0004进行赋值操作,产生HardFault。


2.对函数的返回结果检查问题
在进行RAM测试时,程序
  
  /*--------------------------------------------------------------------------*/
  /* --------------------- Variable memory functional test -------------------*/
  /*--------------------------------------------------------------------------*/
  #ifdef STL_EVAL_MODE
    /* LED_VLM On for debug purposes */
    BSP_LED_On(LED_VLM);
  #endif /* STL_EVAL_MODE */
  
  /* no stack operation can be performed during the test */  
        __disable_irq();
  
  /* WARNING: Stack is zero-initialized when exiting from this routine */
  if (STL_FullRamMarchC(RAM_START, RAM_END, BCKGRND) != SUCCESS)
  {
    #ifdef STL_VERBOSE_POR
      /* restore interrupt capability */
      __enable_irq();
对函数STL_FullRamMarchC()的返回结果进行检查时没有使用自定义的枚举类型,而是文件“stm32f1x.h”中的枚举类型

typedef enum
{
  SUCCESS = 0U,
  ERROR = !SUCCESS
} ErrorStatus;
但是函数STL_FullRamMarchC()内的返回结果却是
STL_FullRamMarchC
  MOVS  R4, #0x1       ; Test success status by default

__FULL_ERR
  MOVS  R4,#0       ; error result

__FULL_RET
  MOVS  R0,R4
  BX    LR          ; return to the caller


与前面枚举结果的定义正好相反,导致检查成功时返回的却是错误的结果,令人疑惑的是这里if (STL_FullRamMarchC(RAM_START, RAM_END, BCKGRND) != SUCCESS)的处理方式与前文 if (STL_StartUpCPUTest() != CPUTEST_SUCCESS)并不一致,明明之前会使用自定义的枚举类型进行检查,到这里怎么又偷懒了?

很难理解一个用于安全认证的库会这么不严谨,我都开始怀疑它真的可以保证产品的安全性能么,还有就是这种安全认证库是否可以直接修改?修改后安全认证还有没有效果?




使用特权

评论回复
沙发
mmuuss586| | 2020-5-16 20:33 | 只看该作者

使用特权

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

本版积分规则

1

主题

2

帖子

0

粉丝