-
Notifications
You must be signed in to change notification settings - Fork 8.2k
drivers: i2c_nrfx_twim: add exclusive access API #86721
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
Conversation
0b23af0 to
3f3004c
Compare
|
This problem of wanting to start transfers from an ISR was solved in a general way with .submit already using lock-free queues, is there some reason we need to add a custom API here? I believe @bjarki-andreasen added support for this in fact |
|
@teburd Well, @JordanYates added RTIO support to the TWIM, I added an RTIO I2C sample an a few patches :) @ankuns See https://github.com/zephyrproject-rtos/zephyr/tree/main/samples/drivers/i2c/rtio_loopback Is there a reason not to use RTIO? |
|
@bjarki-andreasen , does the I2C RTIO support operation on ZLI priority? My use case is that I need to perform I2C transfers in a time window given by a scheduler external to Zephyr. I get the notification from the scheduler in ZLI interrupt. The scheduler does not tolerate any delays. |
|
rtio is completely detached from thread scheduler with two ways to opt into getting threads to wait for completions if needed. You can start interrupts from any context, including ZLI interrupts. The entire thing is built on a lock-free queue of I/O like work given to a driver. This can be done at any time, from any where. Safely! |
Not tolerating delays on a shared bus does not seem to be a valid requirement, what if there is already a transaction in progress? In that case you will still need to wait for the transaction to be complete before aquiring the bus. Seems like the solution is to not share the bus in the first place :) |
|
Please add tests/samples with use cases you have described. |
Are you certain it is safe from ZLIs? zephyr APIs can not be used safely from ZLIs, since the kernel has no way of synchronizing access to data, given ZLIs can not be masked by the kernel (k_spin_lock, k_sem, k_mutex etc. are not safe, they don't prevent ZLIs from accessing the same resource). Hacks like zephyr/drivers/clock_control/clock_control_nrf2_hfxo.c Lines 81 to 96 in fb4bb5d
|
@bjarki-andreasen I call the |
|
@teburd Bad question, can we introduce a lock to RTIO :D Maybe we could have a An initial proposal: if the sqe when submitted is already signaled, its is treated as a nop :) |
Yes, I'm positive. Submit work to the device driver from any context, regardless of above Kconfigs (lock free queue push) rtio_submit(r, 0); /* Submit asynchronous work to do, can be done from *anywhere* including a ZLI */ Now if you need the completion interrupts (e.g. i2c transfer complete IRQ) be a ZLI then you would need to turn off the semaphores and poll the queues rather than having threads wait, but this seems unlikely. E.g. CONFIG_RTIO_CONSUME_SEM=n ZLI I2C completion IRQ.. rtio_cqe_submit(...);Wait for completion of work from a thread, using polling on the atomics (lock free queue pop). /* In a thread somewhere... wait on a completion */
struct rtio_cqe *cqe;
do {
cqe = rtio_cqe_consume(r);
} while (cqe == NULL); |
Exclusive access is not something built into the current APIs. We could add it to RTIO, and it would need to be asynchronous acquire/release kind of pairing to work correctly because there may be asynchronous transactions already in flight still. So to do that we'd want basically a RTIO_SQE_ACQUIRE_OP and RTIO_SQE_RELEASE_OP pair, which could lend out and return an exclusively owned iodev the user could submit work to. Only this exclusive queue would be pulled from while its checked out. This sort of pattern would require one more struct rtio_iodev, basically a mpsc queue head (I believe two pointers) be stored in the device data struct and loaned out when asked for, used exclusively when loaned. |
3f3004c to
e79b334
Compare
This commit provides an extension to the i2c_nrfx_twim driver. It introduces possibility to acquire/release exclusive access to the i2c bus. While the exclusive access to the i2c bus is acquired you can access the underlying nrfx_twim driver directly. Signed-off-by: Andrzej Kuros <andrzej.kuros@nordicsemi.no>
e79b334 to
e398816
Compare
|
@carlescufi @anangl @bjarki-andreasen @nika-nordic according to the internal discussion the PR is changed so that only the |
|
Reassigned as it isn't really a question of i2c anymore |
|
ping @anangl |
This commit provides an extension to the i2c_nrfx_twim driver. It introduces possibility to acquire/release exclusive access to the i2c bus.
Background:
The need for such feature comes from nRF Connect SDK, where i2c write transfers (on nRF SoCs only) must be performed while having a timeslot granted by a scheduler external to Zephyr. The scheduler has very strict timing requirements, which cannot be met if i2c transfers are performed from a thread context (even of the highest priority). The solution is to make i2c transfers asynchronous relying only on underlying nrfx_twim driver from ZLI priority. To make this approach work with regular i2c.h - compatible drivers exclusive access to the i2c bus is necessary.
Usage:
From a thread context call
i2c_nrfx_twim_exclusive_access_acquireThen perform nrfx_twim direct access calls of your choice, possibly asynchronous transfers.
From a thread context call
i2c_nrfx_twim_exclusive_access_release