打印
[应用相关]

AT32F423系列安全库区应用笔记

[复制链接]
1007|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 muyichuan2012 于 2023-4-27 14:19 编辑

AT32F423系列安全库区应用笔记



前言
这篇应用笔记主要在阐述AT32F423系列安全库区的应用原理、软件使用方法及范例程序。
支持型号 AT32F423
目录
概述 .............................................................. 7
应用原理 ................................................................... 8
安全库区的应用原理 ......................................... 8
如何启动安全库区保护 ........................................ 9
如何解除安全库区保护 .................................. 10
编排及执行安全库区的程序 ............................. 10
不可将中断向量表设置为安全库区的指令区 ........ 11
安全库区代码与用户区代码的关联性 ................... 11
安全库区范例程序 ................................... 14
范例需求 ............................................... 14
硬件需求 ..................................................... 14
软件需求 ................................................. 14
范例概述 .................................................... 14
安全库区保护的代码:FIR 低通滤波器 .......... 15
Project_L0:方案商范例 ............................ 15
产生只执行(Execute-only)代码 ................ 16
编排安全库区的地址 .................................. 18
启用安全库区保护 ......................................... 22
Project_L0 执行流程 ................................ 24
产生头文件及符号定义文件 ........................ 26
Project_L1:终端用户范例 ...................... 27
建立用户的应用项目 ................................. 28
在项目中加入符号定义文件 ........................... 28
调用SLIB 保护区的函数 ................................. 29
Project_L1 执行流程 ................................... 30
调试模式下的SLIB 保护 ............................... 30

方案商和终端用户代码整合及下载操作流程 ........... 33
方案商和终端用户代码分别烧录 ....................... 33
方案商和终端用户代码合并烧录 ........................ 36
版本历史 .................................................... 39


1 概述
目前越来越多的微控器(MCU)应用需要使用到复杂的算法及中间件解决方案(middleware solution),
因此,如何保护软件方案商开发出来的核心算法等知识产权代码(IP-Code),便成为微控制器应用中
一项很重要的课题。
因为这一重要的需求,AT32F423系列提供了安全库区(SLIB)的功能,以防止重要的IP-Code被终端
用户的程序做修改或读取,进而达到保护的目的。
本文档将详细阐述AT32F423系列安全库区的应用原理和软件使用方法。

2 应用原理
2.1 安全库区的应用原理

- 设定以密码保护主闪存中指定范围的程序区(即安全库区), 软件方案商可将核心算
法存放到此区域, 以达到保护的功能, 其余空白程序区可以提供给终端商客户进行
二次开发。
-  安全库区划分为唯读区(SLIB_READ_ONLY)及指令区(SLIB_INSTRUCTION), 并可
选择部分或是整个安全库区存放唯读区或者指令区。
 唯读安全库区(SLIB_READ_ONLY)的数据能透过I-Code和D-Code总线读取, 不能
写入。
-  指令安全库区(SLIB_INSTRUCTION)内的程序代码仅能被MCU透过I-Code总线抓取
指令(仅能被执行), 不能透过D-Code总线以读取数据的方式读取(包含ISP/ICP/调试
模式以及从内部RAM启动的程序), 以读取数据的方式去访问SLIB_INSTRUCTION
时, 读到的数值全都是0xFF。
-  安全库区的程序代码及数据, 除非输入正确的密码, 否则无法被擦除。在密码不正
确时, 对安全库区执行写入或擦除, 将会在FLASH_STS寄存器的EPPERR位置"1"
提出警告。
-  终端用户执行主闪存的整片擦除时, 安全库区的程序代码及数据不会被擦除。
-  当安全库区的保护功能被启动后, 可以透过在SLIB_PWD_CLR寄存器写入先前设置
的密码来解除保护功能。解除安全库区的保护时, 芯片将会执行主闪存的整片擦除
(包含安全库区的内容)。因此即使软件方案商设置的密码被泄漏,也不会有程序代
码外泄的疑虑。
下图是包含安全库区的主闪存区映射示意图,安全库区的程序代码可以很容易地被终端
用户调用并执行, 但不能直接被读取, 因而达到保护的功能。



安全库区的范围大小是以扇区(sector)为单位做设定, 每一扇区的大小以实际MCU型号
为准。表1是AT32F423系列各型号的主闪存大小、每扇区大小及可设置范围。
另外启动程序代码区在开启了主存扩展功能后, 整个20KB区域也是可以作为安全库
区。




2.2 如何启动安全库区保护
默认状态下, 安全库区设定寄存器始终是不可读且被写保护。要想对安全库区设定寄存
器进行写操作, 首先要对安全库区设定寄存器解锁, 对SLIB_UNLOCK寄存器写入解锁
0xA35F6D24值, 通过查看SLIB_MISC_STS寄存器的SLIB_ULKF位确认解锁成功, 随
后便允许对安全库区设定寄存器写入设定值。
启动主闪存安全库区的步骤如下:
-  检查FLASH_STS寄存器的OBF位, 以确认没有其他正在进行的闪存操作;
-  对SLIB_UNLOCK寄存器写入0xA35F6D24, 以进行安全库区解锁;
-  检查SLIB_MISC_STS寄存器的SLIB_ULKF位, 以确认解锁成功;
-  在SLIB_SET_RANGE寄存器设定要保护的区域, 包含SLIB的起始和结束地址以及
SLIB指令区的起始地址;
-  等待OBF位变为‘ 0’ ;
-  在SLIB_SET_PWD寄存器设定安全区域密码;
-  等待OBF位变为‘ 0’ ;
-  烧录将存入安全库区的代码;
-  进行系统复位, 重装载安全库区设定字;
-  读出SLIB_STS0/STS1寄存器用于判断安全库区设定结果。


注意事项:
-  可在主闪存和主闪存扩展区中设置安全库区, 实际可设置范围参见表1;
-  安全库区代码必须以扇区为单位进行烧录,且起始地址必须与主闪存地址或者扩展
区地址对齐;
-  中断向量表是数据型态且通常会被放置在闪存的第一扇区(扇区0)内, 请勿将闪存的
第一扇区设定为安全库区的指令区;
关于安全库区设定寄存器的详细说明, 请参阅AT32F423系列技术手册。
启动安全库区的程序可参考安全库区应用范例project_l0中位于main.c中的slib_enable()
函数。亦可使用雅特力的ICP或ISP刻录工具做设定, 后面章节将会有详细的说明。


2.3 如何解除安全库区保护
当安全库区的保护功能被启动后, 可以透过在SLIB_PWD_CLR寄存器写入先前设置的
密码来解除保护功能。解除安全库区的保护时, 芯片将会执行主闪存的整片擦除(包含
安全库区的内容)。
解除主闪存安全库区的步骤如下:
-  检查FLASH_STS寄存器的OBF位, 以确认没有其他正在进行的编程操作;
-  在SLIB_PWD_CLR寄存器写入先前设置的安全区域密码;
-  进行系统复位, 重装载安全库区设定字;
-  读出SLIB_STS0寄存器用于判断安全库区设定结果。
2.4 编排及执行安全库区的程序
如前面章节所提到,在指令安全库区(SLIB_INSTRUCTION)内的的程序代码可以被
MCU经由I-Code总线抓取, 但不能经由D-Code总线以读取数据的方式去读出, 这样的
保护是全面性的, 也就是说在指令安全库区之内的程序代码, 也不能读取同样被放置在
指令安全库区之内的数据, 例如C程序代码常被编译成的文字池(li teral pool)、分支表
(branch table)或常数(constant)等之类当指令被执行时会经由D-Code总线去读取的数
据。
这代表指令安全库区之内只能放置指令, 不能放置任何数据。因此用户在编排要放置在
指令安全库区之内的程序代码时, 必须配置编译程序(compiler)的设定去产生只执行
(execute-only)的代码以避免上述那些型态的数据产生。
图2及图3是一般常见的文字池跟分支表的例子:
swi tch()是C程序中常用的跳转指令, 此例子中的sclk_source变量是去读取CRM_CFG
寄存器, 图2可看到编译出来的汇编代码(as sembl y co de ) “LDR R7, [PC, #2 88 ]”, 会用
程序计数器(program counter, PC)间接寻址的方式去取得CRM_CFG寄存器的地址, 而
CRM_CFG的地址会被以常数的方式存放在邻近的指令区(也在指令安全库区之内), 因
此执行swi tch()指令时就会发生数据的读取。如果指令安全库区内有这类的程序代码,
在执行的时候就会产生错误。

第三章的范例程序将会说明如何设定编译程序的配置来避免这样的问题。

2.4.1 不可将中断向量表设置为安全库区的指令区
中断向量表包含每个中断处理程序的入口点地址, 由MCU通过D-Code总线读取。通
常, 中断向量表位于主闪存第一扇区(sector 0)的起始地址0x08000000, 因此在设置指
令安全库区时, 必须遵守以下的规则:
-  不可将主闪存的第一扇区设置为安全库区的指令区。
2.4.2 安全库区代码与用户区代码的关联性
受安全库区保护的程序代码(IP-Code)可以从位于用户代码区(安全库区之外的区域)的函
数库中调用函数。在这种情形下, IP-Code将会包含这些函数的地址, 允许PC( 程序计
数器) 在执行IP-Code时跳转到这些函数。一旦安全库区被启动,这些函数的地址就不
能被改变, 此时, 这些位于用户代码区的函数的地址就必须固定下来, 否则PC将跳转
到错误的地址而无法正常工作。因此在设置安全库区的时候, 应该将所有与IP-Code相
关联的函数都一起编排到安全库区之内以避免此情况发生。下图显示出一个被保护的函
数Function_A()调用到用户区内的函数Function_B()的例子。



此外, 另一个最常见的情形就是使用到C语言的标准函式库, 例如memset()及
memcpy()这类函数。如果IP-Code跟用户区代码都有调用到这类函数, 就会有上述问题
的困扰。列举两种常用的解决方法:
1) 将其编译到安全库区范围内, 具体如何实现可以查看keil或IAR的相关文档。
2) 避免在IP-Code内使用C的标准函式库, 若非要使用, 就必须将用到的函数改写为其
他名称, 以下是一个范例, 在IP-Code 中写一个my_memset()函数取代原先的
memset()。


3 安全库区范例程序
本章节将介绍安全库区的使用范例,并详述完成此范例程序所需的每一个步骤。
3.1 范例需求
3.1.1 硬件需求
-  带有AT32F423VCT7芯片的AT-START-F423实验板
-  AT-Link仿真器,用来调试范例程序
3.1.2 软件需求
-  Keil® μvision IDE (本范例使用μvision V5.36.0.0) 或 IAR Embedded workbench IDE(本范例使
用IAR V8.22.2)
-  雅特力ICP或ISP刻录工具,主要是用来启动或解除安全库区的设置
3.2 范例概述
本应用指南提供了两个范例项目,展示了软件开发商开发智权代码(IP-Code)给终端用户应用的场
景。其中
-  Project_L0为方案商开发算法并编排到安全库区的示例
-  Project_L1为终端用户应用此算法的示例
Project_L0完成的算法将预先下载刻录到AT32F423芯片并设置安全库区保护,同时提供下列各项设
定讯息给终端客户应用程序使用:
-  主闪存区块的映像,说明安全库区所占用的区域以及用户可开发程序的区域
-  包含算法函数定义的头文件,让终端用户可以用来调用相关的函数
-  符号定义文件(symbol definition file),此符号文件内含IP-Code的各个函数的实际地址,让终端
用户程序可以正确的调用,下图为此范例的示意图。




软件方案商可以参考Project_L0范例开发算法代码,并参考Project_L1提供终端用户使用,下图为应
用示意图。


3.3 安全库区保护的代码:FIR 低通滤波器
本范例使用CMSIS-DSP库提供的FIR低通滤波器(FIR lowpass filter)算法作为被安全库保护的IPCode,
关于FIR低通滤波器算法可详阅CMSIS-DSP的相关文件,这里仅着重在说明如何设置安全库
以保护此算法及如何被终端用户的程序代码调用。
范例中的低通滤波器的输入信号是一个混和了频率各为1KHz及15KHz的两个正弦波的讯号,而低通
滤波器的截止频率约为6KHz。经过低通滤波后,将15KHz的讯号滤除而仅剩下1KHz的正弦波输出。
下图为FIR低通滤波功能的示意图。


使用到的CMSIS DSP库的函数及文件包括:
-  arm_fir_init_f32()
此函数的功能是做滤波器函数的初始化设定,包含在arm_fir_init_f32.c文件里
-  arm_fir_f32()
此函数为滤波器算法的主要部分,包含在arm_fir_f32.c文件里
-  FIR_lowpass_filter()
此函数为使用上述两个基本函数写成的FIR低通滤波器全局函数,供终端用户调用,包含在fir_filter.c
文件里
-  fir_coefficient.c
此C文件内含FIR滤波器函数所使用的系数(只读的常数),在范例中会将这些系数放置到唯读安全库区
在此范例中,MCU内嵌的FPU及DSP指令会被用来做信号处理以及浮点运算,以达到准确的运算及
正确的输出信号。

3.4 Project_L0:方案商范例
在此阶段的范例程序,将完成下列几个项目:

-  将算法的相关函数编译成只可执行(execute-only)的代码
-  将算法的程序代码编排放置到主闪存区的扇区4(sector 4)
-  将滤波器函数的系数编排放置到主闪存区的扇区2(sector 2)
-  在主程序中执行FIR_lowpass_filter()以验证其正确性
-  验证成功后,将扇区4(sector 4)设置为指令安全库区,并将扇区2(sector 2)设置为唯读安全库
区,此部分可在范例的主程序中以调用slib_enable()函数来完成,或使用Artery ICP
Programmer来完成(建议使用ICP工具完成设置)
-  产出终端用户程序调用低通滤波函数时需用到的头文件及符号定义文件

3.4.1 产生只执行(Execute-only)代码
每一种工具链(toolchain)都有自己的设定选项,可以防止编译程序生成文字池(literal pools)和分支表
(branch table)这些在指令执行时会发生读取数据的指令格式,例如”LDR Rn, [PC, #offset]”这类指
令。关于文字池及分支表的例子可参照章节2.4的说明。
以Keil® μvision为例,Keil® μvision有Execute-only Code的选项来做设定,设定的方式如下:
Keil® μvision:使用Execute-only Code选项
设置的方式是:
-  选择C文件群组或个别的C文件,范例中是把要保护的相关C文件都放在fir_filter群组
-  按鼠标右键然后选择对应文件,例如本例程的Option for File ‘arm_fir_f32.c’,如下图


-  勾选 C/C++ 窗口里的Execute-only Code选项,然后--execute_only命令就会被加到编译过程控
制字符串里...

...

75561644a11dd764ae.png (30.79 KB )

75561644a11dd764ae.png

20452644a1262b1051.png (41.79 KB )

20452644a1262b1051.png

AN0164_AT32F423_Security_Library_Application_Note_ZH_V2.0.0.pdf

2.04 MB

使用特权

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

本版积分规则

198

主题

1907

帖子

28

粉丝