版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、光盘和全部用户手册: 8 章 专题篇........88.4.9STM32地址2理解51 单片机地址原理2STM32STM32 重寄存器地址的封装6功能8STM32 的重所有的管脚都可以重 为什么要有STM32 重. 8吗8这个功能8举例说明8深入分析STM32 重架构原理9STM32 重关键指点11STM32 的内存管理研究(KEIL 编程环境下)11研究意义11举例说明并详细分析11举
2、例分析12观察堆栈15STM32关于 关于 常规 增加加密17加密的定义17方法的理论总结17过程18难度的一些建议总结19STM32 加密思路-01 串口ISP 设置加密20STM32 加密思路-02加密20STM32 加密思路-03 外置ID. 21STM32 加密思路-04 程序自毁21STM32 加密思路-05 磨IC 型号21STM32 加密思路-06 高端硬件加密21STM32 加密思路-07 AES 加密......7STM32 低功耗经验总结22S
3、TM32 低功耗实战项目案例故事(). 22STM32 低功耗三种模式26STM32 低功耗需注意的地方27STM32 的中断与事件关系的区别27STM32 库函数分析29STM32 库函数到底是什么29STM32 库函数的好处29STM32 库结构剖析30CMSIS 标准30库目录,文件简介32关于core_cm3.c 文件33system_stm32f10 x.c 文件34stm32f10 x.h 文件34启动文件35STM32F10 x_StdPeriph_Driver 文件夹36stm32f10 x_it.c、 stm32f10 x_conf.h 文件37库各文件间的关系388.7.8
4、...14常用资料40库函数帮助文档使用40第8章 专题篇8.1 STM32地址8.1.1理解51单片机地址原理首先回顾一下在51单片机上点亮LED是怎样实现的。#includemain(void)P0=0;while(1);以上代码将P0的引脚拉低。当然,这里省略了头文件。为什么这个P0 =0;.5.6.句子就能控制P0端口为低电平?关键之处在于这个代码所包含的头文件。在这个文件下有以下的定义:这些定义被称为地址。器 甚至I/O等资源与地址建立一一对应的关系。如所谓地址,就是将上的果某地址对应着某寄存器,从而实现修改该
5、寄存器的内容。就可以运用c语言的指针来寻址并修改这个地址上的内容,正是因为头文件中有了对于各种寄存器和I/O端口的地址,才可以在51单片机程序中方便地使用P20 =0 xFF; TMOD =0 xFF等赋值句子对寄存器进行配置,从而控制单片机。Cortex-M3的地址也是类似的。Cortex-M3有32根地址线,所以它的寻址空间大小为232 bit=4GB。ARM公司设计时,预先把这4GB的寻址空间大致地分配好了。它把地址从0 x4000 0000至0 x5F( 512MB )的地址分配给片上外设。通过把片上外设的寄存器映射到这个地址区,就可以简单地以的工作。结果,片上外设可以使用内存的方式,
6、语言来操作。M3这些外设的寄存器,从而控制外设C器见下图:图 5-7stm32f10 x.h这个文件中重要的内容就是把STM32的所有寄存器进行地址。如同51单片机的头文件一样,stm32f10 x h像一个大表格,定义进行类似查表的操作,大家想像一下没有这个文件的话,在使用的时候就是通过宏要怎样STM32的寄存器?缺点?不进行这些宏定义的缺点有:1、地址容易写错2、需要查大量册来确定哪个地址对应哪个寄存器3、看起来还不好看,且容易造成编程的错误,效率低,影响开发进度。当然,这些工作都是由ST的固件工程师来完成的,只有设计M3的才能写出完美的库。是最了解M3的,在这里以外接了LED灯的外设GP
7、IOD为例,在这个文件中有这样的一系列宏定义:这几个宏定义是从文件中的几个部分出来的,具体的读者可参考stm32f10 x.h源码。外设址首先看到PERIPH_BASE这个宏,宏展开为0 x4000 0000,并把它强制转换为u32_t的32位类型数据,这是因为地STM32的地址是32位的,是不是觉得0 x4000 0000这个地址很熟?是的,这个是Cortex-M3核分配给片上外设的从0 x4000 0000至0 x5F的512MB寻址空间中 的第一个地址,把0 x4000 0000称为外设址。总线址接下来是宏APB2PERIPH_BASE,宏展开为PERIPH_BASE(外设址)加上偏移地
8、址0 x1 0000,即指向的地址为0 x4001 0000。这个APB2PERIPH_BASE宏是什么地址呢?STM32不同的外设是挂载在不同的总线上的。有AHB总线、APB2总线、APB1总线,挂载在这些总线上的外设有特定的地址范围。其中像GPIO、串口1、ADC及部分定时器是挂载这个被称为APB2的总线上,挂载到APB2总线上的外设地址空间是从0 x4001 0000至地址0 x4001 3。这里的第一个地址,也就是0 x4001 0000,被称为APB2PERIPH_BASE (APB2总线外设的址)。而APB2总线址的偏移地址。见表:址相对于外设址的偏移量为0 x1 0000个地址,
9、即为APB2相对外设由这个表可以知道,stm32f10 x h这个文件中必然还有以下的宏:1. #define APB1PERIPH_BASEPERIPH_BASE因为偏移量为零,所以APB1的地址直接就等于外设址寄存器组址最后到了宏GPIOC_BASE,宏展开为APB2PERIPH_BASE (APB2总线外设的址)加上相对APB2总线址的偏移量0 x1000得到了GPIOC端口的寄存器组的址。这个所谓的寄存器组又是什么呢?它包括什么寄存器?细看stm32f10 x.h文件,还可以发现以下类似的宏:除了GPIOC寄存器组的地址,还有GPIOA、GPIOB、GPIOD的地址,并且这些地址是不一
10、样的。前面提到,每组GPIO都对应着独立的一组寄存器,查看stm32的datasheet,看到寄存器说明如下图:图 5-9注意到这个说明中有一个偏移地址:0 x00,这里的偏移地址的是相对哪个地址的偏移呢?下面进行举例说明。对于GPIOD组的寄存器,GPIOD含有的 端口配置低8位寄存器(GPIOD_CRL) 寄存器地址为:GPIOD_BASE +0 x00。假如是GPIOA组的寄存器,则GPIOA含有的 端口配置低8位寄存器(GPIOA_CRL)寄存器地址为:GPIOA_BASE+0 x00。也就是说,这个偏移地址,就是该寄存器 相对所在寄存器组于是,读者可能会想,大概这个文件含有一个类似如
11、下的宏:址的偏移量。1. #define GPIOD_CRL(GPIOD_BASE + 0 x00)这个宏,定义了GPIOC_CRH寄存器的具体地址,然而,在stm32f10 x.h文件中并没有这样的宏。ST公司的工程师采用了更巧妙的方式来确定这些地址,请看下一小节STM32寄存器的封装。8.1.2STM32寄存器地址的封装ST的工程师用结构体的形式,封装了寄存器组,c语言结构体学的不好的同学,可以在这里补补课了。在stm32f10 x.h文件中,有以下代码:有了这些宏,就可以定位到具体的寄存器地址。像GPIOA、GPIOB等这个的,可以直接追溯到它们的地址。可以像GPIOA_CRL这样的寄存
12、器,在stm32f10 x.h文件中并没有找到像GPIOA、GPIOB等类似的地址定义。那么它们是怎么定义的呢?在这里发现了一个陌生的类型GPIO_TypeDef ,追踪它的定义,可以在stm32f10 x h 文件中找到如下代码:其中 IO也是一个ST库定义的宏,宏定义如下:volatitle 是c语言的一个关键字,有关volatitle的用法可查阅相关的C语言书籍。回到GPIO_TypeDef这段代码,这个代码用typedef关键字了名为GPIO_TypeDef的结构体类型,结构体内又定义了7个 IOu32_t类型的变量。这些变量每个都为32位,也就是每个变量占内存空间4个字节。在c语言中
13、,结构体内变量的空间是连续的,也就是说假如定义了一个GPIO_TypeDef ,这个结构体的首地址(变量CRL的地址)若为0 x4001 1000, 那体中第二个变量(CRH)的地址即为0 x4001 1000 +0 x04 ,加上的这个0 x04 ,正是代表4个字节地址的偏移量。细心的读者会发现,这个0 x04偏移量,正是GPIOx_CRH寄存器相对于所在寄存器组的偏移地址。同理,GPIO_TypeDef结构体内其它变量的偏移量,也和相应的寄存器偏移地址相符。于是,只要匹配了结构体的首地址,就可以确定各寄存器的具体地址了。有了这些准备,就可以分析本小节的第一段代码了:GPIOA_BASE 在
14、上一小节已 , 是一 GPIOA 组寄存器的址。 (GPIO_TypeDef *) 在这里的作用则是把GPIOA_BASE地址转换为GPIO_TypeDef结构体指针类型。有了这样的宏,以后写代码的时候,如果要修改GPIO的寄存器,就可以用以下的方式来实现。代码分析见注释。通过类似的方式,就可以给具体的寄存器写上适当的参数,控制STM32了。是不是觉得很巧妙?但这只是库开发的皮毛,而且实际上供了更简单的开发方式。M3的库可谓尽情绽放了c的并不是这样使用库的,库为提,如果你是单片机初学者,c语言初学者,那么请你不要放弃与M3库邂逅的机会。是否选择库,就差你一个闪亮的回眸。8.2 STM32重功能
15、8.2.1STM32的重就好像乾坤大挪移,移动穴位,把这个管脚的功能移到另外一个管脚上。重的作用简单的说就是把管脚的外设功能到另一个管脚,但是不是可以随便映射的,具体对应关系参考手册上的管脚说明。比如 USART2_TX 默认在 PA2 管脚,当启用复用功能后就会将 PD5 管脚作为 USART2_TX。8.2.2所有的管脚都可以重吗大部分都可以,但不是所有的管脚功能都能重,比如 ADC1_IN0 就只能在 PA0,这个具体要看的。8.2.3为什么要有STM32重这个功能知道每个内置外设都有若干个输入输出引脚,一般这些引脚的输出脚位都是固定不变的,为了让设计工程师可以更好地安排引脚的和功能,在
16、 STM32 中引入了外设引脚重的概念,即一个外设的引脚除了具有默认的脚位外,还可以通过设置重寄存器的方式,把这个外设的引脚到其它的脚 位。比如设计的这个电路板,要 3 个串口接口,并且这 2 个串口要连在一起,那么 STM32本身的 2 个串口接口的管脚分布到各处的,如果按照实际管脚功能来设计电路板,可能不太好走线,这样可以通过重原来不是串口的管脚初重的功能,把另外好连的管脚连在一起,通过程序去把成串口即可;这样就只需要修改就可以,根本不用改变硬件,这样就增加了的灵活性,也增加了硬件设计者以及产品的灵活性。8.2.4举例说明在这里随便举一个例子,可能的不是这个型号,但是都是同样的原理,就跟九
17、阳神功一样,神舟团队认为,这样举的例子才更有可重用性,你学懂了就是真的懂了,大家可以查看一下 STM32的摘要片段:手册,这里举的是 STM32F103xC 中有关 USART3 引脚从这里可以看出,USART3_TX 的默认引出脚是 PB10,USART3_RX 的默认引出脚是PB11;但经过重出脚为 PD9。后,可以变更 USART3_TX 的引出脚为 PD8,变更 USART3_RX 的引STM32 中的很多内置外设都具有重的功能,比如 USART、定时器、CAN、SPI、I2C 等,详细请看 STM32 参考手册(RM0008)和 STM32。有些模块(内置外设)的重功能还可以有多种选
18、择,下面是 RM0008 上有关 USART3输入输出引脚的重功能表:从这个表中可以看出,USART3 的 TX 和 RX 引脚默认的引出脚位是 PB10 和 PB11,根据配置位的设置,可以重到 PC10 和 PC11,还可以重到 PD8 和 PD9。8.2.5深入分析STM32重架构原理一个模块的功能引脚不管是从默认的脚位引出还是从重的脚位引出,都要通过GPIO 端口模块实现,相应的 GPIO 端口必须配置为输入(对应模块的输入功能,如 USART的 RX)或复用输出(对应模块的输出功能,如 USART 的 TX),对于输出引脚,可以按照需要配置为推挽复用输出或开漏复用输出。这里就好比,你
19、可以把土地的白菜移到另外一块有土的菜地,它还是可以继续茁壮的成长;但你不能把白菜放在被子里睡觉,让它跟你一样成长,至少要有最基本的土壤;在 STM32里,一个管脚无非就是输入或者输出,这个基本的属性一定要配对,一个串口打印输出,如果你把管脚配置成输入,那一定是的,也不可能配置成功的。上图是 STM32 的 GPIO 端口模块,使用复用功能时的配置。从图中可以看出,配置为复用输出时,该端口对应的 GPIO 输出功能将不起作用。例如当配置 PB10 对应的引脚为复用输出功能时,操作 PB10 对应的输出寄存器将不影响引脚上的信号。从图中还可以看出,普通的 GPIO 端口输入功能与复用的输入功能的配
20、置方式没有分别,这意味着在使用引脚的复用输入功能时,可以在这个引脚的输入寄 存器上读出引脚上的信号。例如在使能了 USART3 模块时,可以读 GPIOB_IDR 寄存器,得到 PB11 信号线上的当前状态。有不少引脚上配备了来自多个模块的复用功能引出脚,例如本文第一中显示的PB10,默认复用功能就有 I2C2_SCL 和 USART3_TX 两个功能,TIM2 重也使用 PB10 的复用功能。后,TIM2_CH3在使用引脚的复用功能时,需要注意在上只可以使能一个外设模块,否则在引出脚上可能产生信号。例如,如果使能了 USART3 模块,同时没有 对 USART3 进行重配置,则不可以使能 I
21、2C2 模块;同理如果需要使用 I2C2 模块,则不能使能 USART3 模块。但是如果配置了 USART3 的引 脚重,USART3 的 TX 和 RX 信号将从 PC10 和 PC11,或 PD8 和 PD9 引出,避开了 I2C2 使用的 PB10 和 PB11,这时就可以同时使用 I2C2 模块和USART3 模块了。USART3 模块共有 5 个信号,分别为 TX、RX、CK、CTS 和 RTS,从上面给出的第二中可以看出,重是对所有信号同时有效。这 5 个信号中,在使能了 USART3 模块后,只有 TX 和 RX 是始终与对应的引出脚相连,而其它 3 个信号分别有独立的控制位,控
22、制它们是否与外部引脚 相连,如果程序中不使用某个信号的功能,则可以关闭这个信号的功能,对应的引脚可以做为其它功能的引出脚。例如,当关闭了 USART3 的 CK、CTS 和 RTS 功能并且没有重和 PB14USART3 时,PB12、PB13可以作为通用输入输出端口使用,也可以作为其它模块的复用功能引出脚。下面这是一个控制连接的等效示意图,它并不表示真正的连接,但可以有效地帮助理解重的输入输出模块。和复用引脚的概念。图中右边引出的信号,分别连接到了本文第三8.2.6STM32重关键指点这里所说明的原理,如果没看明白没有关系,可以先继续往下学习,这样的概念有个映像就可以,这个知识说明透彻之后,
23、其他的只能在实际的代码中学习;你完全可以打开STM32 的手册,然后请注意观察那些管脚第一个主功能,以及重功能是什么,然后看看代码如何去控制他们的,有疑问再回来查看这一个章节,这才是真正的学习成功之道。8.3 STM32的内存管理研究(KEIL编程环境下)8.3.1研究意义8.3.2举例说明并详细分析非常简单的一个工程,没有用到任何 IO 操作,与 STM32 有关的仅仅只有的选择,即其 SRAM 大小有区别。上图是工程示意图,从图中可以看出,除了自己编写的代码外,仅仅增加了 2 个文件, 即 system_stm32f10 x.c 和 startup_stm32f10 x_hd.s , 其中
24、为了对startup_stm32f10 x_hd.s 进行修改,将其从库文件夹到了项目文件夹中。8.3.3举例分析代码 1main()a,b,c,d;a=10;b=20;c=a+b;for(;);myex1.c(3): warning:#550-D: variable c was set but never usedlinking.Program Size: Code=796 RO-data=336 RW-data=20 ZI-data=1636FromELF: creating hex file.myex1.axf - 0 Error(s), 1 Warning(s).代码 2main()c
25、onstx=16;a,b,c,d;a=10;b=20;c=a+b;for(;);myex1.c(2): warning:#177-D: variable x was declared but never referencedmyex1.c(3): warning:#550-D: variable c was set but never usedlinking.Program Size: Code=800 RO-data=336 RW-data=20 ZI-data=1636FromELF: creating hex file.myex1.axf - 0 Error(s), 2 Warning(
26、s).说明:(1)Code 增加了 4 字节(2)其余没有任何变化代码 3main()constx=16;myArry100;i;a,b,c,d;a=10;b=20;c=a+b;for(i=0;i100;i+)myArryi=i;for(;);myex1.c(2): warning:#177-D: variable x was declared but never referencedmyex1.c(3): warning:#550-D: variable myArry was set but never usedmyex1.c(5): warning:myex1.c(5): warning:
27、#550-D: variable c was set but never used#177-D: variable d was declared but never referencedlinking.Program Size: Code=816 RO-data=336 RW-data=20 ZI-data=1636FromELF: creating hex file.myex1.axf - 0 Error(s), 4 Warning(s).分析:程序中增加了数组 myArry,Code 增加为 816 字节,但是 RO-data 等仍未变化代码 4main()constx=16;myArry
28、100=1,2,3,4,5,6;i;a,b,c,d;a=10;b=20;c=a+b;for(i=0;i100;i+)myArryi=i;for(;);myex1.c(2): warning:#177-D: variable x was declared but never referencedmyex1.c(3): warning:myex1.c(5): warning:#550-D: variable myArry was set but never used#550-D: variable c was set but never usedmyex1.c(5): warning:linkin
29、g.#177-D: variable d was declared but never referencedProgram Size: Code=1024 RO-data=360 RW-data=20 ZI-data=1636FromELF: creating hex file.myex1.axf - 0 Error(s), 4 Warning(s).分析:(1)由于 myArry 作了初始化,因此 RO-data 增加了 360-336=24 字节。原因是 32 位机型变量是 32 位的,占 4 字节,所以初始 6 个值后,增加了 24 字节。中(2)再增加初始化变量的数量,则 RO-dat
30、a 随之增加,而 Code 不再变化,也就是 Code由代码 3 的 816 字节增加到 1024 字节,是增加了初始化处理的代码量。根据以上分析,似乎与已知资料有。*RO 是程序中的指令和常量RW 是程序中的已初始化变量ZI 是程序中的未初始化的变量由以上 3 点说明可以理解为:RO 就是 readonly,RW 就是 read/write,ZI 就是 zero*如果按此说明,增加变量应该增加 RO,但从代码 1 到代码 2 的变化来看,仅是增加了Code,却没有增加 RO。初始化变量时,应该增加 RW,但是从代码 2代码 4,RW 却没有任何变化。看来这个说法只能适用于 ARM,即运行时需
31、要将代码调入 RAM 运行的,对于 STM32 这类并不完全适用。8.3.4观察堆栈1) 当使用myArray300时:2) 当使得myArray100时:3) 当使得myArray450时:当然,执行是错误的,当这个地址没有影响;myArray409时:正指向 0 x2000000,去掉其他变量,对于堆栈应该是向下生成的,而且与无关,无论选择 6K RAM 还是 48K RAM 都是如此,且当数组再大时,就会将地址置于小于 0 x2000000 的地址,但编译并不报错。4)代码 5myArray400=1,2,3,4,5,6,7,8,9,10,11,12,13,14;main()constx
32、=16;a,b,c,d;i;a=10;b=20;c=a+b;for(i=0;i100;i+)myArrayi=i;for(i=0;i100;i+)c+=myArrayi;d+=x;for(;);编译结果:compiling myex1.c.linking.Program Size: Code=876 RO-data=336 RW-data=1620 ZI-data=1636FromELF: creating hex file.myex1.axf - 0 Error(s), 0 Warning(s).分析:将数组作为全局变量来定义,情况立即发生了变化。RW-data 变成了 1620。其本中的
33、1600 应该是这个数组增加的 4*400=1600,而 20 则是代码 1代码 4 中一直都有的。经查验资料,栈的大小应该在启动代码中修改。更改这个:startup_stm32f10 x_hd.s 可以更改栈的大小。RO 是程序中的指令和常量(Code + RO Data);RW 是程序中的已初始化变量;ZI 是程序中的未初始化的变量;由以上 3 点说明可以理解为:1)RO 就是 readonly,RW 就是 read/write,ZI 就是 zero简单的说就是在烧写完的时候是:FLASH 中:Code+RO Data+RW Data,运行的时候: RAM: RW Data + ZI Da
34、ta,当然还要有堆栈的空间。Program Size: Code=876 RO-data=336 RW-data=1620 ZI-data=1636FLASH 占 Total ROM Size (Code + RO Data + RW Data) = 876 + 3362.8KB= 2832 =SRAM 占 Total RW Size (RW Data + ZI Data) = 1620 + 1636 = 3256 = 3.3KB如果你对 ZI-Data 理解还有疑问,可以尝试一下:myArray400=1,2,3,4,5,6,7,8,9,10,11,12,13,14; 会增加 RW,但是就可
35、以增加 ZI 了。myArray400=0;8.4 STM32加密8.4.1关于加密的定义是指从已经被加密了的里,把的代码拷贝出来。嵌入了程序代码的芯片有很多种,而 MCU 只是其中一种。单片机(MCU)一般都有EEPROM/FLASH 供用户存放程序和工作数据。为了防止或拷贝单片机的机内程序,大部分单片机都带有加密锁定位或者加密字节,以保护片内程序。如果在编程时加密锁定位被使能(锁定),就无法用普通编程器直接单片机内的程序,这就叫单片机加密或加密。单片机者借助设备或者设备,利用单片机设计上的或缺陷,通过多种技术手。段,就可以从中提取关键信息,获取单片机内程序这就叫又叫单片机,单片机,把 CP
36、LD,IC,DSP,但是这严格说来这几种称呼都不科学,但已经成了单片机只是能装载程序叫法,都称为。的其中一个类。能烧录程序并能加密的还有 DSP,CPLD,或设计验证厂家代码PLD,AVR,ARM 等。也有专门设计有加密算法用于专业加密的工作等功能,该类也能实现防止电子产品的目的。8.4.2关于方法的理论总结1.该技术通常使用处理器通口并利用协议、加密算法或这些算法中的安全来进行。取得成功的一个典型事例是对早期 ATMEL AT89C 系列单片机的。攻击者利用了该系列单片机擦除操作时序设计上的,使用自编程序在擦除加密锁定位后,停止下一步擦除片内程序器数据的操作,从而使加过密的单片成没加密的单片
37、机,然后利用编程器读出片内程序。至于在其他加密方法的基础上,可以研究出一些设备,配合一定的,来做。近期国内出现了一种泰斗科技 51设备(一位高手搞出来的),这种器主要针对 SyncMos.,在生产工艺上的,利用某些编程器定位插字节,通过一定的方法查找中是否有连续空位,也就是说查找中连续的F 字节,的字节能够执行把片内的程序送到片外的指令,然后用密完成了。的设备进行截获,这样的程序就被解2.电子探测该技术通常以高时间分辨率来处理器在正常操作时所有电源和接口连接的模拟特性,并通过它的电磁辐射特性来实施。因为单片机是一个活动的电子器件,当它执行不同的指令时,对应的电源功率消耗也相应变化。这样通过使用
38、特殊的电子测量仪器和数学统计方法分析和检测这些变化,即可获取单片机中的特定关键信息。至于 RF 编程器可以直接读出老的型号的加密 MCU 中的程序,就是采用这个原理。3.过错产生技术该技术使用异常工作条件来使处理器出错,然后提供额外的来进行可用来。使用最广保护电路泛的过错产生包括电压冲击和时钟冲击。低电压和高电压工作或强制处理器执行错误操作。时钟瞬态跳变也许会复位保护电路而不会破坏受保护信息。电源和时钟瞬态跳变可以在某些处理器中影响单条指令的和执行。4.探针技术该技术是直接连线,然后观察、操控、干扰单片机以达到目的。为了方便起见,人们将以上四种技术分成两类,一类是侵入型(物理),花这类需要破坏
39、封装,然后借助半导体测试设备、显微镜和微,在专门的上几小时甚至几周时间才能完成。所有的微探针技术都属于侵入型。另外三种方法属于非侵入型,被的单片机不会被物理损坏。在某些场合非侵入型是特别的,这是因为非侵入型所需设备通常可以和升级,因此非常廉价。大部分非侵入型需要者具备良好的处理器知识和知识。与之相反,侵入型的探针则不需要太多的初始知识,而且通常可用一整套相似的技术对付宽范围的产品。因此,对单片机的速的非侵入型往往从侵入型的反向工程开始,积累的经验有助于开发更加廉价和快技术。8.4.3常规侵入型过程的第一步是揭去封装(简称“开盖”有时候称“开封”,英文为“DECAP”,decapsulation
40、)。有两种方法可以达到这一目的:第一种是完全溶解掉封装,金属连线。第二种是只移掉硅核上面的封装。第法需要将绑定到测试夹具上,借助绑定台来操作。第二种方法除了需要具备者一定的知识和必要的技能外,还需要个人的智慧和耐心,但操作起来相对比较方便,完全家庭中操作。上面的可以用小刀揭开,周围的环氧树脂可以用浓硝酸腐蚀掉。热的浓硝酸会溶解掉封装而不会影响及连线。该过程一般在非常干燥的条件下进行,因为水的存在可能会侵蚀已的铝线连接 (这就可能造成失败)。接着在超声池里先用该以除去残余硝酸,并浸泡。最后一步是寻找保护熔丝的位置并将保护熔丝少 100 倍的显微镜,从编程电压输入脚的连线在紫外光下。一般用一台放大
41、倍数至进去,来寻找保护熔丝。若没有显微镜,则采用将的不同部分到紫外光下并观察结果的方式进行简单的搜索。操作时应用不透明的纸片覆盖以保护程序器不被紫外光擦除。将保护熔丝在紫外光下 510分钟就能破坏掉保护位的保护作用,之后,使用简单的编程器就可直接读出程序容。器的内对于使用了防护层来保护 EEPROM 单元的单片机来说,使用紫外位保护电路是不可行的。对于这种类型的单片机,一般使用微探针技术来器内容。在封装打开后,将置于显微镜下就能够很容易的找到从器连到电路其它部分的数据总线。由于某种原因,锁定位在编程模式下并不锁定对器的。利用这一缺陷将探针放在数据线的上面就能读到所有想要的数据。在编程模式下,重
42、启读过程并连接探针到另外的数据线上就可以读出程序和数据器中的所有信息。还有一种可能的是借助显微镜和激光切割机等设备来寻找保护熔丝,从而寻查和这部分电路相联系的所有信号线。由于设计有缺陷,因此,只要切断从保护熔丝到其它电路的某一根信号线(或切割掉整个加密电路)或连接 13 根金线(通常称 FIB:focused ionbeam),就能整个保护功能,这样,使用简单的编程器就能直接读出程序器的内容。虽然大多数普通单片机都具有熔丝烧断保护单片机内代码的功能,但由于通用低档的单片机并非定位于制作安全类产品,因此,它们往往没有提供有针对性的防范措施且安全级别较低。加上单片机应用场合广泛,销售量大,厂商间委
43、托加工与技术转让频繁,大量技术资料外泻,使得利用该类或非侵入型的设计和厂商的测试接口,并通过修改熔丝保护位等侵入型来单片机的程序变得比较容易。8.4.4增加难度的一些建议总结任何一款单片机从理论上讲,者均可利用足够的投资和时间使用以上方法来攻破。这是系统设计者应该始终牢记的基本原则。因此,作为电子产品的设计工程师非常有必要了解当前单片机的技术,做到知己知彼,心中有数,才能有效防止自己花费大量金钱和时间辛辛苦苦设计出来的产品议:家之间仿冒的事情发生。根据实践提出下面建(1)在选定加密前,要充分调研,了解技术的新进展,包括哪些单片机是已经确认可以的。尽量不选用已可或同系列、同型号的选择采用新工艺、
44、新结构、上市时间较短的单片机,如可以使用 ATMEGA88PA,这种国内的费用一需要 6K 左右,另外相对难的有 ST12 系列,dsPIC30F 系列等;其他也可以和 CPLD 结合加密,这样解密费用很高,一般的 CPLD 也要 1 万左右。(2)尽量不要选用 MCS51 系列单片机,因为该单片机在国内的普及程度最高,被研究得也最透。(3)产品的者,一般具有产量大的特点,所以可选用比较生僻、偏冷门的单片机来加大 仿 冒 者 采 购 的 难 度 , 选 用 一 些 生 僻 的 单 片 机 , 比 如ATTINY2313,AT89C51RD2,AT89C51RC2,motorola 单片机等比较
45、难的,目前国内会开发使用熟悉 motorola 单片机的人很少,所以的费用也相当高,从 30003 万左右。(4)在设计成本的条件下,应选用具有硬件自毁功能的智能卡,以有效对付物理;另外程序设计的时候,加入时间到计时功能,比如使用到 1 年,自动停止所有功能的运行,这样会增加者的成本。(5)如果条件,可采用两片不同型号单片机互为备份,相互验证,从而增加成本。(6)打磨掉也要抹掉,很多型号等信息或者重新印上其它的型号,以假乱真(注意,有 LOGO 的,者可以从判断出型号,比如 51,MDT 等)。(7)可以利用单片机未公开,未被利用的标志位或单元,作为标志位。(8)利用 MCS-51 中 A5
46、指令加密,其实世界上所有资料,包括英文资料都没有讲这条指令,其实这是很好的加密指令,A5 功能是二字节空操作指令加密方法在 A5 后加一个二字节或三字节操作码,因为所有反汇编都不会反汇编 A5 指令,造成正常程序反汇编乱套,执行程序无问题仿制者就不能改变你的源程序。(9)你应在程序区写上你的大位开发时间及仿制的说法,以备获得法律保护;另外写上你的大名的时候,可以是随机的,也就是说,采用某种算法,外部不同条件下,你的名字不同,比如等,这样比较难反汇编修改。(10)采用高档的编程器,烧断的部分管脚,还可以采用的设备烧断金线,这个目前国内几乎不能,即使,也需要上万的费用,需要多个母片。(11)采用硅
47、胶(环氧树脂灌封胶)封住整个电路板,PCB 上多一些没有用途的焊盘,在硅胶中还可以掺杂一些没有用途的元件,同时把MCU 周围电路的电子元件尽量抹掉型号。(12)对 SyncMos,单片机,将把要烧录的文件转成 HEX 文件,这样烧录到的程序空位自动添 00,如果你BIN 文件,也可以用编程器把空白区域中的 FF 改成 00,这样一般器也就找不到中的空位,也就无法执行以后的操作。(13)比较有水平的加密例如:18F4620 有锁相环可以利用 RC 震荡产生高精度的时钟,利用上电时擦除 18F4620 的数据,所以导致出来的文件根本不能用。(14) NEC 系列单片机作为日系的代表,单片机中设计了
48、充足的保护措施来保证其程序代码的安全,同时,该系列单片机没有 PROGRAM READ 功能,因此无法利用编程器将程序读出。(注:用编程器给编程时的校验功能并不是将程序读出来进行校验,而是编程器将数据送给器)。,由内核独立完成与区数据的比较,然后将比较结果返回给编程当然,要想从根本上防止单片机被,那是不可能的,加密技术不断发展,技术也不断发展,至今不管哪个单片机,只要有人肯出钱去做,基本都可以做出来,只不过代价高低和周期长短,编程者还可以从法律的途径对自己的开发作出保护(比如专利)。8.4.5STM32加密思路-01 串口ISP设置加密STM32 的加密,最基本的方法是置读保护,这样可以防止外
49、部工具,在 STM32官网发布的 串口 ISP中有置读保护和加密选项,选择一个就可以了,这样外部工具就无法对 FLASH 进行读写操作,但我要重新烧写 FLASH 怎么办?只能清读保护,而清读保护后,会自动擦除 FLASH 全部内容。8.4.6在STM32加密思路-02加密里做加密,比如利用 CPU 的唯一的 96 位 ID(请见神舟 IV 号的例程“产品唯一标识(Unique Device ID)实验(96 位唯一 ID 实验)”),或者甚至利用网卡的 MAC,如果你说人家反汇编你的程序,那是可以做到的,但是成本没法估算,没人愿意出钱尝试,也就起到保护作用了,加密,可以看它的闪存编程手册。利
50、用 STM32 的 UID 加密,具体程序可以做到比如 main 函数开始的时候,可以加一句:if(UID = 正确的 UID)运行后面代码;else 不理会/运行错误的代码;这里还可以迷惑对手,可以运行一段的代码,模拟产品正常启动的样子,但就是不运行部分的代码,这样可以使得成本。误认为成功了,为对手造成一些经济上的采用内的唯一 ID 来加密,在程序里识别的 ID,如果 ID 不对,则程序不运行,当然,这样也是有缺陷的,因为每个的 ID 不一样,因此对应的程序也应该不一样,那如何处理呢?有人建议说:采购的时候,产品同批生产的 ID 号应该是连续的,可以通过判别 ID 的范围;还有人说,在烧录工
51、具里做一个算法,ID,再修改相应的二进制文件。当然还会有很多种方法,这里不展开。8.4.7STM32加密思路-03 外置ID可以考虑外置 ID,如果成本没有问题,可以考虑增加一颗 CPU,两颗 CPU 相互进行验证,才执行真正的程序,增加的成本和难度,而且这颗可以是不常用的,或者是型号不同的进行处理。,这里面很多的想象空间,可以利用产品的特点,来寻找合适的8.4.8STM32加密思路-04 程序自毁可以考虑设置某种检测机制,发现异常时程序自毁,比如程序一启动,如果发现某几个管脚的电平出现变化,比如已经封死的 JTAG 管脚出现了其他异常的电平进入,那么就自毁程序,拷贝一段 FF 去刷自己的 F
52、LASH,只要覆盖一小。就足以让者无法成功这些预先可以根据自身的产品来设置一些场景,出现这些情况就做相应的急救措施。8.4.9STM32加密思路-05 磨IC型号磨掉 IC 的型号,重新打一个错误的上去;还可以在周围的电阻电容上动手脚,打错的值上去,使得成功后,周围的电路有个关键部分的配件的值不对,导致产品运行不正常,增加的难度。8.4.10STM32加密思路-06 高端硬件加密目前 STM32高端的增加了硬件的加密,比如 STM32F4具有个 PDR 寄存器,可以设置三级加密,如果你代码都写好了,直接设置到 LEVE2,那就 stm32 就不进去了,直接死,暂时没有听说解决办法,以后有没有不
53、清楚。还有像 STM32F4推出的 417 系列带哈希加密的,这些都是 ST 厂商提供的一些解决办法,另外的与时俱进进行相应的增加吧。8.4.11STM32加密思路-07 AES加密知道,STM32 的FLASH 是用户可编程的,也就是说它支持 IAP,而 IAP 中的APP 代码一般是需要开放的,那么只有保证 BOOT 的代码安全,才能确保不被。前面提到,当 IC 置读保护后,外部工具不能FLASH,但 CPU 可以,破解者完全可以自已编写一段代码通过 BOOT代码。到 IC 运行,然后在程序中读出你的 BOOT所以解决办法就只能加以限制想办法使别人的代码运行不了,才能保证 BOOT 不被读
54、出。常用的方法是采用加密算法,如 AES;流程如下:APP 代码加密,时,在 BOOT 中,这样,只有通过正确加密的 APP 代码才能正常的运行,因此加密的算法就成了你的密钥,而这个是你独有的。而且这样做的好处也可以方便去客户那升级,也为了保证程序的安全;程序分为两部分,一是 boot 引导程序,二是 app 应用程序部分,产品在出厂时,先用串口 ISP 烧写 boot,烧写的时候置读保护,写完后,可以用 JLINK 测试了一下,确认程序读不出来,说明 FLASH 保护位有效,没有因为后面烧写 APP 而清掉。关键之处到了,为了安全,这里还需要把 APP 程序用 AES 之类的加密,在 BOO
55、T 中解密写到 APP 区,这样就是说 BOOT 部分需要加入一段的 APP 也没用。的代码,这样人家拿到你加密后ST有一个公开源码版本的 bootloader,很稳定,再找个 AES 在 STM32 进行移植,合体变身,这样一个强大好用的 bootloader 就诞生了;关于 AES 的可以由每颗 STM32都有唯一的 ID 来作为一个唯一输入进行产生,这样可以直接将加密后的文件交给客户自己去也是放心的。这样 BOOT 代码确保不会被读出,APP 也加密了,这样就是目前最安全的模式。8.5 STM32低功耗经验总结8.5.1STM32低功耗实战项目案例故事()前两个月在公司做了一个低功耗项目
56、,现在功耗最低 10uA 不到,平均功耗 40uA 左右,算是达标了。因为是公司产品,就不方便贴代码、原理图了,该产品是一个小模块,可以方便的嵌入到各种系统里面。跟 NRF2401 类似,是一个。做这个项目中间也请了技术支持,因为方的反复交流,对方提供了低功耗的成为的产品,功耗比较满意。电路的功耗一直降不下来,经过与对、硬件方案、方案,经过修改测试,最终硬件方案选择的是 STM32,外加某公司的读卡。前期完成了读卡等功能的开发,最后一项开发内容是最艰巨也是最的-低功耗。在开发过,从硬件设计上不断裁剪元器件,上不断精简代码,功耗最低也都保持在 3-4mA 左右,经过许多努力,才解决问题,解决过程
57、如下。电路设计上,只用到了一个 LED、串口 1、一个模拟 SPI、一个中断线、一个读卡芯片 RESET 线,硬件上就只剩下这么点东西了,这个时候我采用的是待机模式,使用的是读卡的中断接 PA0 唤醒 STM32,在此之前要先使得读卡进入低功耗、然后 STM32进入低功耗,这一步完成了,貌似没什么问题,功耗确实从几十 mA 骤降到 3mA 左右,开始还挺满意的,但是测试厂商提供的样板,功耗却只有几十 uA,有点郁闷了。为什么会这样?反复查看硬件、程序,都找不出原因,而且这个时候的工作效果很烂,根本就不能唤醒,所以我就怀疑是读卡一端低功耗有问题,因为我将 PA0 脚直接短接 VCC,这样就可以产
58、生一个边沿触发 STM32 唤醒了,但是用读卡无法唤醒,所以我怀疑是读卡的RESET 脚电平不对,经检查,确实是因为 RESET 脚加了上拉电阻,读卡是复位,在 STM32 进入待机后,管脚全都浮空了,导致 RESET 被拉高,一直在复位;我去掉上拉电阻,觉得很有希望解决问题了,但是是:有时候能唤醒,有时候不能,我仔细一想难道是因为 STM32 待机后管脚电平不确定,导致读卡RESET 脚电平不定,而工作不正常,看样子只有换用其他方案了。后面确实验证了想法,使用 STOP 模式后,唤醒问题引刃而解。就在关键时刻,原厂火种送炭,送来急需的技术支持资料,一个包含低功耗源代码,赶紧拿过来测试,先研读
59、下代码,使用的是 STOP 模式,而不是待机模式,使用的是任意外部中断唤醒,这个时候就相当激动啊,赶快1mA,跟人家一比多了几十倍啊 。测试啊,结果功耗确实降了,但还是有我第一反应是硬件不对,经过测试修改,首先找到第一个原因,读卡RESET 管脚上拉电阻又给焊上去了.,拆掉后功耗骤降到几百 uA,还是。 测试过,为了去掉 LDO 的干扰,整板采用 3.3V 供电,但是后面经过测试,LDO 的功耗其实也只有 5uA 不到,这 LDO 功耗值得赞一个;虽然结果还是没达到预期,但是看到了希望,胜利就在眼前啊。为此我反复看了技术支持提供的程序,发现他们的 STM32 的所有管脚的设置都有所考究:(因为
60、公司原则,代码中删除掉了关于该读卡的前缀信息等)GPIO_InitTypeDef GPIO_InitStructure;/* GPIOriph clock enable */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);/* GPIOB Periph clock enable */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);/* GPIOC Periph clock enable */RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2022年大学水利专业大学物理下册开学考试试题D卷-附解析
- 北京版四年级下册数学第二单元 小数加、减法 测试卷附参考答案(精练)
- 2022年大学口腔医学专业大学物理二期中考试试卷B卷-附解析
- 铁路建设项目试验检测流程制度
- 教育行业教师福利制度研究
- 医院病房日常清洁保洁方案
- 银行客户服务反馈信箱制度
- 大理石窗台板色彩搭配方案
- 疫苗配送与医用耗材方案
- 电气系统检修吊装方案
- 电力工程施工行业分析报告
- 2023年七年级地理上册期末测试卷(附答案)
- HYT 147.7-2013 海洋监测技术规程 第7部分:卫星遥感技术方法
- 化妆品市场微观环境分析
- MOOC 金羽飞扬-世界冠军的羽毛球课堂-哈尔滨工业大学 中国大学慕课答案
- (正式版)SHT 3075-2024 石油化工钢制压力容器材料选用规范
- 大学生的自己的职业生涯规划
- 教育科学规划课题申请书《基于生活化的幼儿数学教学活动研究》
- 小班数学《认识数字4》课件
- (高清版)DZT 0270-2014 地下水监测井建设规范
- 脑梗死合并高血压患者个案护理
评论
0/150
提交评论