RTEMS GPIO API

André Marques andre.lousa.marques at gmail.com
Tue Jun 16 12:14:52 UTC 2015


Hello ,

Thank you for the responses. Sorry for the late response and lengthy mail.

At this point the features mentioned in the blog post are almost done in 
the code (apart from some details). There are some differences from what 
is mentioned in the blog, but the overall idea still stands (an blog 
update is in order, as well as more documentation in the code).

One major change is related with the interaction with the API. It 
currently maintains a data structure which holds the current GPIO status 
(which pins are used, what interrupt handlers they have associated, 
...), so an application can either fill a different structure to 
configure a pin, which is passed to the API through an API call, or 
configure the pin directly through API calls.

The struct approach can be used either to define a new pin to be 
requested, or to update its configuration, all done by updating/changing 
the struct and doing the same function call to the API. Since the 
structs can be defined on a separate file, the application code can be 
the same across different platforms, as the only diference is the 
configuration file that is used/called. The platform specific 
configuration (which pin in y platform corresponds to the warning led?) 
for an application would then be reduced to file management.

The API call that does the processing of these structs parses them and 
does the necessary API calls to setup/update the GPIO hardware as needed.

By having both a struct based interface and direct API call options an 
user can choose what is best for their need. The direct API calls can be 
specially useful for an interactive usage, through a shell program.

The current implementation for the above can be seen in [1], [2] and 
[3]. Note that the gpio.c and gpio.h can be anywhere else at this point, 
as they do not have any rpi code anymore (another question is where they 
could go then?).

A pending issue is related with pin definitions. It would be useful if 
after the pin request to the API, the application could have a 
gpio_pin_id which would be used as a reference to an application pin.

Small example with direct API call:

gpio_pin_id warning_led;

gpio_request_pin(RPI_GPIO_23, &warning_led, DIGITAL_OUT, ..);

gpio_set(warning_led);

The RPI_GPIO_23 would be the platform pin number (the API calculates the 
bank and pin number from this), but after the request the application 
uses the gpio_pin_id to refer to it. The gpio_pin_id would be a simple 
struct filled by the API with the calculated bank and pin numbers, which 
no one else is supposed (or have the need to) to modify/use this struct 
other than to pass it to the API to refer to a pin. This would also 
avoid the constant bank/pin numbers calculation and pin number boundary 
validation that is made currenty in every API call.

A final note would be the need for multiple pin operations. The rpi and 
most platforms (I suppose) allow several pins to be defined on a single 
call, by writting a more complete bitmask to the registers. This could 
be a challenge with the struct approach (maybe by having pin arrays, 
instead of a single pin in the struct, if they all share the same 
configuration). As for direct pin calls maybe through variadic functions.

[1] - 
https://github.com/asuol/rtems/tree/GPIO_API/c/src/lib/libbsp/arm/raspberrypi/gpio
[2] - 
https://github.com/asuol/rtems/blob/GPIO_API/c/src/lib/libbsp/arm/raspberrypi/include/gpio.h
[3] - 
https://github.com/asuol/rtems/blob/GPIO_API/c/src/lib/libbsp/arm/raspberrypi/include/rpi-gpio.h

--André Marques.

On 11-06-2015 15:13, Gedare Bloom wrote:
> On Wed, Jun 10, 2015 at 7:09 PM, Chris Johns <chrisj at rtems.org> wrote:
>> On 11/06/2015 3:01 am, Gedare Bloom wrote:
>>> On Mon, Jun 8, 2015 at 5:44 AM, André Marques
>>> <andre.lousa.marques at gmail.com> wrote:
>>>> Hello,
>>>>
>>>> I have just updated my GSOC blog [1] with a detailed post about how a
>>>> rtems-wide GPIO API could look like, and at the same time exposing the
>>>> current features of the Raspberry Pi GPIO API and how it can evolve to that
>>>> level.
>>>>
>>>> I tried to make it as generic and flexible as possible, but that can be hard
>>>> with the number of platforms where rtems can be used. Api and method naming
>>>> were somewhat overlooked, as well as the definition of possible error codes
>>>> since I am not sure if it would be correct to have a set of error codes for
>>>> this API, or if it should use rtems_status_code, or other.
>>>>
>>>> Current code for the Raspberry Pi GPIO API can be looked at in [2], where I
>>>> am currently carving out the rpi specific code.
>>>>
>>>> I tried to be as clear as possible in the blog, and now I would like to ask
>>>> any interested party to have a look and hopefully point failure points and
>>>> suggestions, or ask for clarifications. It would also be interesting to hear
>>>> the community expectations towards an API such as this one.
>>>>
>>> Great write-up.
>> I agree, it is a nice write up.
>>
>>> Here are some comments/questions:
>>> - The "user application must fill a gpio_pin struct for every pin it
>>> needs" should probably be done through some set of API calls that help
>>> filling out that struct. I'd imagine some alloc with initialization,
>>> and dealloc, with most of the complexity in alloc/init.
>> Being const lets you fill them out when coding as a table which I have
>> found easy to review plus being const has the advantage on small RAM
>> devices of only using ROM type storage which they usually have more of.
>>
>> I think an API to fill the struct in would be confusing and so think at
>> this point in time we should limit what we do.
>>
> OK that is fair. On the other hand, anything we can do to make the
> const initializer easier would be good. I especially was concerned by
> #ifdef's inside the initializer.
>
>> I currently have 3 Zynq variants with similar IO requirements with very
>> different pin selections due to easier PCB routing and I have a separate
>> C file with pin definitions per variant. The resulting user code is
>> clean and simple.
>>
> That makes much more sense, where the struct definition will be pulled
> in through the build system logic to choose the correct file to
> compile.
>
>>> - The bsp_specific pointer might be better implemented with a
>>> zero-length array
>>> [https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html]. Since you embed
>>> the type of the struct, you can tell whether that array should have
>>> any data in it or not.
>>> - I wonder if eventually we can refactor all this to work with the
>>> libdrvmgr. This is a long-term question but might be one worth
>>> thinking about now. (libdrvmgr mainly focuses on providing
>>> abstractions for device drivers that attached to bus-based i/o
>>> protocols. You may like to take a look at its documentation.)
>> I have not looked at that API so I cannot comment but I wonder if this
>> is outside the scope of this GSoC project.
>>
> Definitely outside the scope.
>
>> Chris




More information about the devel mailing list