大家好,我是痞子衡,是正经搞技术的痞子。今天痞子衡给大家介绍的是恩智浦i.MX RTxxx系列MCU的OTP

  在i.MXRTxxx启动系列第二篇文章 Boot配置(ISP Pin, OTP) 里痞子衡提到了OTP,部分Boot配置都存储在OTP memory里,但是对OTP的介绍仅仅浅尝辄止,没有深入,今天痞子衡就为大家再进一步介绍OTP。

  OTP是i.MXRTxxx里一块特殊的存储区域,用于存放全部芯片配置信息,其中有一部分配置信息和Boot相关。这块特殊存储区域并不在ARM的4G system address空间里,需要用特殊的方式去访问(读/写),如何访问OTP是本篇文章的重点。

一、OTP基本原理

1.1 OTP属性(OTP, Shadow Lock)

  OTP本质上就是i.MXRTxxx内嵌的一块One Time Programmable memory,仅可被烧写一次,但可以被多次读取。OTP memory的烧写大部分是按Word进行的(也有极少部分是按Bit进行的),初始状态下所有OTP bit均为0,通过特殊的烧写时序可以将bit从0改成1,一旦某bit被烧写成1后便再也无法被修改(可理解为硬件熔丝烧断了无法恢复)。

  i.MXRT600的OTP memory总地址空间有16Kbit(地址范围为0x000 - 0x7FF),分为64个BANK,每个BANK含8个word(1word = 4bytes)。下图中4、8、9(总范围是0x000 - 0x1FF)是OTP word索引地址(也叫index地址),其与OTP空间地址对应关系是:

otp_address = otp_index * 0x4

  OTP memory空间除了OTP特性外,还有Shadow Lock控制特性,Shadow Lock控制是OTP memory的标配,Lock控制有二种:第一种是WP,即写保护,用于保护OTP区域对应的shadow register不能被改写;第二种是RP,即读保护,被保护的OTP区域对应的shadow register不能被读取。看到这里,你会发现i.MXRTyyyy的efuse里的LOCK控制是同时针对efuse本身和shadow register的;而i.MXRTxxx的OTP里的LOCK控制仅针对shadow register,那么对OTP本身的保护在哪里呢?先别急,后面会给你答案。

  Shadow Lock控制在OTP的BANK0_word4、BANK1_word8/9,如下是RT600具体Lock bit定义:

关于OTP空间所有bit定义详见Reference Manual里的otpmap Descriptions。

1.2 OCOTP控制器与Shadow Register

  i.MXRTxxx内部有一个硬件IP模块叫OCOTP_CTRL,即OCOTP控制器,对OTP memory的读写控制操作其实都是通过这个OCOTP控制器实现的,下图是OCOTP_CTRL模块图:

  OCOTP_CTRL模块寄存器一共分两类:一类是IP控制寄存器,用于实现对OTP memory的读写操作时序控制;一类是Shadow register,用于上电时自动从OTP memory获取数据并缓存,这样我们可以直接访问Shadow register而不用访问OTP memory也能获取OTP内容(注意:当芯片运行中烧写OTP,Shadow register的值并不会立刻更新,需要执行IP控制器的reload命令或者将芯片reset才能同步)。

  下图是RT600里的OCOTP_CTRL模块寄存器map,其中Shadow register寄存器偏移地址范围是0x000 - 0x7FF(注意并不是所有OTP Word都会被加载到Shadow register里,虽然Shadow register预留了全部的OTP位置。这点与i.MXRTyyyy efuse会全部加载到Shadow register不同,原因是i.MXRTxxx的OTP里会有很多Peripheral寄存器加载初值,如果这些OTP值目的是加载Peripheral,那就没有必要再加载到Shadow register里,而i.MXRTyyyy的efuse值没有加载Peripheral寄存器的用途)。IP控制寄存器偏移地址范围是0x800 - 0x82C:

  痞子衡写过关于i.MXRTyyyy的eFUSE烧写的文章 飞思卡尔i.MX RTyyyy系列MCU启动那些事(5)- 再聊eFUSE及其烧写方法 ,其实i.MXRTxxx的OCOTP控制器与i.MXRTyyyy里的OCOTP控制器非常相似,虽然两者在寄存器组织上有差异,但其共同点更多。不过提及差异,有一个地方痞子衡不得不提,那就是CTRL寄存器的bit15,在i.MXRTyyyy上这个bit是保留的,但是i.MXRTxxx上这个bit为WORDLOCK,顾名思义即提供对操作的OTP word区域进行保护(主要是写保护),下一节介绍的efuse-program-once命令第三个可选参数[nolock/lock]其实就是利用了这个bit。

二、使用blhost烧写OTP

  OTP memory的烧写是通过OCOTP_CTRL模块来实现的,我们当然可以在Application中集成OCOTP_CTRL的驱动程序,然后在Application调用OCOTP_CTRL的驱动程序完成OTP的烧写,但这种方式并不是痞子衡要介绍的重点,痞子衡要介绍的是通过Serial ISP模式配套的blhost.exe上位机工具实现OTP的烧写。

  痞子衡在前面的文章里介绍过如何进入Serial ISP模式与BootROM通信,此处假设你已经使用blhost与BootROM建立了通信。让我们再来回顾一下blhost的命令help,可以得知efuse-program-once这个命令就是我们想要的命令。

PS D:\NXP-MCUBootUtility\tools\blhost2_3\win> .\blhost.exe
usage: D:\NXP-MCUBootUtility\tools\blhost2_3\win\blhost.exe
[-p|--port <name>[,<speed>]]
[-u|--usb [[[<vid>,]<pid>]]]
-- command <args...> Command:
efuse-program-once <addr> <data> [nolock/lock]
Program one word of OCOTP Field
<addr> is ADDR of OTP word, not the shadowed memory address.
<data> is hex digits without prefix '0x'
efuse-read-once <addr>
Read one word of OCOTP Field
<addr> is ADDR of OTP word, not the shadowed memory address.

  让我们试一下efuse-program-once这个命令,开始试之前要解决2个问题:

  addr参数到底是什么地址?帮助里说是OTP word address,其实这个地址就是1.1节里介绍的word index,index范围为0x000 - 0x1FF,对应512个可读写操作的OTP Word。

  data参数到底是什么格式?帮助里说是hex digits without prefix '0x',但是似乎没有指明长度,我们知道每一个index对应的是4byte,那就应该是8位16进制数据(实测下来必须要填8位,如果是非8位会返回Error: invalid command or arguments)。

  弄清了问题,那我们做一个小测试:要求将OTP里的REVOKE_IMG_KEY word的最低byte烧写成0x5A。翻看OTP Memory Footprint表,找到REVOKE_IMG_KEY的index地址是0x66(对应Shadow register地址是0x40130198),命令搞起来:

PS D:\NXP-MCUBootUtility\tools\blhost2_3\win> .\blhost.exe -u -- efuse-program-once 0x66 0000005A

Inject command 'efuse-program-once'
Successful generic response to command 'efuse-program-once'
Response status = 0 (0x0) Success.

PS D:\NXP-MCUBootUtility\tools\blhost2_3\win> .\blhost.exe -u -- efuse-read-once 0x66

Inject command 'efuse-read-once'
Response status = 0 (0x0) Success.
Response word 1 = 4 (0x4)
Response word 2 = 90 (0x5a)

  看起来命令执行正常,如果此时你用J-Link去读取对应Shadow register的值,你会发现刚才烧写的OTP数据并没有自动同步更新到Shadow register里。与i.MXRTyyyy系列下Flashloader里efuse program操作有所不同的是,i.MXRTxxx Serial ISP模式下blhost里的efuse-program-once命令仅包含program命令,没有集成reload命令。因此想要刷新Shadow register,必须复位芯片。

  至此,恩智浦i.MX RTxxx系列MCU的OTP痞子衡便介绍完毕了,掌声在哪里~~~

欢迎订阅

文章会同时发布到我的 博客园主页CSDN主页微信公众号 平台上。

微信搜索"痞子衡嵌入式"或者扫描下面二维码,就可以在手机上第一时间看了哦。

痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU启动那些事(4)- OTP及其烧写方法的更多相关文章

  1. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU启动那些事(3)- Serial ISP模式(blhost)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RTxxx系列MCU的Serial ISP模式. 在上一篇文章 Boot配置(ISP Pin, OTP) 里痞子衡为大家 ...

  2. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU启动那些事(8)- 从Serial(1-bit SPI) NOR恢复启动

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RTxxx系列MCU的1-bit SPI NOR恢复启动. 在前几篇里痞子衡介绍的Boot Device都属于主动启动的 ...

  3. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU启动那些事(1)- Boot简介

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RTxxx系列MCU的BootROM功能简介. 截止目前为止i.MX RTxxx系列已公布的芯片仅有一款i.MXRT60 ...

  4. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU启动那些事(2)- Boot配置(ISP_Pin, OTP)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RTxxx系列MCU的Boot配置. 在上一篇文章 Boot简介 里痞子衡为大家介绍了Boot基本原理以及i.MXRTx ...

  5. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU启动那些事(6.1)- FlexSPI NOR连接方式大全(RT600)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RT600的FlexSPI NOR启动的连接方式. 痞子衡前段时间一鼓作气写完了三篇关于i.MXRT1xxx系列Flex ...

  6. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU启动那些事(6.B)- FlexSPI NOR连接方式大全(RT500)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MX RT500的FlexSPI NOR启动的连接方式. 这个i.MXRT FlexSPI NOR启动连接方式系列文章,痞子衡 ...

  7. 痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU启动那些事(7)- 从SD/eMMC启动

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是恩智浦i.MXRTxxx系列MCU的SD/eMMC卡启动. 关于 i.MXRT 启动设备,痞子衡之前写过很多篇文章,都是关于串并行 NO ...

  8. 痞子衡嵌入式:飞思卡尔Kinetis系列MCU启动那些事(1)- KBOOT架构

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔Kinetis系列MCU的KBOOT架构. Bootloader是嵌入式MCU开发里很常见的一种专用的应用程序,在一个没有Boo ...

  9. 痞子衡嵌入式:飞思卡尔Kinetis系列MCU启动那些事(9)- KBOOT特性(IntegrityCheck)

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是飞思卡尔Kinetis系列MCU的KBOOT之完整性检测(Integrity Check)特性. Application完整性检测是非常 ...

随机推荐

  1. Vue中Form表单验证无法消除验证问题

    iView的表单api给出了一个resetFields方法,用于重置整个表单输入的内容并清除验证提示. 但是有时候需要只消除部分的iview的resetFields方法源码是这样的resetField ...

  2. 从比特币、以太坊、libra的不同特点认识move语言

    关于比特币.以太坊.libra,我们知道他们是不同的区块链应用,那么他们的根本差别在哪里呢. 其实,单从白皮书的标题,就可以大概看出三个项目在设计目标上的差异. 比特币的目标是 -- 可编程货币(Pr ...

  3. MIT线性代数:11.矩阵空间、秩1矩阵和小世界图

  4. AndroidOS体系结构

    首先上图一张 对照着图,我们再来看Android 系统的体系结构就爽多了.我们从底层向上进行分析. 一.Linux 内核层 Linux Kernel 基于linux2.6.其核心系统服务如安全性.内存 ...

  5. ASP.NET Core 3.0 gRPC 拦截器

    目录 ASP.NET Core 3.0 使用gRPC ASP.NET Core 3.0 gRPC 双向流 ASP.NET Core 3.0 gRPC 拦截器 一. 前言 前面两篇文章给大家介绍了使用g ...

  6. js中函数的原型

    js中每一个构造函数都有一个prototype的属性,prototype指向一个对象,而这个对象的属性和方法都会被构造函数的实例所继承,因此,需要一些共享的属性和方法可以写在构造函数的原型中 1  用 ...

  7. Python调用函数加括号和不加括号的区别

    Python调用函数加括号和不加括号的区别 # -*- coding: utf-8 -*- #!/usr/bin/env python # @Time : 2018/7/3 10:03 # @Desc ...

  8. Java 8 Streams API 详解

    流式编程作为Java 8的亮点之一,是继Java 5之后对集合的再一次升级,可以说Java 8几大特性中,Streams API 是作为Java 函数式的主角来设计的,夸张的说,有了Streams A ...

  9. 项目——基于httpd镜像演示Dockerfile所有的指令

    基于httpd镜像演示Dockerfile所有的指令: 第一步:创建Dockerfile工作目录 [root@localhost harbor]# mkdir /test [root@localhos ...

  10. C语言:互质

    今天遇到一道奇怪的程序题,和平常的不同.同样都是互质,但是一般的题目都是判断两个数字是否互质,但这道题则是给定一个数字n,要求输出所有小于等于n的与n互质的数,题目已经在下面给出: 质数与互质概念不是 ...