STM32CubeProgrammer OTP management

Revision as of 11:21, 26 July 2022 by Registered User (→‎Examples)
Applicable for STM32MP13x lines, STM32MP15x lines

STM32CubeProgrammer can be used to read and update the OTP of the device, which is seen as a partition on the device.

This page describes the format of the partition used by the embedded programming service to allow OTP access by STM32CubeProgrammer (see AN5275: USB DFU/USART protocols used in STM32MP1 Series bootloaders for protocol details).

Refer to STM32CubeProgrammer article to know how to use the STM32CubeProgrammer that is the official STMicroelectronics tool for update OTP on STM32 platforms.

1. OTP partition[edit source]

The OTP partition is identified with the reserved Id 0xF2 and is exported as:

  • a specific alternate setting of the USB DFU [1].
  • a special operation: OTP write (0xF2), for UART download command (0x31) and read partition command (0x12)

This is used to access the STM32MP's on-chip one time-programmable memory by the ST32CubeProgrammer (see option -otp). It is only supported in the embedded programming service = U-Boot.

The OTP partition must be programmed without a header and have a fixed size following the structure described in chapter #Data Structure.

The OTP operation can be limited in OP-TEE or in SP_MIN, e.g for security reason. In OpenSTLinux distribution the service is available only for open device and for serial boot (see OP-TEE PTA for details) and the OTP partition is only present when the operations are supported.

1.1. Access operation[edit source]

For read operation, the host requests the OTP partition data, and the platform replies with all the partition content.

For write operation, the host needs to send the full structure containing one or more modifications. The platform analyses each field.

First the OTP values are updated, then the OTP controls (such as lock) are updated.

After any write operation, a read must be done to update the Host information.

1.2. Data structure[edit source]

The data structure version 2 is described in the table below.

For ecosystem release ≥ v4.0.0 , the same structure is used for

The previous data structure version 1 used for ecosystem release ≤ v3.1.0 is no more used.

Its size is 776 bytes with 96 OTP for STM32MP1 series = (2 * 96 + 2) * 4 bytes for 32 bits word, with M = 0 to 95:

Word Field name Description
0 Version Version of this structure = 2
1 Global State bit-field with state of BSEC the OTP provider[GlobalState 1]
2 OTP[0] OTP value
  • 0x0 on read error or read lock
  • 0x0 to write with unmodified value (lock only)
3 OTP[0] status Status of OTP:
  • [0]: 1 bit read error detected: 1 = OTP value isn't valid
  • [26]: 1 bit lock error
  • [27]: 1 bit sticky programming lock
  • [28]: 1 bit shadow write sticky lock
  • [29]: 1 bit shadow read sticky lock
  • [30]: 1 bit permanent write lock
  • [31]: 1 bit prog requested an update of this OTP, value and/or status (only for write, always 0 on read)
4 OTP[1] OTP value
5 OTP[1] status Status of OTP
... ... ...
2+M*2 OTP[M] Value of OTP M
3+M*2 OTP[M] status Status of OTP M
  1. Global state: is not used during a write operation, its value should be 0 for write request
  2. Provisioning = OTP-SECURED open_device BSEC state, the secrets are not provisioned (see Life cycle for detail).
  3. Secured = OTP-SECURED closed_device BSEC state, the secrets are provisioned and protected (see Life cycle for detail).
  4. Hardware Key set bit indicates the provisioned firmware encryption key for STM32MP13x lines More info.png, not used for STM32MP15x lines More info.png
  5. Encrypted data bit is reserved to indicate an encrypted content of OTP for read or write operation, not yet implemented.

You can write OTP without read operation by using a buffer initialized with 0x0, except the version word set to 0x2.

You can also read the current value of the OTP in a buffer and reuse the same buffer for the write operation, as bit 31 of OTP status is 0 for read.

To update an OTP, you need to update the used buffer for the modified OTP:

  • the OTP value, set at 0x0 if unmodified for lock only operation
  • the OTP status lock values for prog lock and/or read lock after OTP value update, set to 0x0 if unmodified
  • request the update: set the bit 31 of the OTP status to indicate a modification request of this OTP

The operation is interrupted on the first error.

1.2.1. Examples[edit source]

With OTP[0] status bit-field values:

  • programmation request: bit31 => 0x80000000
  • permanent lock: bit 30 => 0x40000000

Some simple operations are, with the structure full of zero except:

  • write X in OTP_N
    • OTP[N] value = X
    • OTP[N] status = 0x80000000
  • prog lock OTP N
    • OTP[N] value = 0x0
    • OTP[N] status = 0xC0000000
  • write and lock OTP N
    • OTP[N] value = X
    • OTP[N] status = 0xC0000000
  • write value and sticky read+permanent lock for OTP N to N+2
    • OTP[N] value = X
    • OTP[N] status = 0xE0000000
    • OTP[N + 1] value = Y
    • OTP[N + 1] status = 0xE0000000
    • OTP[N + 2] value = Z
    • OTP[N + 2] status = 0xE0000000

1.2.2. Examples with STM32Programmer CLI[edit source]

1.2.3. Examples with dfu-util[edit source]

Start the DFU stack with the U-Boot command:

stm32prog usb 0

Search the alternate associated to OTP, phase 0xf2:

 dfu-util -l
 dfu-util 0.9

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2016 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/

Found DFU: [0483:df11] ver=0200, devnum=9, cfg=1, intf=0, path="1-5.4.4", alt=3, name="@PMIC/0xf4/1*8Be", serial="004100323338511634383330"
Found DFU: [0483:df11] ver=0200, devnum=9, cfg=1, intf=0, path="1-5.4.4", alt=2, name="@OTP/0xf2/1*776Be", serial="004100323338511634383330"
Found DFU: [0483:df11] ver=0200, devnum=9, cfg=1, intf=0, path="1-5.4.4", alt=1, name="@virtual/0xf1/1*512Be", serial="004100323338511634383330"
Found DFU: [0483:df11] ver=0200, devnum=9, cfg=1, intf=0, path="1-5.4.4", alt=0, name="@FlashLayout/0x00/1*256Ke", serial="004100323338511634383330"
1.2.3.1. Read OTP with upload command[edit source]
 dfu-util -a 2 -U otp.bin
dfu-util 0.9
 
Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2016 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/

Opening DFU capable USB device...
ID 0483:df11
Run-time device DFU version 0110
Claiming USB DFU Interface...
Setting Alternate Setting #2 ...
Determining device status: state = dfuIDLE, status = 0
dfuIDLE, continuing
DFU mode device DFU version 0110
Device returned transfer size 4096
Copying data from DFU device to PC
Upload	[=========================] 100%          776 bytes
Upload done.

Then you can display the OTP structure version 2, including the header. For example:

 hexdump otp.bin
0000000 0002 0000 0000 0000 0017 0000 0000 3000
0000010 8000 0000 0000 5000 0000 0000 0000 1800
0000020 0000 0000 0000 0000 0000 0000 0000 0000
*
0000040 beef dead 0000 4000 0000 0000 0000 1000
0000050 0000 0000 0000 0000 0000 0000 0000 0000
0000060 0000 0000 0000 0000 f0f9 7cf5 0000 4000
0000070 0032 0041 0000 4000 5116 3338 0000 4000
0000080 3330 3438 0000 4000 75aa 1296 0000 5800
0000090 215e 2931 0000 4000 0140 7a55 0000 3000
00000a0 13ec 0690 0000 4000 0042 5e36 0000 4000
00000b0 0000 0000 0000 4000 0000 0000 0000 4000
00000c0 3023 4013 0000 4000 bbcd 4e31 0000 5000
00000d0 27dd 51e8 0000 5000 cc11 aabb 0000 1000
00000e0 0000 0000 0000 1000 0000 0000 0000 1000
*
0000100 0000 0000 0000 1000 0000 0000 0000 7800
0000110 0000 0000 0000 7800 0000 0000 0000 7800
*
0000140 0000 0000 0000 7800 3e40 aa33 0000 5800
0000150 0dda b5e9 0000 5800 4678 f15f 0000 5800
0000160 1400 8ab4 0000 5800 fe3a b74e 0000 5800
0000170 3b1b f0a0 0000 5800 16b3 01e0 0000 5800
0000180 79dd d06a 0000 5800 6fbe 48b9 0000 5800
0000190 d352 20fb 0000 5800 dbf4 6732 0000 5800
00001a0 95f9 edc3 0000 5800 5575 cdf1 0000 5800
00001b0 d3d0 418f 0000 5800 d994 0bb7 0000 5800
00001c0 29d0 8dc9 0000 5800 0000 0000 0000 3000
00001d0 8000 42e1 0000 4000 e448 0000 0000 4000
00001e0 2301 1272 0000 4000 0000 0000 0000 0000
00001f0 0000 0000 0000 0000 0000 0000 0000 0000
*
00002e0 0000 0000 0000 0000 0000 0000 0000 4000
00002f0 0000 0000 0000 4000 0000 0000 0000 0000
0000300 0000 0000 0000 0000                    
0000308

In this example the OTP7 value is 0xdeadbeef at 0x40 offset and the status 40000000 indicate a permanent lock.

1.2.3.2. Write OTP with download command[edit source]

To update OTP you need to prepare a binary file with the operation to performs, see OTP status descriptionn #Data structure for details.

You can update the previous file or start with a empty file, and request programmation with bit31 of the status to update.

For example:

 hexdump otp.bin
0000000 0002 0000 0000 0000 0000 0000 0000 0000
0000010 0000 0000 0000 0000 0000 0000 0000 0000
0000020 0000 0000 0000 0000 0000 0000 0000 0000
*
0000040 0000 0000 0000 0000 0000 0000 0000 0000
0000050 4567 0123 0000 C000 DEF0 8ABC C000 0000 
0000060 0000 0000 0000 0000 0000 0000 0000 0000
*
0000300 0000 0000 0000 0000                    
0000308

Request write and lock in OTP9 and OTP10 with

  • 0x50: OTP[9] value = 0x01234567
  • 0x54: OTP[9] status = 0xC0000000
  • 0x58: OTP[10] value = 0xABCDEF0
  • 0x5C: OTP[10] status = 0xC0000000

See #Examples for other operations.

Download this file with dfu-util

 dfu-util -a 2 -D otp.bin
dfu-util -a 2 -D otp.bin
dfu-util 0.9

Copyright 2005-2009 Weston Schmidt, Harald Welte and OpenMoko Inc.
Copyright 2010-2016 Tormod Volden and Stefan Schmidt
This program is Free Software and has ABSOLUTELY NO WARRANTY
Please report bugs to http://sourceforge.net/p/dfu-util/tickets/

dfu-util: Invalid DFU suffix signature
dfu-util: A valid DFU suffix will be required in a future dfu-util release!!!
Opening DFU capable USB device...
ID 0483:df11
Run-time device DFU version 0110
Claiming USB DFU Interface...
Setting Alternate Setting #2 ...
Determining device status: state = dfuIDLE, status = 0
dfuIDLE, continuing
DFU mode device DFU version 0110
Device returned transfer size 4096
Copying data from PC to DFU device
Download	[=========================] 100%          776 bytes
Download done.
state(7) = dfuMANIFEST, status(0) = No error condition is present
state(2) = dfuIDLE, status(0) = No error condition is present
Done!

2. Reference list[edit source]