FreeRTOS_IPInit function Variable MAC Address

Hi,

I am working on a project where I need to make the MAC address variable such that my ucontroller is connected to a chip which has 32bit unique ID. I read this 32bit ID into a buffer and then I want to use this 32bit ID for MAC Address.

The problem is FreeRTOS_IPInit function takes a const MAC address as shown in the following declaration in FreeRTOS_IP.h file.

BaseType_t FreeRTOS_IPInit( const uint8_t ucIPAddress[ ipIP_ADDRESS_LENGTH_BYTES ],
const uint8_t ucNetMask[ ipIP_ADDRESS_LENGTH_BYTES ],
const uint8_t ucGatewayAddress[ ipIP_ADDRESS_LENGTH_BYTES ],
const uint8_t ucDNSServerAddress[ ipIP_ADDRESS_LENGTH_BYTES ],
const uint8_t ucMACAddress[ ipMAC_ADDRESS_LENGTH_BYTES ] );

When I modify the above function by removing “const” term. I can pass the 32bit ID and can initialize the IP stack. I can even see my board gets IP address assigned by the DHCP, however when I try to communicate with Development board (TM4C129E). My Putty/YAT terminal says the connection refused. YAT terminal gives me following message;
<Warning: An existing connection was forcibly closed by the remote host>

Please note, if I do not modify the above function and rather use a const MAC address. Everything works perfect and I can talk to my board using Putty/YAT Terminal.

Any hint or any alternative approach that can make me accomplish it?

Regards,
Abid

1 Like

Store the ID in a persistent (static) buffer and you should be fine. The const buffer of the MAC address buffer implies that the buffer must not change after IPInit because I think it’s not copied ‘into’ the stack but the provided data is just used (by reference). You might check the stack sources if this assumption is right.
I assume the unique chip ID is truly unique. Otherwise … strange things might happen.

Hartmut, thanks for getting into this!

I think it’s not copied ‘into’ the stack but the
provided data is just used (by reference)

Yes it is copied into a safe place:

    /* The MAC address is stored in the start of the default packet
    header fragment, which is used when sending UDP packets. */
    memcpy( ipLOCAL_MAC_ADDRESS, ucMACAddress,  ipMAC_ADDRESS_LENGTH_BYTES );

ipLOCAL_MAC_ADDRESS points to a structure owned by the IP-stack. So the bytes are stored, not the address.

Normally, for commercial products, a special MAC chip is mounted onto the board. It gives an administered, globally unique MAC address. The chip normally has a simple 1-wire access.

If you make up your own MAC-address, please look at e.g. this Wiki page about MAC addresses.

So unless your unique ID is a real MAC address, please set the lower to bis of the first byte to 0x02.

I do not see why you need to change the const-ness of the ucMACAddress parameter?
And I don’t see neither why it would change anything to its behaviour.

What happens is the following:

int main()
{
    /* No need for const here. The bytes will be copied into another buffer. */
    uint8_t ucMACAddress[ 6 ];
    /* Your function reads the unique ID. */
    read_unique_ID( ucMACAddress );
    /* Initialise the IP-stack. ucMACAddress is casted to const uint8_t*
    in the call. */
    FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGateway, ucDNS, ucMACAddress );
    /* And start the scheduler. */
    vTaskStartScheduler();
}

After FreeRTOS_IPInit: the MAC-address ( stored in ipLOCAL_MAC_ADDRESS ) will be written into the MAC registers of the EMAC, so your device gets an address.

As it is now, a FreeRTOS+TCP project takes a MAC address at start-up and never changes this address.

Summary: it makes no difference whether your MAC-address is defined with #define ( configMAC_ADDR0 ), or dynamically obtained before calling FreeRTOS_IPInit().

2 Likes

I’m really stuck on this problem. The things that Hein said make sense… but it can’t be the right answer. I tried updating the default IP address freeRTOS uses to the one I was trying to change it to and then it worked fine. If I change uMACAddress to be non const and then dynamically update it, pings always fail. Its weird because I see the entry for the device in the arp cache but it just wont reply to pings. There’s something going on with that ucMACAddress variable. It cannot be changed it seems. Has anybody successfully updated their mac address dynamically in freertos? Its crazy this question is still unsolved.

You have two posts with an almost identical title. Do forget to read the answers to the new one.

Old: FreeRTOS_IPInit function Variable MAC Address (April this year)
New: Cannot change MAC address dynamically? (now in December)