Arm Mbed OS support forum

Setting a Mac Address - K66

Hi,

I’ve been using the following code to set the Mac address on the LPC1768: for a few years now and it works perfectly.

NetworkInterface *net;

char mac[] = {’\xB2’, ‘\x40’, ‘\x62’, ‘\xB7’, ‘\x42’, ‘\x88’};

extern “C” void mbed_mac_address(char *s)
{
memcpy(s, mac, 6);
};

I’ve now moved to the K66 processor and now I get the error:

Error: Symbol mbed_mac_address multiply defined (by …/…/build/mbed-os/targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K66F/TARGET_FRDM/mbed_overrides.K66F.o and …/…/build/main.K66F.o).

I’ve tried the K64 code mentioned here: K64f mac address - #8 by hudakz While this does compile, the OS crashes instantly.

Regards

Roger

Hello Roger,

I don’t have a K66 (and I’ve never had one) to test the code.
In the referred code, try to replace:

    static Kinetis_EMAC emac;
 
    emac.set_hwaddr(my_macaddr);
    net = new  EthernetInterface(emac, OnboardNetworkStack::get_default_instance());

with

    EMAC::get_default_instance().set_hwaddr(my_macaddr);
    net = new  EthernetInterface;

Also try to run the program with the default Mac Address to check whether that works.

    net = NetworkInterface::get_default_instance();

Best regards, Zoltan

For STM32 I used the following code:

// Hidden callback from mbed
// https://os.mbed.com/questions/87591/How-to-change-MAC-address-of-non-LPC1768/
// To make things worst it's not even the same call for all platforms.
uint8_t mbed_otp_mac_address(char *mac) {
    memcpy(mac, Settings::get_eth_mac_address(), 6);
    return 1;
}

I had to look into the target hal code to figure it out. Try to look for weak symbols. EthernetInterface::set_mac_address simply doesn’t work for STM32. It might work on your platform.
They really should fix this mac address issue, having different ways to set your mac address is quite anoying.

Hi Zoltan,

Thanks for this, I have tested it and it still crashes when “EMAC::get_default_instance().set_hwaddr(my_macaddr);” is called.

The dafault Mac Address (net = NetworkInterface::get_default_instance():wink: works fine.

I don’t know if this is any help, but here’s the crash report;

++ MbedOS Fault Handler ++

FaultType: HardFault

Context:
R0 : 400C0000
R1 : 00000088
R2 : 000000AA
R3 : 00000000
R4 : 20000ACC
R5 : 00000000
R6 : 20000A74
R7 : 20000ACC
R8 : 200009C8
R9 : 20000844
R10 : 0000E701
R11 : 20000A08
R12 : 000189E9
SP : 20002F30
LR : 00007915
PC : 00003DB6
xPSR : 01000000
PSP : 20002EC8
MSP : 2002FFD0
CPUID: 410FC241
HFSR : 40000000
MMFSR: 00000000
BFSR : 00000004
UFSR : 00000000
DFSR : 00000000
AFSR : 00000000
Mode : Thread
Priv : Privileged
Stack: PSP

– MbedOS Fault Handler –

Regards

Roger

Hi Thiago,

What do I declare ‘Settings’ as? The compiler throws up the error: "Use of undeclared identifer ‘Settings’ ".

Regards

Roger

Hi Roger,

On my code that’s just a function on a namespace. It simply returns a 6 bytes uint8_t array:

   namespace Settings {

   uint8_t* get_eth_mac_address() {
       static uint8_t macAddress[6] = {0x00, 0x50, 0x00, 0x00 0x00, 0x00};
       return macAddress;
   }
   }

you could replace that function with the macAddress array directly like this:

uint8_t mbed_otp_mac_address(char *mac) {
    static uint8_t macAddress[6] = {0x00, 0x50, 0x00, 0x00 0x00, 0x00};
    memcpy(mac, macAddress, 6);
    return 1;
}

As far as I can tell from grep mbed_otp_mac_address is used by STM and NXP targets I couldn’t find it in TARGET_Freescale folder. It might be something similar but named differently.

Hi Roger,

Looking into mbed-os/connectivity/drivers/emac/TARGET_Freescale_EMAC/kinetis_emac.cpp I think that this platform has the EthernetInterface::set_mac_address implemented (unlike mine which doesn’t work). Could you try this and see if it works?

EthernetInterface eth;
static uint8_t macAddress[6] = {0x00, 0x50, 0xC2, 0x5F, 0xE0, 0x00};
eth.set_mac_address(macAddress, 6);

Hi Thiago,

I get a compiler message saying: No member named ‘set_mac_address’ in ‘EthernetInterface’

I’m using OS5 rather than OS6 if that is any help.

Regards

Roger

Ah, i’m using OS 6.5, have never used 5 before. Might want to check the *_emac.cpp file in your os folder and see if there are references to mac or macaddress to give a clue.

Hi Thiago,

I have ‘sl_emac.cpp’ and within that the mac address is set with:

void SL_EMAC::set_hwaddr(const uint8_t *addr)
{
tr_debug(“Setting MAC address %02x:%02x:%02x:%02x:%02x:%02x”,
addr[0],
addr[1],
addr[2],
addr[3],
addr[4],
addr[5]);

ETH->SPECADDR1BOTTOM = ((uint32_t)addr[0] << (0)) |
                       ((uint32_t)addr[1] << (8)) |
                       ((uint32_t)addr[2] << (16))|
                       ((uint32_t)addr[3] << (24));

ETH->SPECADDR1TOP = ((uint32_t)addr[4] << (0)) |
                    ((uint32_t)addr[5] << (8));

}

Which seems to correspond to the code that Zoltan suggested which compile fine and then crashes the processor.

Regards

Roger