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, 11 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, 11 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");