Skip to content

Conversation

@kapi-no
Copy link
Contributor

@kapi-no kapi-no commented Nov 8, 2019

  • Bluetooth HCI over OpenAMP sample
  • Bluetooth HCI driver over OpenAMP

@jhedberg jhedberg self-requested a review November 8, 2019 14:37
Copy link
Contributor Author

@kapi-no kapi-no left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Highlighting a few unresolved issues

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a DTS symbol for shared memory?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@galak ^^

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, @kapi-no there is DTS information in the nrf5340 DTS structure that points to the shared memory.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I see - there is sram0_shared DT node, but I don't see any alias / define generated for it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to configure channel direction here. However, this syntax does not work

select IPM_MSG_CH_0_TX
select IPM_MSG_CH_1_RX

since IPM_MSG_CH_0_TX is a choice item. How can I work around this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you do what we did with choosing a libc implementation?

Add a layer of indirection by having the user choose something that affected the default choice.

https://github.com/zephyrproject-rtos/zephyr/blob/master/lib/libc/Kconfig#L17

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, the choice option is defined within a Kconfig template file (the template file depends on channel number), so it would be messy to have it there (if possible at all)

https://github.com/zephyrproject-rtos/zephyr/blob/9523043d97ce6ed895a02185378971c67e342846/drivers/ipm/Kconfig.nrfx_ipc_channel

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is also impossible to give a parameterized name to the choice option:
choice IPM_MSG_CH_$(nrfx_ipc_num)_DIR
Kconfig python parser scripts cannot handle that.

With name, I could define the default in the Kconfig board file:

choice IPM_MSG_CH_0_DIR
	default IPM_MSG_CH_0_TX if BT_NRF_OPEN_AMP
endchoice

@carlescufi
Copy link
Member

CC @alexandru-porosanu-nxp

Copy link
Member

@carlescufi carlescufi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A quick naming change request.

Both the driver and the sample should be named hci_rpmsg. This is because RPMsg is the transport, and you don't need OpenAMP on the other side, you can use any other RPMsg implementation instead.

Comment on lines 282 to 285
Copy link
Member

@jhedberg jhedberg Nov 8, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The whole idea of the bt_recv_prio() vs. bt_recv() separation is that they do not happen from the same context (thread). This is particularly important when you're implementing the RX thread on the HCI driver side rather than letting the host do it. In this case bt_recv_prio() should probably be called in whatever context is feeding rx_queue (this queue should only be given non-prio packets) and here in the rx_thread you'd only use bt_recv()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, you're not selecting BT_RECV_IS_RX_THREAD in your Kconfig definition but still creating your own RX thread inside the driver? You need to decide whether you want to keep the thread inside the driver or the host (or perhaps both, which would have a substantial memory overhead). As long as you don't select BT_RECV_IS_RX_THREAD it is actually safe to call the recv() APIs like you're doing since the host-side will take care of splitting processing into independent threads, however if you did mean to select BT_RECV_IS_RX_THREAD then you need to separate them inside the driver.

Copy link
Contributor

@joerchan joerchan Nov 8, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, you're not selecting BT_RECV_IS_RX_THREAD in your Kconfig definition but still creating your own RX thread inside the driver?

That BT_RECV_IS_RX_THREAD option is still poorly named, but the documentation is better.

	# If the host has its own RX thread it is safe to call bt_recv and
	# bt_recv_prio from the same priority context.

Since we call it from the same priority context, we need to select the BT_RECV_IS_RX_THREAD option.

Copy link
Member

@carlescufi carlescufi Nov 8, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't that the other way around? The host has its own RX thread when BT_RECV_IS_RX_THREAD is not enabled

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't that the other way around? The host has its own RX thread when BT_RECV_IS_RX_THREAD is not enabled

Yes. The intention of the current option name is to say "The bt_recv() call happens in the Bluetooth RX thread", which then implies that there's no need for the host to have such a thread. I'm open to better names if you think it's confusing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we call it from the same priority context, we need to select the BT_RECV_IS_RX_THREAD option.

But do you need to call it from the same context? What's the reason there's something called the RX thread inside the driver, and that thread uses the Bluetooth RX thread Kconfig options like BT_RX_THREAD_SIZE. That makes it very much look like "the" Bluetooth RX thread 😄

So, do you need a separate thread like this in the driver? If not, just call bt_recv() and bt_recv_prio() directly from the context that currently feeds the rx_queue and let the host take care of the details. If you do need the separate thread, move the bt_recv_prio() like I suggested and select the BT_RECV_IS_RX_THREAD option.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we call it from the same priority context, we need to select the BT_RECV_IS_RX_THREAD option.

Like Carles said it's actually the opposite. My previous comment was based on imagining a "don't" in the above quote 😄

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't that the other way around? The host has its own RX thread when BT_RECV_IS_RX_THREAD is not enabled

Yes, sorry. Messed it up.

In h4.c bt_recv is called from thread. and bt_recv_prio is called from interrupt.
In the hci_driver.c bt_recv is called from a thread, and bt_recv_prio is called from a different thread with higher priority.
In open_amp_nrf.c bt_recv and bt_recv_prio is called from the same thread.

So h4 and hci_driver both fulfull the requirement of sending from different priority contexts, and can select BT_RECV_IS_RX_THREAD.
This one cannot select it because it it calls them from the same priority context.

So then this is correct.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So then this is correct.

It's not wrong from a HCI driver API contract perspective, but my question still remains: is this "RX thread" in the driver actually needed, and why should it have its stack-size determined by the Kconfig option when it never reaches the application level (that's why the normal RX thread size is user-configurable).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for clarifying. I completely misunderstood your comment. And I think you have a good point (assuming I have understood it correctly :P).

@kapi-no Have you considered getting rid of the TX thread here and calling bt_recv and bt_recv_prio directly from bt_open_amp_rx. In bt_recv we are basically doing the same thing as what is being done here (see here: https://github.com/zephyrproject-rtos/zephyr/blob/master/subsys/bluetooth/host/hci_core.c#L4866). That would mean that bt_recv_prio would be processed in the context of bt_open_amp_rx, which seem to be interrupt context.
So I guess the real question is if there is any downside to calling bt_recv_prio directly from interrupt context (there are other HCI drivers that do exactly that).

Comment on lines 10 to 23
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's this about? I don't think we've had Quark SE support in the tree for quite awhile.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, just get rid of all Quark-related changes @kapi-no

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something went really wrong in the rebase

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this is leftover from rebasing

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rsource?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, I haven't seen anyone else figure out how to do this until now.

Copy link
Contributor

@SebastianBoe SebastianBoe Nov 8, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vipm_nrf_##_idx##_init

We should do as little code generation as possible. Co-incidentally,

vipm_nrf_##_idx##_init is the same for all _idx. So we can have vipm_nrf_n_init, and re-use it for all _idx.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, removed

Copy link
Contributor

@SebastianBoe SebastianBoe Nov 8, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would changing RX to a bool, and having

config IPM_MSG_CH_$(nrfx_ipc_num)_TX
  default ! IPM_MSG_CH_$(nrfx_ipc_num)_RX

help with your issues with choice?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean something along these lines?

menu "IPM Message Channel [$(nrfx_ipc_num)] configuration"

config IPM_MSG_CH_$(nrfx_ipc_num)_ENABLE
	bool "Enable IPM Message Channel $(nrfx_ipc_num)"

config IPM_MSG_CH_$(nrfx_ipc_num)_RX
	bool "IPM Message RX Channel"
	depends on IPM_MSG_CH_$(nrfx_ipc_num)_ENABLE

config IPM_MSG_CH_$(nrfx_ipc_num)_TX
	bool "IPM Message TX Channel"
	depends on IPM_MSG_CH_$(nrfx_ipc_num)_ENABLE
	default ! IPM_MSG_CH_$(nrfx_ipc_num)_RX

endmenu

Yes, getting rid of choice option solves issues with choice :) and I can simply select proper configuration.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think RX and TX could both get enabled with that configuration. I was thinking of having one option promptless to prevent this. But that might not allow you to select from other options as you want.

So I don't really see a clean solution here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I am going to use my suggestion in this PR. It could be improved in other PR if we find a cleaner way of doing it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rsource

joerchan
joerchan previously approved these changes Nov 8, 2019
@zephyrbot
Copy link

zephyrbot commented Nov 8, 2019

All checks are passing now.

checkpatch (informational only, not a failure)

-:53: WARNING:LEADING_SPACE: please, no spaces at the start of a line
#53: FILE: boards/arm/nrf5340_dk_nrf5340/nrf5340_dk_nrf5340_shared_sram_planning_conf.dts:15:
+    chosen {$

-:55: WARNING:LEADING_SPACE: please, no spaces at the start of a line
#55: FILE: boards/arm/nrf5340_dk_nrf5340/nrf5340_dk_nrf5340_shared_sram_planning_conf.dts:17:
+      zephyr,ipc_shm = &sram0_shared;$

-:56: WARNING:LEADING_SPACE: please, no spaces at the start of a line
#56: FILE: boards/arm/nrf5340_dk_nrf5340/nrf5340_dk_nrf5340_shared_sram_planning_conf.dts:18:
+    };$

- total: 0 errors, 3 warnings, 1678 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
      mechanically convert to the typical style using --fix or --fix-inplace.

Your patch has style problems, please review.

NOTE: Ignored message types: AVOID_EXTERNS BRACES CONFIG_EXPERIMENTAL CONST_STRUCT DATE_TIME FILE_PATH_CHANGES MINMAX NETWORKING_BLOCK_COMMENT_STYLE PRINTK_WITHOUT_KERN_LEVEL SPLIT_STRING VOLATILE

NOTE: If any of the errors are false positives, please report
      them to the maintainers.

Tip: The bot edits this comment instead of posting a new one, so you can check the comment's history to see earlier messages.

@ioannisg ioannisg added the TSC Topics that need TSC discussion label Nov 9, 2019
@ioannisg ioannisg marked this pull request as ready for review November 9, 2019 13:33
@carlescufi
Copy link
Member

@jhedberg @arnopo @dbkinder can you please take another look?

Copy link
Member

@ioannisg ioannisg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty good now, approved.
@kapi-no can you take care of the minor issues i have spotted i the last pass?

@carlescufi carlescufi dismissed stale reviews from dbkinder and arnopo November 15, 2019 12:24

Stale, please re-review

/* Since we are using name service, we need to wait for a response
* from NS setup and than we need to process it
*/
virtqueue_notification(vq[0]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems useless. when called remote processor still not ready to send the NS message, so nothing to process in queue.
Application will be blocked on sync_sem waiting rpmsg from the remote side.
ipm_callback should call the virtqueue_notification that will process message and call the ns_bind_cb

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right - this is redundant.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

static void ipm_callback(void *context, u32_t id, volatile void *data)
{
BT_DBG("Got callback of id %u", id);
virtqueue_notification(vq[0]);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue, processing in interrupt context

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to switch context for virtqueue_notification from ISR to the workqueue context, but oddly enough this triggers MPU fault.

There is a flash write attempt that crashes the application. It occurs inside sys_dlist_remove in the k_sys_work_q context. Do you see any potential scenario in which the MPU fault could be caused by OpenAMP library (e.g. pointer corruption)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, using a dedicated thread to process virtqueue_notification seems to work.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you are sending a message you can take rdev->lock (rpmsg_virtio_send_offchannel_raw). And ipm_callback is called you will treat received messages , try to take rdev->lock a second time(rpmsg_virtio_rx_callback) => deadlock
yes using a dedicated thread is a good solution

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a dedicated thread for virtqueue_notification

@kapi-no
Copy link
Contributor Author

kapi-no commented Nov 19, 2019

@arnopo, please rereview

ioannisg and others added 11 commits November 19, 2019 14:50
We are adding code owners for the Nordic nRFx IPM
driver files.

Signed-off-by: Ioannis Glaropoulos <[email protected]>
This commit contributes the nRFx IPM driver.

Signed-off-by: Karol Lasończyk <[email protected]>
This commit adds ipc-0 aliases in the DTS framework
for nRF5340 Application and Network MCU.

Signed-off-by: Emil Obalski <[email protected]>
The interprocessor communication can be based on shared memory.
Allow to declare this memory as with a generic name derived from
chosen declaration.

Signed-off-by: Arnaud Pouliquen <[email protected]>
Bound shared memory definition with IPC shim for nRF5340 DK.

Signed-off-by: Kamil Piszczek <[email protected]>
The HCI transport implemented by an application using the HCI raw
interface may have its own buffer headroom requirements. Currently the
available headroom gets completely determined by the selected HCI
driver. E.g. most of the time this is the native controller driver
which doesn't reserve any headroom at all.

To cover for the needs of HCI raw users, add a new Kconfig variable
for the apps to set to whatever they need. Correspondingly, use the
maximum of the HCI driver and HCI raw headroom requirements for the
buffer pool definitions and the headroom initializations.

Signed-off-by: Johan Hedberg <[email protected]>
This commit contributes a BLE HCI-over-RPMsg sample.

Co-authored-by: Kamil Piszczek <[email protected]>
Co-authored-by: Nikodem Kastelik <[email protected]>

Signed-off-by: Kamil Piszczek <[email protected]>
This commit contributes an RPMsg-based transport for BLE HCI.

Signed-off-by: Kamil Piszczek <[email protected]>
When building with support for BLE stack, enable the Vendor Specific
commands for the nRF5340 APP CPU (Application MCU).

Signed-off-by: Kamil Piszczek <[email protected]>
When building with support for BLE stack, enable the BT_ECC
for the nRF5340 NET CPU (Network MCU).

Signed-off-by: Kamil Piszczek <[email protected]>
When building with support for BLE stack on the nRF5340 APP CPU
(Application MCU), use RPMsg HCI driver by default.

Signed-off-by: Kamil Piszczek <[email protected]>
@carlescufi carlescufi merged commit 2cceb62 into zephyrproject-rtos:master Nov 20, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: API Changes to public APIs area: Bluetooth area: Boards area: Devicetree area: Samples Samples TSC Topics that need TSC discussion

Projects

None yet

Development

Successfully merging this pull request may close these issues.