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.

MSP432E401Y: Location of Interrupt Routines in nortos Examples

Part Number: MSP432E401Y
Other Parts Discussed in Thread: MSP-EXP432E401Y,

Hi,

I'm working with the nortos ethernet_weather example on the MSP-EXP432E401Y development board with CCS.

My question: Since the example doesn't use an operating system can I assume that the interrupt routines are located in the example's files?

Thank you in advance for any assistance I can get in locating the interrupt routines for this example.

Regards,
Brad McMillan

  • Which one(s)?

    The Systick_Handler is in enet_weather.c. The UART0_IRQHandler is in uartstdio.c. The EMAC0_IRQHandler is in lwiplib.c (source\third_party\lwip\ports\msp432e4\utils).

    In the nortos port, most of the lwIP work is done via a call from the Systick_Handler.

  • I'm trying to extract data I'm receiving over Ethernet so I am interested in the EMAC0_IRQHandler.  

    I'm sending a short TCP burst of 10 bytes from a server pointed to the same IP address.  It is "05 64 05 C9 01 00 01 00 90 25".  It looks like the data is being received OK because the counters advance when the burst is sent, the IP Payload type in the Receive Descriptor indicates that TCP Ethernet frames have been received, and the memory at the buffer address is updated.

    But when I look at the Ethernet Frame I can't see anything that resembles the 10 bytes that were received, low bit first or high bit first.

    Any idea how the extract the incoming data from the Ethernet frame?

    I also read that there might be a routine that extracts the incoming bytes and stores them somewhere.  It would be perfect if that were the case and I could find where the incoming data is being stored.

  • It's possible your packet was part of a group of packets. Are you sure you were looking at the right one?

    There is a collection of "xxx_DEBUG" options in "source\third_party\lwip\src\include\lwip\opt.h". Maybe one or more of them would be instructive.

  • Maybe I'm not looking in the right place. Here is what I'm doing. Please tell me if I'm making a mistake.

    When I send the 10 bytes (05 64 05 C9 01 00 01 00 90 25), I get this response in the Receive Descriptors.

    0x2000BCF4 g_pRxDescriptors
    0x2000BCF4 80000000 00004200 20009D04 2000BD18 00000042 00000000 00000000 00000000 20009CF4
    0x2000BD18 80000000 00004200 200094C4 2000BD3C 00000042 00000000 00000000 00000000 200094B4
    0x2000BD3C 80000000 00004200 200092B4 2000BD60 00000041 00000000 00000000 00000000 200092A4
    0x2000BD60 80000000 00004200 200090A4 2000BD84 00000041 00000000 00000000 00000000 20009094
    0x2000BD84 80000000 00004200 20009F14 2000BDA8 00000041 00000000 00000000 00000000 20009F04
    0x2000BDA8 80000000 00004200 200098E4 2000BDCC 00000042 00000000 00000000 00000000 200098D4
    0x2000BDCC 80000000 00004200 200096D4 2000BDF0 00000042 00000000 00000000 00000000 200096C4
    0x2000BDF0 80000000 00004200 20008E94 2000BCF4 00000042 00000000 00000000 00000000 20008E84

    The 5 00000042's tell me I received 5 IPv4 Ethernet Frames of type TCP and the Buffer Addresses tell me that the Ethernet Frames are located in address spaces from 0x20008E94 to around 0x2000A200. I can see the 10 bytes I sent in that block of memory, but they seem to be at random spots so I wouldn't know how to extract them.

    Am I looking at this correctly? And if so, is there a reference for the structure of the Ethernet Frames so I can figure out how to extract the 10 bytes that were sent?

    It would also be very useful if the ethernet_weather example I'm working with already has some routines that extract the incoming data from the Ethernet Frames.

  • These descriptors all have the OWN bit set, so it looks like you stopped after the incoming buffered data was "harvested". In that case, the buffer pointers that were there aren't there now, since they've been passed to the higher layers and the descriptors have been supplied with fresh (empty) buffers.

    The buffer contents can be expected to look like packet headers, i.e. MAC header, IP header, TCP header, then data. Extracting the incoming data from the frames is what lwIP does for a living. The usual way to obtain the data is to code a TCP server (or client) and let lwIP provide the (application) data to you.

  • That brings up a few questions:

    1. If the data was harvested, does that mean that it resides somewhere that I can access to see what data was received?

    2. If I need to get the data myself I will need to disable the code that is currently extracting it. Any idea where that code is so I can disable it?

    3. And, I assume I can use some of the lwIP routines to extract the data from the frames. Which routines should I use to do the extraction?

    Thank you.

  • 1) Those buffers are somewhere, but it might not be easy to find them. They may be attached to your application's tcp, or may have been put back in the free pool(s). Your best bet is probably to breakpoint in the driver, just before the harvesting loop.

    2) If you don't want to do any TCP/IP processing I suppose you could write your own ethernet_input() function. You can check the driver source (msp432e4if.c) for how that's called.

    3) Maybe you can re-purpose some functions from lwIP. Generally they operate in a context that's maintained by the rest of the code, but the source code is all right there, so you can see for yourself.

    Your goal is not obvious to me. Is it (a) one-time debug? [see (1) above] (b) write your own TCP/IP stack? [a non-trivial task] (c) insert some tracing? [lwIP might already have this, ref the xxx_DEBUG symbols I mentioned]

    If you don't want to do TCP/IP at all, you can design your own protocol over raw Ethernet. You could probably hack the Ethernet driver to do some of this -- read the driver code to see what it minimally needs. (Keep in mind that you would have to write the code for the other end as well.)

  • My goal: We are looking at the MSP432E401Y as a possible replacement for the existing microcontroller we use in our product line. Our products work in isolated Ethernet networks with one server talking to any number of clients (we are the clients). It is a very simple application where the product receives a command of 10 to 20 bytes and sends a response of 10 to a couple hundred bytes. My goal right now is to be able to isolate the received bytes of data so I can determine what command has come in.

    Right now, I've been running tests trying to look at the Ethernet Frame that comes in when I send the 10 byte string (05 64 05 C9 01 00 01 00 90 25) to the MSP432E401Y. Here is the step-by-step using the Debug feature of CCS:

    1. Start the test and wait for all of the initial Ethernet communications to finish.
    2. Set a breakpoint at line 920 of msp432e4if.c
    3. Send the 10 bytes to the MSP432E401Y which causes the processing to stop at line 920.
    4. Look at the receive descriptors. This one is typical:

    0x2000BCF4 00460321 00004200 200096D4 2000BD18 00000042 00000000 00000000 00000000 200096C4

    5. Look at the associated Ethernet Frame, also typical:

    0x200096D4 1C76FF70 265C4EBB 251E220A 00450008 0C7D3400 06800040 A8C0FCF9 A8C00501 64C26501

    As you can see there is nothing in the Ethernet Frame that looks anything like the 10 bytes I sent.

    Do you know of any reference that provides a clear description of the format of the Ethernet Frames I'm receiving? I've looked all over the internet and I'm getting a lot of contradictory information.

    Since I've been using the debug function in CCS, It's not clear to me how I would use the "xxx_DEBUG" options you mentioned above.

    Also, we don't have any control over the server end so designing my own protocol over raw Ethernet is not an option. TCP is fine. I just need to figure out how it works.

    Thanks again.

  • >0x2000BCF4 0046

    This says the incoming frame is 0x46=70 bytes long, and you've only displayed the first 36 bytes. Your data would be out near the end.

    You're looking at the Ethernet frame header, followed by the IP header, followed by a little bit of the TCP header. I just Googled "ethernet frame header" , "ip header format", and "tcp header format" and the top hits showed the layouts. There are also the RFCs, and (quite a number of) books on the topic. I would guess that the code you're using now would also be a useful reference/base.

    A couple of things to watch out for:

    1) These headers are not fixed-length, there are optional fields whose presence/absence you deduce from dissecting the header.

    2) The TCP/IP items are in big-endian ("network byte order")  and the debugger will usually display them in little-endian ("host byte order" on the MSP432E). 

  • I was able to do further testing with the information you provided, but still can't find the 10 bytes I'm sending (05 64 05 C9 01 00 01 00 90 25).

    After initialization I set the breakpoint at line 920 of msp432e4if.c and sent the 10 bytes to the MSP432E401Y. Here are the receive descriptors that changed:

    0x2000BD60 00400320 00004000 20009D04 2000BD84 00000041 00000000 00000000 00000000 20009CF4
    0x2000BD84 00460321 00004200 20009F14 2000BDA8 00000042 00000000 00000000 00000000 20009F04
    0x2000BDA8 00460321 00004200 200090A4 2000BDCC 00000042 00000000 00000000 00000000 20009094

    And here are the (full-size) Ethernet Frames they reference:

    0x20009D04 FFFFFFFF 265CFFFF 251E220A 01000608 04060008 265C0100 251E220A 0501A8C0

               00000000 A8C00000 00006501 00000000 00000000 00000000 00000000 2780B958


    0x20009F14 1C76FF70 265C4EBB 251E220A 00450008 397D3400 06800040 A8C0CFF9 A8C00501 7EC56501

               919A901F 00003DA9 02800000 86C7F0FA 04020000 0301B405 01010803 88840204 0402


    0x200090A4 1C76FF70 265C4EBB 251E220A 00450008 3A7D3400 06800040 A8C0CEF9 A8C00501 7EC56501

               919A901F 00003DA9 02800000 86C7F0FA 04020000 0301B405 01010803 058A0204 0402

    The first one looks irrelevant to me.  I was able to figure out where the TCP header and data were located by changing the destination port, labelled dp here:

    sp || dp   seq#     ack#    ws  do  urgp cks   opts   | data ->
    919A901F 00003DA9 02800000 86C7F0FA 04020000 0301B405 01010803 88840204 0402

    Which still does not include the 10 bytes I'm sending.  Can you think of any way I can change my testing or any other ideas that will help me find them?

    Thank you.

  • 02800000

    This (02) is a SYN packet, so the other side (which is actually the client) is just starting to create the TCP connection. It won't try to send your data until the connection is complete. The data offset (80) is 8, so there is no user data in this packet. You may need to step your client so you know when the connection is done.

    What state is your server code (on the MSP432) in? It still seems like it would be easier to just see what data lwIP delivers to it. (It always did fine for me.)

  • My understanding is that the MSP432 with the ethernet_weather example (which is what I am working with here) is programmed to be a client so I'm confused when you say that the other side is actually a client.

    I can see where the first few packets could be for synchronization and that I just need to wait for the actual data packet to arrive, but when you say it would be easier to just see what lwIP delivers to it I'm back to my original problem:  

    Where is the data that has been delivered?

  • As I understand it, you're trying to fit a new node implementation (MCU) into your existing system. I don't know how that system works, but I expect it's is all explained in your system's architecture description.

    I did see that your (presumed) master/hub was sending a SYN packet, which tells me that it is initiating the connection, which (in TCP terms) makes it the client. There needs to be an entity on your side (listening on the correct port) to make the connection with, or no data will be sent. The Weather application, besides being a client, knows only how to talk to a Web site (openweathermap.org, apparently), and not with your system.

    The data is provided using a callback function that you specify using tcp_recv(). This is true both in the client and the server. More generally, the client/server distinction largely disappears once the connection is made.

  • Our products are called Remote Terminal Units (RTUs). They are primarily used in the electric power industry to collect data and control relays, etc., in electrical substations. To be honest I never even considered whether or not it was a client or server until I started working with the msp432. Until now, I have been using a module that handles all the Ethernet functionality so it is something I really didn't need to know.

    When I started working with the msp432 I was asked if it needed to be a server or client and I found this link that said that RTUs are clients:

    electrical-engineering-portal.com/hardware-software-scada-systems

    I chose the ethernet_weather example to work with because I was told it was a client and I figured it would be the best choice to start with. But now I'm thinking that maybe client/server means something completely different in the RTU world and in the Ethernet world.

    Up until now my approach has been to start with the ethernet_weather example (because it is a client) and try to re-purpose it to work in my application. But, if the msp432 should actually be a server (in TCP terms) maybe I should be working with the ethernet_with_lwip example instead.

    Thank you in advance for your response.

  • I'm not a MODBUS wizard, but 5 minutes with Google turned up:

    https://www.prosoft-technology.com/kb/assets/intro_modbustcp.pdf

    which looks to be a fairly good overview of MODBUS TCP (with minimal marketing). It repeatedly refers to "master/client" and "slave/server", so I suspect that's the way it's supposed to work.

    I also searched briefly for "modbus tcp lwip" and found some hits (notably github) that might have some useful code to um "borrow". Up at the TCP server level, lwIP will be about the same whatever platform (MCU) you're using.

    A single (MCU) system can have multiple servers and/or clients, so there's no reason you can't graft a new server into whatever base you choose.

  • Since it appears that the sending side is acting as a client, I went back to the ethernet_with_lwip example to do my testing because my understanding is that it is configured to be a server.

    Looking at the Receive Descriptors I was able to see the TCP packets come in when I sent the 10 bytes (05 64 05 C9 01 00 01 00 90 25). It took a few tries, but I was able to look at the packets before they were overwritten and they were all SYN packets with no user data (02800000).

    You mentioned above that I need to specify a callback function using tcp_recv() in order to get the 10 bytes that are being sent. Can you give me more detail about how to do that? It's not clear to me. I'm still trying to figure out how to get the 10 bytes that are being sent to the msp432 through Ethernet.

    Thank you.

  • The significant server in that example is httpd, so try port 80. The connection should succeed, though the server will ignore the data.

  • Changing the destination port # to 80 has finally given me Ethernet Frames that have my 10 bytes (yay!). In fact, it looks like they were received a bunch of times. Here are the TCP header and data packets I received:

    EB985000 0000BAD1 18507728 AE20F0FA 64050000 0001C905 25900001 07A57A1F
    EB985000 0000BAD1 18507728 AE20F0FA 64050000 0001C905 25900001 96FD664D
    EB985000 0000BAD1 10507728 12BEF0FA 00000000 00000000 4FC328EE 5F047473
    D1B90050 000098EB 02800000 C6A5FAF0 04020000 0301B405 01010803 C2580204 0402
    EB985000 0000BAD1 19507728 AD20F0FA 64050000 0001C905 25900001 345D01BD
    EB985000 0000BAD1 19507728 AD20F0FA 64050000 0001C905 25900001 D9422258
    EB985000 0000C4D1 11507728 07BEF0FA 00000000 00000000 19F0208A 43414341
    EB985000 0000BAD1 18507728 AE20F0FA 64050000 0001C905 25900001 89CAF577

    One question: Is it normal to be receiving the same bytes a bunch of times?

    Now I will need to figure out how to extract the incoming bytes and then how to send a response back to the master.

    Thank you so much for your help with this.

  • I was also scratching my head a little over the multiple SYNs the other day, but I figured it was something about the dynamics of your experiment (breakpoints triggering timeouts) or something. I'm glad you got it working.

    [If you can mark this thread as Resolved we will have done our part to prevent spam in the Forum.]