mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04: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:
parent
a41ac2d21d
commit
b22067a8f0
@ -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
|
||||
way as on-chip RAM.
|
||||
|
||||
choice BASE_MAC_ADDRESS_STORAGE
|
||||
prompt "Storage of the base MAC address"
|
||||
default BASE_MAC_STORED_DEFAULT_EFUSE
|
||||
choice NUMBER_OF_UNIVERSAL_MAC_ADDRESS
|
||||
bool "Number of universally administered (by IEEE) MAC address"
|
||||
default FOUR_UNIVERSAL_MAC_ADDRESS
|
||||
help
|
||||
Select storage of the base MAC address which is used for all network interfaces when networking is initialized.
|
||||
If "Default place in EFUSE" is selected, esp32 will use the base MAC address which is written into default
|
||||
place in EFUSE when the chip is manufactured.
|
||||
If "Customer-defined place in EFUSE" is selected, ESP32 will use customer-defined base MAC address which
|
||||
is written into EFUSE Block 3 words 0, 1.
|
||||
If "Other customer-defined place" is selected, esp32 will use customer-defined base MAC address from other
|
||||
place(flash, EEPROM, etc). User code must call esp_base_mac_addr_set_external to set the base MAC address
|
||||
before network features are initialised.
|
||||
Configure the number of universally administered (by IEEE) MAC addresses.
|
||||
During initialisation, MAC addresses for each network interface are generated or derived from a
|
||||
single base MAC address.
|
||||
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.
|
||||
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.
|
||||
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
|
||||
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
|
||||
config TWO_UNIVERSAL_MAC_ADDRESS
|
||||
bool "Two"
|
||||
config FOUR_MAC_ADDRESS_FROM_EFUSE
|
||||
config FOUR_UNIVERSAL_MAC_ADDRESS
|
||||
bool "Four"
|
||||
endchoice
|
||||
|
||||
config NUMBER_OF_MAC_ADDRESS_GENERATED_FROM_EFUSE
|
||||
config NUMBER_OF_UNIVERSAL_MAC_ADDRESS
|
||||
int
|
||||
default 2 if TWO_MAC_ADDRESS_FROM_EFUSE
|
||||
default 4 if FOUR_MAC_ADDRESS_FROM_EFUSE
|
||||
default 2 if TWO_UNIVERSAL_MAC_ADDRESS
|
||||
default 4 if FOUR_UNIVERSAL_MAC_ADDRESS
|
||||
|
||||
config 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_INVALID_RESPONSE 0x108
|
||||
#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 */
|
||||
|
||||
|
@ -31,9 +31,9 @@ typedef enum {
|
||||
ESP_MAC_ETH,
|
||||
} esp_mac_type_t;
|
||||
|
||||
#define TWO_MAC_ADDRESS_FROM_EFUSE 2
|
||||
#define FOUR_MAC_ADDRESS_FROM_EFUSE 4
|
||||
#define NUM_MAC_ADDRESS_FROM_EFUSE CONFIG_NUMBER_OF_MAC_ADDRESS_GENERATED_FROM_EFUSE
|
||||
#define TWO_UNIVERSAL_MAC_ADDR 2
|
||||
#define FOUR_UNIVERSAL_MAC_ADDR 4
|
||||
#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
|
||||
@ -103,60 +103,84 @@ uint32_t system_get_free_heap_size(void) __attribute__ ((deprecated));
|
||||
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.
|
||||
* If using base MAC address stored in external storage, call this API to set base MAC
|
||||
* address from external storage before initializing WiFi/BT/Ethernet.
|
||||
* If using base MAC address stored in BLK3 of EFUSE or external storage, call this API to set base MAC
|
||||
* 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.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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.
|
||||
* If using base MAC address stored in external storage, call this API to set base MAC
|
||||
* address from external storage before initializing WiFi/BT/Ethernet.
|
||||
* This API returns the custom base MAC address which was previously written to BLK3 of EFUSE.
|
||||
* 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
|
||||
*/
|
||||
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.
|
||||
*
|
||||
* In WiFi MAC, only ESP32 station MAC is the hardware MAC, ESP32 softAP MAC is a software MAC
|
||||
* calculated from ESP32 station MAC.
|
||||
* So users need to call esp_wifi_get_macaddr to query the ESP32 softAP MAC if ESP32 station MAC changed.
|
||||
* Function has been renamed to esp_efuse_mac_get_default.
|
||||
* This name will be removed in a future release.
|
||||
*
|
||||
* @param mac hardware MAC address, length: 6 bytes.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @param mac hardware MAC address, length: 6 bytes.
|
||||
* @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
|
||||
* including wifi station, wifi softap, bluetooth and ethernet.
|
||||
* This function first get base MAC address using esp_base_mac_addr_get or reads base MAC address
|
||||
* 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 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);
|
||||
|
||||
/**
|
||||
* @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.
|
||||
* Addresses can either be universally administered addresses or locally administered addresses.
|
||||
* A universally administered address is uniquely assigned to a device by its manufacturer.
|
||||
* The first three octets (in transmission order) identify the organization that issued the identifier
|
||||
* 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.
|
||||
* A `definition of local vs universal MAC address can be found on Wikipedia
|
||||
* <https://en.wikipedia.org/wiki/MAC_address#Universal_vs._local>`.
|
||||
* In ESP32, universal MAC address is generated from base MAC address in EFUSE or other external storage.
|
||||
* Local MAC address is derived from the universal MAC address.
|
||||
*
|
||||
* @param dst_mac Derived local MAC address, length: 6 bytes.
|
||||
* @param src_mac Source universal MAC address, length: 6 bytes.
|
||||
* @param local_mac Derived local MAC address, length: 6 bytes.
|
||||
* @param universal_mac Source universal MAC address, length: 6 bytes.
|
||||
*
|
||||
* @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
|
||||
|
@ -221,7 +221,7 @@ static esp_err_t load_cal_data_from_nvs_handle(nvs_handle handle,
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
}
|
||||
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) {
|
||||
ESP_LOGE(TAG, "%s: calibration data MAC check failed: expected " \
|
||||
MACSTR ", found " MACSTR,
|
||||
@ -252,7 +252,7 @@ static esp_err_t store_cal_data_to_nvs_handle(nvs_handle handle,
|
||||
return err;
|
||||
}
|
||||
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));
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
|
@ -36,63 +36,50 @@
|
||||
|
||||
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()
|
||||
{
|
||||
}
|
||||
|
||||
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) {
|
||||
ESP_LOGE(TAG, "External base MAC address is NULL");
|
||||
ESP_LOGE(TAG, "Base MAC address is NULL");
|
||||
abort();
|
||||
}
|
||||
|
||||
memcpy(ext_base_mac_addr, mac, 6);
|
||||
memcpy(base_mac_addr, mac, 6);
|
||||
|
||||
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};
|
||||
|
||||
if (memcmp(ext_base_mac_addr, null_mac, 6) == 0) {
|
||||
ESP_LOGE(TAG, "External MAC address is not set");
|
||||
abort();
|
||||
if (memcmp(base_mac_addr, null_mac, 6) == 0) {
|
||||
ESP_LOGI(TAG, "Base MAC address is not set, read default base MAC address from BLK0 of EFUSE");
|
||||
return ESP_ERR_INVALID_MAC;
|
||||
}
|
||||
|
||||
memcpy(mac, ext_base_mac_addr, 6);
|
||||
memcpy(mac, base_mac_addr, 6);
|
||||
|
||||
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_high;
|
||||
uint8_t efuse_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;
|
||||
|
||||
if (version != 1) {
|
||||
ESP_LOGE(TAG, "Customer efuse MAC address version error, version = %d", version);
|
||||
abort();
|
||||
ESP_LOGE(TAG, "Base MAC address from BLK3 of EFUSE version error, version = %d", version);
|
||||
return ESP_ERR_INVALID_VERSION;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
@ -118,30 +132,31 @@ esp_err_t esp_efuse_read_mac(uint8_t* mac)
|
||||
return ESP_OK;
|
||||
}
|
||||
} 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();
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
||||
if (dst_mac == NULL || src_mac == NULL) {
|
||||
if (local_mac == NULL || universal_mac == NULL) {
|
||||
ESP_LOGE(TAG, "mac address param is NULL");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
memcpy(dst_mac, src_mac, 6);
|
||||
memcpy(local_mac, universal_mac, 6);
|
||||
for (idx = 0; idx < 64; idx++) {
|
||||
dst_mac[0] = src_mac[0] | 0x02;
|
||||
dst_mac[0] ^= idx << 2;
|
||||
local_mac[0] = universal_mac[0] | 0x02;
|
||||
local_mac[0] ^= idx << 2;
|
||||
|
||||
if (memcmp(dst_mac, src_mac, 6)) {
|
||||
if (memcmp(local_mac, universal_mac, 6)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -163,46 +178,42 @@ esp_err_t esp_read_mac(uint8_t* mac, esp_mac_type_t type)
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
_Static_assert(NUM_MAC_ADDRESS_FROM_EFUSE == FOUR_MAC_ADDRESS_FROM_EFUSE \
|
||||
|| NUM_MAC_ADDRESS_FROM_EFUSE == TWO_MAC_ADDRESS_FROM_EFUSE, \
|
||||
_Static_assert(UNIVERSAL_MAC_ADDR_NUM == FOUR_UNIVERSAL_MAC_ADDR \
|
||||
|| UNIVERSAL_MAC_ADDR_NUM == TWO_UNIVERSAL_MAC_ADDR, \
|
||||
"incorrect NUM_MAC_ADDRESS_FROM_EFUSE value");
|
||||
|
||||
#if defined(CONFIG_BASE_MAC_STORED_DEFAULT_EFUSE) || defined(CONFIG_BASE_MAC_STORED_CUSTOMER_DEFINED_EFUSE)
|
||||
esp_efuse_read_mac(efuse_mac);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_BASE_MAC_STORED_OTHER_CUSTOMER_DEFINED_PLACE)
|
||||
esp_base_mac_addr_get_external(efuse_mac);
|
||||
#endif
|
||||
if (esp_base_mac_addr_get(efuse_mac) != ESP_OK) {
|
||||
esp_efuse_mac_get_default(efuse_mac);
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case ESP_MAC_WIFI_STA:
|
||||
memcpy(mac, efuse_mac, 6);
|
||||
break;
|
||||
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);
|
||||
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);
|
||||
}
|
||||
break;
|
||||
case ESP_MAC_BT:
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
break;
|
||||
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);
|
||||
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;
|
||||
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>
|
||||
Deep Sleep <deep_sleep>
|
||||
Logging <log>
|
||||
Base MAC address <base_mac_address>
|
||||
|
||||
|
||||
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.
|
||||
#
|
Loading…
Reference in New Issue
Block a user