2017年6月14日星期三

NUCLEO-L496ZG防火墙 - 可执行的易失性数据段

STM32L496ZG微控制器提供了防火墙的功能,用于保护FLASHSRAM中的代码或数据。STM32CubeL4提供了两个使用防火墙功能的示例,FIREWALL_VolatileData_ExecutableFIREWALL_VolatileData_Shared。本文主要结合FIREWALL_VolatileData_Executable示例简单介绍防火墙功能的使用方法。

HAL提供的示例主要介绍了如何使用防火墙来保护定义为可执行的易失性数据段。易失性数据段存储在SRAM1中。在防火墙初始化示例中,受保护的易失性数据段是定义为非共享的,以便在防火墙关闭时不受保护的代码时无法访问。

防火墙初始化的一般步骤如下:
1.       配置RCC,使能防火墙模块的时钟;
2.       配置RCC,使能系统配置寄存器的时钟;
3.       设置每个段的起始地址和长度(CSSACSLNVDSSANVDSLVDSSAVDSL寄存器);
4.       设置防火墙的配置寄存器(FW_CR寄存器);
5.       启用防火墙,清除系统配置寄存器中的FWDIS位。

系统配置寄存器
该寄存器连接到APB2总线上,向APB2外设时钟使能寄存器RCC_APB2ENRSYSCFGEN位置1,可以打开系统配置寄存器的时钟。系统配置寄存器(SYSCFG_CFGR1)中的FWDIS位控制防火墙保护功能的使能和禁止,所以需要使能该寄存器。默认情况下是禁止使用防火墙。HAL提供了API函数:__HAL_RCC_SYSCFG_CLK_ENABLE();


防火墙功能配置
HAL提供了防火墙功能配置的API函数:HAL_FIREWALL_Config。该函数主要有三个功能:使能防火墙时钟、配置各段(代码段、易失性数据段和非易失性数据段)的起始地址和长度、配置FW_CR寄存器。
●   使能防火墙时钟
防火墙连接在APB2总线上,地址为0x4001 1C00 - 0x4001 1FFF。向RCC_APB2ENR寄存器的FWEN位置1,使能防火墙时钟。HAL同样提供了一个API函数:__HAL_RCC_FIREWALL_CLK_ENABLE
●   各段的起始地址和长度
HAL中的FIREWALL_InitTypeDef结构体保存着各段的信息。本示例演示的是易失性数据段,因此代码段和非易失性的起始地址和长度都设置为0,易失性数据段的起始地址为0x2000F100,段长为0xF00
●   配置FW_CR寄存器
FW_CR寄存器可以设置易失性数据段的共享性和可执行性。本示例设置为可执行的,并且是非共享的。
  1.     /* No protected code segment (length set to 0) */   
  2.     fw_init.CodeSegmentStartAddress      = 0x0;
  3.     fw_init.CodeSegmentLength            = 0;
  4.     
  5.     /* No protected non-volatile data segment (length set to 0) */   
  6.     fw_init.NonVDataSegmentStartAddress = 0x0;
  7.     fw_init.NonVDataSegmentLength       = 0;
  8.     
  9.     /* Protected volatile data segment (in SRAM1 memory) start address and length */   
  10.     fw_init.VDataSegmentStartAddress    = 0x2000F100;
  11.     fw_init.VDataSegmentLength          = 3840; /* 0xF00 bytes */  
  12.     
  13.     /* The protected volatile data segment can be executed */  
  14.     fw_init.VolatileDataExecution       = FIREWALL_VOLATILEDATA_EXECUTABLE;
  15.     
  16.     /* The protected volatile data segment is not shared with non-protected
  17.       application code */    
  18.     fw_init.VolatileDataShared          = FIREWALL_VOLATILEDATA_NOT_SHARED;
  19.     
  20.     /* Firewall configuration */
  21.     if (HAL_FIREWALL_Config(&fw_init) != HAL_OK)
  22.     {
  23.       Error_Handler();
  24.     }  
复制代码

实验代码
代码的分布通过分散加载文件实现。可执行的易失性数据段位于0x2000F104处,保护的易失性数据段位于0x2000FE00处。当调用vdata_protected_function()函数时,程序进入到可执行的易失性数据段,按照“call gate”序列打开防火墙。退出该函数时,关闭防火墙。
  1.     /* In the example, the protected function processes
  2.        non-protected input data and outputs an internal computation result. 
  3.        For demonstration purposes, vdata_protected_function() accesses as well
  4.        data located in the protected volatile data segment. 
  5.        vdata_protected_function() itself ensures that FPA bit is set
  6.        before exiting the protected area.
  7.        */ 
  8.      
  9.     vdata_function_output = vdata_protected_function(unprotected_vdata); 
  10.     
  11.     /* The Firewall is now closed again. */
  12.         
  13.     /* Check that the output is that expected */
  14.     if (vdata_function_output != expected_vdata_function_output_1)
  15.     {
  16.       /* Processing issue, log it in filling up RTC back-up register BKP0R 
  17.          with 0x2, then exit in Error */  
  18.       WRITE_REG( RTC->BKP0R, 0x2 ); 
  19.       Error_Handler();
  20.     }
复制代码

如果返回的计算结果符合预期,则LED1指示灯常亮。
如果vdata_protected_function退出时未置位FPA,则会触发系统复位,LED1指示灯闪烁。

参考资料
1. STM32L4x6系列用户手册RM0351:https://www.yiboard.com/thread-720-1-1.html

没有评论:

发表评论