Showing results for 
Search instead for 
Did you mean: 

example using HAL ETH without LWiP for raw ethernet frames?

Elwood Downey
Associate II
Posted on June 09, 2017 at 20:41

[reposting after 30 days of no responses]

Hello all,

I have been making great progress using CubeMX and HAL for lots of things, now I want to try ethernet. My application is very simple, I only want to send and receive raw ethernet frames -- no UDP or TCP at all. I also prefer not to use LWiP for something so basic. Can anyone point me to an example of raw ethernet frame IO using just HAL? I will be using Nucleo F429ZI.

My requirements:

[ ] send a raw frame (source and destination MAC address, type IP and payload, total less than 1500 bytes)

[ ] receive interrupt upon receipt of a raw ethernet frame

My transactions are slow and simple, I do not even need any buffer queuing.

Thanks for any tips.

Posted on June 10, 2017 at 15:56

You'll likely need to separate the frame and initialization code from the layer above you don't want

        (##) HAL_ETH_TransmitFrame();

        (##) HAL_ETH_GetReceivedFrame(); (should be called into an infinite loop)

        (##) HAL_ETH_GetReceivedFrame_IT(); (called in IT mode only)

Tear what you need out of ethernetif.c

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on June 22, 2017 at 21:55

Thanks Clive. Making a temporary lwip project thengutting ethernetif.c was extremely helpful. I have it all working now, getting close to wire speeds both ways.

In case others see this thread in the future, here are a few observations:

* Phy address must be 0 for the

Nucleo F429ZI.

CubeMX 4.0 still sets it to 1 by default even though this was reported over a year ago in t


* Never could get HAL_ETH_TxCpltCallback to fire. Fortunately the tx descriptor states allow

reliable in-line retries.


The default MAC filters are such that

RxCplt will only fire on receipt of broadcast MAC FF:FF:FF:FF:FF:FF or the one passed to


* Speaking of MAC, the array to which

heth.Init.MACAddr is set in

MX_ETH_Init() really should be static so it can be used later.

Posted on October 09, 2017 at 14:50


I want to apply Ethernet on my stm32f779I-EVAL board, but i am very new to Ethernet.

I also don't want to use the lwIP driver, because i only want to send some json strings.

Do you have by any change an example program ready?

Posted on October 09, 2017 at 20:07

Are you really really sure you want to use raw frames? Sending variable length strings sounds more like a TCP stream would be more appropriate. Even UDP would require you to reinvent fragmentation, assembly, acknowledgement and  and retransmission. Raw frames are even more basic than UDP because they can not be routed, they are strictly NIC-to-NIC. lwIP works very well and it has a socket-like layer that is pretty easy to use. But anyway, if you really want to see my raw frame code, contact me off-line.


Posted on October 10, 2017 at 10:28


I think i will take a second look at the lwIP libraries.

TCP might, indeed, be a better option for this instance.

Posted on October 13, 2017 at 13:46


By any change, do you have experience with REST API's with the  lwIP library?

The data i want to send are small json strings.

The json strings that i want to send back are kinda static, because the requested data per request is known.

I want to be able to process the types url and give the acording responds.

The repsonds is just a json sting with status data.

If i can read the url, i can split it up and process the requested data, for example set a bit. (

its for remote IO and not for running a complete web server.

The json strings that i want to send back are kinda static, because the requested data per request is known.

I looked at the STMCube application examples and they work with .html.

But i dont want the user to type .html at the end of the server nor weird url that is send with CGI (?id=171504&draftID=30078).

It seems like i am the only one on the internet that is working on a rest api for the stm32, couldn't fins anything.

What would you recommend?

Maybe the raw data frames would be better, because i only need to send/receive simple stuff.


Posted on October 20, 2017 at 13:01


in case that someone needs it:

I got HAL_ETH_TxCpltCallback() to fire by adding the following two lines:





David Dk
Posted on December 06, 2017 at 11:40




any chance that one of you upload a minimal working example?

Best wishes, David

Posted on December 07, 2017 at 10:08

Hi David,

as far as enabling the TX callback is concerned, you can use the provided examples. In low_level_init() add the above mentioned two lines of code. For example, you can add them after initializing descriptors lists:

/* Initialize Tx Descriptors list: Chain Mode */

  HAL_ETH_DMATxDescListInit(&heth, DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB);


  /* Initialize Rx Descriptors list: Chain Mode  */

  HAL_ETH_DMARxDescListInit(&heth, DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB);




I haven't actually used the TX callback for real - I was just curious how to enable it...

Best regards,