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.

Anyone seen EMACSnow _private get overwritten?

I am building a small test application that does nothing more than bring up the ethernet and NDK on a Tiva 129 Launchpad.  I put a breakpoint where EMACSnow_NIMUInit fills in the private database.  The hEvent value gets a good value.  Later when I receive the first packet from the Ethernet controller all of the private data except the link up and isrcount is set back to zero.


Has to be an error on my part, but no clue why it would get reset.

Thanks.

Ray

  • I'd look to see where EMACSnow_private is located. What's above it? Could you have accidently written past the previous item into EMACSnow_private? CCS has a Hardware Watchpoint where you can set a read and/or write to a memory address. You can use this to see who is writing over the EMACSnow_private structure.

    Todd

  • This is a double design error. The first "design error" is on the part of the NDK designers. EMACSnow_private is initialized to all zeros in EMACSnow_init() and then it is filled by the NDK task when the task starts up and calls EMACSnow_NIMUInit(). These are done in two different threads of execution so there is a designed in race condition.

    The second error comes from an incredibly bad design choice here. The examples have you call EMACSnow_init() from an ethernet startup function. In our case, someone decided to put that initialization inside of a task. The problem is that the NDK task can start up before our main startup task so the NDK called EMACSNIMUInit() and set up the data then our task called EMACSnow_init() and cleared the data.

    So, here are the items that need to change:
    1) Don't do what we did!!! We created a task and did all of our hardware init inside that task. Do what is in any of the example programs. We based our system loosely on udpecho. In that example *ALL* of the hardware init is done before you even call BIOS_init().

    2) TI should seriously consider changing EMACSnow.c so that EMACSnow_private is initialized in EMACSnow_NIMUInit() and remove EMACSnow_init() from the file altogether. I can't see any purpose for the extra function. All of its lines of code should be in EMACSnow_NIMUInit(). There is a variable in EMACSnow_init that sets EMAC_initialized to true. That is not really the case. It is not truly initialized until EMACSnow_NIMUInit() runs.

    Many thanks to all the application guys at TI for the very prompt and useful replies when the problem was clearly "a nut loose on our steering wheel". These guys do a great job supporting the community.

    Ray
  • I'm glad you figured it out. I agree that the driver has an undocumented race condition. I need to look at it a little more, but I agree that moving the initialization of EMACSnow_private into NIMUInit is probably a good idea. I'll open a bug report when I get back into the office (I cannot get my VPN up right now). I'll update this thread with the bug number.

    Thanks for the kind words also!

    Todd

  • I've opened the bug:

    SDOCM00114295: EMAC driver for TM4C129 has race condition if EMAC_init is called from a Task

    Todd