[En-Nut-Discussion] Ethernut on TI's Cortex-M3 (Stellaris LM3S...)

Ole Reinhardt ole.reinhardt at embedded-it.de
Tue Oct 30 14:30:22 CET 2012


Hi Philipp,

> This is one of the reasons, why I'd prefer using a distributed SCM in 
> the first place. But Ethernut is on Subversion now, so I don't suppose 
> this to change in the near future...

Yes, me too, but we still use SVN for Nut/OS. And yes, in the _near_
future a change to git etc is unlikely.

> I have, my username is "phlibi". I'd however prefer not to merge in the 
> whole changeset at once as this would generate a huge diff in a single 
> commit. Better split it up into some pieces.

Great! I added you to the project. You should have write permissions.
Further I crated a branch for your project

Here is your SVN URL:

https://phlibi@ethernut.svn.sourceforge.net/svnroot/ethernut/branches/devnut_lm3s


Please merge from trunk regularly, ideally on a daily base to keep in
sync, so we can later re-integrate the branch into the trunk.

Merging from trunk:

Assumes you are in "branches/devnut_lm3s"

svn merge ../../trunk



Could you perhaps start applying patch by patch to the new branch and
drop me a line as soon as everything is checked in? I can than start
testing it on my own board.



> In fact, this guide is the main reason why I'm here. I've heard about 
> Ethernut by coincidence and then found this porting guide. Skimming 
> through it, I thought that porting it would be easy enough and just gave 
> it a try. Well, it became obvious rather quickly that it just looked 
> easy because the guide skips over a lot of problematic parts.

Ah ok :) Yes, sorry, for not having everything documented yet... Same
problem as with most OpenSource projects :) But any help is very
appreciated!

> I've already planned to write down some of the things I found out on my 
> "journey" for those who come after me. But at the moment, I need to get 
> it working for my board, as the software is a critical part of this project.

If you need any help, please drop me a line!



> Ok, I suppose I've got an idea about how the configurator works by now. 
> It took a while to see the behaviour of "provides" and "requires", of 
> "macro" and "file" and so on. There still are a lot of open questions 
> however, but these are not critical right now.

Ok.

> One of my next tasks is the implementation of the ethernet interface, as 
> this is the main reason for using Ethernut. Obviously. Some of the 
> Stellaris parts have an integrated MAC and PHY, so how does this fit 
> into the common API? I haven't dug into the ethernut drivers yet, but I 
> would expect the interface to contain a function for initialization, 
> some interrupt handlers for network events (energy detected, link lost, 
> etc.), a main data transmission interface and something for maintenance 
> tasks (Auto negotiation, MDI-X, etc.). Is there a good example to follow 
> or maybe some documentation?

The Ethernet interface itself is a tricky part in most cases, as there
are lots of settings for the MAC etc. to be implemented.

If you have a look for example to the lpc17xx_emac.c you should get a
good overview. In fact the structure of most ethernet drivers is more or
less the same.

Step 1:

Create a stub for the interrupt handler (you can just create the
interrupt handlers for all the other peripherals in the same step as
well).

You can just take ih_lpc17xx_emac.c as a template. All these ih_***
files follow the same structure, one for each physical interrupt (that
shall be used)

Also create a irqreg header like
include/arch/cm3/nxp/lpc177x_8x_irqreg.h and add your signal variable
there.

Now use the lpc17xx_emac as a template. There you have the following
main functions:


phy_inw(), phy_outw(): Comminucation functions to use the MDI interface
to access the phy. These functions are later assigned to the generic PHY
driver.


Lpc17xxEmacInit():

This should be your initialisation function and should prepare the emac
peripheral, setup power, clocks etc. 

This function should also reset the EMAC and register the interrupt
handler.

Btw: Most PHYs need to be "bootstrapped", which means that their initial
settings are determined when comming out of reset by reading some
bootstrap pins. So it is a good idea to reset the PHY in your board file
and apply the right boostrap values just there. You should better not
reset and apply the bootstrap values in the emac init, as e.g. the PHY
reset GPIO may change from board to board.

This function will also start the receiver thread.



Lpc17xxEmacReset():

Soft reset of the emac and setup of the MAC address etc.

This function should also check for a link and configure the emac
according to the current link speed.

In opposit to most other implementations my driver does not block in
Lpc17xxEmacReset but start a thread which waits until a link is
established and then configures the emac speed registers accordingly.




Lpc17xxEmacRxThread():

The thread which will be started during init. It is used to constantly
read the incomming packets and forward it to the upper network stack
layers. It will call Lpc17xxEmacStart() right at the beginning and then
will wait (with NutEventWait()) for incomming packets.



Lpc17xxEmacStart()

This function sets up the network DMA descriptors and start the RX / TX
datapath of the emac peripheral.


Lpc17xxEmacInterrupt()

General interrupt handler. Beside of other things, it will signal the
input and output event queues as soon as a packet was received or
transmitted.


Lpc17xxEmacGetPacket() 

is called from the reciever thread to read a packet from the DMA buffers
and place it in a NetBuf (the struct which holds the network packets)
and pass it to the upper layers.


Lpc17xxEmacOutput()

Called from the upper network layers to send out an ethernet packet. The
packet will be passed as NutBuf, it will then call
Lpc17xxEmacPutPacket() which places the packet in the output buffers
This function blocks on the transmit event queue as long as there is no
further space in the output buffers.

Lpc17xxEmacPutPacket()

Setup DMA buffers and start transmission.


In most cases you should be able to follow the same driver layout.

Even if you have a network peripheral with integrated PHY, it should be
possible to use the generic PHY driver. In this just just add the PHY
IDs to the PHY driver.



> Still working on the UART driver, I got some linker issues as mentioned 
> in the mail before. When linking this example: 
> http://ethernut.de/nutwiki/Printing_to_Strings
> I get the following output:
>
> The "multiple definition" errors probably arise because the linker sees 
> nutcrt.a and the compiler's own libc. However, passing -nodefaultlibs 
> and -lgcc does not solve anything, still the same errors.
> 
> And what really looks strange are the "overlapping sections". I'm 
> diggin' into some articles concerning this at the moment, maybe I'll 
> figure it out. But if you could give me a hint, this would be greatly 
> appreciated ;)

Oh yes, I had the same problem just several times. In most cases you
have a call to any newlib function included that itself depends on some
other functions that will use the newlib supplied "syscalls".

For example I stumbled about this problem when trying to use 64bit
divisions.

I don't have a real idea right now without looking into the code.

If you could first apply your patches to the newly created branch I will
have a look on it later this day. 

Bye,

Ole


-- 

Thermotemp GmbH, Embedded-IT

Embedded Hard-/ Software and Open Source Development, 
Integration and Consulting

http://www.embedded-it.de

Geschäftsstelle Siegen - Steinstraße 67 - D-57072 Siegen - 
tel +49 (0)271 5513597, +49 (0)271-73681 - fax +49 (0)271 736 97

Hauptsitz - Hademarscher Weg 7 - 13503 Berlin
Tel +49 (0)30 4315205 - Fax +49 (0)30 43665002
Geschäftsführer: Jörg Friedrichs, Ole Reinhardt
Handelsregister Berlin Charlottenburg HRB 45978 UstID DE 156329280 



More information about the En-Nut-Discussion mailing list