本帖最后由 kai迪皮 于 2022-10-18 11:34 编辑
#申请原创#@21小跑堂
前言
最近在项目中需要使用到极海的APM32F4 芯片,在看到极海的文章悬赏,我也整理了一下自己的一些使用收获跟大家一起分享。权当抛砖引玉了,因个人技术实力有限,文章内容如有偏差错误还望各位同行不吝斧正。
在使用APM32F407的芯片时,我们的使用到了其一个非常有意思的存储区域“OTP”区域,这个区域与普通的Flash不一样。那它有哪些特性呢,又如何使用呢?且同我一一往下看。
1 APM32F4的OTP区域
OTP,它的全称是“One-time programmable bytes ”简单直译便是一次性可编程字节,它的特性就是我们对这个区域只能进行*一次的编程*。APM32F4一共有16块数据块和一个锁定控制块。数据块的每块大小是32个字节,一共有512个字节。其地址区域是:0x1FFF7800——0x1FFF79FF。
这个意味着我们可以保存512个字节的内容在APM32F4上,这些内容经过我们写入该区域后将不会被串改,包括像芯片全擦然后重新下载程序的场景。
2 OTP 区域的作用
搞清楚了这个区域的位置,那我们下一步就是搞清楚这个区域的一个作用或者说应用场景有哪些。由于OTP区域的特性,这意味着它可以保存一些我们产品在使用过程中一下不能改变的重要数据。比如说以下的一些场景:
2.1 外部设备的校准值
我们的产品一般会接入一些传感器,如温度传感器、气体传感器等,或者一些像频率发生器这些设备。这些设备的一个共同点需要进行一些校准,校准的过程我们可以放在生产线上。在生产线上,我们的产品可以专门烧录校准的固件,在产线的标准流程上完成对外部仪器的校准(标准环境下的区间),得到相应的校准值得以保存在OTP区域。然后我们再下载发布固件,以使用这些参数,这样子就可以保证我们的参数不会因为固件升级等对Flash的高危操作而导致校准参数的丢失。
2.2 序列号的保存
我们知道,APM32的芯片都有一个唯一的ID,是芯片的唯一标识,对于芯片厂家而言,这个ID标识这这块芯片从出厂配置至我们用户在使用的流程跟踪,它完成了哪些测试,测试数据如何。厂家都可以通过这个ID追溯。
那对于我们的产品应用而言,我们也会有一个产品序列号的需求。由于芯片UID的编码规则不会给到我们应用端,而且我们也需要一些类似于产品编号的东西(比如APM32F4我会应用于A和B两款不一样的产品),芯片的UID不满足我们的使用需求。
那我们产品ID 的一个重要特性是:不允许更改。那APM32F4的OTP区域就很好的满足了我们的需求。
2.3 产品加密
我们的产品总是会因为各种各样的原因会被“有心之人”进行逆向。我们可以通过使用APM32芯片的唯一UID,再配合一定的加密算法得到一个与芯片UID绑定的信息串保存在OTP区域,每次产品运行时去校准我们的UID和信息串。若我们的固件被“有心之人”复制到同类型的芯片里面,由于UID和信息串无法匹配,这就会他们“复制”的程序无法正常运行。
3 OTP 区域的使用
说了那么多,那这个区域如何“使用”起来呢?对于该区域,我们一般的使用方法是自编程、ISP编程、仿真下载编程等方式。
3.1 自编程方式
该方式使用场景一般是2.1小结的情况,在该场景下,我们只需要把OTP的编程接口预留好就可以了。比如我们下面举个例子。
具体代码的实现流程也非常简单,就是解锁Flash,编程OTP,上锁Flash。
具体代码实现如下:
/* Unlock Flash for Erase or Write*/
FMC_Unlock();
/* Set address*/
address = 0x1FFF7800;
data = 0x20221018;
if (*(volatile uint32_t *)address == 0xFFFFFFFF)
{
/* Read Address data*/
printf("\r\nBefore the programming,address = 0x1FFF7800;data = 0x%08X\r\n", *(volatile uint32_t *)address);
/* Write data in address*/
FMC_ProgramWord(address, data);
}
/* Read data again*/
printf("After the programming,address = 0x1FFF7800,data = 0x%08X\r\n", *(volatile uint32_t *)address);
/* Lock Flash*/
FMC_Lock();
实现仿真截图和串口助手如下图所示:
3.2 ISP 下载编程
在产品烧录固件的时候,我们通常在产线使用的一种烧录方式是ISP烧录。APM32F4也是提供了相应的烧录方式,这里我也演示一下使用ISP方式对OTP区域进行编程。
我们这里选用极海提供的DFUProgrammer[https://geehy.com/uploads/tool/DFUProgrammer.msi]上位机,在PC上安装相应的驱动后,我们按照如下操作对OTP进行编程。
1. 将芯片的BOOT0接高,BOOT1接低。使得芯片进入ISP模式。
2. 使用USB线缆接入我们的产品(PA11/PA12);
3. 在DFUProgrammer搜索连接设备;
4. 在“读取芯片”界面,设置读取地址为0x1FFF7800,大小为0x210,显示模式选择32bit。以显示OTP区域;
5. 修改一个bin文件以保存我们想写入的内容,这里我的是0x00120059;
6. 在“固件升级”界面选择我们的下载文件,地址我这里选择0x1FFF7804,点击“开始更新固件”,得到成功提示窗口;
7. 再次读取OTP区域内容,查看是否编程成功。
以上便是我们使用ISP对APM32F4 OTP区域编程的一个操作流程,很多时候我们不会使用官方提供的操作软件,但是使用的流程都是在ISP流程里面的,同理可得其他ISP的其他软件的操作方式。
3.3 仿真下载编程
在大多数的使用场景下,我们一般使用的烧录器或者编程对我们的芯片进行编程。产线的烧录工具多种多样,但是万变不离其宗,大多数烧录器走的是SWD/JTAG接口对芯片进行编程。
我这里给大家分享一个在日常开发中使用J-Link编程的一个方法。
1. 添加apm32f4xx_otp.s文件进入我们的工程。
2. 修改apm32f4xx_otp.s文件内容为我们所需要的值,如下图。
3. 添加APM32F4的OTP下载算法至我们的工程。
4. 编译工程并下载。
5. 在仿真界面查看OTP区域内容,看看是否编程成功。
4 总结
APM32F4的OTP区域是一个非常好的功能,给我们广大用户以使用便利。它可以用用序列号保存,固件加密等使用场景。各位小伙伴都有对OTP区域使用在什么场景下呢?欢迎大家一起在评论区讨论。
本文的参考代码示例,请移步查阅:
APM32F4xx_SDK_V1.2_OTP.zip
(2.85 MB)
|
学习一下
@21小跑堂 :好的,Thanks♪(・ω・)ノ
楼主好,可以给您设置原创标识,但极海的征文活动和21ic的原创申请活动不可以重复参与哦。