I want to add the FNET stack to a PE project. So far I imported the stack, set-up the needed ISRs (for timer and ethernet), increase the stack size and wrote a simple application.
Unfortunately the firmware doesn't work. It fails during the ethernet IO initialization within the FNET stack causing a HW failure interrupt, so my question is: What is the proper way to import the stack? Perhaps someone can also explain why the ethernet IO initialization fails and how it is possible to fix it. In my mind this is caused through the previous low level init of the PE code. It might lock the configuration against changes.
I attached my project for FRDM K64F to this post.
Original Attachment has been moved to: Test_PEnFNET.zip
Okay, I got why it fails through setting the PCR17. The clock for the ports isn't active; therefore the registers cannot be read or write.
I added the following line before the fapp_init() call and overcome this issue :smileyhappy::
SIM_SCGC5 |= (SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTB_MASK);
But still this project hangs. :smileysad:
I'm not sure what to do next, but it could be a hardware configuration problem like you've said. The fact that it's tight looping on a volatile means that elsewhere that status is supposed to be getting set, but it isn't. Have you gone through all of the FNET enet init code to make sure all of the pins are configured properly? Is there a doc somewhere that outlines what FNET API calls need to be made, and in which order before trying to send data?
I was thinking the same, so I took over the start-up code from the FNET demo, but still it hangs. Perhaps I've missed something. I also checked the Interrupt getting called. That works fine. I will look over the code again.
1. Check that the buffer descriptor status values are all initialised to 0 when they are constructed during initialisation. This means that they are not owned by the Ethernet controller and can be used for new Tx frames.
2. Check how many such buffer descriptors are availabe - at least 2 should be used but often more are present.
3. The first usage of a tx buffer descriptor should work since they are all free (initialisation 1) but are the frames being sent out? If they are not they will fill up and then block further usage.
4. Check that the code includes erratas - the Tx can fail to start if the erratas are not respected. This is usually seen as delayed transmissions rather than blocking but could fail if only one buffer descriptor is used.
5. If the TX blocks with the ready bit set check the content of all of the buffer descriptors since they must all have blocked. In particular, check the length field set in the Tx buffer descriptors because if a length of 0 is set anywhere (which would be an error elsewhere) the Tx will never clear the buffer descriptor and they will effectively stall.
6. It may be best to have a short timeout in the wait loop, with an error return, since it is best to drop a transmission rather than lock up the board. This wait would normally be very short, even in heavily loaded networks.
Kinetis: µTasker Kinetis support
For the complete "out-of-the-box" Kinetis experience and faster time to market
Thanks for your hints. I checked them and all were fine. Yes, the loops seem not to be the best way of implementation. I would also expect some sort of time-out with a return of an error.
I got the project run now. I removed the __init_hardware(); from PE in the start-up code and now it works as intended. :smileyhappy:
So, my next steps are to clean up the project and figure out what configuration causes the FNET stack to fail.
dave408, thank you as well. If I've more information then I'll post it.
You bet -- just wish I could have been more help. It was a good debugging exercise. Glad you got it working! It will be interesting to hear which part of the configuration barfed.
I got it run without modifications of PE code. It's all about the clock configuration. I took the PE configuration from my LDD_Eth test project. PE advised me in choosing the setting. The LDD_Eth test project didn't work, but at least the clock configuration was fine. The FNET demo has also a clock configuration within the start-up code, but it seems not to overwrite all settings which are need and anyway it's cleaner to configure the clock settings just once (using PE).
Now I will add MQX again and see if I'm having more battles to fight.
The only thing I see so far that might be wrong is that since you're using PEx to initialize peripherals, you need to map the ENET pins via your Pins1 component:
That said, after adding that, I still ended up in the hard fault handler. I have been trying to diagnose it with Erich Styger's assembly code approach, but now I get this:
I'm going to reimport your project and try again.
FYI to others, even though PEx is involved in this project, you do *not* need to configure the ENET pins in the Pins component. As I debugged the hardfault on my end some more, I found that the hard fault is triggered when PCR17 is set, and then it was clear that FNET handles the enet pin configuration for you. :smileyhappy:
I've shifted the fnet initialization to the very beginning, right at the top of main(); but still I get the hard fault handler called. So, it might be even the start-up which needs to be changed.
It also seems that the ethernet task doesn't actually run in some cases. I tried to disable Task1 by removing it from the task and stack arrays, but then I get a hard fault. Perhaps I should try using the PEx disable feature and regenerate code instead. But when I have both tasks running and put a breakpoint in Eth_task, it never gets hit. However, I know MQX is running because my green LED is blinking. Even though it's in a tight loop, I would expect the other task to be able to start.
Have you tried starting only Task1, and then have Task1 start Eth_task?
ChrisTango I "fixed" the problem. The call to _time_delay_ticks(100); in Task1_task is causing the hard fault. I just don't know why. I replaced it with a tight loop just to see what would happen and now my LED blinks fine. I have to re-enable Eth_task next and see what happens.
I think you are right. I disabled your Eth_task completely by removing it from the MQX task array, and also put LED blink code in your Task1. But when I run it, it blinks the LED once and then goes into PE_DEBUGHALT().