Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
5 years, 4 months ago.
How to change MAC address of non LPC1768 based boards?
Hi,
I have been trying to migrate a LPC1768 based board to STM32F407. One issue I ran into is how to set MAC address. The previous working solution somehow only works on LPC1768.
extern "C" void mbed_mac_address(char *mac) { mac[0] = 0x00; mac[1] = 0x02; mac[2] = 0xf7; mac[3] = 0xf2; mac[4] = 0x04; mac[5] = 0xa7; }
When I tried to build on ARCH_MAX, NUCLEO-F429ZI, FRDM_K64F, I get error:
L6200E: Symbol mbed_mac_address multiply defined (by ../../build/source/main-http.K64F.o and ../../build/mbed-os/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_MCU_K64F/TARGET_FRDM/mbed_overrides.K64F.o).
A previous post didn't mention having problems on K64F though. https://os.mbed.com/forum/bugs-suggestions/topic/31870/
1 Answer
5 years, 4 months ago.
Hello Zhiyong,
The mbed_mac_address(char* mac)
function (defined in mbed-os\platform\sourceplatform\mbed_interface.c
as WEAK
) is for the STM32 target boards
overridden in the mbed-os\features\netsocket\emac-drivers\TARGET_STM\stm32xx_emac.cpp
file as follows:
stm32xx_emac.cpp
... void mbed_mac_address(char *mac) { if (mbed_otp_mac_address(mac)) { return; } else { mbed_default_mac_address(mac); } return; } __weak uint8_t mbed_otp_mac_address(char *mac) { return 0; } ...
That allows us to change the MAC address for the STM32
boards by defining our uint8_t mbed_otp_mac_address(char *mac)
function (it will override the __weak mbed_otp_mac_address
function defined by STM). For example:
main.cpp
#include "mbed.h" #include "EthernetInterface.h" ... uint8_t mbed_otp_mac_address(char *mac) { mac[0] = 0x00; mac[1] = 0x02; mac[2] = 0xf7; mac[3] = 0xf2; mac[4] = 0x04; mac[5] = 0xa7; return 1; } ... int main(void) { ... }
For the K64F
target board the mbed_mac_address(char* mac)
function is overridden in the mbed-os\targets\TARGET_Freescale\TARGET_MCUXpresso_MCUS\TARGET_MCU_K64F\TARGET_FRDM\mbed_overrides.c
file as follows:
mbed_overrides.c
... void mbed_mac_address(char *mac) { uint16_t MAC[3]; // 3 16 bits words for the MAC // get UID via SIM_UID macros defined in the K64F MCU CMSIS header file uint32_t UID[4]; UID[0] = SIM->UIDH; UID[1] = SIM->UIDMH; UID[2] = SIM->UIDML; UID[3] = SIM->UIDL; // generate three CRC16's using different slices of the UUID MAC[0] = crcSlow((const uint8_t *)UID, 8); // most significant half-word MAC[1] = crcSlow((const uint8_t *)UID, 12); MAC[2] = crcSlow((const uint8_t *)UID, 16); // least significant half word // The network stack expects an array of 6 bytes // so we copy, and shift and copy from the half-word array to the byte array mac[0] = MAC[0] >> 8; mac[1] = MAC[0]; mac[2] = MAC[1] >> 8; mac[3] = MAC[1]; mac[4] = MAC[2] >> 8; mac[5] = MAC[2]; // We want to force bits [1:0] of the most significant byte [0] // to be "10" // http://en.wikipedia.org/wiki/MAC_address mac[0] |= 0x02; // force bit 1 to a "1" = "Locally Administered" mac[0] &= 0xFE; // force bit 0 to a "0" = Unicast } ...
Unfortunately, that does not allow us to change the MAC address for the K64F
target.
Later on I found I can change MAC address of STM32 based boards like this:
char mac[] = {0x00, 0x02, 0xf7, 0xf2, 0x04, 0xA8}; mbed_mac_address(mac);
I didn't try this on K64F though.
posted by 24 Nov 2019That compiles but doesn't change the MAC address of STM32 boards. A code like below shows unchanged MAC address:
char mac[] = {0x00, 0x02, 0xf7, 0xf2, 0x04, 0xA8}; mbed_mac_address(mac); const char* myMac = net->get_mac_address(); printf("MAC address: %s\r\n", myMac ? myMac : "None");