Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support peripheral deallocation at runtime #20012

Open
gon1332 opened this issue Oct 22, 2019 · 11 comments
Open

Support peripheral deallocation at runtime #20012

gon1332 opened this issue Oct 22, 2019 · 11 comments
Assignees

Comments

@gon1332
Copy link
Contributor

gon1332 commented Oct 22, 2019

Is your feature request related to a problem? Please describe.
Until now, Zephyr allows enabling of the needed peripherals at compile time via Kconfig infrastructure. This is done to reduce code size. In this way the firmware expects that the needed peripheral devices are connected. If the devices are not connected, e.g. a disconnected shield, the firmware can handle this by omitting reading from this port.

The downside to this one is increased power consumption. The GPIO pins have already been initialized in a mode that expects active connection (UART, I2C). These pins are floating and their state is not power efficient. Also clocks for the peripherals have been enabled, so also these should be disabled.

Describe the solution you'd like
I would like to have a driver API like some_peripheral_deinit. This will for sure disable the peripheral's clock. Either called by the user after a failed call to device_get_binding, or automatically in the driver's init(). The last case could be mapped to a Kconfig symbol.

The above is easy for the peripheral's clocks. For the GPIOs needed to be disabled some extra DTS fixups should be added for each peripheral to make them accessible.

Describe alternatives you've considered
Currently I'm doing the whole procedure either at application level, after checking a device_get_binding(). I've also done some of the solution previously described in a private clone.

Additional context
The use case I want to achieve is to have a dynamic firmware that on board power checks ports for known to-be-connected devices (UART, I2C). If there isn't a connected device then disables the port to reduce power consumption. For this kind of application I don't care for code size. I enable a big number of supported peripherals and then sense which are connected.

@gon1332 gon1332 added the Feature Request A request for a new feature label Oct 22, 2019
@tbursztyka
Copy link
Collaborator

There is no need to add anything to the device API. This is a PM issue.

However, I would not say it is possible to do it with the PM API at the moment. It's far from being usable (this is a known issue).

@StefJar
Copy link

StefJar commented Jan 21, 2020

I am agreeing on @gon1332 view.

Like to give some examples where at least a deinit function is quite useful.

1.) sleep modes: To disable the peripherals to save some energy
2.) error states/partial failure of the pcb: After production and delivery the device/pcb gets broken. We can detect the error state and would like to put the device into save operation mode
3.) production/self test: the pcb gets assembled, we have some self test/production state for the firmware. For these tests we like to reconfigure the devices or disable the devices

@tbursztyka even in the linux kernel you can unload the kernel modules/disable them.

I think on the long run this adds well to the Zephyr API.

@pabigot
Copy link
Collaborator

pabigot commented Jul 7, 2020

API 2020-07-07: Closing as duplicate of #19448 which covers specifying which devices are to be present but not started, and ties to the ability turn devices off (for power management). Please add to that issue any requirements from this that are not implicitly or explicitly addressed.

@pabigot pabigot closed this as completed Jul 7, 2020
@carlescufi
Copy link
Member

Reopening this issue since this has not been addressed.

@tbursztyka
Copy link
Collaborator

I am yet to be convinced that current init procedure and PM would not be able to handle that case described in the very first comment. Now that PM has/is being reworked deeply, it seems to be fully suited for this.

Or: is it also wanted to avoid any successful device_get_binding() on the device afterwards? This is not clearly stated anywhere above, apart from @StefJar's comment comparing linux and zephyr somehow. This is quite different actually: the device is put off AND is non-accessible as well (so a device_deinit() would first call PM OFF state and then set state->initialized to false I guess)

I am just trying to be conservative here. If PM really cannot fix this, then yes perhaps we could add something.
Let's just avoid adding function that users would miss-use (like de-initializing to save power... no PM IS meant to do just that).

@danielstuart14
Copy link
Contributor

I'll give here one example of use of deinit:
-> Use peripheral GPIOs for other functionality (Ex: On my current project, I have to use the slave SPI CS pin for waking up the main controller when it's sleeping. I can do it using the Nordic driver (as it supports deinit), but not with the zephyr driver)

@carlescufi carlescufi moved this from Todo to In Progress in Architecture Review Nov 20, 2023
@zephyrbot zephyrbot added Needs review This PR needs attention from Zephyr's maintainers and removed Needs review This PR needs attention from Zephyr's maintainers labels Feb 8, 2024
@zephyrbot
Copy link
Collaborator

Hi @gmarull, @ceolin,

This issue, marked as an Feature Request, was opened a while ago and did not get any traction. It was just assigned to you based on the labels. If you don't consider yourself the right person to address this issue, please re-assing it to the right person.

Please take a moment to review if the issue is still relevant to the project. If it is, please provide feedback and direction on how to move forward. If it is not, has already been addressed, is a duplicate, or is no longer relevant, please close it with a short comment explaining the reason.

@gon1332 you are also encouraged to help moving this issue forward by providing additional information and confirming this request/issue is still relevant to you.

Thanks!

@CodeFatherG
Copy link

@carlescufi I see that this issue has been passed around a lot but no plan has been made.

I landed on this issue after trying to find driver deinitialisation. My use case would be that a device has general purpose IO/ADC inputs that are configured in runtime over some communication transport to the device. In one operating mode the pin could be an input for a push button, however, in another mode its an output for a LED that tracks the state of something. In yet another mode it's an I2C bus for a peripheral.

The hole in my design is how, using zephyr, I am able initialise and deinitialise drivers (gpio, led, i2c, etc) in runtime based on some configuration state changing? The project is currently implemented using the old nRFSDK5 implementation.

It is not clear to me how this is meant to be done in the zephyr space, hence I am necroing one of the only open tickets I could find referencing deinitialisation

@madone8
Copy link

madone8 commented Aug 9, 2024

I'd also like to add my support for this feature. I have a product where a microcontroller is an SPI master but needs to occasionally release control of the SPI bus so that a different device can be the master (firmware updates etc).

In this case, I need to be able to completely release the SPI lines (configured to input/tri-state).

I am more than willing to help out (code submissions, testing etc) if a plan/roadmap can be put in place.

@benediktibk
Copy link
Collaborator

@gmarull I have got another issue which relates to this: #77980

Here SPI pins are optionally used for bitbanging and it is necessary to reinitialize the pins afterwards into the correct state. Therefore it could be used with something like a deinit and reinit.

@benediktibk
Copy link
Collaborator

Would it be valid and feasible to start using PM for this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: In Progress
Development

No branches or pull requests