Because of the Thanksgiving holiday in the U.S., TI E2E™ design support forum responses may be delayed from November 25 through December 2. Thank you for your patience.

EK-TM4C1294XL: Building and using boot_demo_emac_rom under linux

Part Number: EK-TM4C1294XL
Other Parts Discussed in Thread: ENERGIA

Tool/software:

I have struggled over some time to successfully use the ROM_UpdateEMAC function in a project built using gcc under Ubuntu, and then to successfully flash the board over ethernet.

All attempts so far have failed at the point ROM_UpdateEMAC is called.

Today I thought I would build boot_demo_emac_rom and found that that is failing in exactly the same way. (I had to make the following minor modifications:

1. to correct the linker error .ARM.edidx overlaps .data found this fix https://github.com/hathach/tinyusb/issues/2337

2. to set a static IP address rather than use DHCP

I haven't been able to locate a working official tool for flashing the board from Ubuntu over linux, so have tried 2 alternative:

1. Python script which generates the magic packet and then invokes a tftp loader.

2. I ported the eflash tool in Tivaware from Windows to linux.

When eflash didn't seem to be working, I got it to display verbose messages, from which I can see that the TM4C isn't sending anything so it keeps resending the magic packet.

3. I started a windows VM and tried LMFlash which also hanged.

I then flashed the board with a binary that I had built some years earlier using CCS, and knew to work with 5 existing boards including the ability to update these over wired ethernet,

this doesn't flash with either LMFlash (from a windows VM) or eflash (converted to linux).

The two boards I have tried were bought about 2017 or 2018, whereas the boards that appear to work were bought between 2014 and 2016.

The MAC addresses of the boards that don't appear to flash are 00:1A:B6:03:0E:05 and 00:1A:B6:03:09:AE , unfortunately I don't remember if these could ever be flashed over ethernet.

Is it possible that these later boards don't implement a working ROM_UpdateEMAC ? Is there any other information that could establish this?

My principal objective is now to reflash the original boards with updated (and simpler) software, as these are in fairly inaccessible locations it isn't practical to flash them over USB. These boards are still being used by a live application so I don't want to replace their software until I know I can apply updates easily. At present I suspect that I might be able to update them, but have no means of verifying this using the 2 other existing boards.

  • Hi,

      I'm currently on travel. I will reply your post when I come back on Wednesday. Sorry for the inconvenience.

  • Hi Charles,

    Thanks for getting back to me. Since I posted on Sunday I have done some further investigation. If I am was not able to use Rom_UpdateEMAC with all the boards, then an alternative would be to install an update script in flash. There is an example boot_demo_emac_flash which should work, so I built and installed that, but found that it failed in exactly the same way with eflash, so I debugged it and realised that it didn't appear to be receiving the magic packet. I then installed wireshark and found the eflash was broadcasting magic packets to udp port 9. The data portion of the packets looks correct, and even if it isn't the packet isn't reaching the board. So I now think that the problem lies with the configuration of lwip. (Which is effectively in lwipopts.h, which is part of the example project, so should be correct). I do not know my way round this, but assume that it needs to be configured to use UDP, so I found

    //*****************************************************************************
    //#define LWIP_UDP 1
    //#define LWIP_UDPLITE 0
    //#define UDP_TTL (IP_DEFAULT_TTL)
    This being commented out in the example looks wrong, so I uncommented it but that doesn't seem to make the difference.
    Any light that can be shed on how lwipopt.h should be set up for these examples would be appreciated, this should enable both update examples to be progressed to the point of updating firmware on the board. I would also appreciate an official view of which boards the ROM_Update method should work with.
  • Hi,

     Sorry for my late reply as I just got back from my travel. 

      Have you tried the TivaWare example in C:\ti\TivaWare_C_Series-2.2.0.295\examples\boards\ek-tm4c1294xl\boot_demo_emac_rom that calls Rom_UpdateEMAC?

    this doesn't flash with either LMFlash (from a windows VM) or eflash (converted to linux).

    There is a known issue with LMflash and eflash that it will send the magic packet to a wrong NIC if your computer has mulitple NICs. Can you try to disable all NICs except the one that is on the same network with the MCU board?

  • Hi,

    Disabling network interfaces doesn't seem to make any difference, and isn't consistent with the following findings.

    boot_demo_emac_rom behaves slightly differently from boot_demo_emac_flash. (both from the 2.2.0.295 Tivaware download). 

    boot_demo_emac_rom flashes LED D1 on the board about every 0.5 seconds, whereas boot_demo_emac_flash does not. I am not that sure of my use of gdb and found it difficult to get repeatable results, so I added some trace statements to UART0 instead to see what was going  on. These showed that boot_demo_emac_rom sees the magic packet and gets to 

    SoftwareUpdateBegin(g_ui32SysClock);
    The makefile has CFLAGSgcc=-DTARGET_IS_TM4C129_RA2 , so ROM_UpdateEMAC should be defined and called.
    I think that I should expect a packet on udp port 67 (BOOTP) or 69 (TFTP) at this point from the TM4C, so I looked in Wireshark and see a BOOTP request coming from my board:
    Frame 2549: 342 bytes on wire (2736 bits), 342 bytes captured (2736 bits) on interface enp3s0, id 0
    Section number: 1
    Interface id: 0 (enp3s0)
    Encapsulation type: Ethernet (1)
    Arrival Time: Oct 30, 2024 19:44:38.682609174 GMT
    UTC Arrival Time: Oct 30, 2024 19:44:38.682609174 UTC
    Epoch Arrival Time: 1730317478.682609174
    [Time shift for this packet: 0.000000000 seconds]
    [Time delta from previous captured frame: 0.002030087 seconds]
    [Time delta from previous displayed frame: 1.019991415 seconds]
    [Time since reference or first frame: 38.631688332 seconds]
    Frame Number: 2549
    Frame Length: 342 bytes (2736 bits)
    Capture Length: 342 bytes (2736 bits)
    [Frame is marked: False]
    [Frame is ignored: False]
    [Protocols in frame: eth:ethertype:ip:udp:dhcp]
    [Coloring Rule Name: UDP]
    [Coloring Rule String: udp]
    Ethernet II, Src: TexasInstrum_03:09:ae (00:1a:b6:03:09:ae), Dst: Broadcast (ff:ff:ff:ff:ff:ff)
    Internet Protocol Version 4, Src: 0.0.0.0, Dst: 255.255.255.255
    User Datagram Protocol, Src Port: 68, Dst Port: 67
    Dynamic Host Configuration Protocol
    So it looks like my conversion of eflash isn't seeing the request packet.
    I noticed that the BOOTP packet is broadcast, and the call to CreatePacket in eflash specifies 
    ui32LocalAddr so I tried IN_ADDR_ANY instead, and now it sees a repeating sequence of packets. A request from the board and 2 responses from eflash:
    BOOTP Request:
    Frame 178502: 342 bytes on wire (2736 bits), 342 bytes captured (2736 bits) on interface enp3s0, id 0
    Ethernet II, Src: TexasInstrum_03:09:ae (00:1a:b6:03:09:ae), Dst: Broadcast (ff:ff:ff:ff:ff:ff)
    Internet Protocol Version 4, Src: 0.0.0.0, Dst: 255.255.255.255
    User Datagram Protocol, Src Port: 68, Dst Port: 67
    Dynamic Host Configuration Protocol
    Message type: Boot Request (1)
    Hardware type: Ethernet (0x01)
    Hardware address length: 6
    Hops: 0
    Transaction ID: 0xd4687518
    Seconds elapsed: 726
    Bootp flags: 0x0000 (Unicast)
    Client IP address: 0.0.0.0
    Your (client) IP address: 0.0.0.0
    Next server IP address: 0.0.0.0
    Relay agent IP address: 0.0.0.0
    Client MAC address: TexasInstrum_03:09:ae (00:1a:b6:03:09:ae)
    Client hardware address padding: 00000000000000000000
    Server host name: tiva
    Boot file name not given
    Bootp vendor specific options: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
     Boot Reply:
    Frame 178503: 342 bytes on wire (2736 bits), 342 bytes captured (2736 bits) on interface enp3s0, id 0
    Ethernet II, Src: ASRockIncorp_2e:27:16 (a8:a1:59:2e:27:16), Dst: Broadcast (ff:ff:ff:ff:ff:ff)
    Internet Protocol Version 4, Src: 192.168.1.16, Dst: 255.255.255.255
    User Datagram Protocol, Src Port: 67, Dst Port: 68
    Dynamic Host Configuration Protocol
    Message type: Boot Reply (2)
    Hardware type: Ethernet (0x01)
    Hardware address length: 6
    Hops: 0
    Transaction ID: 0xd4687518
    Seconds elapsed: 726
    Bootp flags: 0x0000 (Unicast)
    Client IP address: 0.0.0.0
    Your (client) IP address: 192.168.1.107
    Next server IP address: 127.0.1.1
    Relay agent IP address: 0.0.0.0
    Client MAC address: TexasInstrum_03:09:ae (00:1a:b6:03:09:ae)
    Client hardware address padding: 00000000000000000000
    Server host name: tiva
    Boot file name: firmware.bin
    Bootp vendor specific options: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
    Boot Reply:
    Frame 178519: 342 bytes on wire (2736 bits), 342 bytes captured (2736 bits) on interface enp3s0, id 0
    Ethernet II, Src: ASRockIncorp_2e:27:16 (a8:a1:59:2e:27:16), Dst: Broadcast (ff:ff:ff:ff:ff:ff)
    Internet Protocol Version 4, Src: 192.168.1.16, Dst: 255.255.255.255
    User Datagram Protocol, Src Port: 67, Dst Port: 68
    Dynamic Host Configuration Protocol
    Message type: Boot Reply (2)
    Hardware type: Ethernet (0x01)
    Hardware address length: 6
    Hops: 0
    Transaction ID: 0xd4687518
    Seconds elapsed: 726
    Bootp flags: 0x0000 (Unicast)
    0... .... .... .... = Broadcast flag: Unicast
    .000 0000 0000 0000 = Reserved flags: 0x0000
    Client IP address: 0.0.0.0
    Your (client) IP address: 192.168.1.107
    Next server IP address: 127.0.1.1
    Relay agent IP address: 0.0.0.0
    Client MAC address: TexasInstrum_03:09:ae (00:1a:b6:03:09:ae)
    Client hardware address padding: 00000000000000000000
    Server host name: tiva
    Boot file name: firmware.bin
    Bootp vendor specific options: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
    This pattern has been repeating for about 30 minutes now, so I think something else is expected.
    The BOOTP Reply doesn't seem to contain much data, and the eflash logic only seems to send one reply packet.
    Should I expect a TFTP packet next?


    .
  • Now it looks like I am nearer to getting the examples to work, I would like to know if I should pursue my current approach to the application I am developing or rethink a bit.

    I have used Energia, and for EthernetClient and EthernetUdp classes for communication. The main difference as far as software update is concerned is that rather than receiving the magic packet via a callback function and setting a flag, I do a call within loop to look for a magic packet. If this is found I then attempt to call ROM_UpdateEMAC after disabling interrupts. This gets to the ROM_UpdateEMAC call but doesn't send a BOOTP Request. Instead after some delay it reboots.

    The main reason for using the EthernetClient and EthernetUdp classes is that I use an mqtt class that depends on them.

    There is a mqtt application in the main source of lwip, which uses callbacks, would I be more likely to succeed if I used this and followed the pattern used in the example?

  • Disabling network interfaces doesn't seem to make any difference, and isn't consistent with the following findings.

    boot_demo_emac_rom behaves slightly differently from boot_demo_emac_flash. (both from the 2.2.0.295 Tivaware download). 

    boot_demo_emac_rom flashes LED D1 on the board about every 0.5 seconds, whereas boot_demo_emac_flash does not. I am not that sure of my use of gdb and found it difficult to get repeatable results, so I added some trace statements to UART0 instead to see what was going  on. These showed that boot_demo_emac_rom sees the magic packet and gets to 

    Hi Julian,

      Are you saying both examples do not work for you with only one NIC active on your computer? Have you tried to run the examples on a Windows PC. I want to know if it has anything to do with the Linux. 

    SoftwareUpdateBegin(g_ui32SysClock);
    The makefile has CFLAGSgcc=-DTARGET_IS_TM4C129_RA2 , so ROM_UpdateEMAC should be defined and called.

    The major difference between the two examples is that for the boot_demo_emac_flash example, it has the USE_FLASH_BOOT_LOADER symbol defined so the ROM_UpdateEMAC() is called. You don't need to add the ROM_UpdateEMAC symbol in your command line. The ROM_UpdateEMAC symbol is already defined in the rom.h header file. 

    See the below snippet 

    //
    // Return control to the boot loader. This is a call to the SVC
    // handler in the flashed-based boot loader, or to the ROM if configured.
    //
    #if ((defined ROM_UpdateEMAC) && !(defined USE_FLASH_BOOT_LOADER))
    ROM_UpdateEMAC(ui32SysClock);
    #else
    (*((void (*)(void))(*(uint32_t *)0x2c)))();
    #endif

    Now it looks like I am nearer to getting the examples to work, I would like to know if I should pursue my current approach to the application I am developing or rethink a bit.

    Glad you are making progress but I'm not clear with your details that you are near getting it to work. 

  • Hi Charles,

    I now have a successful upload!

    Thanks for persisting with the disable all but one NIC, though I don't have easy access to a Windows PC (VM isn't quite the same thing), it made me look more carefully at the converted eflash.

    The problem in eflash is that the local address is set to localhost (127.0.1.1), I hard coded it to the correct address (192.168.1.16) this then completed an upload.  This is apparently a weakness of using gethostname to derive the IP address of the network card under linux. So I need to find an alternative means of deriving the right IP address.

    One other change that I needed to make was to create the bootp socket using INADDR_ANY rather than ui32LocalAddress. 

    Kind Regards

    Jules