[En-Nut-Discussion] What is the best way to deal with different I/O pin configuration on different boards

Ole Reinhardt ole.reinhardt at embedded-it.de
Tue Oct 16 15:34:28 CEST 2012

Hi Harald,

> Regarding b) I think that your list is incomplete.
> b1) Drivers may refer to on-chip interfaces (e.g. LCDs or image sensors)
> which are rarely implemented. All GPIO specific settings (enabling
> peripherals etc.) may be hard coded.

Yes, but only of these settings are fix. So if you have a peripheral
like an SPI or perhaps also a camera interface that can be connected to
different I/O pins, you will either end up in a large .conf script with
thousands of settings of you leave it up to the user to setup the I/O
pins before registering the device driver.

In most cases you will only have to set the alternate function and
perhaps some specific settings.

On the LPC for example you can configure pullups etc. even in the
alternate function mode. So a lot of configuration options for the

> b2) Drivers may refer to often implemented on-chip interfaces, which
> vary among members of a specific target. Hard coding might be
> acceptable, but some kind of (minimized) configuration would ease
> implementation of new family members.

Right. Even some on-chip peripheral drivers could be shared among
different CPU architectures as long as you completely remove any CPU
dependency from the code. One example it the AT91/AVR32 emac.

Now we have two drivers which had a lot of GPIO setup code included in
their early days.

> c) Drivers may refer to external chips. This is then mostly board
> specific. Right now, these definitions are set in the conf file of the
> board and partly in the board initialization. If a board is supported,
> users don't need to change that.

Right. Again I would vote for removing any such options from the
configurator and move it into the board init or user code.

As soon as we remove any board specific configuration we could easily
use the same Nut/OS tree for several boards.

I really would prefer if device setup could be done by passing a struct
with the device specific settings to the NutRegisterDevice function or
as pointet out before a new NutRegisterPlatformDevice() function. 

> > On the arm architecture pin setup is mostly done by defining a list of
> > I/O pin settings and to initially set them up during boot time in the
> > board init file.
> This is how it was done. Today, board init files will be rejected after
> Linus became upset by the number of redundant changes in the ARM tree
> and threatens to entirely remove ARM support from the kernel.

A short look into the vanilla 3.6.3 tree still shows lots of examples
where this kind of initialisation is still used:

I just took a look into


Others indeed implement it different. At91 for example. Here a special
init function for each device is implemented in the at91xxx_devices.c

This approach looks a littel inflexible to me.

Anyway, I don't know what would be the best way. And things that are not
optimal in Linux may not be bad for Nut/OS.

My basic intention is just to keep the configurator and the drivers free
from board specific settings.

> > Beside of that, some platform drivers provide a so called "plaform data"
> > struct which is initialised and assigned to the device struct right
> > before initialising the driver. This platform data is set at a reference
> > in the DBC struct of the driver and the driver can access this struct
> > later at any time it needs the informations.
> Not sure, if that is the same that I have in mind. AFAIK, a so called
> flattend device tree (FTD) is passed from the boot loader to the kernel,
> which contains all the features that the board provides. Note, the
> board, not the CPU.

I don't think we mean the same thing.

Lets stay for example with the AT91 implementation in Linux and look at


The following code is a simple and nice example showing the MMC driver

static struct at91_mmc_data __initdata ek_mmc_data = {
	.slot_b		= 1,	/* Only one slot so use slot B */
	.wire4		= 1,
	.det_pin	= AT91_PIN_PC9,
	.wp_pin		= -EINVAL,
	.vcc_pin	= -EINVAL,

static void __init ek_add_device_mmc(void)
	at91_add_device_mmc(0, &ek_mmc_data);

This samples includes both: I/O pin and device configuration in one
struct that is passed along with the driver registration.

Unfortunately the exact syntax differs between the different
architectures. But the general idea should become clear.

> > Further I find the concept of the platform data which could hold driver
> > specific default configurations for each board quite appealing.
> > 
> > They could hold for example the default baud rate etc. for a UART or the
> > MAC address for the network interface and the default ID of a I2C
> > device.
> There are probably 99 ways to implement this and 99 possible pitfalls.
> Do you have any more specific details yet, or just the general idea?

Currently it's just a general idea. I did not want to start writing
something new without having discussed the general idea and acceptance.

> > This way we would likely end up in cleaner configurator scripts and more
> > flexible configurations for the end-user. Last but not least it would
> > became easy to have only one .conf file that is usable for several
> > boards.
> The PIO configurations are a mess, overused and abused. But to that time
> we didn't have any board specific initialization. As this is available
> now, it should be used.

I know about the history, but why not thinking about improvements as we
just started these discussions anyway.

> But there are still different requirements and board variations (also
> called jumpers ;-)). And not all boards do have a board initialization
> right now. As an intermediate solution and for the remaining configs,
> which cannot be hard coded, I'd suggest to move all this GPIO
> configuration to one single place, instead of spreading it all over the
> configuration tree. That would also provide a good overview about which
> pins are used for what purpose.

Any suggestions for "such a place"?

Indeed we can not remove everything in one big step, but we should agree
about the future and should start porting drivers step by step.

> But to underline my general general view: Move as much as possible to
> the board init file.




Thermotemp GmbH, Embedded-IT

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


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