RTEMS GPIO API
gedare at gwu.edu
Tue Jun 16 16:54:13 UTC 2015
On Tue, Jun 16, 2015 at 8:14 AM, André Marques
<andre.lousa.marques at gmail.com> wrote:
> 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 ,  and .
> 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
I think the first place to migrate shared code is libbsp/shared. After
that, we can consider whether the code is generic enough to put in
cpukit, which is where other driver frameworks (i2c, libdrvmgr) have
> 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, ..);
> 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.
That makes sense. You could define an opaque type to store the
identifier. However, if it is a struct, passing it by value could be
an expensive operation, so care should be taken there. (If you can fit
it in 32-bits, you can union the gpio_pin_id with a uint32_t)
> 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.
I just got done writing about zero-length arrays for Yang Qiao
but perhaps you could use something similar albeit simpler in this
case too. You define the pin as a zero-length array (it should always
be at least 1 though), and then include the number of pins in the
>  -
>  -
>  -
> --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:
>>>>> I have just updated my GSOC blog  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
>>>>> I tried to make it as generic and flexible as possible, but that can be
>>>>> with the number of platforms where rtems can be used. Api and method
>>>>> were somewhat overlooked, as well as the definition of possible error
>>>>> since I am not sure if it would be correct to have a set of error codes
>>>>> 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 ,
>>>>> 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
>>>>> any interested party to have a look and hopefully point failure points
>>>>> suggestions, or ask for clarifications. It would also be interesting to
>>>>> 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
>>>> - 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.
> devel mailing list
> devel at rtems.org
More information about the devel