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

Philipp Burch phip at hb9etc.ch
Mon Oct 29 20:55:03 CET 2012

Hi Ole,

thanks for your response.

On 10/29/2012 02:52 PM, Ole Reinhardt wrote:
> Hi Philipp,
>> Could anyone point out the "usual way" to add support for existing
>> devices to new platforms?
> First of all, to make collaboration and later integration of your work
> to the mainline Nut/OS easier, I'd suggest that we should create a SVN
> branch for your work. It would appreciate if you could use this SVN tree
> for your development, so everyone who is interested can have an (easy)
> look and can compare files with svn diff.
> I did not yet found a good workflow to use your git repo / patches / and
> the SVN trunk together to follow your development.

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...

> So my suggestion:
> Do you have a sourceforge account? If yes, please send me a mail with
> your account name. I could than add you as developer to the project and
> grant you write access. I also could create a branch and add your latest
> changeset there.

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.

> Next:
> Yes, there is a porting guide:
> http://www.ethernut.de/en/firmware/porting.html
> But I think this one is still far from complete. So feel free to note
> down everything you learned while porting, perhaps we can then complete
> this guide.

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.

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.

> In general:
> First try to understand how the configurator works and setup you own set
> of .conf flags. Create a new subtree in nur/conf/arch/cm3 for your own
> platform.

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.

> Concerning the device drivers:
> Try to compare the different implementations, e.g. AT91, LPC, STM32. If
> you start with AT91 and LPC, you might get a nice overview, STM32 just
> implements drivers for so much different sub-types, that you might
> easily lose the overview.

Ok, good point, thanks.

>> Example: There is a file uart.h and a usart.h. What is the
>> difference? I'd expect them to be almost identical, with the only
>> exception that a USART also supports synchronous interfaces. But the
>> two headers do not seem to be similar in any way.
> AFAIK uart.h is more or less deprecated, all modern drivers use usart.h

So that's the way to go. Good to know that my choice was the right one.

>> According to what I've seen in the source tree, I'd probably add UART
>> support for the LM3S this way:
>> - Add some UART device to the LM3S family configuration.
> Exactly
>> - Create a header lm3s_uart.h which exports the available UARTs as
>> DEV_UART0, DEV_UART1 and so on.
> Right. Depending on the way you want to implement the driver, you might
> want to create the UART driver according to the LPC implementation,
> where your driver consists of two parts:
> a) generic functions in a lm3s_usart.c
> b) one file for each instance, including the first one. Each providing
>     one device for this instance (e.g. lm3s_usart0.c, lm3s_usart1.c, ...)

Yup, did that according to the style in the other ports.

>> - Create a source file lm3s_uart.c which populates and exports a
>> NUTDEVICE structure per device and implements the necessary callbacks.
> Yes, but ideally split up these implementations as explained above. This
> way only the code which is realy needed by an application is linked.
> Dead code (for driver instances that are not used anyway) will be
> omitted by the linker.

Oh, I forgot that we're talking about a library. This is one thing I 
wondered before. What if an application doesn't even use a single UART? 
But the linker is free to omit all of the related code and data of course.

>> Is this correct, or are there other levels of abstraction which should
>> be taken into account?
> For some other drivers we just have a common API as well:
> - Debug UART (UART in polling mode)
> - GPIO api
> - SPI bus api
> - TWI bus api
> - RTC api
> - Not really a generic api, but a more or less common way to implement
>    ADC
> - Some kind of CAN-Bus api
> - Ethernet PHYs
> - Network interface

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?

> If you have specific questions for some drivers, please let me know.

I have :)

Still working on the UART driver, I got some linker issues as mentioned 
in the mail before. When linking this example: 
I get the following output:

-------- 8< --------- 8< -----------
arm-none-eabi-gcc -c 
-DNUT_THREAD_STACK_MULT=3 -DDK_LM3S9B96  -MD -MP -mcpu=cortex-m3 -mthumb 
-mlittle-endian -D__CORTEX__ -ffunction-sections -fdata-sections 
-fomit-frame-pointer -mfix-cortex-m3-ldrd -O0 -gdwarf-2 -Wall 
-Wstrict-prototypes -fverbose-asm -Wa,-ahlms=printing_to_strings.lst 
-DNUT_THREAD_STACK_MULT=3 -DDK_LM3S9B96 -Wall -Wstrict-prototypes 
-Wa,-a=printing_to_strings.lst  -DNUT_THREAD_STACK_MULT=3 -DDK_LM3S9B96 
-o printing_to_strings.o printing_to_strings.c

arm-none-eabi-gcc printing_to_strings.o -mcpu=cortex-m3 -mthumb 
-mlittle-endian -D__CORTEX__ -nostartfiles 
-lnutos -lnutarch -lnutdev -lnutarch -lnutcrt   -Wl,--end-group -o 

In function `_open':
multiple definition of `_open'
first defined here
In function `_write':
multiple definition of `_write'
first defined here
section .ARM.exidx [00000000000064f0 -> 0000000000006617] overlaps 
section .data [00000000000064f0 -> 0000000000006e3f]
In function `get_eit_entry':
undefined reference to `__exidx_start'
undefined reference to `__exidx_end'
collect2: ld returned 1 exit status
make: *** [printing_to_strings.elf] Error 1
-------- 8< --------- 8< -----------

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 ;)

Thanks and best regards,

More information about the En-Nut-Discussion mailing list