[En-Nut-Discussion] Nut/OS GPIO API Initial Design and Current Status
bon at elektron.ikp.physik.tu-darmstadt.de
Sat Oct 13 00:08:38 CEST 2012
>>>>> "Harald" == Harald Kipp <harald.kipp at egnite.de> writes:
Harald> I know, I'm blamable for some confusion. Unfortunately, a
Harald> statement I made in another thread about GPIO banks and PIO IDs
Harald> was wrong.
Harald> In fact, banks are not assigned to IDs, they are simply numbered
Harald> upwards. Sorry for the confusion. Hopefully I'll get it right
Harald> now. :-)
I started from a different background. I casually contributed to
ethernut since some years and ethernut helped me to renovate our
accelerator control system. But using the AVR with it's 5 Volt design and
low RAM hit many limits. So Cortex Chips seemed promissing and Ulrichs
STM32 cm3-devel trunk on sourceforge too. But as developpment stalled and even more
powerfull STM32 appeared, I got deeper involved.
And here the different views arose: For the CM3 trees, "bank" was always a
"handle" in the Win32 API view or "magic number" as it is the port base
address in the arm memory range. I never knew other until recent.
Harald> GpioPinSetLow() and friends had been intentionally implemented
Harald> as simple functions, which can be easily ported to any
Harald> platform. The initial idea was: As soon as this is done for any
Harald> new target, many (bit-banging and polling) drivers should be
Harald> available without any further effort.
Harald> This means: Implement a few simple functions and you'll get low
Harald> level I2C, SPI, MMC and higher level parts like file systems,
Harald> calender chips, serial flash and much more goodies for
Harald> free. Motto: "Porting Nut/OS in 2 hours."
Well, I have a bitbanging debug driver under my fingers. This will allow to
use the STM32F4 discovery boards nearly self-contained, after reflashing the
original ST-LINK with the "Blackmagic Debug Probe" code. It uses the Gpio
Api and at the moment the CM3 systick for timing. So it will work not only
for STM32 but any CM3 arch.
Harald> GpioPinSetLow() expects 2 arguments, a bank number (port
Harald> identifier) and the bit number. The bank number has been 1 for
Harald> PORTA, 2 for PORTB and so on for Atmel targets. As a special
Harald> exception, early Atmel targets do only provide as single PORT
Harald> (without a letter), which has been assigned to bank 0. Still
Harald> simple, isn't it?
Harald> After the first version had been created, it looked as a good
Harald> idea to use this API in other places. For example, Ethernet
Harald> drivers for memory mapped Ethernet controller chips do not
Harald> really depend on the target they are running on, except a few
Harald> GPIO functions, which are used to control the controller's reset
Harald> line or to monitor the controller's IRQ line. As a portable
Harald> interrupt API existed already, it was simple to replace any
Harald> outr() with GpioPinXXX() to get a portable driver. Other
Harald> examples are the MMA745X velocity driver or the VS10XX audio
Harald> codec drivers.
Harald> So far so good. Are you still with me? :-)
Harald> Having an embedded system without samples that demonstrate GPIO
Harald> is somehow incomplete. Such samples existed, but were
Harald> contaminated with #ifdefs to handle all those different
Harald> platforms. It looked attractive to use the new GPIO API to
Harald> create portable applications. And, in my view, this is where all
Harald> the trouble starts.
Harald> Suddenly users demand to implement all these special functions,
Harald> that their target chip provides. Enabling pull-ups or switching
Harald> from push/pull to open drain are the most harmless variants
Harald> (which btw. would have been required by an I2C driver
Harald> anyway). Other, less harmless extensions were debouncing,
Harald> repeater mode and other exotic stuff. Instead of one simple
Harald> dev/gpio.h and its related implementations arch/arm/at91_gpio.c,
Harald> arch/avr/gpio.c etc. we now have several headers, and a growing
Harald> number of features. This makes it harder and harder for newbies
Harald> to implement GPIO on a new platform. The initial idea was
I don't agree with your view. Each architecture needs a setup for it's GPIO,
and this setup is getting more complicated as chips get more
compilcated. This results in more available feature, but many features are
only features, nice things to have, but not nescessary for general examples.
This is where my plea from July for a definition of a common subset for
features, defined in include/dev/gpio.h came from. Other architecture
specific features can then be defined in the dev/gpio_<arch>.h files. But
other architecture must know what to do if they find such a feature
request. Is it really a request or a requirement? Should they fail in
GpioPinConfigSet or should they ignore the request? That we need to agree
Harald> What happed to the intended bit-banging GPIO API based drivers?
Harald> Almost nothing! Well, there is one SPI bus driver and a
Harald> MultiMediaCard driver, but no one is using it. They are quite
Harald> bulky and slow, not very attractive for board supporters. Just
Harald> for the completeness: Recently a 1-wire bus driver had been
Harald> Scanning the current trunk shows, that GpioPinConfigSet()
Harald> appears in 63 files! Who is using this then?
Harald> Now the fun really begins: The GPIO API is mainly used by target
Harald> specific drivers. Why, the hell, do target specific drivers
Harald> prefer the bulky and slow GPIO API, instead of using native port
Harald> access? My assumption is, that this was motivated by the
Harald> configuration feature. The Nut/OS Configurator offers to define
Harald> banks in a user friendly way, depending on the current target as
Harald> PORTA on Atmel chips or PORT0 on NXP chips. So using GpioPinXX()
Harald> allows to (ab-)use this feature.
Or you view it another way: GPIO API offers such a flexible way that
using it was the most straightforward thing.
Harald> Of course, developer's recognized, that GpioPinXX() was bulky
Harald> and slow. To overcome this limitation, target specific inline
Harald> versions had been created to replace the original
Harald> versions. IMHO, that's the final stab.
Harald> GPIO API, REST IN PIECE. ;-)
I hope, I oversee the smiley.
My work on the AVR showed, that even for that arch you could defined the
GpioApi in a way that will result in most cases in the single commands sbi()
and cbi() as would unportable direct coding. And even
the bank argument as a runtime variable can be handled without a big runtime
switch case but by a pointer access if you look at the three consecutive AVR
port/pin/ddr register as a structure.
Harald> Now I'm really coming to an end. Just a few seconds...
Harald> A few target specific drivers use a different approach to avoid
Harald> the GPIO API and still provide configuration capabilities. They
Harald> are based on macros and include/cfg/arch/porttran.h. And they
Harald> are very tricky to implement, difficult to use and result in
Harald> ugly, hard to follow code. Beside that, they use PIO IDs, not
Harald> port banks.
Seems like a lot of code has not been touched for ages. Does it really work
still ? Has anybody tested?
So let me come to an end too:
I hope that GPIO API prospers!
At the moment AVR and STM32 make the most use of it. Other architecture need
some work. Let's start after the 5.x release to get things straight.
Uwe Bonnes bon at elektron.ikp.physik.tu-darmstadt.de
Institut fuer Kernphysik Schlossgartenstrasse 9 64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------
More information about the En-Nut-Discussion