Hello Duc,

Am 27.06.22 um 05:34 schrieb Duc Doan:
Hello Karel and Christian,

I am thinking of this way: referring to a pin using a number. Each BSP
will map that pin number to its specific port and pin. For example, for
STM32F4 which has 16 pins per GPIO port, pin 6 will correspond to GPIOA
pin 6, and pin 20 will correspond to GPIOB pin 4. The get controller
function will be as follow:

That numbering scheme is used by for example Linux. Seems to work for them as an universal one so I don't think that we should get problems.

Please think about whether you want to start at 0 or at 1!


rtems_gpio_ctrl_t *bsp_gpio_get_ctrl(uint32_t pin);

This function must be implemented by each BSP. This will take the pin
number and return the corresponding controller object. The example
application could be as follow:

rtems_gpio_ctrl_t *ctrl0 = bsp_gpio_get_ctrl(60); //corresponds to
GPIOD pin 12 on F4

rtems_gpio_write(ctrl, 60, RTEMS_GPIO_PIN_SET);

Be really careful with that syntax. If you use increasing numbers like you suggested, every controller would have to know it's own offest. On the other hand, if there is a unique number to each pin, you don't necessarily need the "ctrl" pointer at all. You can just use something like

   rtems_gpio_write(60, RTEMS_GPIO_PIN_SET);

That's an advantage from the usage perspective because you don't have to fetch the GPIO controller and can work with a single pin number.

Disadvantage is a overhead in the API: You have to create some global table with GPIO controllers and their first and last pins. That table has to be searched for every operation. In the worst case it adds a loop over the table with one comparison for each entry. Most systems should only have a hand full of GPIO controller so it's not too much but it's a lot more than just one pointer de-referencing. There could be methods to optimize the search so the loop might isn't the best solution. But every search is slower than if you already have the pointer.

It's more or less a trade-off. There are good arguments for both directions. I think I have seen both directions implemented in different situations.


This, however, only returns integrated GPIO from a BSP. In order to use
a GPIO expansion, a separate function must be used. Each GPIO expander
driver will have its own get_ctrl function. For example, when using 2
different expanders exA and exB:

rtems_gpio_ctrl_t *exA_ctrl = exA_get_ctrl(pin);
rtems_gpio_ctrl_t *exB_ctrl = exB_get_ctrl(pin);

What would be the pin numbers in that case? You mentioned that the STM32F4 has 16 pins per GPIO. Let's assume it's 4 GPIOs so the last internal GPIO would be 16*4-1=63. Would the first registered expander have pin numbers starting at 64 or again at 0?

I would strongly suggest to use the same method for internal and external GPIOs. If you start with 0 for an expander, start with 0 for each internal GPIO controller too (in the STM example: You should have 4 internal pins with the number 0). If you plan to have an increasing number, use that for the external GPIO controllers too.

Best regards

Christian


I think this method will assure that it compiles and works on all BSPs
but needs an additional function to get the controller of an expander.
A drawback might be added computation because of translating abstract
pin number to physical pin/port.

What do you think about this?

Best,

Duc Doan

On Sun, 2022-06-26 at 20:48 +0200, Karel Gardas wrote:
On 6/26/22 10:49, Duc Doan wrote:
#define rtems_gpio_get_ctrl(_driver, _arg, _out) \
       _driver##_gpio_get_ctrl( _arg , _out )

In the application code:

rtems_gpio_get_ctrl(stm32f4, GPIOD, &led_ctrl);
rtems_gpio_get_ctrl(stm32f4, GPIOA, &button_ctrl);

It's only a different method of writing the same. It won't solve
Karels
problem because it still wouldn't compile on another BSP.


Do you mean this application code should compile on other BSPs
without
changing the source?

Yes, that's exactly what portability means and that's exactly what is
desired outcome of the API here -- if I'm not mistaken in your
project
outcome specification. :-)

I'm not expert here, so please bear with me, but as I see it, you
will
need to come with some abstraction for groups and pins and write API
around it. Then in BSP you will perform/provide a mapping between
your
abstracted group/pins construct and between actual hardware. This
way,
if I take example from stm32f4 and try to compile on rpi4, it will
compile well -- but it will not run well (probably!) of course. But
API
wise, it will compile. Now, to make it run, I'll need to connect LED
example following BSP specific mapping and for that I need to consult
BSP docs.

I am a bit confused about that because I thought
at least we still need to specify the pin/port. And if we have
multiple
GPIO controllers, we still need to select one right?

Yes, and this needs to be done in abstract manner mapped down into
actual BSP implementation code. Abstract mapping here ensure
portability
between BSPs/boards.

E.g. for stm32f4 you do not select GPIOA group and pin1, but you
select
group 0 and pin 1 and in f4 BSP this group 0 is mapped to GPIOA and
pin
1 is mapped to its pin 1. -- something like that.

Karel

_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

--
--------------------------------------------
embedded brains GmbH
Herr Christian MAUDERER
Dornierstr. 4
82178 Puchheim
Germany
email:  christian.maude...@embedded-brains.de
phone:  +49-89-18 94 741 - 18
mobile: +49-176-152 206 08

Registergericht: Amtsgericht München
Registernummer: HRB 157899
Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
Unsere Datenschutzerklärung finden Sie hier:
https://embedded-brains.de/datenschutzerklaerung/
_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Reply via email to