jerabaul29 / OpenMetBuoy-v2021a

An easy to build, affordable, customizable, open source instrument for oceanographic measurements - with global Iridium coverage
MIT License
37 stars 7 forks source link

peripherals manager #8

Open jerabaul29 opened 2 years ago

jerabaul29 commented 2 years ago

@gauteh I am building now something I felt I mess in the previous version of the buoy - a way to keep track of whether a peripheral is in use or not, to talk to which devices, and how this knowledge should be used to swith the peripheral on / off.

This is what I am implementing here:

https://github.com/jerabaul29/OpenMetBuoy-v2021a/blob/feat/platformio-tracker-add-peripheral-manager/tracker/lib/peripheral_manager/peripheral_manager.h

https://github.com/jerabaul29/OpenMetBuoy-v2021a/blob/feat/platformio-tracker-add-peripheral-manager/tracker/lib/peripheral_manager/peripheral_manager.cpp

If you have any comments / criticisms / thoughts etc, as usual will be happy to hear, but as usual no problem if you are too busy to look at it :) .

gauteh commented 2 years ago

This is a bit similar to a bus manager, or shared_bus in rust (but without the power management of the device). You probably have to assume that the PeripheralManager or BusManage(?) will be used from multiple threads, so it needs to use a cortex-m mutex (essentially using interrupt_free context), see the shared-bus source code.

One way to do this is to wrap the I2C device in the BusManager, then you can hand out new leases to it to each device and the bus manager will synchronize their access. Both sharing the I2C bus and doing power-management at the same time might complicate the design, maybe it should be two split in two concepts?

jerabaul29 commented 2 years ago

Many thanks for the comments :) . I think I will work with the hypothesis that it is single threaded so far :) . When not using a RTOS the code is single threaded except for the interrupts, and this is not some operations that should be done from within an interrupt. What do you think?

gauteh commented 2 years ago

Yeah. Just reading from the same I2C bus in an interrupt - say sampling the IMU from RTC or new-sample-interrupt will be unsafe unless you sync the bus access.

jerabaul29 commented 2 years ago

Right, I had not thought about that, thanks. I will think a bit extra about it. My idea originally was to use this manager to only keep track of switching things on and off, but I see what you mean. Thanks! :)

jerabaul29 commented 2 years ago

This is really interesting - I am so used to the arduino way of thinking, where we do "everything" in a single thread, and interrupts are not used for "hidden multithreading", that I forget that such things can happen ^^ :) .

I have one worry, and it is that, given that I use arduino libraries that are often quite "low quality" / not thought for ISR driven mutlithreading, if I start doing things more complex than updating a counter from an ISR (like, if I communicate with a device on I2C / SPI from within an interrupt), things will likely break (like, getting stuck in an ISR, because it relies on some delay that is implemented using an ISR, or something like this). So I think I will avoid doing stuff like reading a device from an ISR, and instead have my own hand-engineered "event loop" of some kind. This is a poor man's fix, but I think I am stuck there as long as I remain in the arduino ecosystem - and I think alternatives are not fully mature yet, and anyways I do things that go quite slow, so arduino ecosystem is good enough to me so far :) . But many thanks, will keep it in head.

I will update the documentation to make this clear :) .

jerabaul29 commented 2 years ago

Actually, the library for the 6dof for example looks very good; I think I will implement what you suggest here, as there should be no issues using the library from withing an ISR triggered context.

So what I plan would be to implement things so that:

I have to think if I create 2 methods (loan and give_back), or if I build an additional object to do RAII.

Anything I am missing @gauteh ? :) (and thank you again for your patience and explanations :) ).

gauteh commented 2 years ago

If you are the sole owner (own with mutability in rust) you don't need to protect it with the mutex (that is you have no other devices on the same I2C bus, and can pass it to the ISR). Otherwise Mutex (implemented using interrupt guards) works!