RTEMS GPIO API

Gedare Bloom gedare at gwu.edu
Sun Jun 21 23:30:06 UTC 2015


On Sun, Jun 21, 2015 at 7:04 PM, André Marques
<andre.lousa.marques at gmail.com> wrote:
> On 16-06-2015 17:54, Gedare Bloom wrote:
>>
>> 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 [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?).
>>>
>> 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
>> landed recently.
>
>
> I have moved it to libbsp/shared, and at this point I think we can start the
> code review process. I have cleaned the code and updated the doxygen and
> comments, should I post a patch here in two parts (one for the generic API,
> and other for the RPI implementation) for review, or should it be done in
> github?
>
Here if you're confident it's ready.

>>
>>> 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.
>>>
>> 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)
>
> I left this out for the moment.
>
>
>>> 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
>>
>> [https://github.com/yangqiao/rtems/commit/38c26a49126e5cff92ae389dba252cb180362c90#commitcomment-11707035],
>> 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
>> struct.
>>
>>> [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
>>>
>>>
>>> _______________________________________________
>>> devel mailing list
>>> devel at rtems.org
>>> http://lists.rtems.org/mailman/listinfo/devel
>
>



More information about the devel mailing list