Hello,
I am using the Stellaris EKC-LM3S6965 Evaluation Kit Rev D14 in order to create a packet sniffer. I am just compiling using GCC and I am a little confused as to why my program is not working.
I am using the Stellaris Peripheral Driver Library and its library functions to use the Ethernet port and OLED. I based my project off of the "hello" project in the example projects. I also used the example code they gave me from the Stellaris Peripheral Driver Library to just sniff one packet. I basically took that example from the library and stuck it in the main code of the "hello" project along with printing something to the OLED after each call to an Ethernet function from the library. I cannot get anything to appear on the screen, which leads me to believe that the Ethernet function calls are not working. If I take them out, and just run the "hello" project, it runs just fine on the eval board. I'm not sure if its just the fact that I might be missing a library to include or perhaps it is something else? (I have #include "driverlib/ethernet.h" so I am including that library)
This is my first time ever using the board so I am quite new to this. I noticed the vector table in the startup_gcc.c file. Is there something that I need to change there in order to get it to work (have a specific interrupt handler for the Ethernet?) And if so, what should it be or be based on?
By the way, this is how I compile in GCC (pinkle.c is the name of the file which contains the main code):
arm-none-eabi-gcc -Wall -O3 -march=armv7-m -mcpu=cortex-m3 -mthumb -mfix-cortex-m3-ldrd -IC:\StellarisWare -IC:\StellarisWare\boards\ek-lm3s6965 -LC:\StellarisWare\driverlib\gcc -o pinkle.elf pinkle.c startup_gcc.c C:\StellarisWare\driverlib\ethernet.c C:\StellarisWare\boards\ek-lm3s6965\drivers\rit128x96x4.c -ldriver -T pinkle.ld --entry ResetISR -Wl,--gc-sections
Thank you very much.
-Charlie
Charles WhitlockI also used the example code they gave me from the Stellaris Peripheral Driver Library to just sniff one packet.
Which example code (specifically) did you use to write your sniffer?
Charles WhitlockI noticed the vector table in the startup_gcc.c file. Is there something that I need to change there in order to get it to work
Quite possibly. I'd suggest trying diff enet_lwip/startup_gcc.c hello/startup_gcc.c from the 'boards' directory. It could provide an essential clue. Usually, when you let IntDefaultHandler handle an IRQ, it complains. Do you have a JTAG debugger or a serial console connected?
--Miles
Hi Miles,
The example code I used was the following from the Stellaris Peripheral Driver Library User's Guide:
unsigned char pucMACAddress[6];unsigned char pucMyRxPacket[];unsigned char pucMyTxPacket[];unsigned long ulMyTxPacketLength;//// Initialize the Ethernet controller for operation//EthernetInitExpClk(ETH_BASE, SysCtlClockGet());//// Configure the Ethernet controller for normal operation// Enable TX Duplex Mode// Enable TX Padding//EthernetConfigSet(ETH_BASE, (ETH_CFG_TX_DPLXEN | ETH_CFG_TX_PADEN));//// Program the MAC Address (01-23-45-67-89-AB)//pucMACAddress[0] = 0x01;pucMACAddress[1] = 0x23;pucMACAddress[2] = 0x45;pucMACAddress[3] = 0x67;pucMACAddress[4] = 0x89;pucMACAddress[5] = 0xAB;EthernetMACAddrSet(ETH_BASE, pucMACAddress);//// Enable the Ethernet controller//EthernetEnable(ETH_BASE);//// Send a packet.// (assume that the packet has been filled in appropriately elsewhere// in the code).//EthernetPacketPut(ETH_BASE, pucMyTxPacket, ulMyTxPacketLength);//// Wait for a packet to come in.//EthernetPacketGet(ETH_BASE, pucMyRxPacket, sizeof(pucMyRxPacket));
I am using the LM Flash Programmer to program the board via USB connection. I tried using the startup_gcc.c file in the enet_lwip and seems like I need to include many more files. I make sure they are in my include path for the call to GCC and it just seems like I'm always missing something. Is all of this really necessary just to get the above code to run (I'm actually not sending out a packet, just sniffing one).
Thank you for your time.
-Charles Whitlock
(edited to address line-wrap issues)
In the example code you provided above you shouldn't need to worry about interrupts.
Are you generating ethernet traffic for the mac address 01:23:45:67:89:AB? If so, how are you generating that ethernet packet? Also, keep in mind the difference in functionality between an ethernet switch and an ethernet hub. A switch (internally) establishes point-to-point communication between devices, thus: not all ports are privy to all traffic. A hub, in contrast, sends all traffic to all ports. I'd suggest using a program like WireShark in conjunction with an ethernet HUB to validate that your ethernet segment is actually carrying the packet you're trying to capture.
If you're NOT crafting a packet specially for 01:23:45:67:89:AB then keep in mind that the ethernet hardware will only return packets addressed to your MAC. If you want to capture ALL packets (including those NOT addressed to you), you'll need to set ETH_CFG_RX_PRMSEN in the call to ConfigSet().
I am not generating traffic for that mac address. I am using a hub and have set the device into promiscuous mode by doing the following function call:
EthernetConfigSet(ETH_BASE, (ETH_CFG_RX_PRMSEN | ETH_CFG_RX_AMULEN));
However I have found where the problem lies. I am now using Code Composer Studio Version 4 in order to debug the program while it is running. I call the following functions below in my main():
SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_8MHZ);
RIT128x96x4Init(1000000);
EthernetInitExpClk(ETH_BASE, SysCtlClockGet());
Once I get into the EthernetInitExpClk() function, after that function is called, it then goes to the startup_ccs.c file to the FaultISR function.
I stepped through the code in the EthernetInitExpClk() function and noticed that it was skipping the following equation:
ulDiv = (ulEthClk / 2) / 2500000;
I attempted to add volatile to the definition of ulDiv so now it reads
volatile unsigned long ulDiv;
at the beginning of the function. I was then able to see the value of ulDiv after the equation, which is 1.6 on my device, but becomes truncated to 1 since it is of type long.
(8000000 / 2) / 2500000) = 1.6
It then executes the following:
HWREG(ulBase + MAC_O_MDV) = (ulDiv & MAC_MDV_DIV_M);
and after the closing curly brace of the function, the program then goes to the FaultISR.
On my system, the address it is setting is 4004.8024 and is setting it to 1 (MAC_MDV_DIV_M is defined as 1 elsewhere).
From the datasheet for the LM3S6965 (page 558), it says the following:
"The DIV bits are used to set the clock divider for the MDC clock used
to transmit data between the MAC and PHY layers over the serial MII
interface."
Is this setting it to 1MHz? I am not quite sure what the value is supposed to be, and if it is correct, why is it triggering a fault interrupt?
(edited to correct line wrap issues)
Charles Whitlock I also used the example code they gave me...
Who is "they" ?
Have you asked "them" about this?
This is my first time ever using the board so I am quite new to this.
When you say "this" is that just this specific board? or Stellaris in general? or embedded microcontrollers in general? or programming in general? or what?
Might it be a little ambitious for a first project?
As I stated above, they is referring to the Stellaris Peripheral Library.
This referring to anything to do with the Stellaris board (programming on it directly) and using the Stellaris Peripheral Library.
Have I clarified enough for you?
Charles Whitlock I stepped through the code in the EthernetInitExpClk() function and noticed that it was skipping the following equation: ulDiv = (ulEthClk / 2) / 2500000;
Can you be more specific about "skipping"? Did you single step through the function and see the debugger "leap" over that line of code? Or did you attempt to look at the variable ulDiv and not see the value you expected? Be careful with what you think you observe. The compiler knows that it doesn't have to write that variable back to the stack (it stays in a register). Sometimes the debugger isn't smart enough to figure out where the most recent value of a variable lives and will show a wrong value. I would highly recommend you look at your C and assembly side by side to make sure it is coherent. You'll likely find your value of ulDiv in one of the CPU registers. By declaring it volatile you force the compiler to to store and fetch the value to RAM -- which has the side-effect of helping the debugger.
Charles Whitlock and after the closing curly brace of the function, the program then goes to the FaultISR.
Did you decode the fault registers to determine what kind of fault you encountered? My guess is that you experienced a bus fault. You can't write to a peripheral register if the peripheral isn't enabled.
Do you ever make a call to SysCtlPeripheralEnable(SYSCTL_PERIPH_ETH) ?