mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-02 12:14:32 +02:00
Optimize configuration of base MAC address
Application developer can call APIs to configure base MAC address instead of using menuconfig.
This commit is contained in:
@@ -153,48 +153,35 @@ config MEMMAP_SPISRAM
|
|||||||
main memory map. Enable this if you have this hardware and want to use it in the same
|
main memory map. Enable this if you have this hardware and want to use it in the same
|
||||||
way as on-chip RAM.
|
way as on-chip RAM.
|
||||||
|
|
||||||
choice BASE_MAC_ADDRESS_STORAGE
|
choice NUMBER_OF_UNIVERSAL_MAC_ADDRESS
|
||||||
prompt "Storage of the base MAC address"
|
bool "Number of universally administered (by IEEE) MAC address"
|
||||||
default BASE_MAC_STORED_DEFAULT_EFUSE
|
default FOUR_UNIVERSAL_MAC_ADDRESS
|
||||||
help
|
help
|
||||||
Select storage of the base MAC address which is used for all network interfaces when networking is initialized.
|
Configure the number of universally administered (by IEEE) MAC addresses.
|
||||||
If "Default place in EFUSE" is selected, esp32 will use the base MAC address which is written into default
|
During initialisation, MAC addresses for each network interface are generated or derived from a
|
||||||
place in EFUSE when the chip is manufactured.
|
single base MAC address.
|
||||||
If "Customer-defined place in EFUSE" is selected, ESP32 will use customer-defined base MAC address which
|
If the number of universal MAC addresses is four, all four interfaces (WiFi station, WiFi softap,
|
||||||
is written into EFUSE Block 3 words 0, 1.
|
Bluetooth and Ethernet) receive a universally administered MAC address. These are generated
|
||||||
If "Other customer-defined place" is selected, esp32 will use customer-defined base MAC address from other
|
sequentially by adding 0, 1, 2 and 3 (respectively) to the final octet of the base MAC address.
|
||||||
place(flash, EEPROM, etc). User code must call esp_base_mac_addr_set_external to set the base MAC address
|
If the number of universal MAC addresses is two, only two interfaces (WiFi station and Bluetooth)
|
||||||
before network features are initialised.
|
receive a universally administered MAC address. These are generated sequentially by adding 0
|
||||||
|
and 1 (respectively) to the base MAC address. The remaining two interfaces (WiFi softap and Ethernet)
|
||||||
|
receive local MAC addresses. These are derived from the universal WiFi station and Bluetooth MAC
|
||||||
|
addresses, respectively.
|
||||||
|
When using the default (Espressif-assigned) base MAC address, either setting can be used. When using
|
||||||
|
a custom universal MAC address range, the correct setting will depend on the allocation of MAC
|
||||||
|
addresses in this range (either 2 or 4 per device.)
|
||||||
|
|
||||||
config BASE_MAC_STORED_DEFAULT_EFUSE
|
config TWO_UNIVERSAL_MAC_ADDRESS
|
||||||
bool "Default place in EFUSE"
|
|
||||||
config BASE_MAC_STORED_CUSTOMER_DEFINED_EFUSE
|
|
||||||
bool "Customer-defined place in EFUSE"
|
|
||||||
config BASE_MAC_STORED_OTHER_CUSTOMER_DEFINED_PLACE
|
|
||||||
bool "Other customer-defined place"
|
|
||||||
endchoice
|
|
||||||
|
|
||||||
choice NUMBER_OF_MAC_ADDRESS_GENERATED_FROM_EFUSE
|
|
||||||
bool "Number of MAC address generated from the hardware MAC address in efuse"
|
|
||||||
default FOUR_MAC_ADDRESS_FROM_EFUSE
|
|
||||||
help
|
|
||||||
Config the number of MAC address which is generated from the base MAC address in efuse.
|
|
||||||
If the number is two, the MAC addresses of WiFi station and bluetooth are generated from
|
|
||||||
the base MAC address in efuse. The MAC addresses of WiFi softap and ethernet are derived
|
|
||||||
from that of WiFi station and bluetooth respectively.
|
|
||||||
If the number is four, the MAC addresses of WiFi station, WiFi softap, bluetooth and ethernet
|
|
||||||
are all generated from the base MAC address in efuse.
|
|
||||||
|
|
||||||
config TWO_MAC_ADDRESS_FROM_EFUSE
|
|
||||||
bool "Two"
|
bool "Two"
|
||||||
config FOUR_MAC_ADDRESS_FROM_EFUSE
|
config FOUR_UNIVERSAL_MAC_ADDRESS
|
||||||
bool "Four"
|
bool "Four"
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
config NUMBER_OF_MAC_ADDRESS_GENERATED_FROM_EFUSE
|
config NUMBER_OF_UNIVERSAL_MAC_ADDRESS
|
||||||
int
|
int
|
||||||
default 2 if TWO_MAC_ADDRESS_FROM_EFUSE
|
default 2 if TWO_UNIVERSAL_MAC_ADDRESS
|
||||||
default 4 if FOUR_MAC_ADDRESS_FROM_EFUSE
|
default 4 if FOUR_UNIVERSAL_MAC_ADDRESS
|
||||||
|
|
||||||
config SYSTEM_EVENT_QUEUE_SIZE
|
config SYSTEM_EVENT_QUEUE_SIZE
|
||||||
int "System event queue size"
|
int "System event queue size"
|
||||||
|
@@ -37,6 +37,8 @@ typedef int32_t esp_err_t;
|
|||||||
#define ESP_ERR_TIMEOUT 0x107
|
#define ESP_ERR_TIMEOUT 0x107
|
||||||
#define ESP_ERR_INVALID_RESPONSE 0x108
|
#define ESP_ERR_INVALID_RESPONSE 0x108
|
||||||
#define ESP_ERR_INVALID_CRC 0x109
|
#define ESP_ERR_INVALID_CRC 0x109
|
||||||
|
#define ESP_ERR_INVALID_VERSION 0x10A
|
||||||
|
#define ESP_ERR_INVALID_MAC 0x10B
|
||||||
|
|
||||||
#define ESP_ERR_WIFI_BASE 0x3000 /*!< Starting number of WiFi error codes */
|
#define ESP_ERR_WIFI_BASE 0x3000 /*!< Starting number of WiFi error codes */
|
||||||
|
|
||||||
|
@@ -31,9 +31,9 @@ typedef enum {
|
|||||||
ESP_MAC_ETH,
|
ESP_MAC_ETH,
|
||||||
} esp_mac_type_t;
|
} esp_mac_type_t;
|
||||||
|
|
||||||
#define TWO_MAC_ADDRESS_FROM_EFUSE 2
|
#define TWO_UNIVERSAL_MAC_ADDR 2
|
||||||
#define FOUR_MAC_ADDRESS_FROM_EFUSE 4
|
#define FOUR_UNIVERSAL_MAC_ADDR 4
|
||||||
#define NUM_MAC_ADDRESS_FROM_EFUSE CONFIG_NUMBER_OF_MAC_ADDRESS_GENERATED_FROM_EFUSE
|
#define UNIVERSAL_MAC_ADDR_NUM CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @attention application don't need to call this function anymore. It do nothing and will
|
* @attention application don't need to call this function anymore. It do nothing and will
|
||||||
@@ -103,60 +103,84 @@ uint32_t system_get_free_heap_size(void) __attribute__ ((deprecated));
|
|||||||
uint32_t esp_random(void);
|
uint32_t esp_random(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set base MAC address from external storage e.g. flash and EEPROM.
|
* @brief Set base MAC address with the MAC address which is stored in BLK3 of EFUSE or
|
||||||
|
* external storage e.g. flash and EEPROM.
|
||||||
*
|
*
|
||||||
* Base MAC address is used to generate the MAC addresses used by the networking interfaces.
|
* Base MAC address is used to generate the MAC addresses used by the networking interfaces.
|
||||||
* If using base MAC address stored in external storage, call this API to set base MAC
|
* If using base MAC address stored in BLK3 of EFUSE or external storage, call this API to set base MAC
|
||||||
* address from external storage before initializing WiFi/BT/Ethernet.
|
* address with the MAC address which is stored in BLK3 of EFUSE or external storage before initializing
|
||||||
|
* WiFi/BT/Ethernet.
|
||||||
*
|
*
|
||||||
* @param mac base MAC address, length: 6 bytes.
|
* @param mac base MAC address, length: 6 bytes.
|
||||||
*
|
*
|
||||||
* @return ESP_OK on success
|
* @return ESP_OK on success
|
||||||
*/
|
*/
|
||||||
esp_err_t esp_base_mac_addr_set_external(uint8_t *mac);
|
esp_err_t esp_base_mac_addr_set(uint8_t *mac);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return base MAC address set using esp_mac_addr_set_external.
|
* @brief Return base MAC address which is set using esp_base_mac_addr_set.
|
||||||
*
|
*
|
||||||
* @param mac base MAC address, length: 6 bytes.
|
* @param mac base MAC address, length: 6 bytes.
|
||||||
*
|
*
|
||||||
|
* @return ESP_OK on success
|
||||||
|
* ESP_ERR_INVALID_MAC base MAC address has not been set
|
||||||
|
*/
|
||||||
|
esp_err_t esp_base_mac_addr_get(uint8_t *mac);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return base MAC address which was previously written to BLK3 of EFUSE.
|
||||||
|
*
|
||||||
* Base MAC address is used to generate the MAC addresses used by the networking interfaces.
|
* Base MAC address is used to generate the MAC addresses used by the networking interfaces.
|
||||||
* If using base MAC address stored in external storage, call this API to set base MAC
|
* This API returns the custom base MAC address which was previously written to BLK3 of EFUSE.
|
||||||
* address from external storage before initializing WiFi/BT/Ethernet.
|
* Writing this EFUSE allows setting of a different (non-Espressif) base MAC address. It is also
|
||||||
|
* possible to store a custom base MAC address elsewhere, see esp_base_mac_addr_set() for details.
|
||||||
|
*
|
||||||
|
* @param mac base MAC address, length: 6 bytes.
|
||||||
|
*
|
||||||
|
* @return ESP_OK on success
|
||||||
|
* ESP_ERR_INVALID_VERSION An invalid MAC version field was read from BLK3 of EFUSE
|
||||||
|
* ESP_ERR_INVALID_CRC An invalid MAC CRC was read from BLK3 of EFUSE
|
||||||
|
*/
|
||||||
|
esp_err_t esp_efuse_mac_get_custom(uint8_t *mac);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Return base MAC address which is factory-programmed by Espressif in BLK0 of EFUSE.
|
||||||
|
*
|
||||||
|
* @param mac base MAC address, length: 6 bytes.
|
||||||
*
|
*
|
||||||
* @return ESP_OK on success
|
* @return ESP_OK on success
|
||||||
*/
|
*/
|
||||||
esp_err_t esp_base_mac_addr_get_external(uint8_t *mac);
|
esp_err_t esp_efuse_mac_get_default(uint8_t *mac);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read hardware MAC address from efuse.
|
* @brief Read hardware MAC address from efuse.
|
||||||
*
|
*
|
||||||
* In WiFi MAC, only ESP32 station MAC is the hardware MAC, ESP32 softAP MAC is a software MAC
|
* Function has been renamed to esp_efuse_mac_get_default.
|
||||||
* calculated from ESP32 station MAC.
|
* This name will be removed in a future release.
|
||||||
* So users need to call esp_wifi_get_macaddr to query the ESP32 softAP MAC if ESP32 station MAC changed.
|
|
||||||
*
|
*
|
||||||
* @param mac hardware MAC address, length: 6 bytes.
|
* @param mac hardware MAC address, length: 6 bytes.
|
||||||
*
|
*
|
||||||
* @return ESP_OK on success
|
* @return ESP_OK on success
|
||||||
*/
|
*/
|
||||||
esp_err_t esp_efuse_read_mac(uint8_t* mac);
|
esp_err_t esp_efuse_read_mac(uint8_t *mac) __attribute__ ((deprecated));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read hardware MAC address.
|
* @brief Read hardware MAC address.
|
||||||
*
|
*
|
||||||
* Function has been renamed to esp_efuse_read_mac.
|
* Function has been renamed to esp_efuse_mac_get_default.
|
||||||
* This name will be removed in a future release.
|
* This name will be removed in a future release.
|
||||||
*
|
*
|
||||||
* @param mac hardware MAC address, length: 6 bytes.
|
* @param mac hardware MAC address, length: 6 bytes.
|
||||||
* @return ESP_OK on success
|
* @return ESP_OK on success
|
||||||
*/
|
*/
|
||||||
esp_err_t system_efuse_read_mac(uint8_t mac[6]) __attribute__ ((deprecated));
|
esp_err_t system_efuse_read_mac(uint8_t *mac) __attribute__ ((deprecated));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read hardware MAC address and set MAC address of the interface.
|
* @brief Read base MAC address and set MAC address of the interface.
|
||||||
*
|
*
|
||||||
* This function first reads hardware MAC address from efuse. Then set the MAC address of the interface
|
* This function first get base MAC address using esp_base_mac_addr_get or reads base MAC address
|
||||||
* including wifi station, wifi softap, bluetooth and ethernet.
|
* from BLK0 of EFUSE. Then set the MAC address of the interface including wifi station, wifi softap,
|
||||||
|
* bluetooth and ethernet.
|
||||||
*
|
*
|
||||||
* @param mac MAC address of the interface, length: 6 bytes.
|
* @param mac MAC address of the interface, length: 6 bytes.
|
||||||
* @param type type of MAC address, 0:wifi station, 1:wifi softap, 2:bluetooth, 3:ethernet.
|
* @param type type of MAC address, 0:wifi station, 1:wifi softap, 2:bluetooth, 3:ethernet.
|
||||||
@@ -166,32 +190,20 @@ esp_err_t system_efuse_read_mac(uint8_t mac[6]) __attribute__ ((deprecated));
|
|||||||
esp_err_t esp_read_mac(uint8_t* mac, esp_mac_type_t type);
|
esp_err_t esp_read_mac(uint8_t* mac, esp_mac_type_t type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Derive MAC address.
|
* @brief Derive local MAC address from universal MAC address.
|
||||||
*
|
*
|
||||||
* This function derives a local MAC address from an universal MAC address.
|
* This function derives a local MAC address from an universal MAC address.
|
||||||
* Addresses can either be universally administered addresses or locally administered addresses.
|
* A `definition of local vs universal MAC address can be found on Wikipedia
|
||||||
* A universally administered address is uniquely assigned to a device by its manufacturer.
|
* <https://en.wikipedia.org/wiki/MAC_address#Universal_vs._local>`.
|
||||||
* The first three octets (in transmission order) identify the organization that issued the identifier
|
* In ESP32, universal MAC address is generated from base MAC address in EFUSE or other external storage.
|
||||||
* and are known as the Organizationally Unique Identifier (OUI).[4] The remainder of the address
|
|
||||||
* (three octets for MAC-48 and EUI-48 or five for EUI-64) are assigned by that organization in nearly
|
|
||||||
* any manner they please, subject to the constraint of uniqueness. A locally administered address is
|
|
||||||
* assigned to a device by a network administrator, overriding the burned-in address.
|
|
||||||
* Universally administered and locally administered addresses are distinguished by setting
|
|
||||||
* the second-least-significant bit of the first octet of the address. This bit is also referred to
|
|
||||||
* as the U/L bit, short for Universal/Local, which identifies how the address is administered.
|
|
||||||
* If the bit is 0, the address is universally administered. If it is 1, the address is locally administered.
|
|
||||||
* In the example address 06-00-00-00-00-00 the first octet is 06 (hex), the binary form of which is 00000110,
|
|
||||||
* where the second-least-significant bit is 1. Therefore, it is a locally administered address.[7] Consequently,
|
|
||||||
* this bit is 0 in all OUIs.
|
|
||||||
* In ESP32, universal MAC address is generated from the hardware MAC address in efuse.
|
|
||||||
* Local MAC address is derived from the universal MAC address.
|
* Local MAC address is derived from the universal MAC address.
|
||||||
*
|
*
|
||||||
* @param dst_mac Derived local MAC address, length: 6 bytes.
|
* @param local_mac Derived local MAC address, length: 6 bytes.
|
||||||
* @param src_mac Source universal MAC address, length: 6 bytes.
|
* @param universal_mac Source universal MAC address, length: 6 bytes.
|
||||||
*
|
*
|
||||||
* @return ESP_OK on success
|
* @return ESP_OK on success
|
||||||
*/
|
*/
|
||||||
esp_err_t esp_derive_mac(uint8_t* dst_mac, const uint8_t* src_mac);
|
esp_err_t esp_derive_local_mac(uint8_t* local_mac, const uint8_t* universal_mac);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get SDK version
|
* Get SDK version
|
||||||
|
@@ -221,7 +221,7 @@ static esp_err_t load_cal_data_from_nvs_handle(nvs_handle handle,
|
|||||||
return ESP_ERR_INVALID_SIZE;
|
return ESP_ERR_INVALID_SIZE;
|
||||||
}
|
}
|
||||||
uint8_t sta_mac[6];
|
uint8_t sta_mac[6];
|
||||||
esp_efuse_read_mac(sta_mac);
|
esp_efuse_mac_get_default(sta_mac);
|
||||||
if (memcmp(sta_mac, cal_data_mac, sizeof(sta_mac)) != 0) {
|
if (memcmp(sta_mac, cal_data_mac, sizeof(sta_mac)) != 0) {
|
||||||
ESP_LOGE(TAG, "%s: calibration data MAC check failed: expected " \
|
ESP_LOGE(TAG, "%s: calibration data MAC check failed: expected " \
|
||||||
MACSTR ", found " MACSTR,
|
MACSTR ", found " MACSTR,
|
||||||
@@ -252,7 +252,7 @@ static esp_err_t store_cal_data_to_nvs_handle(nvs_handle handle,
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
uint8_t sta_mac[6];
|
uint8_t sta_mac[6];
|
||||||
esp_efuse_read_mac(sta_mac);
|
esp_efuse_mac_get_default(sta_mac);
|
||||||
err = nvs_set_blob(handle, PHY_CAL_MAC_KEY, sta_mac, sizeof(sta_mac));
|
err = nvs_set_blob(handle, PHY_CAL_MAC_KEY, sta_mac, sizeof(sta_mac));
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
return err;
|
return err;
|
||||||
|
@@ -36,63 +36,50 @@
|
|||||||
|
|
||||||
static const char* TAG = "system_api";
|
static const char* TAG = "system_api";
|
||||||
|
|
||||||
static uint8_t ext_base_mac_addr[6] = {0};
|
static uint8_t base_mac_addr[6] = { 0 };
|
||||||
|
|
||||||
void system_init()
|
void system_init()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t esp_base_mac_addr_set_external(uint8_t *mac)
|
esp_err_t esp_base_mac_addr_set(uint8_t *mac)
|
||||||
{
|
{
|
||||||
if (mac == NULL) {
|
if (mac == NULL) {
|
||||||
ESP_LOGE(TAG, "External base MAC address is NULL");
|
ESP_LOGE(TAG, "Base MAC address is NULL");
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(ext_base_mac_addr, mac, 6);
|
memcpy(base_mac_addr, mac, 6);
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t esp_base_mac_addr_get_external(uint8_t *mac)
|
esp_err_t esp_base_mac_addr_get(uint8_t *mac)
|
||||||
{
|
{
|
||||||
uint8_t null_mac[6] = {0};
|
uint8_t null_mac[6] = {0};
|
||||||
|
|
||||||
if (memcmp(ext_base_mac_addr, null_mac, 6) == 0) {
|
if (memcmp(base_mac_addr, null_mac, 6) == 0) {
|
||||||
ESP_LOGE(TAG, "External MAC address is not set");
|
ESP_LOGI(TAG, "Base MAC address is not set, read default base MAC address from BLK0 of EFUSE");
|
||||||
abort();
|
return ESP_ERR_INVALID_MAC;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(mac, ext_base_mac_addr, 6);
|
memcpy(mac, base_mac_addr, 6);
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t esp_efuse_read_mac(uint8_t* mac)
|
esp_err_t esp_efuse_mac_get_custom(uint8_t *mac)
|
||||||
{
|
{
|
||||||
uint32_t mac_low;
|
uint32_t mac_low;
|
||||||
uint32_t mac_high;
|
uint32_t mac_high;
|
||||||
uint8_t efuse_crc;
|
uint8_t efuse_crc;
|
||||||
uint8_t calc_crc;
|
uint8_t calc_crc;
|
||||||
|
|
||||||
#ifdef CONFIG_BASE_MAC_STORED_DEFAULT_EFUSE
|
|
||||||
mac_low = REG_READ(EFUSE_BLK0_RDATA1_REG);
|
|
||||||
mac_high = REG_READ(EFUSE_BLK0_RDATA2_REG);
|
|
||||||
|
|
||||||
mac[0] = mac_high >> 8;
|
|
||||||
mac[1] = mac_high;
|
|
||||||
mac[2] = mac_low >> 24;
|
|
||||||
mac[3] = mac_low >> 16;
|
|
||||||
mac[4] = mac_low >> 8;
|
|
||||||
mac[5] = mac_low;
|
|
||||||
|
|
||||||
efuse_crc = mac_high >> 16;
|
|
||||||
#else
|
|
||||||
uint8_t version = REG_READ(EFUSE_BLK3_RDATA5_REG) >> 24;
|
uint8_t version = REG_READ(EFUSE_BLK3_RDATA5_REG) >> 24;
|
||||||
|
|
||||||
if (version != 1) {
|
if (version != 1) {
|
||||||
ESP_LOGE(TAG, "Customer efuse MAC address version error, version = %d", version);
|
ESP_LOGE(TAG, "Base MAC address from BLK3 of EFUSE version error, version = %d", version);
|
||||||
abort();
|
return ESP_ERR_INVALID_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
mac_low = REG_READ(EFUSE_BLK3_RDATA1_REG);
|
mac_low = REG_READ(EFUSE_BLK3_RDATA1_REG);
|
||||||
@@ -106,7 +93,34 @@ esp_err_t esp_efuse_read_mac(uint8_t* mac)
|
|||||||
mac[5] = mac_low >> 16;
|
mac[5] = mac_low >> 16;
|
||||||
|
|
||||||
efuse_crc = mac_high;
|
efuse_crc = mac_high;
|
||||||
#endif //CONFIG_BASE_MAC_STORED_DEFAULT_EFUSE
|
|
||||||
|
calc_crc = esp_crc8(mac, 6);
|
||||||
|
|
||||||
|
if (efuse_crc != calc_crc) {
|
||||||
|
ESP_LOGE(TAG, "Base MAC address from BLK3 of EFUSE CRC error, efuse_crc = 0x%02x; calc_crc = 0x%02x", efuse_crc, calc_crc);
|
||||||
|
return ESP_ERR_INVALID_CRC;
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t esp_efuse_mac_get_default(uint8_t* mac)
|
||||||
|
{
|
||||||
|
uint32_t mac_low;
|
||||||
|
uint32_t mac_high;
|
||||||
|
uint8_t efuse_crc;
|
||||||
|
uint8_t calc_crc;
|
||||||
|
|
||||||
|
mac_low = REG_READ(EFUSE_BLK0_RDATA1_REG);
|
||||||
|
mac_high = REG_READ(EFUSE_BLK0_RDATA2_REG);
|
||||||
|
|
||||||
|
mac[0] = mac_high >> 8;
|
||||||
|
mac[1] = mac_high;
|
||||||
|
mac[2] = mac_low >> 24;
|
||||||
|
mac[3] = mac_low >> 16;
|
||||||
|
mac[4] = mac_low >> 8;
|
||||||
|
mac[5] = mac_low;
|
||||||
|
|
||||||
|
efuse_crc = mac_high >> 16;
|
||||||
|
|
||||||
calc_crc = esp_crc8(mac, 6);
|
calc_crc = esp_crc8(mac, 6);
|
||||||
|
|
||||||
@@ -118,30 +132,31 @@ esp_err_t esp_efuse_read_mac(uint8_t* mac)
|
|||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGE(TAG, "MAC address CRC error, efuse_crc = 0x%02x; calc_crc = 0x%02x", efuse_crc, calc_crc);
|
ESP_LOGE(TAG, "Base MAC address from BLK0 of EFUSE CRC error, efuse_crc = 0x%02x; calc_crc = 0x%02x", efuse_crc, calc_crc);
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t system_efuse_read_mac(uint8_t mac[6]) __attribute__((alias("esp_efuse_read_mac")));
|
esp_err_t system_efuse_read_mac(uint8_t *mac) __attribute__((alias("esp_efuse_mac_get_default")));
|
||||||
|
esp_err_t esp_efuse_read_mac(uint8_t *mac) __attribute__((alias("esp_efuse_mac_get_default")));
|
||||||
|
|
||||||
esp_err_t esp_derive_mac(uint8_t* dst_mac, const uint8_t* src_mac)
|
esp_err_t esp_derive_mac(uint8_t* local_mac, const uint8_t* universal_mac)
|
||||||
{
|
{
|
||||||
uint8_t idx;
|
uint8_t idx;
|
||||||
|
|
||||||
if (dst_mac == NULL || src_mac == NULL) {
|
if (local_mac == NULL || universal_mac == NULL) {
|
||||||
ESP_LOGE(TAG, "mac address param is NULL");
|
ESP_LOGE(TAG, "mac address param is NULL");
|
||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(dst_mac, src_mac, 6);
|
memcpy(local_mac, universal_mac, 6);
|
||||||
for (idx = 0; idx < 64; idx++) {
|
for (idx = 0; idx < 64; idx++) {
|
||||||
dst_mac[0] = src_mac[0] | 0x02;
|
local_mac[0] = universal_mac[0] | 0x02;
|
||||||
dst_mac[0] ^= idx << 2;
|
local_mac[0] ^= idx << 2;
|
||||||
|
|
||||||
if (memcmp(dst_mac, src_mac, 6)) {
|
if (memcmp(local_mac, universal_mac, 6)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,50 +174,46 @@ esp_err_t esp_read_mac(uint8_t* mac, esp_mac_type_t type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type < ESP_MAC_WIFI_STA || type > ESP_MAC_ETH) {
|
if (type < ESP_MAC_WIFI_STA || type > ESP_MAC_ETH) {
|
||||||
ESP_LOGE(TAG, "mac type is incorrect");
|
ESP_LOGE(TAG, "mac type is incorrect");
|
||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
_Static_assert(NUM_MAC_ADDRESS_FROM_EFUSE == FOUR_MAC_ADDRESS_FROM_EFUSE \
|
_Static_assert(UNIVERSAL_MAC_ADDR_NUM == FOUR_UNIVERSAL_MAC_ADDR \
|
||||||
|| NUM_MAC_ADDRESS_FROM_EFUSE == TWO_MAC_ADDRESS_FROM_EFUSE, \
|
|| UNIVERSAL_MAC_ADDR_NUM == TWO_UNIVERSAL_MAC_ADDR, \
|
||||||
"incorrect NUM_MAC_ADDRESS_FROM_EFUSE value");
|
"incorrect NUM_MAC_ADDRESS_FROM_EFUSE value");
|
||||||
|
|
||||||
#if defined(CONFIG_BASE_MAC_STORED_DEFAULT_EFUSE) || defined(CONFIG_BASE_MAC_STORED_CUSTOMER_DEFINED_EFUSE)
|
if (esp_base_mac_addr_get(efuse_mac) != ESP_OK) {
|
||||||
esp_efuse_read_mac(efuse_mac);
|
esp_efuse_mac_get_default(efuse_mac);
|
||||||
#endif
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_BASE_MAC_STORED_OTHER_CUSTOMER_DEFINED_PLACE)
|
|
||||||
esp_base_mac_addr_get_external(efuse_mac);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ESP_MAC_WIFI_STA:
|
case ESP_MAC_WIFI_STA:
|
||||||
memcpy(mac, efuse_mac, 6);
|
memcpy(mac, efuse_mac, 6);
|
||||||
break;
|
break;
|
||||||
case ESP_MAC_WIFI_SOFTAP:
|
case ESP_MAC_WIFI_SOFTAP:
|
||||||
if (NUM_MAC_ADDRESS_FROM_EFUSE == FOUR_MAC_ADDRESS_FROM_EFUSE) {
|
if (UNIVERSAL_MAC_ADDR_NUM == FOUR_UNIVERSAL_MAC_ADDR) {
|
||||||
memcpy(mac, efuse_mac, 6);
|
memcpy(mac, efuse_mac, 6);
|
||||||
mac[5] += 1;
|
mac[5] += 1;
|
||||||
}
|
}
|
||||||
else if (NUM_MAC_ADDRESS_FROM_EFUSE == TWO_MAC_ADDRESS_FROM_EFUSE) {
|
else if (UNIVERSAL_MAC_ADDR_NUM == TWO_UNIVERSAL_MAC_ADDR) {
|
||||||
esp_derive_mac(mac, efuse_mac);
|
esp_derive_mac(mac, efuse_mac);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ESP_MAC_BT:
|
case ESP_MAC_BT:
|
||||||
memcpy(mac, efuse_mac, 6);
|
memcpy(mac, efuse_mac, 6);
|
||||||
if (NUM_MAC_ADDRESS_FROM_EFUSE == FOUR_MAC_ADDRESS_FROM_EFUSE) {
|
if (UNIVERSAL_MAC_ADDR_NUM == FOUR_UNIVERSAL_MAC_ADDR) {
|
||||||
mac[5] += 2;
|
mac[5] += 2;
|
||||||
}
|
}
|
||||||
else if (NUM_MAC_ADDRESS_FROM_EFUSE == TWO_MAC_ADDRESS_FROM_EFUSE) {
|
else if (UNIVERSAL_MAC_ADDR_NUM == TWO_UNIVERSAL_MAC_ADDR) {
|
||||||
mac[5] += 1;
|
mac[5] += 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ESP_MAC_ETH:
|
case ESP_MAC_ETH:
|
||||||
if (NUM_MAC_ADDRESS_FROM_EFUSE == FOUR_MAC_ADDRESS_FROM_EFUSE) {
|
if (UNIVERSAL_MAC_ADDR_NUM == FOUR_UNIVERSAL_MAC_ADDR) {
|
||||||
memcpy(mac, efuse_mac, 6);
|
memcpy(mac, efuse_mac, 6);
|
||||||
mac[5] += 3;
|
mac[5] += 3;
|
||||||
}
|
}
|
||||||
else if (NUM_MAC_ADDRESS_FROM_EFUSE == TWO_MAC_ADDRESS_FROM_EFUSE) {
|
else if (UNIVERSAL_MAC_ADDR_NUM == TWO_UNIVERSAL_MAC_ADDR) {
|
||||||
efuse_mac[5] += 1;
|
efuse_mac[5] += 1;
|
||||||
esp_derive_mac(mac, efuse_mac);
|
esp_derive_mac(mac, efuse_mac);
|
||||||
}
|
}
|
||||||
|
77
docs/api-reference/system/base_mac_address.rst
Normal file
77
docs/api-reference/system/base_mac_address.rst
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
Base MAC address
|
||||||
|
================
|
||||||
|
|
||||||
|
Overview
|
||||||
|
--------
|
||||||
|
|
||||||
|
Serveral universally administered(by IEEE) MAC addresses are uniquely assigned to the networking interfaces(WiFi/BT/Ethernet).
|
||||||
|
The final octet of each universally administered MAC address increases by one. Only the first one which is called base MAC address
|
||||||
|
of them is stored in EFUSE or external storage, the others are generated from it. Here, 'generate' means adding 0, 1, 2 and 3
|
||||||
|
(respectively) to the final octet of the base MAC address.
|
||||||
|
|
||||||
|
If the universally administered MAC addresses are not enough for all of the networking interfaces. Local administered MAC addresses
|
||||||
|
which are derived from universally administered MAC addresses are assigned to the reset of networking interfaces.
|
||||||
|
|
||||||
|
A `definition of local vs universal MAC address can be found on Wikipedia<https://en.wikipedia.org/wiki/MAC_address#Universal_vs._local>`.
|
||||||
|
|
||||||
|
The number of universally administered MAC address can be configured using ``make menuconfig``.
|
||||||
|
|
||||||
|
Base MAC address
|
||||||
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
If using the default base MAC address factory programmed by Espressif in BLK0 of EFUSE, nothing needs to be done.
|
||||||
|
|
||||||
|
If using a custom base MAC address stored in BLK3 of EFUSE, call API esp_efuse_mac_get_custom() to get the base MAC address
|
||||||
|
which is stored in BLK3 of EFUSE. If correct MAC address is returned, then call esp_base_mac_addr_set() to set the base MAC
|
||||||
|
address for system to generate the MAC addresses used by the networking interfaces(WiFi/BT/Ethernet).
|
||||||
|
There are 192 bits storage spaces for custom to store base MAC address in BLK3 of EFUSE. They are EFUSE_BLK3_RDATA0,
|
||||||
|
EFUSE_BLK3_RDATA1, EFUSE_BLK3_RDATA2, EFUSE_BLK3_RDATA3, EFUSE_BLK3_RDATA4 and EFUSE_BLK3_RDATA5, each of them is 32 bits
|
||||||
|
register. The format of the 192 bits storage spaces is:
|
||||||
|
------------------------------------------------------
|
||||||
|
Field |Bits |Range |Description
|
||||||
|
------------------------------------------------------
|
||||||
|
version |8 |[191:184] |1: useful. 0: useless
|
||||||
|
------------------------------------------------------
|
||||||
|
reserve |112 |[183:72] |reserved
|
||||||
|
------------------------------------------------------
|
||||||
|
mac address |64 |[71:8] |base MAC address
|
||||||
|
------------------------------------------------------
|
||||||
|
mac crc |8 |[7:0] |crc of base MAC address
|
||||||
|
------------------------------------------------------
|
||||||
|
|
||||||
|
If using base MAC address stored in external storage, firstly get the base MAC address stored in external storage, then call
|
||||||
|
API esp_base_mac_addr_set() to set the base MAC address for system to generate the MAC addresses used by the networking
|
||||||
|
interfaces(WiFi/BT/Ethernet).
|
||||||
|
|
||||||
|
All of the steps must be done before initializing the networking interfaces(WiFi/BT/Ethernet). It is recommended to do it in
|
||||||
|
app_main() which can be referenced in example `system/base_mac_address`.
|
||||||
|
|
||||||
|
Number of universally administered MAC address
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
If the number of universal MAC addresses is two, only two interfaces (WiFi station and Bluetooth) receive a universally
|
||||||
|
administered MAC address. These are generated sequentially by adding 0 and 1 (respectively) to the base MAC address.
|
||||||
|
The remaining two interfaces (WiFi softap and Ethernet) receive local MAC addresses. These are derived from the universal
|
||||||
|
WiFi station and Bluetooth MAC addresses, respectively.
|
||||||
|
|
||||||
|
If the number of universal MAC addresses is four, all four interfaces (WiFi station, WiFi softap, Bluetooth and Ethernet)
|
||||||
|
receive a universally administered MAC address. These are generated sequentially by adding 0, 1, 2 and 3 (respectively)
|
||||||
|
to the final octet of the base MAC address.
|
||||||
|
|
||||||
|
When using the default (Espressif-assigned) base MAC address, either setting can be used. When using a custom universal MAC
|
||||||
|
address range, the correct setting will depend on the allocation of MAC addresses in this range (either 2 or 4 per device.)
|
||||||
|
|
||||||
|
API Reference
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Header Files
|
||||||
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
|
* :component_file:`esp32/include/esp_system.h`
|
||||||
|
|
||||||
|
|
||||||
|
Functions
|
||||||
|
---------
|
||||||
|
|
||||||
|
.. doxygenfunction:: esp_base_mac_addr_set
|
||||||
|
.. doxygenfunction:: esp_efuse_mac_get_custom
|
@@ -10,6 +10,7 @@ System API
|
|||||||
Over The Air Updates (OTA) <ota>
|
Over The Air Updates (OTA) <ota>
|
||||||
Deep Sleep <deep_sleep>
|
Deep Sleep <deep_sleep>
|
||||||
Logging <log>
|
Logging <log>
|
||||||
|
Base MAC address <base_mac_address>
|
||||||
|
|
||||||
|
|
||||||
Example code for this API section is provided in :example:`system` directory of ESP-IDF examples.
|
Example code for this API section is provided in :example:`system` directory of ESP-IDF examples.
|
||||||
|
9
examples/system/base_mac_address/Makefile
Normal file
9
examples/system/base_mac_address/Makefile
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#
|
||||||
|
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
|
||||||
|
# project subdirectory.
|
||||||
|
#
|
||||||
|
|
||||||
|
PROJECT_NAME := base_mac_address
|
||||||
|
|
||||||
|
include $(IDF_PATH)/make/project.mk
|
||||||
|
|
4
examples/system/base_mac_address/README.md
Normal file
4
examples/system/base_mac_address/README.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# Example: base mac address
|
||||||
|
|
||||||
|
This example illustrates how to get and set base MAC address.
|
||||||
|
|
42
examples/system/base_mac_address/main/Kconfig.projbuild
Normal file
42
examples/system/base_mac_address/main/Kconfig.projbuild
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
menu "Example Configuration"
|
||||||
|
|
||||||
|
choice BASE_MAC_ADDRESS_STORAGE
|
||||||
|
prompt "Storage of the base MAC address"
|
||||||
|
default BASE_MAC_STORED_EFUSE_BLK0
|
||||||
|
help
|
||||||
|
Select storage of the base MAC address which is used to generate MAC addresses of all network interfaces
|
||||||
|
when networking is initialized.
|
||||||
|
If "Default (Espressif factory) EFUSE BLK0" is selected, esp32 will use default base MAC address which is
|
||||||
|
written into EFUSE block 0 words 1, 2 when the chip is manufactured.
|
||||||
|
If "Custom EFUSE BLK3" is selected, ESP32 will use customer-defined base MAC address which is written into
|
||||||
|
EFUSE Block 3 words 0, 1. Users must call esp_efuse_mac_get_custom to get base MAC address and
|
||||||
|
esp_base_mac_addr_set to set the base MAC address before network interfaces are initialised.
|
||||||
|
If "Other external storage" is selected, esp32 will use customer-defined base MAC address from external
|
||||||
|
storage(flash, EEPROM, etc). Users must get the base MAC address first and call esp_base_mac_addr_set to
|
||||||
|
set the base MAC address before network interfaces are initialised.
|
||||||
|
|
||||||
|
config BASE_MAC_STORED_EFUSE_BLK0
|
||||||
|
bool "Default (Espressif factory) EFUSE BLK0"
|
||||||
|
config BASE_MAC_STORED_EFUSE_BLK3
|
||||||
|
bool "Custom EFUSE BLK3"
|
||||||
|
config BASE_MAC_STORED_OTHER_EXTERNAL_STORAGE
|
||||||
|
bool "Other external storage"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
choice BASE_MAC_STORED_EFUSE_BLK3_ERROR_BEHAVIOR
|
||||||
|
prompt "Read base MAC address from BLK3 of EFUSE error behavior"
|
||||||
|
depends on BASE_MAC_STORED_EFUSE_BLK3
|
||||||
|
default BASE_MAC_STORED_EFUSE_BLK3_ERROR_USE_DEFAULT
|
||||||
|
help
|
||||||
|
Select behavior when reading base MAC address from BLK3 of EFUSE error.
|
||||||
|
If "Abort" is selected, esp32 will abort.
|
||||||
|
If "Use base MAC address from BLK3 of EFUSE" is selected, esp32 will use the base MAC address which is
|
||||||
|
written into EFUSE block 0 words 1, 2 when the chip is manufactured.
|
||||||
|
|
||||||
|
config BASE_MAC_STORED_EFUSE_BLK3_ERROR_ABORT
|
||||||
|
bool "Abort"
|
||||||
|
config BASE_MAC_STORED_EFUSE_BLK3_ERROR_USE_DEFAULT
|
||||||
|
bool "Use base MAC address from BLK3 of EFUSE"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
endmenu
|
@@ -0,0 +1,76 @@
|
|||||||
|
/* Base mac address example
|
||||||
|
|
||||||
|
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, this
|
||||||
|
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||||
|
CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_system.h"
|
||||||
|
|
||||||
|
#define TAG "BASE_MAC"
|
||||||
|
|
||||||
|
#ifdef CONFIG_BASE_MAC_STORED_OTHER_EXTERNAL_STORAGE
|
||||||
|
/* This is an example to show getting base MAC address from other external storage (flash, EEPROM, etc). */
|
||||||
|
static esp_err_t external_storage_mac_get(uint8_t *mac)
|
||||||
|
{
|
||||||
|
uint8_t external_storage_mac_addr[8] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 };
|
||||||
|
|
||||||
|
if (mac == NULL) {
|
||||||
|
ESP_LOGE(TAG, "The mac parameter is NULL");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(mac, external_storage_mac_addr, 6);
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
#endif//CONFIG_BASE_MAC_STORED_OTHER_EXTERNAL_STORAGE
|
||||||
|
|
||||||
|
void app_main()
|
||||||
|
{
|
||||||
|
#if defined(CONFIG_BASE_MAC_STORED_EFUSE_BLK3) || defined(CONFIG_BASE_MAC_STORED_OTHER_EXTERNAL_STORAGE)
|
||||||
|
uint8_t mac_addr[8] = {0};
|
||||||
|
esp_err_t ret = ESP_OK;
|
||||||
|
|
||||||
|
#ifdef CONFIG_BASE_MAC_STORED_EFUSE_BLK3
|
||||||
|
/* Get base MAC address from BLK3 of EFUSE */
|
||||||
|
ret = esp_efuse_mac_get_custom(mac_addr);
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
ESP_LOGE(TAG, "Get base MAC address from BLK3 of EFUSE error");
|
||||||
|
/* If get custom base MAC address error, the application developer can decide what to do:
|
||||||
|
* abort or use the default base MAC address which is stored in BLK0 of EFUSE by doing
|
||||||
|
* nothing.
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_BASE_MAC_STORED_EFUSE_BLK3_ERROR_ABORT
|
||||||
|
abort();
|
||||||
|
#else
|
||||||
|
ESP_LOGI(TAG, "Use base MAC address which is stored in BLK0 of EFUSE");
|
||||||
|
#endif//CONFIG_BASE_MAC_STORED_EFUSE_BLK3_ERROR_ABORT
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
esp_base_mac_addr_set(mac_addr);
|
||||||
|
ESP_LOGI(TAG, "Use base MAC address which is stored in BLK3 of EFUSE");
|
||||||
|
}
|
||||||
|
#endif//CONFIG_BASE_MAC_STORED_EFUSE_BLK3
|
||||||
|
|
||||||
|
#ifdef CONFIG_BASE_MAC_STORED_OTHER_EXTERNAL_STORAGE
|
||||||
|
/* the application developer can get base MAC address which is stored in other external
|
||||||
|
* storage (flash, EEPROM, etc) by calling some functions here.
|
||||||
|
*/
|
||||||
|
ret = external_storage_mac_get(mac_addr);
|
||||||
|
if (ret == ESP_OK) {
|
||||||
|
esp_base_mac_addr_set(mac_addr);
|
||||||
|
ESP_LOGI(TAG, "Use base MAC address which is stored in other external storage(flash, EEPROM, etc)");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ESP_LOGI(TAG, "Use base MAC address which is stored in BLK0 of EFUSE");
|
||||||
|
}
|
||||||
|
#endif//CONFIG_BASE_MAC_STORED_OTHER_EXTERNAL_STORAGE
|
||||||
|
#else
|
||||||
|
ESP_LOGI(TAG, "Use base MAC address which is stored in BLK0 of EFUSE");
|
||||||
|
#endif//CONFIG_BASE_MAC_STORED_EFUSE_BLK3 || CONFIG_BASE_MAC_STORED_OTHER_EXTERNAL_STORAGE
|
||||||
|
}
|
3
examples/system/base_mac_address/main/component.mk
Normal file
3
examples/system/base_mac_address/main/component.mk
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#
|
||||||
|
# Main Makefile. This is basically the same as a component makefile.
|
||||||
|
#
|
Reference in New Issue
Block a user