efuse question
efuse question
I'd like to store an 11 digit (88 bits) serial number in eFuse. I'm currently on IDF v3.1.1. When I look at the docs for the latest IDF the definition of storage for eFuse block 3 is different than the v3.1.3 IDF. For example there is no mention of ADC store in v3.1.3 but it's in the latest. We are planning to use the default MAC addresses as supplied with the ESP32 module. So I'm curious where to put those 11 digits that won't conflict with an IDF version in the future.
In the v3.1.3 docs it shows bits 72-183 as reserved. Does that mean they are off limits for us to use? If so then I've got 72 bits before the reserved area and 8 bits after for something called version for a total of 80 bits. The docs say there is only 192 bits of storage. The latest says I can create Block 3 with 256 bits.
Bottom line is that using eFuse for permanent storage is confusing to me. Not sure how to craft a plan that won't be broken in the future.
John A
In the v3.1.3 docs it shows bits 72-183 as reserved. Does that mean they are off limits for us to use? If so then I've got 72 bits before the reserved area and 8 bits after for something called version for a total of 80 bits. The docs say there is only 192 bits of storage. The latest says I can create Block 3 with 256 bits.
Bottom line is that using eFuse for permanent storage is confusing to me. Not sure how to craft a plan that won't be broken in the future.
John A
Re: efuse question
Hi John,
The latest master branch has the "eFuse Manager" feature (will be added in IDF v3.3), so this is why the ESP-IDF Programming Guide is a little varied between versions. The ESP32 Technical Reference manual also has some information about efuse ranges and coding schemes.
ESP-IDF is very unlikely to start claiming new efuse bits, but there were some ESP32 modules produced which came with data stored in bits 72-183 of efuse BLK3, and also set the 3/4 Coding Scheme which reduces the size of BLK1,BLK2,BLK3 to 192 bits each. Some additional explanation is here. This modification is no longer being done, and new ESP32 chips and modules all come with empty BLK3 and "normal" coding scheme (256 bit BLK1, BLK2 and BLK3 blocks).
AFAIK there are no plans to resume storing data in these bits of BLK3, or to set the Coding Scheme. However these bits were reserved so it's not impossible that future modules may come with these bits pre-burned again.
The options that you have are (in what I'd consider to be most desirable option first):
The latest master branch has the "eFuse Manager" feature (will be added in IDF v3.3), so this is why the ESP-IDF Programming Guide is a little varied between versions. The ESP32 Technical Reference manual also has some information about efuse ranges and coding schemes.
ESP-IDF is very unlikely to start claiming new efuse bits, but there were some ESP32 modules produced which came with data stored in bits 72-183 of efuse BLK3, and also set the 3/4 Coding Scheme which reduces the size of BLK1,BLK2,BLK3 to 192 bits each. Some additional explanation is here. This modification is no longer being done, and new ESP32 chips and modules all come with empty BLK3 and "normal" coding scheme (256 bit BLK1, BLK2 and BLK3 blocks).
AFAIK there are no plans to resume storing data in these bits of BLK3, or to set the Coding Scheme. However these bits were reserved so it's not impossible that future modules may come with these bits pre-burned again.
The options that you have are (in what I'd consider to be most desirable option first):
- If you're not going to be using flash encryption or not using secure boot then store your data anywhere in BLK1 or BLK2 (respectively). These blocks will always be empty on new chips and modules.
- If you are going to be using flash encryption and secure boot, use the NVS Encryption feature. This allows you to store arbitrary amounts of encrypted per-device data in the NVS partition. It is also more secure than storing in efuse (because it uses flash encryption, the values can't be read out unless it's by code running on the chip).
- If none of these options sound desirable, create a partition somewhere in the flash and store the serial number there in plaintext. If not using secure boot, there's a 4KB sector at offset 0x0 which is used for nothing else.
- Assume you're not going to be getting modules from the batches with the modifications mentioned above, and store the serial number in efuse BLK3. Also sign up for PCN updates on the espressif.com website, and you'll be emailed if there are product changes of this kind in the future (there will almost certainly still be a way to order modules with empty BLK3, even if the BLK3 usage changes again.)
-
- Posts: 9766
- Joined: Thu Nov 26, 2015 4:08 am
Re: efuse question
Also note that it's a bit excessive to need 88 bits to store 11 digits. Even with an encoding like packed BCD, you can halve that to 44 bits. If you convert the 11-bit number to binary (easy to do, as they'll fit a 64-bit integer) you can get away with the bare minimum of 37 bits even.
Re: efuse question
Speaking of more secure, any update to viewtopic.php?f=13&t=7672&p=33951ESP_Angus wrote: ↑Wed Mar 27, 2019 10:41 pm[*] If you are going to be using flash encryption and secure boot, use the NVS Encryption feature. This allows you to store arbitrary amounts of encrypted per-device data in the NVS partition. It is also more secure than storing in efuse (because it uses flash encryption, the values can't be read out unless it's by code running on the chip).
Re: efuse question
OK, that's a lot of info to digest and distill into something that won't come back to byte (pun intended) me. Looks like a simple form of compression is a good idea if I use the eFuse. I just wanted something that if the flash was erased, it would still retain it's serial#.
John A
John A
Re: efuse question
I decided to store my data in Block 3 starting at bit 192. But then I looked at the v3.1.3 documentation and it doesn't have any API listed for my application to read the eFuse.
John A
EDIT: I searched the forum and found some code that reads it. So if I understand correctly these two calls should read 8 bytes of which I'm only using 6. I needed 11 digits and am storing one digit per nibble. Actually some are letters, but a small enough set to store each in a nibble and map back to the letter. On my first run it read all zeros, but I haven't written anything yet.
uint32_t ser1 = REG_READ(EFUSE_BLK3_RDATA6_REG);
uint32_t ser2 = REG_READ(EFUSE_BLK3_RDATA7_REG);
That should be reading bits 192-255.
John A
EDIT: I searched the forum and found some code that reads it. So if I understand correctly these two calls should read 8 bytes of which I'm only using 6. I needed 11 digits and am storing one digit per nibble. Actually some are letters, but a small enough set to store each in a nibble and map back to the letter. On my first run it read all zeros, but I haven't written anything yet.
uint32_t ser1 = REG_READ(EFUSE_BLK3_RDATA6_REG);
uint32_t ser2 = REG_READ(EFUSE_BLK3_RDATA7_REG);
That should be reading bits 192-255.
Re: efuse question
Hi John,
Yes, this is a bit rudimentary pre-IDF v3.3.
The soc/efuse_reg.h header defines the read registers for the Efuse address space. All written efuse values will appear in these registers (more details can be found in the ESP32 TRM).
To read the full block, you can do something like
If you just want the last 64 bits:
Always use word-aligned addresses and lengths when reading from registers (ie round to multiples of 4 and then discard what you don't need).
You can also use the REG_READ() macro to read these registers individually.
Yes, this is a bit rudimentary pre-IDF v3.3.
The soc/efuse_reg.h header defines the read registers for the Efuse address space. All written efuse values will appear in these registers (more details can be found in the ESP32 TRM).
To read the full block, you can do something like
Code: Select all
uint8_t block[32];
memcpy(block, (void *)EFUSE_BLK3_RDATA0_REG, sizeof(block));
Code: Select all
uint8_t block[8];
memcpy(block, (void *)(EFUSE_BLK3_RDATA0_REG + 192/8), sizeof(block));
You can also use the REG_READ() macro to read these registers individually.
Re: efuse question
Just saw your EDIT comment, yes using REG_READ like this will also work. You may need to shuffle some byte orders around by hand.
Re: efuse question
The documentation says that the bytes are written backwards, which I assume means that the last byte of the block is written in the first uint32_t. Not sure how the endianess is ordered in this case exactly.
However the documentation for the burn_block_data command says the bytes are in normal order.
Also concerned about the offset. Out of the 8 uint32_t words that are written (0...7) and considering that I want to write to uint32_t 6 & 7, should I be using "--offset 6", and should my device_id.bin be 8 bytes in length?espefuse.py -p PORT burn_block_data --offset 6 BLK3 device_id.bin
Data is written to the Efuse block in normal byte order.
Part of the Efuse block can be written at a time. The --offset argument allows writing at an offset in the Efuse block itself.
John A
Re: efuse question
Trying to wrap my head around this. My device_id.bin file contains the following 8 bytes as displayed by HexEdit
And this is what I get when I dump using espefuse.py... I expected to see the values at one or the other end of the BLK3. So I'm guessing that offset starts with 1 instead of 0? Is the far right 32 bit word at offset=1? Would like to get this figured out before I blow all the BLK3 fuses on every device I have trying to get it right.
Also the 40 should be in the same 32 bit word as the 20 & 45. Not sure how it jumped to the next word.
John A
I write these to BLK3 offset = 620 45 40 00 00 10 00 00
And this is what I get when I dump using espefuse.py... I expected to see the values at one or the other end of the BLK3. So I'm guessing that offset starts with 1 instead of 0? Is the far right 32 bit word at offset=1? Would like to get this figured out before I blow all the BLK3 fuses on every device I have trying to get it right.
Also the 40 should be in the same 32 bit word as the 20 & 45. Not sure how it jumped to the next word.
John A
Last edited by fly135 on Wed Apr 03, 2019 1:24 am, edited 1 time in total.
Who is online
Users browsing this forum: No registered users and 133 guests