-
-
Notifications
You must be signed in to change notification settings - Fork 8.2k
stm32: Add support for ETH RMII peripheral (version 2) #4541
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Some users of this module may require the LwIP stack to run at an elevated priority, to protect against concurrency issues with processing done by the underlying network interface. Since LwIP doesn't provide such protection it must be done here (the other option is to run LwIP in a separate thread, and use thread protection mechanisms, but that is a more heavyweight solution).
Works fine on my NUCLEO_F767ZI. Great !! |
I think the last byte of MAC address calcurated in mp_hal_get_mac() might be the same value between many STM boards, which means we might not able to connect multiple STM boards of the same netowrk IF to single LAN. |
Thx for the major progress dpgeorge! Added F429 support - see below Testing now. Pretty solid performance. Getting ~55-73Mbps HTTP/TCP data throughput on large transfers (also seeing ~80Mbps on a F767). Running simultaneous stress tests revealed holes in my exception handling with (fast) non-blocking sockets (see code example below). HTTP request responses that are ~2MB and larger are losing data. Not sure why yet. Testing with 1.792MB max for now. FROM LINUX BOX FLOOD PING... FROM OpenWRT/TPLINK STD PING... FROM WINDOWS PYTHON RESTTEST... NON-OPTIMIZED TEST CODE SNIPPIT USED TO ACHIEVE 73Mbps NON-BLOCKING SOCKET WRITES:
CODE DIFF FOR ADDING F429 SUPPORT TO #4541:
|
Thanks @t35tB0t for testing, and confirming that the F429 board works. I've now added a commit here to enable the ETH on that Nucleo board. Not sure why you see errors with 2MB transfer. I'll try to reproduce it. Does the function |
Yes, that's what I'm planning. It's pretty much good to go in now.
I did see that code you wrote in the other PR @boochow . But MAC addresses are something which really need to be assigned properly, not at random. I made the But, for testing and internal use, it might be a good idea to have the function provide a random locally administered MAC address. Then it would make sense to use a hash function for the lower bits of the MAC. |
Still testing #4541 on STM32F429ZI Nucleo board. Once any embarrassing
bugs are worked out of the test code, I'll post details to recreate any
remaining issues. Right now, the testing is focused on STM32 ethernet
in a server role. Wireshark showed some TCP window zero probing with
very large transfers. And data was being lost in the STM32 RMII
buffering- somewhere. So, reduced to <2MB where things stabilized. The
bigdata() function stuffs data into the STM32 server's response to an
HTTP request. I added a known byte pattern with some tags at the end to
the bigdata() paylaod and wrote a Python client to hammer requests,
verify the 1792KB payload pattern and post the tags. I'm getting very
fast data payload transfer speeds ~70Mbps from server to local
windows/Python client via single switch. But local Linux clients doing
simple wgets are having issues. And NMAP can crash the code. Simply
switching from non-blocking to blocking fixes the Linux clients but they
only get 8Mbps while the Python/Windows tester app gets 61Mbps with same
server code. Managing the micropython socket reads, writes, and
exceptions/errors is where I need to go first before I claim "bug" in
the micropython core. Originally, I was happy to get >2MB/sec but what
you've done with the ethernet drivers is simply awesome! Now that we've
tasted >50Mbps transfer rates, we don't want to settle for less. Side
note: After running a brutal stress test for 9 hours, the 429 was
barely warm to the touch.
|
@boochow I pushed a change here to implement this, to generate a unique local MAC address based on the MCU unique id. I just used a very simple algorithm for the "hash", based on the DFU USB algorithm used in usbd_desc.c. What do you think? |
Great ! I'm so happy to hear this. It will open much wider micropython application world including industrial use or office use!
First of all, I agree that the MAC address should be administered. I think your original mp_hal_get_mac() code should be used only for pyboards because it uses your vendor code 0x48 0x4a 0x30. The new code for LAA seems good but I suppose that it is better to use id[11] somewhere and the usage of id[7] should be 'id[7] << 2' rather than 'id[7] & 0xfc'. Some description about STM's unique device id format can be found in I guess that id[0..3] shows a lot number, id[4..7] is a silicon wafer number, id[8..9] and id[10..11] are a coordinates on the wafer. id[4..7] shows a wafer number, whereas id[4] is some small value, id[5] may be a upper case alphabet, id[6] and id[7] falls between '0' and '9'. This part is the second important part but I guess that the same value might be shared between tens of devices. id[0] is also a number ('0'-'9') and id[2] is an upper case alphabet ('A'-'Z'). I suspect that id[1] and id[3] are not used because they are always zero for all of my STM32 boards. So, your code uses most of the bytes which have meaningful value but I think id[11] should be included. Also, It is better to avoid dropping bit 0 and 1 of id[7] because they are the most meaningful part of id[7]. |
Thanks @boochow, that's helpful. In my experience id[0] and id[2] actually contain the most information (about 7 bits each) and, yes, id[1] and id[3] are always zero. I have changed the MAC function to use as much info from the unique ID as possible. This PR was merged in 75a3544 through 823b31e @t35tB0t if you find some reproducible bugs/issues with the driver please open a new issue for it. |
How can I make this works on NUCLEO_F746ZG ? |
It now handles deinit, never_reset and sharing tracking. PWM now runs in the WAIT state as well during a time.sleep(). _reset_ok() was removed because it was called in one spot right before deinit(). Some PWMOut were also switched to a bitmap for use instead of reference count. That way init and deinit are idempotent. Fixes micropython#6589. Fixes micropython#4841. Fixes micropython#4541.
This is an improved version of #3808, to add full Ethernet support to the stm32 port. It is actually a complete rewrite from scratch of the Ethernet driver.
Features of this version are:
lan.config(trace=7)
Tested on a NUCLEO_F767ZI and STM32F769DISC board. The following code will get it connected:
DHCP is automatically enabled. IP can be statically assigned via
lan.ifconfig(...)
. The API is the same as WLAN and LAN on other ports.The following network performance was obtained with the STM32F769DISC board on a 100Mbit full-duplex LAN:
I think the UDP receive rate can be improved by some minor improvements to
extmod/modlwip.c
, since the TCP receive is much higher (and close to the theoretical maximum).