STM32 FLASH 写入不成功问题
cathy 在 提交

cathy 在 提交
如果你还不了解什么是STM32对其Flash的保护,那么今天就来给你讲解一下什么是STM32的Flash保护!
01、什么是Flash?
STM32的FLASH组织结构,可能因不同系列、型号略有不同。比如大家熟悉的STM32F1中小容量一页大小只有1K,而F1大容量一页有2K。
还比如有些系列以扇区为最小单元,有的扇区最小16K,有的128K不等。
通常Flash包含几大块,这里以F40x为例:
主存储器:用来存放用户代码或数据。
系统存储器:用来存放出厂程序,一般是启动程序代码。
OTP 区域:一小段一次性可编程区域,供用户存放特定的数据。
选项字节:存放与芯片资源或属性相关的配置信息。
02、什么是STM32对内部Flash的保护?
所有的STM32芯片都会提供对Flash的保护,防止对Flash的非法访问,分为:写保护和读保护。
1、读保护就是大家通常说的“加密”,作用于整个Flash存储区域。如果一旦设置了Flash的读保护,那么单片机内置的Flash存储区就只能通过程序的正常执行才能读出,而不能通过下述方式读出:
(1) 使用调试器(JTAG或SWD);
(2)从内存RAM中启动并执行的程序;
2、写保护是以四页(1KB/页) Flash存储区为单位提供写保护,如果对Flash设置了写保护,那么就无法对Flash进行编程和擦除,而且同时产生操作错误标志。 当出现下图标志的时候,就要检查Flash是否被保护起来了。
03、读保护与写保护的相关效果
当设置读保护与写保护时,其效果如下图所示:
1)flash保护的相关函数
2)STM32如何设置读保护?
我们只需要在程序开头加入“设置读保护”的代码就可以,这样就可以在每次运行代码的时候都检查一下,如果没有开的话就打开,如果开了就跳过。下面是读保护的代码:
当我们在程序的开头执行了上面的代码之后,使用j-link就不能在读出程序了,这样就实现了读保护。
3)如何通过代码解除Flash保护
解除读保护可以下面代码来进行解除,我们为了方便解锁,可以设置一个按键。
来源:玩转单片机与嵌入式
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。
本文将介绍如何拆焊Flash芯片,设计及制作相应的分线板。了解对嵌入式设备的非易失性存储的简单有效攻击手段。这些攻击包括:
读取存储芯片内容
修改芯片内容
监视对存储芯片的读取操作并远程修改(中间人攻击)
想想,当你拆开一个嵌入式产品,却被挡在Flash之外,好奇的你一定想对它一探究竟。
那么,下面我们就开始。
拆焊Flash芯片
为了读取Flash芯片的内容,有以下两个基本途径:
直接将导线连接到 芯片的引脚
把芯片拆下来,插到另一块板子上
下面介绍的Flash为BGA(球形栅格阵列)封装——无外露引脚。因此,只能选择拆焊的方法。
拆焊法的优点:
可避免对电路板上其他器件造成影响;
可以很容易看到芯片底部的布线;
可用其他芯片或微控制器代替原芯片。
一些不便之处:
电路在缺少完整器件的情况下无法运行;
在拆卸过程中,一些邻近器件可能被损坏;
如果操作不恰当,Flash本身可能毁坏。
OK,拆焊是吧?你看,下图所示的热风枪简直就是神器。只要将芯片周围加热,便可以很容易地拿下芯片:
这种办法简单、快速只是可能伤及无辜——焊掉邻近的元件,所以,务必小心翼翼。
下图显示芯片拆下后PCB的布线。观察图片,猜想底部的两列引脚为空引脚,因为他们压根就没接入电路。
用KiCAD定制分线板
现在该做什么?BGA封装简直就是一团糟,依然无法外接导线。
一种可行的方法是制作分线板。通常,分线板是将芯片的所有针脚的位置“镜像”下来,这样就能将芯片的引脚引接出来。
为此,我们首先要搜集芯片的相关信息。大多数情况下,芯片的型号都印制在芯片上,这样我们就很容易识别。如上图,芯片上第一行为MXIC代表Macronix International公司,第二行为芯片的具体型号MX25L3255EXCI datasheet 。以下为datasheet资料:
PCB的设计可由KiCAD ,常用的EDA软件实现。
分线板的设计过程与其他PCB板一样:
新建电路板,画出电路简图,标明元器件的具体型号
确定芯片的具体尺寸
根据之前datasheet的资料。我们添加1个4×6的网格作为整个芯片的BGA封装,2个1×4的网格作为连接芯片8个有效引脚的接线柱。最后一步是,用线路将这些器件连接起来:
转接板的设计到此为止,接下来是如何把设计转化成的PCB。
PCB制作
PCB就像是由两层铜和一层基板压制成的三明治,导线分布在铜上面。
根据制作流程,分为:
蚀刻法
数控铣法
以下为两种方法的具体步骤。
蚀刻法
蚀刻,即是用化学药品逐步除去铜的过程。我们先用油墨保护覆铜板上的线路及要保留下来的铜。
1、首先,用热转印法制作PCB。PCB电路图用激光打印机打印在亮光纸上。然后,把亮光纸紧贴在覆铜板上,加热和施以压力,使亮光纸上的电路图转印到覆铜板上。通常,这个过程用熨衣服的熨斗即可完成,但是专用的压制器会使加热及受力更加均匀,更容易成功。
2、接下来是蚀刻,将整块PCB板浸没在腐蚀液,以此来去除多余的铜。
蚀刻后的分线板,转印的墨粉还附着在上面:
除去墨粉后:
现在可以准备手工焊接了。微型焊接与正常焊接一样,只是器件的尺寸极小,因此需要借助显微镜。
此外,传统的焊接用的是线状的焊锡丝,而BGA微型焊接用的是锡球。
接下来,开始重整锡球:
将一个新的锡球放置在凹槽上,加热,熔化锡球;
校准芯片和板子;
回流。
锡球重整完成:
芯片焊接完成后的最终结果:
数控铣
作为替代方法,数控铣仅是将需要的线路和剩余的铜隔离开来而已。
(1)5X5的BGA通常用于制作 PCB,而4X6的常用于分线板。我们设计5X5的是为了该分线板可以直接插接在通用EEPROM 编程器的ZIF插槽里,电路简图如下:
(2)芯片的尺寸与前面设计的4X6的一样,只是网格变成5X5,板上的布线也稍显复杂:
(3)由于KiCAD无法直接生成与数控铣兼容的目标文件,因此,我们用Flatcam接收Gerber文件并确定数控铣隔离的导线的路径:
(4)接下来将生成的STL文件导入bCNC——数控铣的终端控制程序,如下图所示:
雕刻过程中:
(5)板子雕刻完成:
最终结果:
(6)下一步,涂覆阻焊层,保护铜不被氧化,并用紫外灯固化:
(7)阻焊层覆盖了BGA的铜片及1X4的接线柱,我们得刮掉这个薄层,使铜片露出来:
(8)给各个节点焊锡:
(9)回到数控铣,打孔,切削PCB的边缘:
(10)最终成品,BGA焊接在板子上,准备插到EEPROM编程器上:
结论
了解了如何拆焊Flash芯片和如何设计PCB,以及制作PCB的两种不同方法。
来源:STM32嵌入式开发
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。
cathy 在 提交
关于STM32对内部Flash的保护
为了防止对Flash的非法访问,所有STM32的芯片都提供对Flash的保护,具体分为写保护和读保护。
如果对Flash设置了写保护,那就无法对Flash进行编程和擦除。在开发STM32的时候,如果出现这种情况,通常仿真器都支持对Flash进行解锁,像jlink,stlink等仿真器都支持这个功能。
在使用MDK进行调试的时候,可能会遇到如下图所示的报错信息,这时候就要排查Flash是不是被保护起来了。
读保护即大家通常说的“加密”,是作用于整个Flash存储区域。一旦设置了Flash的读保护,内置的Flash存储区只能通过程序的正常执行才能读出,而不能通过下述任何一种方式读出:
写保护是以四页(1KB/页) Flash存储区为单位提供写保护,对被保护的页实施编程或擦除操作将不被执行,同时产生操作错误标志,读与写设置的效果见下表:
当Flash读保护生效时,CPU执行程序可以读受保护的Flash区,但存在两个例外情况:
STM32还提供了一个特别的保护,即对Flash存储区施加读保护后,即使没有启用写保护,Flash的第 0 ~ 3 页也将处于写保护状态,这是为了防止修改复位或中断向量而跳转到RAM区执行非法程序代码。
Flash保护的相关函数
FLASH_Unlock(); //Flash解锁 FLASH_ReadOutProtection(DISABLE); //Flash读保护禁止 FLASH_ReadOutProtection(ENABLE); //Flash读保护允许
STM32如何设置读保护和解除读保护?
读保护设置后将不能读出Flash中的内容。
如何设置读保护
在程序的开头加入“设置读保护”的代码即可,每次运行代码时都检查一下,如果没有开就打开,如果打开了就跳过。其中,设置读保护的代码如下:
int main(void) { ... if (FLASH_GetReadOutProtectionStatus()!=SET)//检查设置读保护与否 { FLASH_Unlock(); //写保护时可以不用这句话,可用可不用 FLASH_ReadOutProtection(ENABLE); //设置读保护 } ... while(1) { ... } }
上面的代码执行后,使用j-link就不能读出程序了,实现了代码读保护。需要注意的是,芯片读保护后无法再次烧写新的程序到Flash中,必须要解除读保护才可以。但是当解除读保护的时候STM32会自动擦除整个Flash,起到保护数据的作用。
通过代码解除Flash保护
解除读保护可以设置在按键里面,方便实现解锁,也可以设置在命令中。如下是解除读保护代码:
void Off_Protect(void) //关闭保护 { if(FLASH_GetReadOutProtectionStatus() != RESET) { FLASH_Unlock(); //不解锁FALSH也可设置读保护,可用可不用 FLASH_ReadOutProtection(DISABLE); FLASH_Lock(); //上锁 } }
程序中设置一个按键或者命令,可以随时解除Flash的读保护,让芯片又可以重新烧录程序。如果没有留,还可以专门写一个程序,下载到RAM中去运行,用来解除读保护。
注意:执行后,Flash会自动全部擦除。
int main(void) { Chip_Init(); FLASH_Unlock(); //不解锁FALSH也可设置读保护,可用可不用 FLASH_ReadOutProtection(DISABLE); }
通过ST-Link Utility来解除Flash保护
在STLink连接目标板的情况下打开程序烧写软件ST-Link Utility,在菜单栏的Target下选择connect,因为这时候Flash已经被锁住了,能看到如下图所示的错误提示。
下面来操作如何解除Flash保护。
请确保当前已经正确连接了STLink和目标板,在菜单栏Target里打开Option Bytes...选项,发现在这里Read Out Protection选项是Enable,这个表示无法通过SWD读取STM32内部Flash的程序。
将Read Out Protection选项设置为Disable,并点击Apply。
这时候Flash已经成功解锁了,跟上文提到的解除Flash保护的结果一样,内部Flash已经被擦除了,如下图红框中所示。
完成以上步骤之后,在菜单栏Target下选择Disconnect断开与目标板连接。
重新进入MDK,可以正常对目标板烧写程序了。
通过ST-Link Utility来设置Flash保护
在菜单栏Target里打开Option Bytes...选项,可以看到下面有Flash sector protection选项。选择Select all之后,发现所有Page的Protection项都已经变成Write Protection了,只要选择Apply选项就可以对Flash进行写保护,如上图所示。
本文转载自:STM32嵌入式开发
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。
1、前言
单片机内部的FLASH除了存储固件以外,经常将其分成多个区域,用来存储一些参数或存储OTA升级的待更新的固件,这时就会涉及到单片机内部FLASH的编程和擦除操作,STM32不同系列的单片机内部FLASH特性和扇区大小都不太一样,如果不注意这些细节,那就等着爬坑吧
1、FLASH的分区以及扇区大小
FLASH擦除是按照扇区擦的,所以这个很重要,在工程中全局搜索 FLASH_PAGE_SIZE 宏就可以查看该芯片的页(扇区)大小,改宏在 stm32xxx_hal_flash.h中有定义
2、FLASH擦拭后的状态
F1和F4系列的芯片FLASH在擦除后会是0xFFFFFFFF,而L1系列的芯片FLASH在擦除后是0x00000000!!!!!
3、FLASH的编程速度
L1芯片内部FLASH编程速度比F1慢50倍!!!所以在使用L1芯片写入数据时相对于F1慢是正常的
2、STM32 F1、F4、L1系列内部FLASH分区及大小
1、STM32F1系列
对于F1系列的芯片大容量产品的FLASH主存储器每页大小为2K,如【下图】,而中容量和小容量的产品每页大小只有1K
2、STM32F4系列
分为2个Bank,每个Bank分为12个扇区,前4个扇区为16KB大小,第五个扇区是64KB大小,剩下的7个扇区都是128K大小
3、STM32L1系列
3、STM32 F1、F4、L1系列内部FLASH编程时间
信息参考对应芯片的数据手册的 Electrical characteristics 章节
1、STM32F1系列
可以看出F1系列内部FLASH页擦除时间最大为40ms,半字写入的时间为52.2us,比如按字写入1024字节数据,需要26.8ms,还是比较快的
2、STM32F4系列
可以看出F4系列内部不同扇区擦除时间也不一样的,字写入的时间为16us,比如按字写入1024字节数据,只需要4ms,非常快
3、STM32L1系列
可以看出L1系列内部FLASH页擦除和编程的时间都是3.28ms,比如按字写入1024字节数据,需要840ms,非常慢;但是擦除是比较快的
版权声明:本文为CSDN博主 hurryddd 的原创文章,
遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/m0_37845735/article/details/108439644
一.将DSP的Flash里面的函数转移到RAM中
对于独立的嵌入式系统,需要把程序存入non-volitale存储单元中,常用的也就是flash。但是程序在flash中运行相对在RAM中行,速度会变慢很多,具体有多慢,拿28335来说吧,假设系统时钟为150MHz,在RAM中运行时频率还是150MHz,而放在flash中,频率会降到90-95MHz,参照Ti手册SPRA958L,这对于有些对实时性要求较高的函数功能,是不可接受的。所以在系统上电时,把对实时性要求高的函数转移到RAM中去。
下面以initflash函数为例,具体步骤如下:
(1)、将函数定位到section:
#pragma CODE_SECTION(InitFlash, "secureRamFuncs")
当遇到InitFlash(),就到段secureRamFuncs去运行。
当有多个函数需要转移时,重复使用#pragma CODE_SECTION(“函数名", "secureRamFuncs")即可。
即使有多个#pragma CODE_SECTION,后面的步骤只需要一次。
(2)、section分配到memory(红色为memory)。
意思是到FLASH去下载InitFlash(),下载到SECURE_RAM,然后要到SECURE_RAM去运行程序,这个过程给出了下载地址和目标地址。注意此时SECURE_RAM中还没有代码。
1. SECTIONS
2. {
3. /*** User Defined Sections ***/
4. secureRamFuncs: LOAD = FLASH,PAGE = 0
5. RUN =SECURE_RAM, PAGE = 0
6. //定义FLASH和SECURE_RAM的首地址secureRamFuncs_loadstart和secureRamFuncs_loadstart以代替绝对地址
7. LOAD_START(_secureRamFuncs_loadstart),
8. LOAD_SIZE(_secureRamFuncs_loadsize),
9. RUN_START(_secureRamFuncs_runstart),
10. }
(3)、用memcpy()将经过#pragmaCODE_SECTION设定的函数从FLASH弄到SECURE_RAM中去。注意不是将FLASH的东西全部弄到SECURE_RAM中。
1. #include <string.h>
2. //实际应用中这一部分声明可有可无
3. extern unsigned intsecureRamFuncs_loadstart;
4. extern unsigned intsecureRamFuncs_loadsize;
5. extern unsigned intsecureRamFuncs_runstart;
6. void main(void)
7. {
8. /* Copy the secureRamFuncs section */
9. memcpy(&secureRamFuncs_runstart,&secureRamFuncs_loadstart,(Uint32)&secureRamFuncs_loadsize);
10. /* Initialize the on-chip flash registers*/
11. InitFlash();
12. }
二.将MCU的内嵌Flash里的部分代码运行在 RAM 中
MCU 异于资源丰富的linux 平台。MCU(如:基于Cortex V6M 的Cortex M0+ 等) Code通常运行在内嵌Flash中。在某些特定应用场合,需要将部分函数运行于RAM 中。为解决次问题,笔者实现了一种解法,具体做法如下:
1. 实现要运行在RAM的 routine, 本routine 使用纯汇编实现, 如:
__asm void program_word2addr(uint32_t addr, uint32_t data)
{
push {r3, r4, r5, lr} ;save some regsiters
/*your code for this routine*/
pop {r3, r4, r5, pc}
}
2. 编译时,采用code 与运行位置无关的编译选项 如 (Keil --apcs /ropi/rwpi), 生成 *.axf;
3. 通过fromelf -c 将生成 *.axf 反汇编,找到对应program_word2addr 实现部分, 并将routine 对应的binary code Copy 到所要应用的 Code 中,以只读数组的形式出现:
如:
const staic uint16_t s_flashProg2AddressCode[16] = {...., ....}
4. 定义 一个全局数组, 如 static uint16_t g_code[16], size正好等于 s_flashProg2AddressCode的长度;
5. 定义一个函数指针, 如 static void (*callFlashPrg2Address)(uint32_t addr, uint32_t data)
6. 定义一个函数实现将Code 运行与 RAM如:
void run_prgcode_onram(uint32_t addr, uint32_t data)
{
memcpy(g_code,s_flashProg2AddressCode,32 );
callFlashPrg2Address = (void (*)(uint32_t addr, uint32_t data))((uin32_t)g_code + 1);
callFlashPrg2Address (address, data);
}
run_prgcode_onram, 便可以将program_word2addr 运行于RAM中。
callFlashPrg2Address = (void (*)(uint32_t addr, uint32_t data))((uin32_t)g_code + 1); +1 的目的,时由于运行平台为 Cortex V6M , 采用的thumb指令集,根据ARM Spec 要求完成。
callFlashPrg2Address (address, data); 则是实现RAM运行program_word2addr 的关键所在。
本文摘自
https://blog.csdn.net/lansedeyuntkn/article/details/54632541
https://blog.csdn.net/wqzwiseman/article/details/76531653
10月18日,Holtek推出A/D NFC Flash MCU HT45F4050,其最大特点为MCU内建NFC Tag接口,终端产品不须采用MCU加NFC Tag IC的方案,可有效降低零件成本。
HT45F4050 NFC接口RF Data Rate为106 kbit符合NFC Forum Type2及ISO1443 Type A标准,并包含有256 Bytes的NFC EEPROM及64 Bytes的NFC SRAM,可符合NFC Tag应用标准。
HT45F4050另外还包含8K×16程序内存、256×8 RAM、64×8 True EEPROM、12-bit A/D Converter、一组SPI/I2C接口、一个UART接口、4个Timer及一个4-SCOM LCD Driver,提供48LQFP封装,可符合多样应用的需求。
来源:HOLTEK