efuse Driver
Overview
efuse (Electrically Fusable) driver provides access to one-time programmable memory for storing unique identifiers, configuration parameters, and security keys.
Functional Description
One-time programmable memory (0 to 1 only)
Permanent data storage (non-volatile)
Secure storage for keys and certificates
Unique identifier storage
Configuration parameter storage
Address space management
Data verification
Low power mode support
Development Guide
Initialization - Call bk_efuse_driver_init() before any efuse operations - Verify address range availability - Prepare data for writing
Basic Operations - Write: bk_efuse_write_byte(addr, data) - Read: bk_efuse_read_byte(addr, &data) - Note: efuse can only program 0 to 1
Address Management - Verify address range - Avoid duplicate writes - Check address area usage
Data Verification - Read back after write - Verify data correctness - Handle write failures
Notes
efuse can only program 0 to 1, not 1 to 0
Write operations are irreversible
Verify address range before writing
Apply for address area from PM before writing
Consider efuse lifetime limitations
API Reference
bk_efuse_driver_init/deinit() - Driver management
bk_efuse_write_byte() - Write single byte
bk_efuse_read_byte() - Read single byte
Examples
Basic read/write:
bk_efuse_driver_init();
uint8_t write_data = 0xAA;
bk_err_t ret = bk_efuse_write_byte(0x10, write_data);
if (ret != BK_OK) {
printf("efuse write failed: %d\n", ret);
return;
}
uint8_t read_data;
ret = bk_efuse_read_byte(0x10, &read_data);
if (ret == BK_OK) {
printf("efuse read: 0x%02X\n", read_data);
}
Batch operations:
uint8_t write_data[] = {0x01, 0x02, 0x03, 0x04};
uint8_t read_data[4];
// Batch write
for (int i = 0; i < 4; i++) {
bk_err_t ret = bk_efuse_write_byte(0x20 + i, write_data[i]);
if (ret != BK_OK) {
printf("Write failed at address 0x%02X\n", 0x20 + i);
return;
}
}
// Batch read verification
for (int i = 0; i < 4; i++) {
bk_err_t ret = bk_efuse_read_byte(0x20 + i, &read_data[i]);
if (ret == BK_OK) {
printf("Address 0x%02X: 0x%02X\n", 0x20 + i, read_data[i]);
}
}
Secure key storage:
uint8_t key[] = {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0};
uint8_t key_addr = 0x30;
// Write key
for (int i = 0; i < 8; i++) {
bk_err_t ret = bk_efuse_write_byte(key_addr + i, key[i]);
if (ret != BK_OK) {
printf("Key write failed at index %d\n", i);
return;
}
}
// Verify key
uint8_t verify_key[8];
for (int i = 0; i < 8; i++) {
bk_efuse_read_byte(key_addr + i, &verify_key[i]);
}
bool key_match = true;
for (int i = 0; i < 8; i++) {
if (key[i] != verify_key[i]) {
key_match = false;
break;
}
}
printf("Key verification: %s\n", key_match ? "PASS" : "FAIL");
Configuration storage:
struct {
uint8_t device_id;
uint8_t version;
uint8_t features;
uint8_t reserved;
} config = {
.device_id = 0x01,
.version = 0x02,
.features = 0x03,
.reserved = 0x00
};
uint8_t config_addr = 0x40;
bk_efuse_write_byte(config_addr, config.device_id);
bk_efuse_write_byte(config_addr + 1, config.version);
bk_efuse_write_byte(config_addr + 2, config.features);
bk_efuse_write_byte(config_addr + 3, config.reserved);
uint8_t read_config[4];
for (int i = 0; i < 4; i++) {
bk_efuse_read_byte(config_addr + i, &read_config[i]);
}
printf("Device ID: 0x%02X\n", read_config[0]);
printf("Version: 0x%02X\n", read_config[1]);
printf("Features: 0x%02X\n", read_config[2]);
FAQs
Write failure: Check address range, data format, efuse status
Read errors: Verify address validity and driver initialization
Data mismatch: Check write operation success and address correctness
Error Codes
BK_ERR_EFUSE_DRIVER_NOT_INIT: Driver not initialized
BK_ERR_EFUSE_ADDR_OUT_OF_RANGE: Address out of range
BK_ERR_EFUSE_CANNOT_WRTIE: Cannot write (cannot change bit from 1 to 0)
BK_ERR_EFUSE_WRTIE_NOT_EQUAL: Read data not equal to written data