This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TI Concerto Change MAC Address

Other Parts Discussed in Thread: SYSBIOS

I'm using a TI Concerto (F28M35H52C1) with TI RTOS v2_00_02_36/NDK 2_23_01_01 on a custom board where I need to read the MAC Address out of an EEPROM and then configure NDK to use that MAC Address. I'm able to read the MAC address out of the EEPROM (SPI interface) with no problems, but I'm not able to reconfigure NDK with this MAC address. I've been trying to use the NIMUIoctl() function to change the MAC, but it's returning -1. Here's the code I'm using:

    NIMU_IF_REQ if_req;
    UINT16 num_device;
    int ret_code;
    uint8_t mac_address[6];
    uint8_t device_name[20];
    uint8_t lnIdx = 0;

    //Get MAC Address from EEPROM
    GetEepromMACAddr(mac_address);

    System_printf ("MAC Address from EEPROM : 0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
    mac_address[0], mac_address[1], mac_address[2],
    mac_address[3], mac_address[4], mac_address[5]);
    System_flush();

    ret_code = NIMUIoctl (NIMU_GET_NUM_NIMU_OBJ, NULL, &num_device, sizeof(UINT16));

    if (ret_code==0)
    {
        System_printf("Number of NIMU objects:%d\n", num_device);
        System_flush();
    }
    else
    {
        System_printf ("NIMUIOCTL Failed with error code: %d\n",ret_code);
        System_flush();
    }
    uint16_t device_array[num_device];
    ret_code = NIMUIoctl (NIMU_GET_ALL_INDEX, NULL, &device_array, sizeof(device_array));
    if (ret_code==0)
    {
        System_printf("NIMU Index: %d\n", device_array[0]);
        System_flush();
    }
    else
    {
        System_printf ("NIMUIOCTL Failed with error code: %d\n",ret_code);
        System_flush();
    }
    if_req.index = device_array[0];
    ret_code = NIMUIoctl (NIMU_GET_DEVICE_NAME, &if_req, &device_name, sizeof(device_name));

    for(lnIdx=0;lnIdx<sizeof(device_name);lnIdx++)
    {
        if_req.name[lnIdx] = device_name[lnIdx];
    }
    System_printf ("Device Name : %s\n",if_req.name);
    System_flush();
    ret_code = NIMUIoctl (NIMU_SET_DEVICE_MAC, &if_req, &mac_address, sizeof(mac_address));
    if (ret_code==0)
    {
        System_printf("NIMU Set MAC Successful\n");
        System_flush();
    }
    else
    {
        System_printf ("NIMUIOCTL Failed with error code: %d\n",ret_code);
        System_flush();
    }
    ret_code = NIMUIoctl (NIMU_GET_DEVICE_MAC, &if_req, &mac_address, sizeof(mac_address));
    System_printf ("MAC Address : 0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
    mac_address[0], mac_address[1], mac_address[2],
    mac_address[3], mac_address[4], mac_address[5]);
    System_flush();

Thanks,

Will

  • Does anyone have any suggestions here?

    Thanks,
    Will
  • Hi Will,

    I'm looking at the code, but I had some quick questions. Are you using the .cfg to configure the stack or are you doing it manually in your code? Are you wanting to replace the MAC address once the system is running? Or is the problem, you find out the MAC address later in the start-up sequence. If this is the case, why don't you not start the stack until you have the MAC address?

    Todd

  • Todd,


    Thanks for your response! Yes, I've been using the .cfg file to configure the stack. And yes, I want to replace the MAC address after the system is running - because we have several boards in the network all running the same code and we need each of them to have a different IP address and MAC address. So, they all have the same hardcoded MAC in their board file (similar to TMDXDOCKH52C1.c in the example projects) because each board runs the same code, but after they start up, they need to grab their MAC and IP from an EEPROM on the board (accessed over SPI).

    If there was a way for me to grab the MAC and IP from the EEPROM before the EMAC and NDK stack start, I would do that - I'm flexible with implementation in this case.

    I read in the NDK documentation about using the C API (NC_NetStart(), etc.) to manually configure/start/stop the stack, rather than having it created by the .cfg file. Is that what you're talking about? I'll give that a shot.

    Also, do I need to do something different with the EMAC object code and the NIMU_DEVICE_TABLE_ENTRY code in my board file?

    Thanks,

    Will

  • Hi Will,

    Creating the NDK's main stack thread is one way to do this (and how people did it before we had the support in the .cfg file). I think an easier way is to add a begin hook in the .cfg. For example

    Global.stackBeginHook = '&myBeginFxn';

    Then in your code, have the hook grab the MAC address and call the Board_initEMAC code. For example

    void myBeginFxn()
    {
        //grab MAC address and update as needed for Board_initEMAC()
        Board_initEMAC();
    }

     Note: the hook is put at the top of the ndk's main stack Task. You could even pend on a semaphore in the begin hook if needed while getting the MAC address. If you look in the generated stack thread (in debug->configPkg->package->cfg-><app name>_<target type>.c, you'll see where the hook is called.

    /* Main Thread */
    Void ti_ndk_config_Global_stackThread(UArg arg0, UArg arg1)
    {
        int rc;
        HANDLE hCfg;

        ti_sysbios_knl_Clock_Params clockParams;

        /* Create the NDK heart beat */
        ti_sysbios_knl_Clock_Params_init(&clockParams);
        clockParams.startFlag = TRUE;
        clockParams.period = 100;
        ti_sysbios_knl_Clock_create(&llTimerTick, clockParams.period, &clockParams, NULL);


        {
            extern Void myBeginFxn();

            /* call user defined stack beginning hook */
            myBeginFxn();
        }

        /* THIS MUST BE THE ABSOLUTE FIRST THING DONE IN AN APPLICATION!! */
        rc = NC_SystemOpen(NC_PRIORITY_LOW, NC_OPMODE_INTERRUPT);
        ...

    Note some people use the .cfg to generate the code and then cut and paste it into their application to modify as needed (and then turn off the generation via the Global.enableCodeGeneration parameter). For you, I think the begin hook is the easier path.

    Todd 

     

  • Todd,

    Thanks for your suggestion. That worked to use the stack beginning hook. And I didn't have to use the NIMUIoctl functions at all to set the MAC address. Here's what I did (for others who might be interested):

    in my .cfg file:
    Global.stackBeginHook = "&changeMacAddr";

    in my board file (similar to TMDXDOCKH52C1.c that is generated by CCS for an RTOS project):
    (within the section bracketed by "#if TI_DRIVERS_EMAC_INCLUDED")
    unsigned char macAddress[6]; //instead of being statically defined
    (then I added a new function - SetEepromMACAddr() to the board file to update the macAddress variable with the value obtained from EEPROM)

    and here's my stack begin hook function:
    void changeMacAddr (void)
    {
    uint8_t mac_address[6];

    Board_initSPI();

    EPM_Init(); //a function to initialize my EEPROM driver

    CFG_Init(); //a function to read IP and MAC Addresses from NVRAM

    //Send MAC Address from EEPROM to EMAC Init structure
    SetEepromMACAddr(mac_address);

    System_printf ("MAC Address from EEPROM : 0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
    mac_address[0], mac_address[1], mac_address[2],
    mac_address[3], mac_address[4], mac_address[5]);
    System_flush();

    Board_initEMAC();
    }

    Then in my network comms task (which runs after the stack has been started), I confirm that the MAC address was successfully configured with the value that I got from the EEPROM by using the following code:

    NIMU_IF_REQ if_req;
    UINT16 num_device;
    int ret_code;
    uint8_t mac_address[6];
    uint8_t device_name[20];
    uint8_t lnIdx = 0;

    //check that MAC address was successfully changed
    ret_code = NIMUIoctl (NIMU_GET_NUM_NIMU_OBJ, NULL, &num_device, sizeof(UINT16));

    if (ret_code==0)
    {
    System_printf("Number of NIMU objects:%d\n", num_device);
    System_flush();
    }
    else
    {
    System_printf ("NIMUIOCTL GET NUM OBJ Failed with error code: %d\n",ret_code);
    System_flush();
    }
    uint16_t device_array[num_device];
    ret_code = NIMUIoctl (NIMU_GET_ALL_INDEX, NULL, &device_array, sizeof(device_array));
    if (ret_code==0)
    {
    System_printf("NIMU Index: %d\n", device_array[0]);
    System_flush();
    }
    else
    {
    System_printf ("NIMUIOCTL GET ALL IDX Failed with error code: %d\n",ret_code);
    System_flush();
    }
    if_req.index = device_array[0];
    ret_code = NIMUIoctl (NIMU_GET_DEVICE_NAME, &if_req, &device_name, sizeof(device_name));

    for(lnIdx=0;lnIdx<sizeof(device_name);lnIdx++)
    {
    if_req.name[lnIdx] = device_name[lnIdx];
    }
    System_printf ("Device Name : %s\n",if_req.name);
    System_flush();
    ret_code = NIMUIoctl (NIMU_GET_DEVICE_MAC, &if_req, &mac_address, sizeof(mac_address));
    if (ret_code!=0)
    {
    System_printf ("NIMUIOCTL GET MAC Failed with error code: %d\n",ret_code);
    System_flush();
    }
    System_printf ("New MAC Address : 0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n",
    mac_address[0], mac_address[1], mac_address[2],
    mac_address[3], mac_address[4], mac_address[5]);
    System_flush();


    Thanks,
    Will