GithubHelp home page GithubHelp logo

Comments (12)

jannic avatar jannic commented on September 2, 2024 2

From my point of view, the API should prevent easy mistakes like forgetting to initialize a clock that's needed for a peripheral, or changing a clock that's in use by a peripheral by accident, eg. due to some copy & paste mistake. That goal is covered by the current API quite well.

But then, the API should not prevent more advanced use cases where the clocks are intentionally changed while being in use. Ideally, such a facility should still only allow changes that are supported by the hardware. But if it is too difficult to distinguish between valid and invalid changes programmatically, adding more "dangerous" methods would be fine as well, as long as they are clearly recognizable as such. Eg. by giving them names like *_unchecked() and describing the limitations in the docs.

Currently, the only way to get around the API limitations is using unsafe code. That's fine for really unconventional use cases, but has the big disadvantage that it opens the door for accidentally causing undefined behavior. Some middle ground that is more lenient configuration-wise, but still provides the full soundness guarantees of safe rust, is still missing.

from rp-hal.

jnthbdn avatar jnthbdn commented on September 2, 2024

I just found something very strange... Why does the new function of RealTimeClock need the ownership of rtc_clock, since in the code we're just reading the frequency (where a simple reference would be sufficient)?

let freq = clock.freq().to_Hz() - 1;

from rp-hal.

ithinuel avatar ithinuel commented on September 2, 2024

Hi,

Why does the new function of RealTimeClock need the ownership of rtc_clock, since in the code we're just reading the frequency (where a simple reference would be sufficient)?

In some cases this is to (try to) prevent other parts of the firmware from changing the frequency/settings of the clock source.

The clock related code is admittedly not yet very polished. On the other hand, this is a fairly complex topic to address as not all solutions are really practical for the common usecase the hal is used in (eg RTIC application, low power/deepsleep, some level of DFS) while still meeting the requirement from the hardware interms of clock state, stability, and dependencies.

We welcome contributions that could help resolve (at least some of) the issues.
We currently have a few "in flight" PR up for review and testing:

from rp-hal.

jnthbdn avatar jnthbdn commented on September 2, 2024

Hi,

In some cases this is to (try to) prevent other parts of the firmware from changing the frequency/settings of the clock source.

Indeed, it makes sense, but in this case it invalidates the ClockManager, and IMO that's not a good idea.

I therefore see three solutions to this problem:

  • define all the ClockManager fields as options, which is a breaking change.
  • duplicate the ClockManager and implement the previous point
  • modify the RealTimeClock function so that it takes a reference instead of the property.

The last solution is the simplest, and the hal seems to work this way (for example, the setup_pll_blocking function only takes a reference from the ClockManager).

from rp-hal.

jnthbdn avatar jnthbdn commented on September 2, 2024

I just found there is a similar idea in UsbBus...

_pll: UsbClock,

Once again it invalidate your ClockManager, and you lost (forever) the usb_clock field.

from rp-hal.

ithinuel avatar ithinuel commented on September 2, 2024

The typical flow is to:

  1. Setup the clock
  2. Instantiate the peripherals (rtc, usb etc)
  3. don't change the clock

Taking ownership of the clock implicitly freezes the clock's settings.
An option could be that we make all peripherals take ownership of their clock source. Shared clocks, like sys_peri, could be backed by an atomic reference counter behind the scene.

If a user desires the change the clock's config, they'd need to recover those clocks (by disabling or freeing the peripherals), do what ever they want with the clock, and then reenabling or reconstructing the peripheral(s).

We could apply such pattern over all the drivers, but implementing this would be an endeavour going beyond my current time capacity.

from rp-hal.

jnthbdn avatar jnthbdn commented on September 2, 2024

I don't totally agree with the idea of blocking clocks when a device is instantiated. In my mind, clocks remain independent of devices, and changing a clock doesn't necessarily impact the operation of the device. It might even be possible to disable (or reduce the speed of) a device if necessary (if only temporarily, as I think that's how it's presented in the datasheet).
For example, if you want to switch to DOMANT mode, the datasheet specifies that you have to switch off the PLLs manually (except pll_sys, if I've understood correctly). So the PLL_USB must be stopped, but that doesn't mean you have to destroy the UsbBus instantiation, just stop its clock, and restart it when you wake up.

from rp-hal.

ithinuel avatar ithinuel commented on September 2, 2024

but that doesn't mean you have to destroy the UsbBus instantiation, just stop its clock, and restart it when you wake up.

Well, USB is a good example for that matter. If you stop the USB clock, you effectively break the communication with any connected host.

It might even be possible to disable (or reduce the speed of) a device if necessary

You can indeed stop or reduce the speed of a clock according to the datasheet.
But for example, all the UART, SPI and I2C driver are configured in terms of frequency/baudrate and the implementation guaranties that this is what the bus will run at.
But all those speeds are in reality relative to the clock source of that peripheral.

Changing the frequency of that clock, breaks an invariant and the driver's guaranties are rendered obsolete without any way to let the developer know about it.

What I'd like to achieve is not necessarily a perfect API but at least something that prevents easy foot guns such as stopping or changing the frequency of a clock while a peripheral is in operation (eg changing the baudrate in the middle of a transmit/receive).

from rp-hal.

jnthbdn avatar jnthbdn commented on September 2, 2024

Well, USB is a good example for that matter. If you stop the USB clock, you effectively break the communication with any connected host.

Exactly! You deactivate the clocks, so the USB is stopped, and when you restart your clock the USB resumes. It seems to me that this is the very use case for clock enable in the clock tree (2.15 datasheet).
(It's the clocks that drive energy consumption, not necessarily the peripherals.)

I quite agree with @jannic that this seems a good compromise. There should be a system in the ClockManager that checks whether a clock is "busy". But under no circumstances should a clock be "owned" by another instance. So we could imagine having *_unchecked functions.

from rp-hal.

ithinuel avatar ithinuel commented on September 2, 2024

Exactly! You deactivate the clocks, so the USB is stopped, and when you restart your clock the USB resumes. It seems to me that this is the very use case for clock enable in the clock tree (2.15 datasheet).

It doesn't just resume. The usb protocol is broken. The host has lost communication with the device. A whole renumeration process needs to be resumed. Any "class level" protocol has to start again from scratch.
Some class are to some extents resilient to that (HID, CDC) but thing may go terribly wrong with things like MSD.

There should be a system in the ClockManager that checks whether a clock is "busy".

Indeed, what I refered to earlier is one solution to that.

But under no circumstances should a clock be "owned" by another instance.

I don't agree with that statement though. This seems to be a strong statement without strong reasons beyond we don't currently have a nice API.
Note that I'm NOT saying that peripherals should own their reference clock. Only that under no circumstances is too strong a requirement.

I quite agree with @jannic that this seems a good compromise. [...] So we could imagine having *_unchecked functions.

Indeed, that could be a satisfying "temporary" solution until something better is proposed.
Although I like when things are consistent, not all peripherals may need the same sort of API.

from rp-hal.

jnthbdn avatar jnthbdn commented on September 2, 2024

Only that under no circumstances is too strong a requirement.

Sorry, English isn't my mother tongue, and in translation, certain terms can become a bit... excessive ^^.

I honestly don't know how to create such a mechanism. But to avoid any breaking changes, I suggest modifying my PR and adding the free function to UsbBus and RealTimeClock.

from rp-hal.

jnthbdn avatar jnthbdn commented on September 2, 2024

Partial fix with #725

from rp-hal.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.